2014-09-27 2 views
1

У меня есть два класса (Sampling и Stacker). Класс Sampling (мой основной класс) является продолжением JFrame и имеет JButton с ActionListener, чтобы открыть класс Stacker.Открытие нового JFrame с использованием JButton

Проблема заключается в том, что при нажатии кнопки открывается класс 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, Good/Bad Practice?] (Http://stackoverflow.com/q/9554636/418556) 2) Единственная пустая строка пробела в исходном коде - это все, что есть * когда-либо * необходимо. Пустые строки после '{' или before '}' также типично избыточны. 3) Чтобы получить более эффективную помощь, отправьте сообщение [MCVE] (http://stackoverflow.com/help/mcve) (минимальный полный проверяемый пример). –

+0

Выньте 'go();' см., Что происходит. Я тестировал его, и он будет работать. Если вы оставите его там, даже кнопка закрытия рамки застряла. Вы блокируете edt с помощью while-> Thread.sleep. Вы захотите сделать рефакторинг. Тебе сложно следовать, и я понятия не имею, что ты пытаешься сделать, поэтому я даже не попытался. –

+0

'dispose(); st = new Stacker(); 'Это мне говорит **' CardLayout' **. –

ответ

1

Просто поставить все свои замечания в ответ , и дайте вам где-нибудь t о начинать с:

Комментарий 1: Вынимают go(); видеть, что происходит. Я тестировал его, и он будет работать. Если вы оставите его там, даже кнопка закрытия рамки застряла. Вы блокируете edt с помощью while-> Thread.sleep. Вы захотите сделать рефакторинг. Вы код трудно следовать, и я понятия не имею, что вы пытаетесь сделать, так что я даже не пытался его

Комментарий 2: Если вы задаетесь вопросом, почему это работает, когда вы просто запустить основной из класса Stacker, возможно, потому, что вы используете его вне EDT,

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

Что происходит, когда вы нажимаете кнопку, это действие выполняется в пределах EDT, и, следовательно, ваш new Stacker() будет запущен на EDT. В этом случае EDT блокируется вашим циклом while. Если вы попробуете запустить программу из класса Stacker, но оберните ее в 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.invokeLater в main. Вот как вы можете запустить программу на EDT. Ссылка на Concurrency In Swing даст вам больше информации.