简体   繁体   English

Swing GUI不响应输入

[英]Swing GUI not responding to input

I'm working on modeling John Conway's Game of Life for presentation at a conference coming up, and I have the program in a place that should be 95% complete, however, nothing is responding to user input. 我正在为即将到来的会议上演示约翰·康威(John Conway)的《人生游戏》建模,并且我将程序放置在应该完成95%的位置,但是,没有任何内容响应用户输入。 It almost seems like my action listener and mouse listener aren't being implemented correctly, but I'm not sure where. 似乎我的动作侦听器和鼠标侦听器没有正确实现,但是我不确定在哪里。 The program is almost entirely complete; 该程序几乎完全完成。 there are a few portions that are still empty, but it will still compile and create my JFrame properly. 有一些部分仍然是空的,但是它仍然可以编译并正确创建我的JFrame。

/**
* Created by Brendan Kristiansen on 1/26/2017.
*/
public class GameOfLife
{
    public static void main(String[] args)
    {
        MyFrame frame = new MyFrame();
    }
}

Class that contains global information: 包含全局信息的类:

/**
 * Created by Brendan Kristiansen on 1/26/2017.
 */
public class GLOBAL
{
    /**
     * Build Information for GameOfLife
     */
    public static final double BUILDVERSION = 0.1;
    public static final String BUILDNAME = "Alpha 0.1";

    /**
     * Global Constants for GameOfLife
     */
    public static final int FRAMEHEIGHT = 1000;     //Frame Height
    public static final int FRAMEWIDTH = 1000;      //Frame Width
    public static final int HEIGHT = 100;           //Game Height
    public static final int WIDTH = 100;            //Game Width

    /**
     * Global Variables
     */
    public static int delay = 500;                  //Step Delay (Milliseconds)
    public static byte[][] herd0;                   //Herd Byte Array 0
    public static byte[][] herd1;                   //Herd Byte Array 2
    public static byte[][] startHerd;               //Customized herd before animation is started
    public static byte activeArray;                 //Array currently being displayed
    public static boolean active;                   //States if simulation is repeating
    public static long arraySwitches;               //Tallies times active array is switched

    /**
     * Action Commands
     */
    public static final String CLOSE = "close";         //Closes Application
    public static final String START = "go";            //Starts looping simulation
    public static final String STOP = "stop";           //Stops loop
    public static final String RULES = "rules";         //Pops up window with Rules for GOL
    public static final String ABOUT = "about";         //Displays about dialog
    public static final String RESETGRID = "resetGrid"; //Resets the grid to before the simulation
    public static final String NEWGAME = "new";         //Zeroes the grid and arrays
}

Frame: 帧:

/**
 * Created by Brendan Kristiansen on 1/26/2017.
 */

import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.*;

/**
 * @author Brendan Kristiansen
 */
public class MyFrame extends JFrame implements ActionListener, ChangeListener
{
    private JPanel mPanel;
    private JButton start;
    private JButton stop;
    private JButton setGame;
    private JButton resetGame;
    private JButton newGame;

    private JLabel speedLabel;
    private JSlider speed;

    private HerdPanel mHerdPanel;

    /**
     * Constructor
     */
    public MyFrame()
    {
        GLOBAL.active = false;
        initArrays();
        setSize(GLOBAL.FRAMEWIDTH, GLOBAL.FRAMEHEIGHT);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mPanel = new JPanel();
        initForm();
        setVisible(true);
        mPanel.setVisible(true);

        JMenuBar menu = new JMenuBar();

        JMenu game = new JMenu("GameOfLife");
        JMenu help = new JMenu("Help");

        JMenuItem gamePlay = new JMenuItem("Play");
        JMenuItem gameExit = new JMenuItem("Exit");
        JMenuItem helpRules = new JMenuItem("Rules");
        JMenuItem helpAbout = new JMenuItem("About");

        gamePlay.addActionListener(this);
        gameExit.addActionListener(this);
        helpRules.addActionListener(this);
        helpAbout.addActionListener(this);

        gamePlay.setActionCommand(GLOBAL.START);
        gameExit.setActionCommand(GLOBAL.CLOSE);
        helpRules.setActionCommand(GLOBAL.RULES);
        helpAbout.setActionCommand(GLOBAL.ABOUT);

        game.add(gamePlay);
        game.add(gameExit);
        help.add(helpRules);
        help.add(helpAbout);

        menu.add(game);
        menu.add(help);

        this.setJMenuBar(menu);
        this.setVisible(true);
    }

