嵌入式时监听JOptionPane事件?

时间:2013-03-05 14:02:52

标签: java swing actionlistener joptionpane

JOptionPane可以用作“嵌入式”组件,如下所示:

JOptionPane pane = new JOptionPane(message, JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION);
log.debug("Options are: ", pane.getOptions());
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(chartPanel, BorderLayout.CENTER);
frame.add(pane, BorderLayout.SOUTH);
frame.pack();
frame.setSize(800, 800);
frame.setLocationRelativeTo(null);
frame.setVisible(true);

如何将监听器附加到选项窗格按钮,以便在用户单击某个按钮时做出反应?

3 个答案:

答案 0 :(得分:2)

JOptionPane并不意味着嵌入JFrame,而是要在对话框中显示。

现在,我看到了3种方法来实现你想要的目标:

  1. 递归扫描JOptionPane组件层次结构以查找JButton并添加ActionListener。这个解决方案的缺点是你必须以某种方式识别哪个按钮是哪个(组件顺序可能根据不同的L& F而改变)。

  2. 覆盖单击按钮时调用的JOptionPane.setValue(Object object)

  3. 更新只需添加PropertyChangeListener即可监听JOptionPane.VALUE_PROPERTY上的更改。每次按下按钮都会收到通知。

  4. 选项3似乎是最合适的,并且代码量最少。

    以下是第二个解决方案的片段。您可以随意将匿名类增强到内部类中,甚至可以添加到自己的文件中,以便您可以使用更好的方法来访问它。

    import java.awt.BorderLayout;
    import java.awt.Dimension;
    
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.SwingUtilities;
    
    public class TestOptionPane {
    
        protected void initUI() {
            final JFrame frame = new JFrame();
            JOptionPane pane = new JOptionPane("Some message", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION) {
                @Override
                public void setValue(Object newValue) {
                    super.setValue(newValue);
                    JOptionPane.showMessageDialog(frame.getContentPane(), "You have hit " + newValue);
                }
            };
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLayout(new BorderLayout());
            frame.add(new JLabel("Some panel in the middle") {
                @Override
                public java.awt.Dimension getPreferredSize() {
                    return new Dimension(800, 500);
                };
            }, BorderLayout.CENTER);
            frame.add(pane, BorderLayout.SOUTH);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
    
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    new TestOptionPane().initUI();
                }
            });
        }
    }
    

答案 1 :(得分:0)

您可以使用pane.showConfirmDialog()来捕捉活动。它将根据具体情况返回JOptionPane.YESJOptionPane.CANCEL 尽管如此,我认为你需要创建一个传统的JPanel,因为JOptionPane用于弹出对话框,而不是嵌入JFrame。 你知道,即使你可以,但这并不意味着你应该做点什么。

答案 2 :(得分:0)

这是你想要的。

    JOptionPane pane = new JOptionPane("Stackoverflow", JOptionPane.QUESTION_MESSAGE,
        JOptionPane.YES_NO_OPTION);

    JPanel buttonArea = (JPanel) pane.getComponents()[1];

    JButton b1 = (JButton)buttonArea.getComponent(0);
    JButton b2 = (JButton)buttonArea.getComponent(1);

    b1.removeActionListener(b1.getActionListeners()[0]);

    b1.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.out.println("Stackoverflow");
        }
    });

    JFrame frame = new JFrame();

    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    frame.setLayout(new BorderLayout());
    frame.add(pane, BorderLayout.SOUTH);

    frame.pack();
    frame.setSize(800, 800);

    frame.setLocationRelativeTo(null);
    frame.setVisible(true);