在actionListener中创建GUI时,不显示按钮/标签

时间:2014-04-05 19:41:42

标签: java swing user-interface render actionlistener

==============

我正在创建一个小型2D游戏,其中包含一个“主菜单”GUI和一个“游戏内”GUI(用于渲染图形)。

主菜单自然有一个“开始”按钮来创建游戏世界和游戏内GUI。如果单独运行它们,所有组件都可以正常工作,但如果调用“开始”按钮上的动作侦听器中的“actionPerformed”,则游戏内GUI不会正确呈现所有按钮/标签/滚动窗格,并且不会应用默认关闭操作。

图片http://imgur.com/vYQVcOd

在左侧,不会渲染按钮。在右边,他们是。

产生左/右图像的代码之间的差异:

-FOR LEFT IMAGE -

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


public class BensGUI extends JFrame{

    public BensGUI()
    {
        final JFrame bensGUI = this;
        Container pane = this.getContentPane();
        JPanel mainPanel = new JPanel();
        JButton start = new JButton("Start");
        mainPanel.add(start);

        //This GUI is simplified from the real Main Menu


        start.addActionListener(new ActionListener() { 
              public void actionPerformed(ActionEvent e) { 
                    Player p1 = new Player("player 1", new AntBrainParser().parseBrain("cleverbrain2.brain"));
                    Player p2 = new Player("player 2", new AntBrainParser().parseBrain("horseshoe.brain"));
                    Pos[][] ps = new MapParser().parseMap("5.world"); //The World class creates the in-game GUI inside its constructor
                    World w = new World(p1, p2, ps, 3427);
                  } 
        } );



        pane.add(mainPanel);
        this.pack();
        this.setVisible(true);
    }
}

-FOR RIGHT IMAGE -

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


public class BensGUI extends JFrame{

    public BensGUI()
    {
        final JFrame bensGUI = this;
        Container pane = this.getContentPane();
        JPanel mainPanel = new JPanel();
        JButton start = new JButton("Start");
        mainPanel.add(start);


        Player p1 = new Player("player 1", new AntBrainParser().parseBrain("cleverbrain2.brain"));
        Player p2 = new Player("player 2", new AntBrainParser().parseBrain("horseshoe.brain"));
        Pos[][] ps = new MapParser().parseMap("5.world");
        World w = new World(p1, p2, ps, 3427); //The World class creates the in-game GUI inside its constructor

        start.addActionListener(new ActionListener() { 
              public void actionPerformed(ActionEvent e) { 

                  } 
        } );

        //This GUI is simplified from the real Main Menu

        pane.add(mainPanel);
        this.pack();
        this.setVisible(true);
    }
}

请注意,当按钮不显示时,您无法通过单击右上角的“X”关闭窗口(尽管执行了setDefaultCloseOperation行)。调整窗口大小会导致重新绘制“毛刺”(imgur.com/bOpCzGC)。点击/悬停时按钮不会重新显示或反应。

  • 如果我在World类中放置一个main方法并在没有任何形式的主菜单GUI的情况下运行它,它可以正常工作。
  • 如果我通过调用World构造函数(调用In-Game GUI构造函数)绕过主菜单,则在它有机会可见之前(与“FOR RIGHT IMAGE”一样)它产生了上面的正确图像。
  • 看起来好像在游戏内GUI中的所有代码行都已执行。
  • 当没有显示按钮时,游戏实际运行。但是您无法控制滚动窗格,按钮或标签。

我看不出是什么导致了这个问题,并试图找到解决办法。有人能在这里帮助我吗?这将不胜感激!

亲切的问候,

-Ben

所有代码

以下是导致问题的所有代码。我只包含了构造函数(现在),因为即使只运行它们也会导致问题。

SimulationGUI(又名游戏内GUI)

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.*;

import javax.imageio.ImageIO;
import java.io.*;
import java.util.ArrayList;
import java.util.Random;
import java.util.HashMap;

public class SimulationGUI extends JFrame{


    Pos[][] position;//2D array of positions which contains all the info about the cells
    int imageXSize = 25;
    int imageYSize = 27;
    int imageXOffset = 21;
    int rowOffsetValue = (imageXOffset/2);
    int imageYOffset = 16;
    int curRound = 0;
    boolean isRendering = true;
    public boolean isActive = true;
    int antTrackerID = 50;

