itemlistener получает событие после удаления фокуса из jcombobox - PullRequest
2 голосов
/ 07 ноября 2010

Это должно быть недоразумение с моей стороны, но у меня есть следующее:
Я добавил ItemListener в Jcombobox.
В прослушивателе элементов я проверяю в событии, имеет ли он тип ItemSelected.
Если это так, я обновляю значение в JTextPane.Проблема в том, что он работает следующим образом:
Я нажимаю на новое значение в jcombobox и ничего не меняется в поле jtext.Я должен фактически щелкнуть другой компонент, например поле jtext, а затем обновить поле jtext.
Кажется, что фокус должен быть удален из jcombobox, чтобы изменение события отправлялось в код элемента списка элементов.
Это как?он должен работать, или я делаю что-то не так?Можно ли обработать событие, не снимая фокус?

ОБНОВЛЕНИЕ: Этот мой код и метод updateJTextPane называются после того, как я щелкаю по другому компоненту , а не при выборе нового значения в комбинированном списке.Т.е. комбо имеет значение «1», я нажимаю на выпадающий список и нажимаю «2».Текущий выбранный пункт теперь "2".Мой метод не вызывается в этот момент.Я нажимаю на второе поле со списком, второе поле имеет фокус, а затем вызывается мой метод updateJTextPane ().Почему?
ОБНОВЛЕНИЕ 2:

//Code from Netbeans generator
JComboBox myCbx = new javax.swing.JComboBox();    
myCbx.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
myCbx.setName("myCbx"); // NOI18N 
//My ItemListener
class myItemListener implements ItemListener{
public void itemStateChanged(ItemEvent ie) {
            if (ie.getStateChange() == ItemEvent.SELECTED) { // Item was just selected
                updateJTextPane();
            }    
         }
    }
//add item listener to combo
myCbx.addItemListener(new myItemListener());

ОБНОВЛЕНИЕ 3: Внутренний класс myItemListener добавляется еще к 5 комбинированным спискам в том же JDialog, если это имеет значение вкстати я не знаю спасибо

Ответы [ 4 ]

1 голос
/ 02 октября 2012

Я сталкивался с подобной ситуацией при выборе.Мне больше нравится ошибка в Java.В моем случае у меня есть два варианта A и B. B зависит от выбора A.Например, A = {a1, a2, a3}.Если A = a1 B, это Список выбора {1, 2, 3}.Если A = a2, B - это список {4,5,6}. Если A = a3, B - это список {7,8,9}.Выберите поток a1, а затем выберите 2 на B. Выберите a2 и B имеет индекс по умолчанию 0 (4) и выберите 5 на B, функция itemStateChanged () вызываться не будет.Похоже, элемент управления представления не синхронизируется с данными, установленными для него.Причина, по которой itemStateChanged () не вызывается, поскольку 5 имеет тот же индекс предыдущего выбора.

1 голос
/ 07 ноября 2010

Можно ли обработать событие, не снимая фокус?Конечно да!:)

Вот пример того, как это может работать, при условии, что я правильно понимаю ваши требования:

class ComboListener implements ItemListener {
    @Override
    public void itemStateChanged(ItemEvent e) {
        if (e.getStateChange() == ItemEvent.SELECTED) {
            System.out.println("Selected Item: \""
                + ((JComboBox)e.getSource()).getSelectedItem() + "\"");
        }
    } 
}

Если вы не добавите проверку if, выбудет выполнять действие как для первого невыбранного элемента, так и для второго выбранного.

1 голос
/ 07 ноября 2010

Это должно работать так, как вы это описали, следующее прекрасно работает:

class Frame extends JFrame {
    JComboBox  box;
    JTextField field;
    String[]   entries = { "one", "two", "three" };

    Frame() {
        setLayout(new FlowLayout());

        box = new JComboBox(entries);
        box.addItemListener(new ItemListener() {
            @Override
            public void itemStateChanged(ItemEvent e) {
                if (e.getStateChange() == ItemEvent.SELECTED) {
                    field.setText((String) box.getSelectedItem());
                }
            }
        });
        add(box);

        field = new JTextField();
        field.setColumns(10);
        add(field);

        setSize(400, 300);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setVisible(true);
    }
}

public class Test {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                Frame frame = new Frame();
            }
        });

    }
}
1 голос
/ 07 ноября 2010

Это не так, как это должно работать. События элемента должны генерироваться немедленно при изменении выбранного элемента.

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

Обновление:

Ваш itemStateChanged метод выглядит нормально, проблема должна быть в другом месте. Возможно, что-то не так с updateJTextPane. Что произойдет, если вы замените вызов на updateJTextPane на System.out.println? Кроме того, можете ли вы распечатать источник события (ie.getSource()) и убедиться, что событие действительно происходит из первого поля со списком?

Если вы опубликуете автономный пример, который можно скомпилировать и запустить, вам будет гораздо проще определить проблему.

...