Упрямый JComboBox - PullRequest
       2

Упрямый JComboBox

4 голосов
/ 04 января 2012

У меня есть JComboBox, показанный в коде ниже. Когда программа запускает событие actionPerformed, оно немедленно запускается, вызывая некоторые исключения нулевого указателя, поэтому я хочу начать с того, что ни один из элементов не выбран. Однако по какой-то причине он не работает (он всегда начинается с отображения «USD / TRY», что бы я ни делал). У кого-нибудь есть идеи?

JComboBox comboBox = new JComboBox(new String[]{"USD/TRY", "EUR/TRY", "GBP/TRY"});

comboBox.setSelectedIndex(-1); // doesnt change anything
comboBox.setSelectedIndex(2); // doesnt change anything     
comboBox.setSelectedItem(null); // doesnt change anything

ОБНОВЛЕНИЕ: построение поля со списком, как показано ниже, ничего не меняет либо

JComboBox comboBox = new JComboBox(); 

comboBox.addItem("USD/TRY"); 
comboBox.addItem("EUR/TRY"); 
comboBox.addItem("GBP/TRY"); 

Вот SSCCE:

public class MainFrame {

    private final JTextArea textArea = new JTextArea();
    private IExchangeSource s;

    public MainFrame(final IExchangeSource s) {
        //build gui
        final JComboBox comboBox = new JComboBox();

        comboBox.addItem("USD/TRY");
        comboBox.addItem("EUR/TRY");
        comboBox.addItem("GBP/TRY");

        comboBox.setSelectedIndex(-1); // doesnt change anything
        //comboBox.setSelectedIndex(2); // doesnt change anything


        JFrame f = new JFrame("Currency Converter");
        JPanel p = new JPanel(new BorderLayout());
        textArea.setName("textarea");
        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);
        this.s = s;

        comboBox.addActionListener(new ActionListener() {

            public void actionPerformed(ActionEvent e) {
                String exchange = (String) comboBox.getSelectedItem();

                s.getData(exchange);
            }
        });

        p.add(comboBox, BorderLayout.NORTH);
        p.add(textArea, BorderLayout.CENTER);
        f.setPreferredSize(new Dimension(300, 300));
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.add(p);
        comboBox.setSelectedIndex(0);
        f.setVisible(true);
    }
}

Ответы [ 3 ]

7 голосов
/ 04 января 2012

Ваш (неполный) пример вызывает

comboBox.setSelectedIndex(0);

прямо перед тем, как стать видимым, отменяя любую предыдущую настройку.Установите желаемый начальный индекс перед добавлением слушателя, и не забудьте запустить EDT , как показано на sscce ниже.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextArea;

public class MainFrame {

    private final JTextArea textArea = new JTextArea();


    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new MainFrame();
            }
        });
    }
    public MainFrame() {
        //build gui
        final JComboBox comboBox = new JComboBox();

        comboBox.addItem("USD/TRY");
        comboBox.addItem("EUR/TRY");
        comboBox.addItem("GBP/TRY");

        JFrame f = new JFrame("Currency Converter");
        JPanel p = new JPanel(new BorderLayout());
        textArea.setName("textarea");
        textArea.setWrapStyleWord(true);
        textArea.setLineWrap(true);

        comboBox.setSelectedIndex(-1);
        comboBox.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                System.out.println(comboBox.getSelectedItem() + ": " + e);
            }
        });

        p.add(comboBox, BorderLayout.NORTH);
        p.add(textArea, BorderLayout.CENTER);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setSize(new Dimension(300, 300));
        f.add(p);
        f.setVisible(true);
    }
}
2 голосов
/ 04 января 2012

1) добавьте ItemListener вместо ActionListener, но это ItemListener всегда запускает дважды события SELECTED и DESELECTED,

  myComboBox.addItemListener(new ItemListener() {

        @Override
        public void itemStateChanged(ItemEvent e) {
            if (e.getStateChange() == ItemEvent.SELECTED) {
                //some stuff
            }
        }
    });

2) ваш графический интерфейс может быть или не создан на EventDispashThread , но в этом случае это не имеет значения, вы должны отложить этот метод, заключив в invokeLater (), например

public class MainFrame {
     .
     .
     .

    f.setPreferredSize(new Dimension(300, 300));
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    f.pack();
    f.add(p);
    comboBox.setSelectedIndex(0);
    f.setVisible(true);
    selectDesiredItem();
}

private void selectDesiredItem() {
  EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            comboBox.setSelectedIndex(-1);
        }
    });  
}

3) лучше бы орудия труда AutoCompete JComboBox / JTextField для валютных пар

4) возможно не важно, но у CcyPairs по умолчанию есть четыре стороны

  • Buy BaseCcy

  • Sell BaseCcy

  • Buy VariableCcy

  • Sell VariableCcy

0 голосов
/ 04 января 2012

Предложения пока хорошие. Но иногда, когда вещи действительно запутаны в том, как Компоненты конструируются, требуется более прямое исправление:

  1. подкласс JComboBox (или любой другой класс Swing, запускающий события, JList и т. Д ...)
  2. добавить поле, private boolean fireEvents = false; Попробуйте сделать это volatile.
  3. переопределяет соответствующие fireXXX() методы для проверки состояния fireEvents
  4. устанавливается только fireEvents = true после завершения всех построений и инициализации
  5. если позднее потребуется «капитальный ремонт», например, при загрузке нового файла, новых настроек, вы можете установить для fireEvents значение false при восстановлении всего.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...