    JFrame simGUIFrame = this;


//  public static void main(String[] args)
//  {
//      System.setProperty("sun.java2d.opengl","True");
//      MapParser mp = new MapParser();
//      SimulationGUI gui = new SimulationGUI("Some text", mp.parseMap("1.world"));
//      gui.setUpWorld();
//  }


    //GUI ELEMENTS
    JPanel groundCanvas;
    BufferedImage offscreen;
    BufferedImage background;
    Graphics2D offScrGfx;
    Graphics2D bckGrdGfx;

    JScrollPane scrollPane;
    //Graphics2D g2d = new Graphics2D();


    //A load of ant and food images
    BufferedImage antBLK_S;
    BufferedImage antBLK_SE;
    BufferedImage antBLK_E;
    BufferedImage antBLK_NE;
    BufferedImage antBLK_N;
    BufferedImage antBLK_NW;
    BufferedImage antBLK_W;
    BufferedImage antBLK_SW; 

    BufferedImage antBLKF_S;
    BufferedImage antBLKF_SE;
    BufferedImage antBLKF_E;
    BufferedImage antBLKF_NE;
    BufferedImage antBLKF_N;
    BufferedImage antBLKF_NW;
    BufferedImage antBLKF_W;
    BufferedImage antBLKF_SW; 


    BufferedImage antRED_S;
    BufferedImage antRED_SE;
    BufferedImage antRED_E;
    BufferedImage antRED_NE;
    BufferedImage antRED_N;
    BufferedImage antRED_NW;
    BufferedImage antRED_W;
    BufferedImage antRED_SW; 

    BufferedImage antREDF_S;
    BufferedImage antREDF_SE;
    BufferedImage antREDF_E;
    BufferedImage antREDF_NE;
    BufferedImage antREDF_N;
    BufferedImage antREDF_NW;
    BufferedImage antREDF_W;
    BufferedImage antREDF_SW; 


    BufferedImage food_5;
    BufferedImage food_4;
    BufferedImage food_3;
    BufferedImage food_2;
    BufferedImage food_1;

    BufferedImage antTrackCell;


    ImageIcon boxChecked = new ImageIcon("Images/Check Button checked.png");
    ImageIcon boxUnChecked = new ImageIcon("Images/Check Button unchecked.png");
    ImageIcon playButton = new ImageIcon("Images/Play Button.png");
    ImageIcon pausedButton = new ImageIcon("Images/Paused Button.png");
    ImageIcon restartIcon = new ImageIcon("Images/Restart Icon.png");
    ImageIcon quitIcon = new ImageIcon("Images/Quit Icon.png");
    ImageIcon foodIcon = new ImageIcon("Images/foodIcon.png");


    //Variables used in GUI
    JProgressBar progressBar;
    World world;
    JLabel roundCounter;
    String roundNum;
    JLabel redCount;
    JLabel blkCount;
    JLabel foodCount;
    JButton renderPause;
    JLabel redScore;
    JLabel blkScore;
    JLabel antTrackerLabel;
    JTextField antTrackerIDBox;





    //Parameters used by the World Class
    HashMap<Integer, Ant> antMap = new HashMap<Integer, Ant>();
    ArrayList<Pos> foodPosArray = new ArrayList<Pos>();



    public SimulationGUI(String title, Pos[][] positionArray, World w)
    {



        groundCanvas = new JPanel();

        redCount = new JLabel("Red Ants:   ######", boxUnChecked, JLabel.LEFT);
        blkCount = new JLabel("Black Ants: ######", boxUnChecked,  JLabel.LEFT);
        foodCount = new JLabel("Food: ######", foodIcon,  JLabel.LEFT);
        redScore = new JLabel("Red Score:  ######");
        blkScore = new JLabel("Blk Score:  ######");
        renderPause = new JButton("Render", boxChecked);
        scrollPane = new JScrollPane(groundCanvas);
        antTrackerLabel = new JLabel("Ant ID");
        antTrackerIDBox = new JTextField("20");

        this.world = w;
        this.position = positionArray;
        this.setTitle("Ant Simulation | "+title);
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);



        this.setLocation(400, 400);
        this.setVisible(true);
        Container pane = this.getContentPane();


        //Graphics Setup
//      System.setProperty("sun.java2d.opengl","True");

        //Canvas and JScrollPane

