0

私は Java で少数の推測ゲームを作成しました。私のメイン JFrame (メイン メニュー) には、Play、Sound、Exit の 3 つの JButtons があります。

再生ボタンを押すとゲームが開始され、一連の JOptionPanes が表示され、ユーザーに数字の入力を求めます。正常に動作し、ゲームは正常に実行されます。しかし、プレイボタンを押してゲームをプレイすると、ゲームの終了ボタン、サウンドボタン、またはその他のボタンを押すことができません。ゲームを完全にプレイするか、JOptionPane を閉じて現在のゲームを閉じるまで、メインの JFrame ウィンドウの X(閉じる) ボタンを押すことさえできません。

すでにサウンドボタンを押してバックグラウンドサウンドを開始しているときに、終了ボタンを押すことができます。すでにサウンドボタンを押しているときに、再生ボタンを押すことができます。

助言がありますか?

私の質問は、JOptionPanes を使用して小さなゲームを作成しているとします。

ここに私の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);

 }
});





}
4

1 に答える 1

4

残念ながら、JOptionPane はモーダル オブジェクトであるため、すべてのダイアログを通過するまで、それらを終了することはできません。ドキュメントから、すべてのダイアログはモーダルです。各 showXxxDialog メソッドは、ユーザーの操作が完了するまで現在のスレッドをブロックします。

非モーダル ダイアログを作成することで、問題を解決できる場合があります。 非モーダル ダイアログの作成例

代わりに、JDialogはJFrameに似ています。その中に Button 、イベントリスナーを追加できます。 簡単な例

自分用にカスタマイズされたJDialogクラスを作成できます:)

カスタマイズの一例です 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);
}
于 2012-10-14T16:22:41.493 に答える