当前位置: 首页 > 知识库问答 >
问题:

如何从JOptionPane返回主菜单(JFrame)

饶铭
2023-03-14

我在Java中做了一个小数字猜谜游戏。我的主JFrame(主菜单)有三个J按钮,播放,声音和退出。

按下play按钮开始我的游戏,一系列的JOptionPanes出现,要求用户输入数字。它工作正常,游戏运行正常。但是当我按play键玩游戏的时候,我不能按exit或者sound键或者游戏中的其他任何键。我甚至不能按JFrame主窗口的X(关闭)按钮,直到我完全玩完游戏,或者关闭JOptionPane从而关闭当前游戏。

我可以按退出按钮,当我已经按下声音按钮来启动背景声音。当我已经按下声音按钮时,我可以按播放按钮。

有什么建议吗?

我的问题是,假设我正在使用JOptionPane制作一个小游戏,当JOptionPane已经打开时,如何按下主JFrame(主菜单)上的JButtons

这是我的SSCCE。

import javax.swing.*;
import java.awt.event.*;

class Test2 {
    static JFrame frame;
    static JPanel jp;

    static JButton b1;
    static JButton b2;
    static JButton b3;

    public static void main(String[] args)  {
        final long startTime = System.currentTimeMillis();
        frame=new JFrame("Game ");
        jp=new JPanel();
        b1=new JButton("Play");
        b1.addActionListener (new Action());
        b2=new JButton("Exit");
        b2.addActionListener (new Action1());
        b3=new JButton("Sound");
        b3.addActionListener (new Action2());

        jp.add(b1);
        jp.add(b2);
        jp.add(b3);

        frame.add(jp);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300,400);
        frame.setVisible(true);
    }

    static class Action implements ActionListener { // For (game) Play button
        public void actionPerformed (ActionEvent e) {
            Thread  bb=new Thread(new Runnable(){
                public void run(){
                    new Test2().start();
                }});
            bb.setPriority(1);
            bb.start();
        }
    }

    static class Action1 implements ActionListener { // For Exit button
        public void actionPerformed (ActionEvent e) {

            Thread  tt=new Thread( new Runnable(){
                public void run(){
                    int response = JOptionPane.showConfirmDialog(
                            null,
                            "Exit application?",
                            "Confirm",
                            JOptionPane.YES_NO_OPTION,
                            JOptionPane.QUESTION_MESSAGE);
                    if (response == JOptionPane.NO_OPTION) {

                    }
                    else if (response == JOptionPane.YES_OPTION) {
                        System.exit(0);
                    }
                }
            });
            tt.setPriority(10);
            tt.start();
        }
    }

    static class Action2 implements ActionListener { //For Sound Button
        public void actionPerformed (ActionEvent e)  {

            try {
                /* Code to play sound */
            }
            catch(Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    void start() { //   sample  game
        JOptionPane.showMessageDialog(null,"Step 1  ..click OK  to continue");
        JOptionPane.showMessageDialog(null,"Step 2  ..click OK  to continue");
        JOptionPane.showMessageDialog(null,"Step 3  ..click OK  to continue");
        JOptionPane.showMessageDialog(null,"Step 4  ..click OK  to continue");
        JOptionPane.showMessageDialog(null,"Step 5  ..click OK  to continue");
        JOptionPane.showMessageDialog(null,"Step 6  ..click OK  to continue");
        JOptionPane.showMessageDialog(null,"Step 7  ..click OK  to continue");
        JOptionPane.showMessageDialog(null,"Step 8  ..click OK  to continue");
    }
}

在我的新代码中,只有start()方法发生了变化

void start()                          //   sample  game
{

JOptionPane pane = new JOptionPane();
 // Configure via set methods
dialog = pane.createDialog(null,"exp 1");
 // the line below is added to the example from the docs

dialog.setSize(300, 200);

 dialog.setModal(false); // this says not to block background components

JButton nextButton = new JButton("Go to Dialog2");


dialog.add(nextButton);
nextButton.setBounds(25,25,20,20);


 dialog.show();

JOptionPane pane2 = new JOptionPane();
 // Configure via set methods
 dialog2 = pane2.createDialog(null,"exp 2");
 // the line below is added to the example from the docs
 dialog2.setModal(false); // this says not to block background components
// dialog2.show();






nextButton.addActionListener(new ActionListener() {
 public void actionPerformed(ActionEvent arg0) {

dialog2.setVisible(true);
dialog.setVisible(false);

 }
});





}

共有1个答案

戈建白
2023-03-14

不幸的是,JOptionPane是一个模式对象,在传递所有对话框之前不能离开它们。从对话中可以看出,所有对话框都是模态对话框。每个showXxxDialog方法都会阻塞当前线程,直到用户的交互完成。

您可以通过创建非模态对话框来解决问题。创建非模态对话框的示例

相反,JDialog类似于JFrame,您可以在其中添加按钮、事件监听器。简单的例子

您可以为自己创建一个自定义的< code>JDialog类:)

有一个自定义< code>JDialog的示例

我对你的代码进行了如下编辑:

void start() { // sample game
    MyDialog dialog7 = new MyDialog(null);
    MyDialog dialog6 = new MyDialog(dialog7);
    MyDialog dialog5 = new MyDialog(dialog6);
    MyDialog dialog4 = new MyDialog(dialog5);
    MyDialog dialog3 = new MyDialog(dialog4);
    MyDialog dialog2 = new MyDialog(dialog3);
    MyDialog dialog1 = new MyDialog(dialog2);

    dialog1.setVisible(true);
}
 类似资料:
  • 在第二个while循环(在用户选择抛硬币模拟器选项之后),当用户选择0时,我遇到了问题,程序没有像我希望的那样返回到主菜单,而是停止了,没有循环回到主菜单,让用户选择另一个选项。 有什么办法解决这个问题吗?我不能使用多个方法,因为这是我正在做的一个项目的要求。我已经被困在这一个部分很长时间了,现在(一个星期),并将感激地感谢任何指针或方向。 下面是当用户运行抛硬币模拟器后选择零时我的程序的样子。

  • 我正在开发一个应用程序,应该支持手机和平板电脑。在这个应用程序中,我使用的是来自Android的片段。 现在应用程序的流程如下所示 MainActivity-->fragment1-->Fragment2 我只是在图像中标记了一个额外的菜单项。那么我为什么要来,我该如何解决呢?

  • 在选定的方法执行后,如何使菜单再次显示? 我有菜单选项打印到控制台。然后接受用户输入(1-6),调用相应的方法,然后返回菜单,供用户再次从菜单中选择。 选择的方法执行后,程序刚好结束。

  • 六个主菜单分别是: 文件(File) Capture Traffic ——启用捕获功能,快捷键 F12 此功能的开启/关闭状态,程序安装后默认是开启的。可以在 Fiddler 底部状态栏最左侧看到:(开启状态)、(关闭状态) 也可以通过鼠标点击状态栏该图标来进行切换。 Load Archive... ——载入本地保存的 Session 压缩包 Save ——保存 All Sessions... —

  • Cocos Creator(Mac) 包括软件信息、设置、窗口控制等功能。 关于 Cocos Creator:显示 Cocos Creator 的版本和版权信息。 偏好设置:打开 设置 面板,设置编辑器的个性化选项。 隐藏 Cocos Creator (Ctrl/Command + H):隐藏编辑器窗口。 隐藏其他应用 (Shift + Ctrl/Command + H):隐藏 Cocos Cre

  • 我有一个html下拉列表(它的纯html)。我需要有根据查询结果选择的值。像这样: 所以如果某个用户的查询返回状态为“CT”,我需要在下拉列表中选择的值为CT,除了检查每一行的if语句之外,还有什么方法可以做到这一点吗?