        groundCanvas.setPreferredSize(new Dimension(imageXOffset*position.length + 10,imageYOffset*position.length + 10));
        offscreen = (BufferedImage) createImage(imageXOffset*position.length + 10,imageYOffset*position.length + 10);
        background = (BufferedImage) createImage(imageXOffset*position.length + 10,imageYOffset*position.length + 10);
        offScrGfx = (Graphics2D) offscreen.getGraphics();
        bckGrdGfx = (Graphics2D) background.getGraphics();


        scrollPane.add(groundCanvas);
        scrollPane.setPreferredSize(new Dimension(800,450));
        scrollPane.setViewportView(groundCanvas);




        ///////////////////////////


        JPanel topPanel = new JPanel();
        JPanel middlePanel = new JPanel();
        JPanel bottomPanel = new JPanel();
        JPanel bottomMainPanel = new JPanel();
        JPanel topMainPanel = new JPanel();
        JPanel antTracker = new JPanel();

        bottomPanel.setLayout(new BorderLayout());
        topMainPanel.setLayout(new GridLayout(2,3));
        topPanel.setLayout(new BorderLayout());
        antTracker.setLayout(new BorderLayout());

        JButton restartButton = new JButton("Restart", restartIcon);
        final JButton pauseButton = new JButton("Pause", playButton);
        JButton quitButton = new JButton("Quit", quitIcon);
        final JButton speedUp = new JButton("");
        final JButton slowDown = new JButton("");
        speedUp.setIcon(new ImageIcon("Images/speedUp.png"));
        slowDown.setIcon(new ImageIcon("Images/slowDown.png"));

//      progressBar = new JProgressBar(0, w.maxRounds);
//      progressBar.setValue(0);
//      progressBar.setStringPainted(true);


        roundCounter = new JLabel("Round: #######");


        //ACTION LISTENERS////////


        //Action listeners are commented out for now...

        //Add the buttons/bars/labels to their panels


        bottomMainPanel.add(roundCounter);
        bottomMainPanel.add(speedUp);
        bottomMainPanel.add(slowDown);
        bottomMainPanel.add(renderPause);
        bottomMainPanel.add(restartButton);
        bottomMainPanel.add(pauseButton);
        bottomMainPanel.add(quitButton);
        bottomPanel.add(bottomMainPanel, BorderLayout.SOUTH);
        //bottomPanel.add(progressBar, BorderLayout.NORTH);


        JPanel antTrackerContainer = new JPanel();

        antTrackerContainer.add(antTrackerLabel);
        antTrackerContainer.add(antTrackerIDBox);
        antTracker.add(antTrackerContainer, BorderLayout.WEST);


        antTrackerIDBox.setPreferredSize(new Dimension(40, 20));


        topMainPanel.add(redCount);
        topMainPanel.add(redScore);
        topMainPanel.add(foodCount);
        topMainPanel.add(blkCount);
        topMainPanel.add(blkScore);
        topMainPanel.add(antTracker);


        middlePanel.add(scrollPane);



        topPanel.add(topMainPanel, BorderLayout.CENTER);

        pane.add(topPanel, BorderLayout.NORTH);
        pane.add(middlePanel, BorderLayout.CENTER);
        pane.add(bottomPanel, BorderLayout.SOUTH);


        this.pack();



    }

World(在BensGUI actionListener 中创建,如上所述

World(Player player1, Player player2, Pos[][] positions, int initialSeed) {
        // initialise variables
        this.player1 = player1;
        this.player2 = player2;
        player1.setColour("red");
        player2.setColour("black");
        this.positions = positions;
        this.foodPositions = new ArrayList<Pos>();
        ants = new HashMap<Integer, Ant>();
        this.initialSeed = initialSeed;

        seed.add(new BigInteger("" + initialSeed)); // initial seed
        for (int i = 1; i < 4; i++) {
            seed.add(seed.get(i - 1).multiply(new BigInteger("22695477"))
                    .add(new BigInteger("1")));
        }

        generateAnts();
        System.out.println(ants.size());
        //In-Game GUI Setup:
        sim = new SimulationGUI("", positions, this);
        sim.setUpWorld();
        sim.pack();
        gameStart();
    }

值得注意的是:

  • 出于测试目的,我暂时在World类中注释掉了与更新相关的方法,这些方法会导致JPanel groundCanvas 在游戏的每一帧上重新绘制。当我这样做时,它会导致(A.)发生(见下面的图像)。
  • 当我允许World类更新 groundCanvas 时,会产生(B。)
  • 图片: http://i.imgur.com/UHjwfmD.png

我已添加了此问题所需的所有代码

0 个答案:

没有答案