使用JButton打开一个新的JFrame

时间:2014-09-27 08:06:25

标签: java swing jframe jbutton

我有两个班级(SamplingStacker)。 Sampling类(我的主类)扩展为JFrameJButtonActionListener以打开Stacker类。

问题是当单击按钮时,Stacker类将打开但只有一个没有任何组件的框架。当我将main方法切换到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) 
    {

    }

}

1 个答案:

答案 0 :(得分:1)

只是将我的所有评论都放到答案中,然后给你一个开头的地方:

  

评论1:   取出go();看看会发生什么。我测试了它,它会工作。如果将其保留在那里,即使是框架的关闭按钮也会卡住。您使用while-&gt; Thread.sleep垃圾阻止了edt。你想要做一些重构。您难以遵循代码,我不知道您尝试做什么,所以我甚至没有尝试过它

     

评论2:   如果你想知道为什么它只能在Stacker类中运行main时,可能是因为你在EDT之外运行它,   

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

当您点击按钮,该操作在EDT内执行,因此您的new Stacker()将在美国东部时间。在这种情况下,您的while循环会阻止EDT。如果您尝试从Stacker类运行该程序,但将其包装在SwingUtilities.invokeLater中,您还会注意到该程序无法正常工作。 Swing程序应该在EDT上运行。

     

评论2:阅读Concurrency with Swing

上的前几节

所以可以做的是使用Swing Timer(在EDT上运行)进行游戏循环。我所做的是重构你的代码。它没有以你想要的方式运行,只是因为我并不真正理解你的代码逻辑。所以我无法让它发挥作用。我做了什么,将一些逻辑放入Timer。

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()来启动计时器。基本上你需要知道的关于计时器的是每个tick(你传递它的毫秒数),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上启动程序的方法。 Swurrency中的Concurrency链接将为您提供更多信息。