1

当我运行这个类(Try 类)时,它完全调用了 Stacker 类(具有完整的功能),但是当我使用其他类(我使用 JFrame 和具有调用 Stacker 类的 actionlistener 的按钮)来运行这个(Stacker 类)时, JFrame(Stacker 类)将弹出但为空,我无法关闭程序。

我试图从其他类运行这个(Stacker),如下所示:

public class Try {

    /**
     * @param args
     */
    public static void main(String[] args) {

        run();

    }

    public static void run(){
        new Stacker();
    }

}

Stacker 类完全运行(我可以与之交互)。但是,当我尝试从 JFrame 中按钮的 actionlistener 调用 stacker 类时,它是空白的并且无法关闭。

请帮我。

这是我的 Stacker 类代码:

import java.awt.Color;
import java.awt.Component;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class Stacker  extends JFrame implements KeyListener {

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

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

    public Stacker() {
        panel = new JPanel();
        panel.setLayout(new GridLayout(20,10));

        this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
        b = new JButton [m][n];

        for (int y = 0;y<n;y++) {
            for (int x = 0;x<m;x++) {
                b[x][y] = new JButton(" ");
                b[x][y].setBackground(Color.white);
                b[x][y].setBorderPainted(false);
                panel.add(b[x][y]);
                b[x][y].setEnabled(true);
            }//end inner for
        }
        setSize(390, 560);
        setLayout(new GridBagLayout());
        add(panel);
        setFocusable(true);
        addKeyListener(this);
        pack();
        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) {
                // TODO Auto-generated catch block
                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!");
        }
        if (length[1] <= 0) {
            JOptionPane.showMessageDialog(temporaryLostComponent, "Game over! You reached line "+(18-layer)+"!");
            System.exit(0);
        }
        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.white);
        }
        for (int x = 0;x<length[1];x++) {
            b[x+deltax[1]][layer].setBackground(Color.BLUE);
        }
    }

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

    @Override
    public void keyReleased(KeyEvent arg0) {
        // TODO Auto-generated method stub
    }

    @Override
    public void keyTyped(KeyEvent arg0) {
        // TODO Auto-generated method stub
    }
}
4

3 回答 3

2

您的 do-while 循环和线程睡眠看起来很可疑,因为它在绑定它的 Swing 事件线程上运行。问题是这些运行时间较长的任务会锁定 Swing Event D ispatch T线程或 EDT,这是一个负责所有 Swing 图形和用户交互的线程,阻止您的应用程序绘制自身及其所有小部件并阻止应用程序从响应任何用户输入。

应用程序可能是孤立运行的,因为我在上面发现的问题超出了 EDT,并且明智地执行此代码是解决您的问题的一种可能解决方案,但我敢打赌,如果有更好的解决方案,我们可以帮助您解决你告诉我们更多关于你的问题的细节。

此外,您似乎以危险的方式使用递归,让 go 方法调用本身。不能说更多,因为我在手机上。

于 2013-09-22T10:31:38.450 回答
1

首先,我会用this.setDefaultCloseOperation(DISPOSE_ON_CLOSE); 以下内容替换:

this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

DISPOSE_ON_CLOSE静态/类变量一样。

事实上,令我惊讶的是,您的 IDE 没有支持这一点(除非您没有使用 IDE)。

于 2013-09-22T10:28:41.627 回答
-1
SwingWorker worker = new SwingWorker<Void, Void>() {

     @Override
       protected Void doInBackground() throws Exception {
               Stacker stack = new Stacker();
               stack.setVisible(true);
              return null;
           }
    };
    worker.execute();

使用此方法后,当我Stacker class从另一个 JFrame 调用时,游戏完美执行。就像Stacker class从调用时一样Try class

感谢您对我的所有回复。:D

于 2013-09-24T04:04:24.693 回答