如果我在开始打滑后通过主菜单运行它,战列舰应用程序崩溃

问题描述:

我正在使用套接字创建4个类的战舰游戏。电脑,玩家信息和菜单类。要开始游戏,我运行服务器的计算机类,然后运行菜单类,调出菜单。通过菜单我点击开始创建一个新的玩家的对象,看起来像这样如果我在开始打滑后通过主菜单运行它,战列舰应用程序崩溃

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


} 

这个完美运行,没有菜单类,如果我运行的计算机类,然后播放器类运行,游戏运行成功。但是,当我调用一个窗口,没有在it.Here弹出的菜单中运行播放器的方法是我的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(); 





      }} 
     }); 
+1

一边注意。我会把你所有的听众凝聚成一个单位。 ActionListener al = new ActionListener(){};将所有按钮注册到该动作侦听器,然后在侦听器内部对源进行检查。如果(e.getSource == start){//开始做些事情......} – maleki 2010-08-23 17:34:22

+1

你说的是,如果你使用计算机然后玩家,那么它在没有菜单的情况下运行良好。然后你说,如果你只是从菜单中运行播放器,它不起作用。如果你运行电脑,然后从菜单中选择播放器,它工作吗?计算机和播放器如何耦合。如果它们相同,那么它们的初始化有何不同。 – maleki 2010-08-23 17:39:07

+0

我强烈建议不要使用单个ActionListener进行多种用途。由于现在一系列不相关的事情正在一起处理,这会产生高耦合和低内聚性。 – 2010-08-23 19:34:59

这是什么地方用提供的信息来回答这个问题有点难。但是我必须猜测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(); 
    } 
}); 
+0

绝对天才大卫,完美作品 谢谢 – user427641 2010-08-23 20:18:20

我认为问题的关键在于你所示的代码之外;它可以是任何东西,从缺少setVisible()synchronization问题。 FWIW,我对代码的一些观察:

  1. 建立在EDT你的GUI,@大卫年轻只是建议。

  2. 使用静态常量来避免重复自己。

  3. 不要使用空格来格式化标签;使用JLabel对齐常量。

  4. 而不是一个空布局,使用嵌套的布局来得到你想要的结果。

  5. 为避免在构造函数中调用公共方法,您重复了代码startMusic()。相反,在构造函数完成后调用它

下面是一个例子:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
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.ImageIcon; 
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 static final String TITLE = "Battleship"; 
    private static final String SOUND_FILE = "./battle.wav"; 
    private javax.swing.JLabel image; 
    JFrame frame = new JFrame(TITLE); 
    JPanel center = new JPanel(new BorderLayout()); 
    JLabel statusbar = new JLabel(TITLE); 
    JLabel battleship = new JLabel(TITLE, JLabel.CENTER); 
    static AudioPlayer MGP = AudioPlayer.player; 
    static AudioStream BGM; 
    static ContinuousAudioDataStream loop = null; 
    AudioData MD; 

    public Menu() { 

     frame.setTitle("Battleship"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

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

     JButton start = new JButton("Start"); 
     JButton exit = new JButton("Exit"); 
     JButton StopMusic = new JButton("Stop Music"); 
     JButton StartMusic = new JButton("Start Music"); 

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

     image = new JLabel(); 
     image.setHorizontalAlignment(JLabel.CENTER); 
     image.setIcon(new ImageIcon("./battleship2.jpg")); 
     center.add(image, BorderLayout.CENTER); 

     JPanel panel = new JPanel(); 
     panel.add(start); 
     panel.add(exit); 
     panel.add(StopMusic); 
     panel.add(StartMusic); 
     center.add(panel, BorderLayout.SOUTH); 

     frame.add(battleship, BorderLayout.NORTH); 
     frame.add(center, BorderLayout.CENTER); 
     frame.add(statusbar, BorderLayout.SOUTH); 

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

     start.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       //frame.dispose(); 
       stopMusic(); 
       runPlayer(); 
      } 
     }); 
     StopMusic.addActionListener(new ActionListener() { 

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

      @Override 
      public void actionPerformed(ActionEvent e) { 
       startMusic(); 
      } 
     }); 

     exit.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 

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

    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(SOUND_FILE); 
      BGM = new AudioStream(test); 
      AudioPlayer.player.start(BGM); 
      MGP.start(loop); 
     } catch (FileNotFoundException e) { 
      System.out.print(e.toString()); 
     } catch (IOException error) { 
      System.out.print(error.toString()); 
     } 
    } 

    public static void runPlayer() { 
     Player client = new Player(); 
     client.createBoard(); 
     client.run(); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       Menu menu = new Menu(); 
       menu.startMusic(); 
      } 
     }); 
    } 

    // stub for missing class 
    private static class Player { 
     void createBoard() {} 
     void run() {} 
    } 
}