2014-09-27 132 views
1

我有两个类(SamplingStacker)。 Sampling类(我的主类)扩展为JFrame,并具有JButtonActionListener以打开Stacker类。使用JButton打开一个新的JFrame

问题是当按钮被点击时,Stacker类将打开,但只有一个没有任何组件的框架。当我将主要方法切换到Stacker类时,该程序正常工作。问题是什么?

下面是代码:

Sampling类:

public class Sampling extends JFrame implements ActionListener 
{ 

    private JButton openStacker; 

    Stacker st; 

    public Sampling() 
    { 
     setSize(300,300); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setLayout(new FlowLayout()); 
     setLocationRelativeTo(null); 

     openStacker = new JButton("Start Stacker!"); 

     add(openStacker); 
     openStacker.addActionListener(this); 

     setVisible(true); 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
     dispose(); 
     st = new Stacker(); 
    } 

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

Stacker游戏类:

public class Stacker extends JFrame implements KeyListener 
{ 
    int iteration = 1; 
    double time = 200; 
    int last = 0; 
    int m = 10; 
    int n = 20; 
    JButton b[][]; 
    int length[] = {5,5}; 
    int layer = 19; 
    int deltax[] = {0,0}; 
    boolean press = false; 
    boolean forward = true; 
    boolean start = true; 


    public Stacker() 
    { 

     this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     this.setSize(400,580); 
     this.setUndecorated(false); 
     this.setLocationRelativeTo(null); 



     b = new JButton [m][n]; 
     setLayout(new GridLayout(n,m)); 
     for (int y = 0;y<n;y++) 
     { 
      for (int x = 0;x<m;x++) 
      { 
        b[x][y] = new JButton(" "); 
        b[x][y].setBackground(Color.DARK_GRAY); 
        add(b[x][y]); 
        b[x][y].setEnabled(false); 
      }//end inner for 
     } 

     this.setFocusable(true); 
     this.pack(); 
     this.addKeyListener(this); 
     this.setVisible(true); 

     go(); 

    } 


    public void go() 
    { 
     int tmp = 0; 
     Component temporaryLostComponent = null; 
     do{ 
     if (forward == true) 
     { 
      forward(); 
     } else { 
      back(); 
     } 
     if (deltax[1] == 10-length[1]) 
     { 
      forward = false; 
     } else if (deltax[1] == 0) 
     { 
      forward = true; 
     } 
     draw(); 
     try 
     { 
      Thread.sleep((long) time); 
     } 
     catch (InterruptedException e) 
     { 

      e.printStackTrace(); 
     } 

     }while(press == false); 
     if (layer>12) 
     { 
      time= 150-(iteration*iteration*2-iteration); 
     } else 
     { 
      time = time - 2.2; 
     } 
     iteration++; 
     layer--; 
     press = false; 
     tmp = check(); 
     length[0] = length[1]; 
     length[1] = tmp; 
     if (layer == -1) 
     { 
      JOptionPane.showMessageDialog(temporaryLostComponent, "Congratulations! You beat the game!"); 

      repeat(); 
     } 
     if (length[1] <= 0) 
     { 
      JOptionPane.showMessageDialog(temporaryLostComponent, "Game over! You reached line "+(18-layer)+"!"); 

      repeat(); 
     } 
     last = deltax[1]; 
     start = false; 
     go(); 
    } 
    public int check() 
    { 
     if (start == true) 
     { 
      return length[1]; 
     } 
     else if (last<deltax[1]) 
     { 
      if (deltax[1]+length[1]-1 <= last+length[0]-1) 
      { 
       return length[1]; 
      } 
      else 
      { 
       return length[1]-Math.abs((deltax[1]+length[1])-(last+length[0])); 
      } 
     } 
     else if (last>deltax[1]) 
     { 
      return length[1]-Math.abs(deltax[1]-last); 
     } 
     else 
     { 
      return length[1]; 
     } 
    } 
    public void forward() 
    { 
     deltax[0] = deltax[1]; 
     deltax[1]++; 
    } 

    public void back() 
    { 
     deltax[0] = deltax[1]; 
     deltax[1]--; 
    } 

