Открытие JXDatePicker при получении фокуса

Я пытаюсь расширить JXDatePicker, чтобы он открывался, когда он получает фокус. Искал предложение, которое я понимаю, но безуспешно. Есть ли элегантный способ сделать это?


person Tony Wolff    schedule 18.03.2013    source источник
comment
как всегда с JSomething: не расширять :-) И как всегда с составными компонентами: регистрация низкоуровневых слушателей должна выполняться на соответствующем дочернем элементе, а не на родительском (так же, как с редактируемым комбо)   -  person kleopatra    schedule 19.03.2013
comment
Я новичок в Java, где-то я могу получить такой совет. В частности, выяснить, почему не следует расширять JSomething, казалось неплохой идеей, и я делал это для ряда других компонентов с очевидным успехом :-) Какая катастрофа меня ждет впереди?   -  person Tony Wolff    schedule 19.03.2013
comment
@kleopatra aaaach пожалуйста :-) этот ответ ничего не говорит о том, что действие показывает JXxxXxxPopup с JXMonthPanel :-)   -  person mKorbel    schedule 19.03.2013
comment
это простые основы объектно-ориентированного программирования :-) @mKorbel эээ .. что вы пытаетесь мне сказать?   -  person kleopatra    schedule 19.03.2013
comment
@клеопатра ............... :-)   -  person mKorbel    schedule 19.03.2013


Ответы (2)


Удивительно, но это невозможно :-(

На этот раз у самого JXDatePicker нет API для отображения/скрытия всплывающего окна (есть только у BasicDatePickerUI). Кроме того, у делегата пользовательского интерфейса есть какая-то внутренняя магия (читай: хаки... кашель), которая делает FocusListener еще хуже в обращении, чем обычно в составных компонентах.

Фрагмент для игры:

final JXDatePicker picker = new JXDatePicker();
FocusListener l = new FocusListener() {

    @Override
    public void focusGained(FocusEvent e) {
        // no api on the picker,  need to use the ui delegate
        BasicDatePickerUI pickerUI = (BasicDatePickerUI) picker.getUI();
        if (!pickerUI.isPopupVisible()) {
            pickerUI.toggleShowPopup();
        }
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                // opening the popup moves the focus to ... ? 
                // need to grab it back onto the editor
                picker.getEditor().requestFocusInWindow();
            }
        });
    }

    @Override
    public void focusLost(FocusEvent e) {
    }
};
// need to register the listener on the editor
picker.getEditor().addFocusListener(l);
JComponent content = new JPanel();
content.add(new JButton("dummy"));
content.add(picker);

Не совсем удовлетворительно, так как автоматическое закрытие всплывающего окна при перемещении фокуса out снова не работает надежно, нужны две вкладки (не знаю, почему)

person kleopatra    schedule 19.03.2013

У меня такая же проблема. Это сработало для меня:

jXDatePicker.getEditor().addFocusListener(new FocusListener() {
    @Override
    public void focusGained(FocusEvent e) {
        BasicDatePickerUI pickerUI = (BasicDatePickerUI) jXDatePicker.getUI();
        if (!pickerUI.isPopupVisible() && e.getOppositeComponent() != getRootPane() && e.getOppositeComponent() != jXDatePicker.getMonthView()) {
            pickerUI.toggleShowPopup();
        }
    }
    @Override
    public void focusLost(FocusEvent e) {}
});

Этот фрагмент кода используется, чтобы избежать проблем с фокусом:

 e.getOppositeComponent() != getRootPane()
person morlic    schedule 13.02.2019