    /**
     * Lays Out Panel
     */
    public void initForm()
    {
        setGame = new JButton("Set Grid");
        resetGame = new JButton("Reset Grid");
        newGame = new JButton("Clear Grid");
        start = new JButton("Start Simulation");
        stop = new JButton("Stop Simulation");
        speedLabel = new JLabel("Simulation Speed (ms): " + GLOBAL.delay);
// N        speed = new JSlider(3000, 50, GLOBAL.delay);

        setGame.addActionListener(this);
        resetGame.addActionListener(this);
        newGame.addActionListener(this);
        start.addActionListener(this);
        stop.addActionListener(this);

//        setGame.setActionCommand(GLOBAL.SETGRID);
        resetGame.setActionCommand(GLOBAL.RESETGRID);
        newGame.setActionCommand(GLOBAL.NEWGAME);
        start.setActionCommand(GLOBAL.START);
        stop.setActionCommand(GLOBAL.STOP);

        mPanel = new JPanel();
        mPanel.setLayout(new BoxLayout(mPanel, BoxLayout.X_AXIS));
        mPanel.setBackground(new Color(100, 100, 100));

        mHerdPanel = new HerdPanel();

        mPanel.add(setGame);
        mPanel.add(resetGame);
        mPanel.add(newGame);
        mPanel.add(start);
        mPanel.add(stop);
//        mPanel.add(speedLabel);
//        mPanel.add(speed);

        getContentPane().add(mPanel, BorderLayout.NORTH);
        getContentPane().add(mHerdPanel, BorderLayout.CENTER);

    }

    /**
     * Directs ActionEvents to the proper functions
     * @param event
     */
    @Override
    public void actionPerformed(ActionEvent event)
    {
        String e = event.toString();
        if(e.equals(GLOBAL.CLOSE))
        {
            System.exit(0);
        }
        else if(e.equals(GLOBAL.START))
        {
            GLOBAL.active = true;
            playGame();
        }
        else if(e.equals(GLOBAL.STOP))
        {
            GLOBAL.active = false;
        }
        else if(e.equals(GLOBAL.NEWGAME))
        {
            initArrays();
            mHerdPanel.paintImage();
        }
        else if(e.equals(GLOBAL.RESETGRID))
        {
            GLOBAL.herd0 = GLOBAL.startHerd;
            GLOBAL.herd1 = GLOBAL.startHerd;
            GLOBAL.activeArray = 0;
            mHerdPanel.paintImage();
        }
        else if (e.equals(GLOBAL.ABOUT))
        {
            JOptionPane.showMessageDialog(null, "Game of Life\n Developed by Brendan Kristiansen with MSU Storytelling.");
        }
        else if (e.equals(GLOBAL.RULES))
        {

        }
    }

    /**
     * Directs ChangeEvents to the proper functions
     * @param e
     */
    @Override
    public void stateChanged(ChangeEvent e)
    {
        GLOBAL.delay = speed.getValue();
    }

    /**
     * initializes byte arrays to be 0
     */
    public void initArrays()
    {
        GLOBAL.herd0 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
        GLOBAL.herd1 = new byte[GLOBAL.HEIGHT][GLOBAL.WIDTH];
        for(int i = 0; i <= GLOBAL.HEIGHT - 1; i++)
        {
            for(int j = 0; j <= GLOBAL.WIDTH - 1; j++)
            {
                GLOBAL.herd0[i][j] = 0;
            }
        }
        GLOBAL.herd1 = GLOBAL.herd0;
        GLOBAL.activeArray = 0;
        GLOBAL.arraySwitches = 0;
    }

    /**
     *Controls the advancement of the game
     */
    public void playGame()
    {
        GLOBAL.startHerd = GLOBAL.herd0;
        if (GLOBAL.active == true)
        {
            while(GLOBAL.active == true)
            {
                nextFrame();
                try
                {
                    wait(GLOBAL.delay);
                }
                catch(Exception e)
                {
                    System.out.println(e);
                }
            }
        }
        else
        {
            nextFrame();
        }
    }