    public void draw() 
    { 
     for (int x = 0;x<length[1];x++) 
     { 
      b[x+deltax[0]][layer].setBackground(Color.DARK_GRAY); 

     } 
     for (int x = 0;x<length[1];x++) 
     { 
      b[x+deltax[1]][layer].setBackground(Color.CYAN); 
     } 
    } 

    public void repeat() 
    { 
     if(JOptionPane.showConfirmDialog(null, "PLAY AGAIN?","WARNING",JOptionPane.YES_NO_OPTION)== JOptionPane.YES_OPTION) 
     { 
      dispose(); 
      new Stacker(); 
     }else{ 
      System.exit(0); 
     } 
    } 


    public void keyPressed(KeyEvent e) 
    { 
     if (e.getKeyCode() == KeyEvent.VK_SPACE) 
     { 
      press = true; 
     } 

    } 


    public void keyReleased(KeyEvent arg0) 
    { 

    } 


    public void keyTyped(KeyEvent arg0) 
    { 

    } 

} 
+0

1)请参阅[使用多个JFrames,好/坏实践?](http://stackoverflow.com/q/9554636/418556)2)源代码中的单个空白行空白全部是*永远*需要。 '{'之后或'}'之前的空行通常也是多余的。 3)为了更快地获得更好的帮助,请发布[MCVE](http://stackoverflow.com/help/mcve)(最小完整可验证示例)。 – 2014-09-27 08:15:37

+0

取出'go();'看看会发生什么。我测试了它,它会工作。如果将其放在那里,即使框架的关闭按钮也被卡住了。你用while-> Thread.sleep垃圾阻止edt。你会想做一些重构。你的代码很难遵循,我不知道你在做什么,所以我甚至没有尝试它。 – 2014-09-27 08:17:39

+0

'dispose(); st = new Stacker();'这表明**'CardLayout' **。 – 2014-09-27 08:17:59

回答

1

只是为了把我所有的注释到一个答案,并在某处给你Ø下手:

注释1: 取出go();看到这种情况发生。我测试了它,它会工作。如果将其放在那里,即使框架的关闭按钮也被卡住了。你用while-> Thread.sleep垃圾阻止edt。你会想做一些重构。你的代码很难跟随,我不知道你想做什么,所以我甚至没有尝试它

注释2: 如果你想知道为什么它的工作原理,当你刚运行Stacker类的main,可能是因为你在EDT外运行它,

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

单击该按钮时会发生什么,该操作在EDT内执行,因此您的new Stacker()将在EDT上运行。在这种情况下,EDT会被while循环阻塞。如果您尝试从堆栈器类运行该程序,但将其包装在SwingUtilities.invokeLater中,您还会注意到该程序无法正常工作。 Swing程序应该在EDT上运行。

注释2:阅读Concurrency with Swing

第几节那么你可以做的是使用一个Swing计时器(它在EDT操作)的游戏循环。我所做的只是重构你的代码。它没有按照你想要的方式运行,只是因为我没有真正理解你的代码的逻辑。所以我无法让它工作。我所做的是将一些逻辑放入定时器中。

Timer timer = new Timer((int)time, new ActionListener(){ 
    public void actionPerformed(ActionEvent event) { 
     if (forward == true) { 
      forward(); 
     } else { 
      back(); 
     } 
     if (deltax[1] == 10 - length[1]) { 
      forward = false; 
     } else if (deltax[1] == 0) { 
      forward = true; 
     } 
     draw(); 
    } 
}); 

而当go()方法被调用,它只是通过调用timer.start()启动定时器。基本上你需要知道的关于定时器的知识是,每一次打勾(通过它的毫秒数),actionPerformed将被调用。因此,您可以使用该方法更新游戏状态,就像您在每次循环的while循环中所做的一样。

花一些时间去了How to Use Swing Timers

获得游戏正常工作,你仍然需要做一些调整,但是这应该给你一个良好的开端。

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

public class Sampling extends JFrame implements ActionListener { 

    private JButton openStacker; 

    Stacker st; 

    public Sampling() { 
     setSize(300, 300); 
     setDefaultCloseOperation(EXIT_ON_CLOSE); 
     setLayout(new FlowLayout()); 
     setLocationRelativeTo(null); 

     openStacker = new JButton("Start Stacker!"); 

     add(openStacker); 
     openStacker.addActionListener(this); 

     setVisible(true); 
    } 

    public void actionPerformed(ActionEvent e) { 
     dispose(); 
     st = new Stacker(); 
    } 

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

class Stacker extends JFrame implements KeyListener { 

    int iteration = 1; 
    double time = 200; 
    int last = 0; 
    int m = 10; 
    int n = 20; 
    JButton b[][]; 
    int length[] = {5, 5}; 
    int layer = 19; 
    int deltax[] = {0, 0}; 
    boolean press = false; 
    boolean forward = true; 
    boolean start = true; 

    Timer timer = new Timer((int)time, new ActionListener(){ 
     public void actionPerformed(ActionEvent event) { 
      if (forward == true) { 
       forward(); 
      } else { 
       back(); 
      } 
      if (deltax[1] == 10 - length[1]) { 
       forward = false; 
      } else if (deltax[1] == 0) { 
       forward = true; 
      } 
      draw(); 
     } 
    }); 

    public Stacker() { 

     this.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     this.setSize(400, 580); 
     this.setUndecorated(false); 
     this.setLocationRelativeTo(null); 

     b = new JButton[m][n]; 
     setLayout(new GridLayout(n, m)); 
     for (int y = 0; y < n; y++) { 
      for (int x = 0; x < m; x++) { 
       b[x][y] = new JButton(" "); 
       b[x][y].setBackground(Color.DARK_GRAY); 
       add(b[x][y]); 
       b[x][y].setEnabled(false); 
      }//end inner for 
     } 

     this.setFocusable(true); 
     this.pack(); 
     JPanel panel = (JPanel)getContentPane(); 
     panel.addKeyListener(this); 
     this.setVisible(true); 
     panel.requestFocusInWindow(); 

     go(); 
    } 

    public void go() { 

     int tmp = 0; 
     Component temporaryLostComponent = null; 
     timer.start(); 
     if (layer > 12) { 
      time = 150 - (iteration * iteration * 2 - iteration); 
     } else { 
      time = time - 2.2; 
     } 
     iteration++; 
     layer--; 
     press = false; 
     tmp = check(); 
     length[0] = length[1]; 
     length[1] = tmp; 
     if (layer == -1) { 
      JOptionPane.showMessageDialog(temporaryLostComponent, "Congratulations! You beat the game!"); 

      repeat(); 
     } 
     if (length[1] <= 0) { 
      JOptionPane.showMessageDialog(temporaryLostComponent, "Game over! You reached line " + (18 - layer) + "!"); 

      repeat(); 
     } 
     last = deltax[1]; 
     start = false; 
     //go(); 
    } 

    public int check() { 
     if (start == true) { 
      return length[1]; 
     } else if (last < deltax[1]) { 
      if (deltax[1] + length[1] - 1 <= last + length[0] - 1) { 
       return length[1]; 
      } else { 
       return length[1] - Math.abs((deltax[1] + length[1]) - (last + length[0])); 
      } 
     } else if (last > deltax[1]) { 
      return length[1] - Math.abs(deltax[1] - last); 
     } else { 
      return length[1]; 
     } 
    } 

    public void forward() { 
     deltax[0] = deltax[1]; 
     deltax[1]++; 
    } 

    public void back() { 
     deltax[0] = deltax[1]; 
     deltax[1]--; 
    } 

    public void draw() { 
     for (int x = 0; x < length[1]; x++) { 
      b[x + deltax[0]][layer].setBackground(Color.DARK_GRAY); 

     } 
     for (int x = 0; x < length[1]; x++) { 
      b[x + deltax[1]][layer].setBackground(Color.CYAN); 
     } 
    } 

    public void repeat() { 
     if (JOptionPane.showConfirmDialog(null, "PLAY AGAIN?", "WARNING", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { 
      dispose(); 
      new Stacker(); 
     } else { 
      System.exit(0); 
     } 
    } 

    public void keyPressed(KeyEvent e) { 
     if (e.getKeyCode() == KeyEvent.VK_SPACE) { 
      System.out.println("Pressed"); 
      press = true; 
     } 

    } 

    public void keyReleased(KeyEvent arg0) { 

    } 

    public void keyTyped(KeyEvent arg0) { 

    } 

} 

注意的SwingUtilities.invokeLatermain。这就是您可以在美国东部时间启动该计划的方式。 Concurrency In Swing上的链接将为您提供更多信息。

相关问题