С Nimbus laf мой JOptionPane не получает фокус при вызове из выпадающего списка ItemEvent - PullRequest
2 голосов
/ 10 ноября 2011

надеюсь, что вы можете помочь.

Я надеюсь, что это не просто ошибка, и мы можем ее исправить.

В настоящее время у меня есть программа на Java с JComboBox. Когда пользователь изменяет выбранный элемент в поле со списком, появляется JOptionPane, чтобы позволить пользователю подтвердить изменение.

Когда новый выбор сделан в поле со списком, JOptionPane появляется по желанию, но вы должны дважды щелкнуть по нему, чтобы использовать его. То есть, нажмите его один раз, чтобы получить фокус, а затем нажмите кнопку, которую вы хотите использовать. Другой способ - щелкнуть в пределах графического интерфейса программы (за панелью параметров), а затем нажать кнопку.

Никаких исключений не происходит, и программа работает как обычно после нажатия кнопок.

Эта функция доступна только при использовании Nimbus LookAndFeel, а не с родным macos laf (сборка на Mac, не тестировалась на Windows), но мне нужно использовать nimbus по другим причинам.

Я просматривал отслеживание проблем Nimbus , но до сих пор не нашел ошибку.

У меня есть JButton, который вызывает тот же код (то есть JOptionPane.showConfirmDialog(...), и это прекрасно работает, это только когда он вызывается из действия поля со списком.

Действительно надеюсь, что вы можете помочь! Приветствия заранее!

import javax.swing.UIManager.*;
import javax.swing.*;

public class TestJavaProblem extends JFrame {
    JComboBox jComboBox1;

    public TestJavaProblem() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        initComponents();
    }

    private void initComponents() {
        jComboBox1 = new JComboBox();

        //give it some values
        jComboBox1.setModel(new DefaultComboBoxModel(new String[] { "1", "2"}));

        //add listener
        jComboBox1.addItemListener(new java.awt.event.ItemListener() {
            public void itemStateChanged(java.awt.event.ItemEvent evt) { fireTask(evt);}
        });

        this.add(jComboBox1);
        pack();
    }

    private void fireTask(java.awt.event.ItemEvent evt) {
        if (evt.getStateChange() == 1) { //so dialog fires only once
            int i = JOptionPane.showConfirmDialog(jComboBox1, "Message Text", "Title", JOptionPane.OK_CANCEL_OPTION);
            System.out.println("Result:" + i);
        }
    }

    public static void main(String args[]) {
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                break;
                }
            }
        } catch (Exception e) {/*no nimbus*/}

        new TestJavaProblem().setVisible(true);
    }
}

1 Ответ

3 голосов
/ 10 ноября 2011

не используйте магическое число,

if (evt.getStateChange() == 1) { //so dialog fires only once

или

int i = JOptionPane.showConfirmDialog(jComboBox1,

здесь есть обходной код, но кажется, что он необходим для MetalLookAndFeel, Вещества в ОС Windows

import javax.swing.UIManager.*;
import javax.swing.*;
import javax.swing.event.PopupMenuEvent;
import javax.swing.event.PopupMenuListener;

public class TestJavaProblem extends JFrame {

    private static final long serialVersionUID = 1L;
    private JComboBox jComboBox1;
    private boolean boloComboBox = false;

    public TestJavaProblem() {
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        initComponents();
    }

    private void initComponents() {
        jComboBox1 = new JComboBox();
        jComboBox1.setModel(new DefaultComboBoxModel(new String[]{"1", "2"}));
        jComboBox1.addItemListener(new java.awt.event.ItemListener() {

            @Override
            public void itemStateChanged(final java.awt.event.ItemEvent evt) {
                if (jComboBox1.isPopupVisible()) {
                    jComboBox1.setPopupVisible(false);
                    SwingUtilities.invokeLater(new Runnable() {

                        @Override
                        public void run() {
                            fireTask(evt);
                        }
                    });
                }
            }
        });
        jComboBox1.addPopupMenuListener(new PopupMenuListener() {

            @Override
            public void popupMenuCanceled(PopupMenuEvent e) {
                System.out.println(e.getSource());
            }

            @Override
            public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
                System.out.println(e.getSource());
            }

            @Override
            public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
                System.out.println(e.getSource());
            }
        });
        add(jComboBox1);
        pack();
    }

    private void fireTask(java.awt.event.ItemEvent evt) {
        if (evt.getStateChange() == 2) {
            int i = JOptionPane.showConfirmDialog(jComboBox1, 
                "Message Text", "Title", JOptionPane.OK_CANCEL_OPTION);
            System.out.println("Result:" + i);
        }
    }

    public static void main(String args[]) {
        try {
            for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (Exception e) {
        }
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                new TestJavaProblem().setVisible(true);
            }
        });
    }
}
...