自定义JOptionPane /如何在将值返回到方法之前等待框架中的按钮被单击

时间:2015-08-10 10:49:08

标签: java swing joptionpane

我正在尝试创建一个方法,用一些文本和4个JButton打开一个JFrame。我需要它像JOptionPane类中的方法一样操作,以便我可以执行类似

的操作
int i = JOptionPane.showConfirmDialog(...);

我希望能够在返回值之前调用该方法并等待其中一个按钮被单击。

这是我到目前为止所尝试过的,但显然有一些错误。任何人都知道我需要做些什么来完成这项工作以及如何解决这些错误。这是方法

private static String displaySetStatus(String text){
        JButton jbtWin = new JButton("Win");
        JButton jbtLose = new JButton("Lose");
        JButton jbtCancelBet = new JButton("Cancel Bet");
        JButton jbtSkip = new JButton("Skip");
        JFrame f = new JFrame("Set Status");

        f.add(new JLabel(text));
        JPanel jpSouth = new JPanel();
        jpSouth.add(jbtWin);
        jpSouth.add(jbtLose);
        jpSouth.add(jbtCancelBet);
        jpSouth.add(jbtSkip);
        f.add(jpSouth, "South");

        f.setSize(200, 150);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
        f.setVisible(true);

        String status = "Empty";

        ActionListener buttonListener = new SetStatusListener();
        jbtWin.addActionListener(buttonListener);
        jbtLose.addActionListener(buttonListener);
        jbtCancelBet.addActionListener(buttonListener);
        jbtSkip.addActionListener(buttonListener);


        class SetStatusListener implements ActionListener{
            @Override
            public void actionPerformed(ActionEvent e) {
                status = ((JButton)e.getSource()).getText();
            } 
        }

        while(status.equals("Empty")){
            //do nothing - wait until button is clicked
        }

        f.setVisible(false);
        return status;
    }

1 个答案:

答案 0 :(得分:3)

如果你想要JOptionPane功能,实际上是模态对话框窗口的功能,为什么不使用JOptionPane呢?或者,如果这不起作用,请使用模态JDialog窗口而不是JFrame。你的while(true)块会让你的程序完全陷入困境,而你的模态就是你想要的。

例如:

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;

import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

@SuppressWarnings("serial")
public class Foo1 extends JPanel {
    private JTextField textField = new JTextField(10);
    private JButton getStatusBtn = new JButton(new GetStatusAction("Get Status"));

    public Foo1() {
        textField.setFocusable(false);
        add(new JLabel("Status:"));
        add(textField);
        add(getStatusBtn);
    }

    private class GetStatusAction extends AbstractAction {
        public GetStatusAction(String name) {
            super(name);
            int mnemonic = name.charAt(0);
            putValue(MNEMONIC_KEY, mnemonic);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            Component parentComponent = Foo1.this;

            // this panel can hold any gui components that you desire
            // here I simply give it a centered JLabel that displays some text
            JPanel message = new JPanel(new GridBagLayout());
            message.setPreferredSize(new Dimension(200, 100));
            message.add(new JLabel("Some Text"));
            String title = "Get Status";
            int optionType = JOptionPane.OK_CANCEL_OPTION;
            int messageType = JOptionPane.PLAIN_MESSAGE;
            Icon icon = null;
            String[] options = { "Win", "Lose" };
            int initialValue = 0;

            // create and show our JOptionPane, and get the information from it
            int selection = JOptionPane.showOptionDialog(parentComponent,
                    message, title, optionType, messageType, icon, options,
                    initialValue);

            // if the selection chosen was valid (win or lose pushed)
            if (selection >= 0) {
                // get the selection and use it
                textField.setText(options[selection]);
            }
        }
    }

    private static void createAndShowGui() {
        Foo1 mainPanel = new Foo1();

        JFrame frame = new JFrame("Foo1");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

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