События JComboBox - Swing - PullRequest
       14

События JComboBox - Swing

3 голосов
/ 16 мая 2019

Как убедиться, что Элемент изменяется в JCombobox от пользователя, а не от другого метода?

Потому что у меня есть метод, который также меняет предмет. Но события должны что-то делать, когда пользователь изменил элемент.

Ответы [ 2 ]

4 голосов
/ 16 мая 2019

Лучшая идея - пометить ваше собственное событие логическим флагом, как это предложено @LucA. Но если по каким-либо причинам вы не можете сделать это, вы можете попытаться проверить отправителя события. Если инициатором является ваш комбобокс - событие было инициировано пользователем. Вот пример:

import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.util.Objects;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.WindowConstants;
import javax.swing.plaf.basic.ComboPopup;

/**
 * <code>JComboText</code>.
 */
public class JComboText {

    public static void main(String[] args) {
        String[] items = new String[] {"First", "Second", "Third", "Fourth"};
        JComboBox<String> combo = new JComboBox<>(items);
        combo.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                boolean byUser = isTriggeredByUser(combo);
                System.out.println("Changed by: " + (byUser ? "user" : "program"));
            }
        });
        JButton button = new JButton("Clear selection");
        button.addActionListener(e -> combo.setSelectedItem(null));
        JFrame frm = new JFrame("Combo test");
        frm.setLayout(new FlowLayout());
        frm.add(combo);
        frm.add(button);
        frm.pack();
        frm.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frm.setLocationRelativeTo(null);
        frm.setVisible(true);
    }

    private static boolean isTriggeredByUser(JComboBox<?> combo) {
        // check whether the change was triggered by another component
        final ComboPopup popup = (ComboPopup) combo.getUI().getAccessibleChild(combo, 0);
        final JList<?> list = popup.getList();
        if (EventQueue.getCurrentEvent() instanceof InputEvent) {
            return Objects.equals(EventQueue.getCurrentEvent().getSource(), combo)
                    || Objects.equals(EventQueue.getCurrentEvent().getSource(), list);
        }
        return false;
    }
}

Вы можете скопировать метод isTriggeredByUser и использовать его в своей программе.

3 голосов
/ 16 мая 2019

Это может работать:

Объявите логическое значение, означающее, что "поле со списком изменяется программой, а не пользователем"

Делайте это true каждый раз, когда ваш код меняет выбранное значение, и false снова сразу после.

В вашем событии actionPerformed ничего не делайте, если ваш логический тип равен true. Если значение равно false, это означает, что пользователь изменяет его.

...