2014-09-27 131 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上的鏈接將爲您提供更多信息。

相關問題