    /**
     *Advances Game of Life by one frame
     */
    public void nextFrame()
    {
        if (GLOBAL.activeArray == 0)
        {
            for(int i = 0; i <= GLOBAL.HEIGHT; i++)
            {
                for(int j = 0; j <= GLOBAL.WIDTH; j++)
                {
                    int neighbors = countNeighbors(i, j, GLOBAL.herd0);
                    if (neighbors == 3 || neighbors == 4)
                    {
                        GLOBAL.herd1[i][j] = 1;
                    }
                    else
                    {
                        GLOBAL.herd1[i][j] = 0;
                    }
                }
            }
            GLOBAL.activeArray = 1;
            mHerdPanel.paintImage();
        }
        else
        {
            for(int i = 0; i <= GLOBAL.HEIGHT; i++)
            {
                for(int j = 0; j <= GLOBAL.WIDTH; j++)
                {
                    int neighbors = countNeighbors(i, j, GLOBAL.herd1);
                    if (neighbors == 3 || neighbors == 4)
                    {
                        GLOBAL.herd0[i][j] = 1;
                    }
                    else
                    {
                        GLOBAL.herd0[i][j] = 0;
                    }
                }
            }
            GLOBAL.activeArray = 0;
            mHerdPanel.paintImage();
        }
        GLOBAL.arraySwitches++;
    }

    /**
     * Counts the living neighbors of a given cell in a herd
     * @param i
     * @param j
     * @param herd
     * @return
     */
    public int countNeighbors(int i, int j, byte[][] herd)
    {
        int neighbors = 0;
        if(i == 0 && j == 0) //Top left case
        {
            if(herd[i + 1][j] == 1){neighbors++;}       //Bottom Neighbor
            if(herd[i + 1][j + 1] == 1){neighbors++;}   //Bottom right neighbor
            if(herd[i][j + 1] == 1){neighbors++;}       //Right neighbor
        }
        else if(i == 0 && j == GLOBAL.WIDTH) //Top right case
        {
            if(herd[i + 1][j] == 1){neighbors++;}       //Bottom neighbor
            if(herd[i + 1][j - 1] == 1){neighbors++;}   //Bottom left neighbor
            if(herd[i][j - 1] == 1){neighbors++;}       //Left neighbor
        }
        else if(i == GLOBAL.HEIGHT && j == 0) //Bottom left case
        {
            if(herd[i - 1][j] == 1){neighbors++;}       //Top neighbor
            if(herd[i - 1][j + 1] == 1){neighbors++;}   //Top right neighbor
            if(herd[i][j + 1] == 1){neighbors++;}       //Right neighbor
        }
        else if(i == GLOBAL.HEIGHT && j == GLOBAL.WIDTH) //Bottom right case
        {
            if(herd[i - 1][j] == 1){neighbors++;}       //Top neighbor
            if(herd[i - 1][j - 1] == 1){neighbors++;}   //Top left neighbor
            if(herd[i][j - 1] == 1){neighbors++;}       //Left neighbor
        }
        else if(i == 0) //Top Row
        {
            if(herd[i + 1][j] == 1){neighbors++;}       //Bottom neighbor
            if(herd[i + 1][j + 1] == 1){neighbors++;}   //Bottom right neighbor
            if(herd[i][j + 1] == 1){neighbors++;}       //Right neighbor
            if(herd[i + 1][j - 1] == 1){neighbors++;}   //Bottom left neighbor
            if(herd[i][j - 1] == 1){neighbors++;}       //Left neighbor
        }
        else if(j == 0) //Left side
        {
            if(herd[i + 1][j] == 1){neighbors++;}       //Bottom neighbor
            if(herd[i + 1][j + 1] == 1){neighbors++;}   //Bottom right neighbor
            if(herd[i][j + 1] == 1){neighbors++;}       //Right neighbor
            if(herd[i - 1][j] == 1){neighbors++;}       //Top neighbor
            if(herd[i - 1][j + 1] == 1){neighbors++;}   //Top right neighbor
        }
        else if(i == GLOBAL.HEIGHT) //Bottom Row
        {
            if(herd[i - 1][j] == 1){neighbors++;}       //Top neighbor
            if(herd[i - 1][j + 1] == 1){neighbors++;}   //Top right neighbor
            if(herd[i][j + 1] == 1){neighbors++;}       //Right neighbor
            if(herd[i - 1][j - 1] == 1){neighbors++;}   //Top left neighbor
            if(herd[i][j - 1] == 1){neighbors++;}       //Left neighbor
        }
        else if(j == GLOBAL.WIDTH) //Right side
        {
            if(herd[i - 1][j - 1] == 1){neighbors++;}   //Top left neighbor
            if(herd[i][j - 1] == 1){neighbors++;}       //Left neighbor
            if(herd[i - 1][j] == 1){neighbors++;}       //Top neighbor
            if(herd[i + 1][j] == 1){neighbors++;}       //Bottom neighbor
            if(herd[i + 1][j - 1] == 1){neighbors++;}   //Bottom left neighbor
        }
        else //Middle of herd
        {
            if(herd[i + 1][j] == 1){neighbors++;}       //Bottom neighbor
            if(herd[i + 1][j - 1] == 1){neighbors++;}   //Bottom left neighbor
            if(herd[i][j - 1] == 1){neighbors++;}       //Left neighbor
            if(herd[i - 1][j - 1] == 1){neighbors++;}   //Top left neighbor
            if(herd[i - 1][j] == 1){neighbors++;}       //Top neighbor
            if(herd[i - 1][j + 1] == 1){neighbors++;}   //Top right neighbor
            if(herd[i][j + 1] == 1){neighbors++;}       //Right neighbor
            if(herd[i + 1][j + 1] == 1){neighbors++;}   //Bottom right neighbor
        }
        return neighbors;
    }
}

