java - 如果我在点击开始后通过主菜单运行它,战舰应用程序会崩溃

标签 java swing

我正在使用套接字创建一个具有 4 个类的战舰游戏。计算机、播放器消息和菜单类。要开始游戏,我运行作为服务器的计算机类,然后运行显示菜单的菜单类。通过菜单我单击开始创建一个新的播放器对象,它看起来像这样

public static void runPlayer()
{
    Player client = new Player();   //creates player
    client.createBoard();
    client.run();


}

如果我运行计算机类然后播放器类,则可以在没有菜单类的情况下完美运行,游戏运行成功。但是当我在菜单中调用 run player 方法时,会弹出一个没有任何内容的窗口。这是我的 Menu 类
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EtchedBorder;
import sun.audio.*;

public class Menu  {
    private javax.swing.JLabel image;
    private static final int EXIT_ON_CLOSE = 0;
    JFrame frame = new JFrame();
    JPanel panel = new JPanel(new BorderLayout());
    JLabel statusbar = new JLabel(" Battleship");
    JLabel Battleship = new JLabel("          Battleship ");
    static AudioPlayer MGP = AudioPlayer.player;
    static AudioStream BGM;
    AudioData MD;

    static ContinuousAudioDataStream loop = null;
    public static void waiting (int n)
    {

        long t0, t1;

        t0 =  System.currentTimeMillis();

        do{
            t1 = System.currentTimeMillis();
        }
        while (t1 - t0 < n);
    }


    public Menu() 
    {

        frame.setTitle("Battleship");


        statusbar.setBorder(BorderFactory.createEtchedBorder(
                EtchedBorder.RAISED));
        Battleship.setBorder(BorderFactory.createEtchedBorder(
                EtchedBorder.RAISED));

        panel.setLayout(null);

        JButton start = new JButton("Start");
        start.setBounds(100, 660, 80, 25);


        JButton exit = new JButton("Exit");
        exit.setBounds(190, 660, 80, 25);

        JButton StopMusic = new JButton("Stop Music");
        StopMusic.setBounds(300, 660, 160, 25);

        JButton StartMusic = new JButton("Start Music");
        StartMusic.setBounds(470, 660, 160, 25);


        Battleship.setFont(new Font("Courier New", Font.ITALIC, 36));
        Battleship.setForeground(Color.BLACK);



        image = new javax.swing.JLabel();
        image.setIcon(new javax.swing.ImageIcon("./battleship2.jpg"));
        frame.add(image, BorderLayout.EAST);
        frame.pack();



        frame.add(start);
        frame.add(exit);
        frame.add(StopMusic);
        frame.add(StartMusic);


        frame.add(panel);
        frame.add(statusbar, BorderLayout.SOUTH);
        frame.add(Battleship, BorderLayout.NORTH );



        frame.setSize(700, 800);
        frame.setLocationRelativeTo(null);
        frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
        frame.setVisible(true);

        music();



        start.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e)
            {

                {                           
                        frame.dispose();                //closes frame
                        stopMusic();                    //stops music
                        //waiting(500);
                        runPlayer();





            }}
         });
        StopMusic.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e)
            {

                {                           
                    stopMusic();

                }
            }
         });
        StartMusic.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e)
            {

                {                           
                    startMusic();

                }
            }
         });

       exit.addActionListener(new ActionListener() 
       {
        public void actionPerformed(ActionEvent e)
        {

            System.out.println( "Ending Game" );
            System.exit(0);
        }
     });}




    public static void music() 
    {       
        try
        {
            InputStream test = new FileInputStream("./battle.wav");
            BGM = new AudioStream(test);
            AudioPlayer.player.start(BGM);




        }
        catch(FileNotFoundException e){
            System.out.print(e.toString());
        }
        catch(IOException error)
        {
            System.out.print(error.toString());
        }
        MGP.start(loop);





    }
    public void stopMusic() 
    {
        if (BGM != null)
          AudioPlayer.player.stop(BGM);
        if (loop != null)
          AudioPlayer.player.stop(loop);
      }
    public void startMusic() {
        try
        {
            InputStream test = new FileInputStream("./battle.wav");
            BGM = new AudioStream(test);
            AudioPlayer.player.start(BGM);




        }
        catch(FileNotFoundException e){
            System.out.print(e.toString());
        }
        catch(IOException error)
        {
            System.out.print(error.toString());
        }
        MGP.start(loop);
      }
    public static void runPlayer()
    {
        Player client = new Player();   //creates player
        client.createBoard();
        client.run();


    }

    public static void main(String[] args) 
    {       
        new Menu();                       
    }
}

我认为我的问题出在这个监听器方法的某个地方
start.addActionListener(new ActionListener() 
        {
            public void actionPerformed(ActionEvent e)
            {

                {                           
                        frame.dispose();                //closes frame
                        stopMusic();                    //stops music
                        //waiting(500);
                        runPlayer();





            }}
         });

最佳答案

用所提供的信息来回答这个问题有点困难。但我必须猜测 runPlayer() 方法在做什么。我假设那里有某种类型的 while 循环可以防止 Event Dispatch Thread刷新您创建的新 JFrame。

尝试将 stopMusic() 和 runPlayer() 放在一个新线程中。

基本上是这样的

start.addActionListener(new ActionListener() {
  public void actionPerformed(ActionEvent e) {
    frame.dispose(); // closes frame

    new Thread(){
      public void run(){
        stopMusic(); // stops music
        runPlayer();
      }
    }.start();
  }
}); 

关于java - 如果我在点击开始后通过主菜单运行它,战舰应用程序会崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3549898/

相关文章:

Java - notifyAll() 和 notify() 失败了吗?是否可以?

java - 如何从命令行添加外部 Jar 并使用文件的完整路径来编译和执行 Java?

java - 将 ArrayList 类中的随机字符串打印到 JLabel 文本中

java - 在Java中如何找到两个字符串之间所有重叠的短语?

java - Active directory auth Tomcat - 在操作中读取用户名?

java - 我如何检测 jpanel 内部的形状并将其与另一个按钮一起使用

java - 如何更改 JTextPane 中特定单词的颜色?

java - 关于ImageIcons的方法不起作用

java - 拖放后移动组件

java - long 类型的方法参数缺少 URI 模板变量 'id'