проблема фокуса с использованием JComboBox в качестве редактора ячеек в JTable - PullRequest
9 голосов
/ 18 февраля 2009

У меня проблемы со следующим кодом, где я использую JComboBox для изменения значения String в ячейке таблицы. JComboBox работает нормально, но если я щелкну в поле и затем выберу , не выбирая ничего , раскрывающийся список JComboBox останется видимым, даже если я удалю строку. Нажатие на другой компонент Swing, такой как JButton, часто приводит к его исчезновению, но не всегда.


    TableColumn col = myTable.getColumnModel().getColumn(0);
    JComboBox eq = new JComboBox();
    eq.addItem("==");
    eq.addItem("!=");
    DefaultCellEditor editor = new DefaultCellEditor(eq);
    col.setCellEditor(editor);

Edit: Я забыл упомянуть, что ранее я установил:


    myTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);

Если я закомментирую эту строку или установлю значение false, то нажатие на другие компоненты Swing НЕ приведет к исчезновению поля. При этом нажатие на все, что требует фокусировки, приводит к тому, что поле исчезает, что делает проблему менее раздражающей, но, возможно, маскирует причину поведения.

Я что-то здесь не так делаю или забываю шаг? С другой стороны, есть ли способ заставить его закрыться?

Спасибо!

Ответы [ 2 ]

11 голосов
/ 19 февраля 2009

Чтобы понять это, вам нужно понять, что происходит с редактируемой таблицей. Краткая теория:

В каждой ячейке есть потенциальный рендер и редактор. Средство визуализации просто сообщает ячейке, как рисовать, и не взаимодействует с событиями. Редактор, однако, является компонентом, который может взаимодействовать с событиями. Когда происходит событие, которое вызывает редактирование, компонент редактора добавляется поверх таблицы. Когда редактирование заканчивается, компонент удаляется.

Чтобы компонент исчез, вам нужно убедиться, что ячейка еще не находится в состоянии «редактирования». Вот почему terminateEditOnFocusLast вызывает исчезновение JComboBox. Если вы хотите, чтобы другие параметры были активированы, вам, вероятно, потребуется вызвать removeEditor () в ответ на определенные события, возможно, фокус или выбор ячейки.

Чтобы по-настоящему разобраться в том, что происходит, я бы порекомендовал быстро взглянуть на исходный код, чтобы удалитьEditor (), editCellAt () и т. Д., И, возможно, один раз пройти через отладчик. Возможно, вы переопределили часть кода обработки событий или вызываете его, когда этого не следует делать. Код редактора / обработки событий в JTable довольно хрупок, и довольно легко случайно получить вызовы в неправильном порядке с забавными побочными эффектами.

Кроме того, Java очень тонко изменила поведение событий и фокуса JTable между версиями один раз, я думаю, что это было между 1.4 и 1.5, когда обработка фокуса для свинга изменилась. Поэтому первое, что я бы порекомендовал попробовать, это ваш код с другой версией Java. Возможно, ошибка была вызвана Sun (некоторые из нашего сложного кода редактора пришлось изменить), и если он отличается в разных выпусках, его легче сообщить Sun.

2 голосов
/ 05 февраля 2016

Я знаю, что этот вопрос старый, но для справки здесь мое решение. Я расширяю DefaultCellEditor и прислушиваюсь к отмене JComboBox, затем заставляю редактор отменить.

import javax.swing.DefaultCellEditor;
import javax.swing.JComboBox;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class ComboBoxCellEditor extends DefaultCellEditor {

    public ComboBoxCellEditor(JComboBox comboBox) {
        super(comboBox);
        comboBox.addPopupMenuListener(new PopupMenuListener() {

            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
            }

            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
            }

            public void popupMenuCanceled(PopupMenuEvent e) {
                cancelCellEditing();
            }
        });
    }
}

Тогда ...

DefaultCellEditor editor = new ComboBoxCellEditor(combobox);
column.setCellEditor(editor);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...