And the HerdPanel class. 还有HerdPanel类。 This should be a grid which you can click on to change the color of a cell, then play Game Of Life with the cells you have highlighted: 这应该是一个网格,您可以单击以更改单元格的颜色,然后与突出显示的单元格一起玩《生命游戏》:

/**
 *
 * @author Brendan Kristiansen
 */
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.awt.image.BufferedImage;

//https://www.shodor.org/stella2java/rgbint.htmlhttps://www.shodor.org/stella2java/rgbint.html

public class HerdPanel extends JPanel implements MouseListener, MouseMotionListener
{
    Graphics2D g;
    Graphics2D g2;
    BufferedImage grid;
    BufferedImage bisonCell;

    /**
     * Constructor
     */
    public HerdPanel()
    {
        setSize(500, 500); //Width, Height
        addMouseListener(this);
        addMouseMotionListener(this);
        try
        {
            bisonCell = ImageIO.read(new File("bison.png"));
        }
        catch (IOException e)
        {
            System.out.println(e);
        }
        grid = new BufferedImage(GLOBAL.WIDTH, GLOBAL.HEIGHT, 1);
        paintImage();
        //g = grid.createGraphics();
    }

    /**
     * Converts byte[][] array to BufferedImage
     */
    public void paintImage()
    {
        if (GLOBAL.activeArray == 0)
        {
            for (int i = 0; i <= GLOBAL.WIDTH - 1; i++)
            {
                for (int j = 0; j <= GLOBAL.HEIGHT - 1; j++)
                {
                    if (GLOBAL.herd0[j][i] == 0)
                    {
                        grid.setRGB(j, i, 16777215);
                    } else
                    {
                        grid.setRGB(j, i, 0);
                    }
                }
            }
        }
        else
        {
            for (int i = 0; i <= GLOBAL.WIDTH; i++)
            {
                for (int j = 0; j <= GLOBAL.HEIGHT; j++)
                {
                    if (GLOBAL.herd1[j][i] == 0)
                    {
                        grid.setRGB(j, i, 16777215);
                    } else
                    {
                        grid.setRGB(j, i, 0);
                    }
                }
            }
        }
        g = grid.createGraphics();
        super.paintComponent(g);
        g.drawImage(grid, null, 0, 0);
        repaint();
    }

    @Override
    public void mouseClicked(MouseEvent e)
    {
        int xClick = (int)(e.getX() / GLOBAL.WIDTH);
        int yClick = (int) (e.getY() / GLOBAL.HEIGHT);
        if(GLOBAL.activeArray == 0)
        {
            GLOBAL.herd0[yClick][xClick] = 1;
        }
        else
        {
            GLOBAL.herd1[yClick][xClick] = 1;
        }
        paintImage();
    }

    @Override
    public void mousePressed(MouseEvent e)
    {
    }

    @Override
    public void mouseReleased(MouseEvent e)
    {
    }

    @Override
    public void mouseEntered(MouseEvent e)
    {
    }

    @Override
    public void mouseExited(MouseEvent e)
    {
    }

    @Override
    public void mouseDragged(MouseEvent e)
    {
    }


    @Override
    public void mouseMoved(MouseEvent e)
    {
    }
}

your playGame function will not return until the game has ended. 游戏结束之前,您的playGame函数将不会返回。 Swing UIs are single threaded. Swing UI是单线程的。 It will not refresh until you return control to the swing runtime. 在将控制权返回到swing运行时之前,它不会刷新。

You need to calculate your game of life in a background task and repaint the ui by triggering a paint event in the frame. 您需要在后台任务中计算生活游戏,并通过触发框架中的绘制事件来重新绘制UI。

You can find a good explanation on how to approach this here: Using threads to paint panel in java 您可以在此处找到有关如何解决此问题的很好的解释: 在Java中使用线程绘制面板

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM