尽管使用validate(),GUI也未更新 [英] GUI not updating despite use of validate()

查看:86
本文介绍了尽管使用validate(),GUI也未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我正在制作的四连环程序。到目前为止,我已经可以将棋盘格添加到空的(合格的)插槽中,每次交替显示红色和黑色。我的代码可能效率很低,因为这是我的第一个swing程序。但是,我唯一的主要问题是,单击空插槽后,我真的无法真正更新GUI。我尝试了validate(),但似乎没有做任何事情。该程序中使用的图像的链接可以在下面找到。非常感谢您的帮助!

Here is a Connect Four program I'm making. So far, I'm able to add checkers to empty (eligible) slots, alternating red and black each time. My code may be quite inefficient, as this is my first swing program. However, my only major problem is that I can't really get the GUI to update after the empty slots are clicked on. I tried validate(), but that didn't appear to do anything. Links to the images used in the program can be found below. Thanks so much for your help!

import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;

import javax.swing.*;

public class GameFrame extends JFrame {

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    frame = new GameFrame();
                    frame.setContentPane(new JLabel(new ImageIcon(getClass()
                            .getResource("675 x 588 Connect Four.png"))));
                    frame.addSlots();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */

    static GameFrame frame;
    private static Icon slotForButton;
    public static JButton slotButton;
    static private JButton[] slot = new JButton[42];
    static private String[] slotColor = new String[42];
    static boolean turn = true;
    static boolean legitClick;
    static String slotClicked;
    static int slotNum;
    static Container gamePane;

    public GameFrame() {
        setBounds(100, 100, 685, 622);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        super.setTitle("Connect Four by Joel Christophel");
    }

    void addSlots() {
        ButtonHandler bh = new ButtonHandler();
        gamePane = getContentPane();
        gamePane.setLayout(new GridLayout(6, 6));
        int counter = 0;

        for (JButton e : slot) {
            slot[counter] = makeSlot("white");
            slot[counter].setBorderPainted(false);
            slot[counter].setContentAreaFilled(false);
            slot[counter].setFocusPainted(false);
            slot[counter].setActionCommand(counter + "");
            slotColor[counter] = "white";

            slot[counter].addActionListener(bh);
            add(slot[counter]);

            counter++;
        }
    }

    static JButton makeSlot(String color) {

        if (color.equals("white")) {
            slotForButton = new ImageIcon(
                    GameFrame.class.getResource("Space.png"));
        }

        else if (color.equals("red")) {
            slotForButton = new ImageIcon(
                    GameFrame.class.getResource("Red Checker.png"));
        }

        else if (color.equals("black")) {
            slotForButton = new ImageIcon(
                    GameFrame.class.getResource("Black Checker.png"));
        }

        slotButton = new JButton(slotForButton);

        return slotButton;
    }

    private class ButtonHandler implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            slotClicked = e.getActionCommand();

            GameFrame.legitClick(slotClicked);
        }

    }

    private static void changeTurn() {
        turn = !turn; // true is red's turn; false is black's
    }

    private static void legitClick(String slotClicked1) {
        legitClick = false;

        slotClicked = slotClicked1;
        Scanner numScan = new Scanner(slotClicked);
        slotNum = numScan.nextInt();

        try {
            if (!slotColor[slotNum + 7].equals("white")&&slotColor[slotNum].equals("white")) {
                legitClick = true;
            }
        }

        catch (ArrayIndexOutOfBoundsException t) {

            if (slotColor[slotNum].equals("white")) {
                legitClick = true;
            }
        }

        if (legitClick == true) {
            if (turn == true) {
                slot[slotNum] = makeSlot("red");
                slotColor[slotNum] = "red";
                System.out.println("Put " + slotColor[slotNum] + " checker     in slot number " + slotNum + ".");
            }

            else if (turn == false) {
                slot[slotNum] = makeSlot("black");
                slotColor[slotNum] = "black";
                System.out.println("Put " + slotColor[slotNum] + " checker      in slot number " + slotNum + ".");
            }

            gamePane.validate();
            GameFrame.changeTurn();
        }
        System.out.println(turn);
    }

}

http://i.stack.imgur.com/8cNB3.png 675 x 588连接Four.png

http://i.stack.imgur.com/8cNB3.png 675 x 588 Connect Four.png

http://i.stack.imgur.com/ 6oX7A.png 黑色Checker.png

http://i.stack.imgur.com/6oX7A.png Black Checker.png

http://i.stack.imgur.com/cdF7u.png Red Checker.png

http://i.stack.imgur.com/cdF7u.png Red Checker.png

http://i.stack.imgur.com/JNT61.png Space.png

http://i.stack.imgur.com/JNT61.png Space.png

推荐答案

两个问题,在我看来,您的代码做错了。

Two thingies, it appears to me that you doing wrong in your code.


  • 首先请检查您在
    legitClick()方法中指定的条件单击时,它始终返回false(legitClick)。因此,视图不会显示任何更改。

  • 似乎您在 makeSlot() JButton 。 $ c>并不是您想要的,您只需更改相应的 JButton Icon 图标,而不是创建一个新的图标即可。

  • First do check the condition that you specifying inside your legitClick() method, no matter when you click, it always returns false (legitClick). Hence no change will appear to the view.
  • It appears that you creating a new JButton inside a makeSlot(), which is not exactly what you want, you simply have to change the Icon for the respective JButton instead of creating a new one.

我在 makeSlot()方法和 legitClick()方法,尽管您必须自己更改逻辑以使其真正按需要工作,因为我不知道检查程序的工作方式:(

I had modified the code a bit, inside the makeSlot() method and legitClick() method, though you have to change the logic yourself to actually make it work as you wanted, since I don't know how checkers work :(

import java.awt.Container;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Scanner;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;

import javax.swing.*;

public class GameFrame extends JFrame {

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    frame = new GameFrame();
                    frame.setContentPane(new JLabel(new ImageIcon(getClass()
                            .getResource("/image/675 x 588 Connect Four.png"))));
                    frame.addSlots();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */

    static GameFrame frame;
    private static Icon slotForButton;
    public static JButton slotButton;
    static private JButton[] slot = new JButton[42];
    static private String[] slotColor = new String[42];
    static boolean turn = true;
    static boolean legitClick;
    static String slotClicked;
    static int slotNum;
    static Container gamePane;

    public GameFrame() {
        setBounds(100, 100, 685, 622);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setResizable(false);
        super.setTitle("Connect Four by Joel Christophel");
    }

    void addSlots() {
        ButtonHandler bh = new ButtonHandler();
        gamePane = getContentPane();
        gamePane.setLayout(new GridLayout(6, 6));

        for (int counter = 0; counter < slot.length; counter++) {
            // Added by me.
            slot[counter] = new JButton();
            slot[counter].setIcon(makeSlot("white", counter));
            slot[counter].setBorderPainted(false);
            slot[counter].setContentAreaFilled(false);
            slot[counter].setFocusPainted(false);
            slot[counter].setActionCommand(counter + "");
            slotColor[counter] = "white";

            slot[counter].addActionListener(bh);
            add(slot[counter]);

            //counter++;
        }
    }

    static Icon makeSlot(String color, int index) {

        if (color.equals("white")) {
            slotForButton = new ImageIcon(
                    GameFrame.class.getResource("/image/Space.png"));
        }

        else if (color.equals("red")) {
            slotForButton = new ImageIcon(
                    GameFrame.class.getResource("/image/Red Checker.png"));
        }

        else if (color.equals("black")) {
            slotForButton = new ImageIcon(
                    GameFrame.class.getResource("/image/Black Checker.png"));
        }

        //slot[index].setIcon(slotForButton);

        return slotForButton;
    }

    private class ButtonHandler implements ActionListener {

        public void actionPerformed(ActionEvent e) {
            slotClicked = e.getActionCommand();

            GameFrame.legitClick(slotClicked);
        }

    }

    private static void changeTurn() {
        turn = !turn; // true is red's turn; false is black's
    }

    private static void legitClick(String slotClicked1) {
        legitClick = false;

        slotClicked = slotClicked1;
        Scanner numScan = new Scanner(slotClicked);
        slotNum = numScan.nextInt();

        try {
            if (slotColor[slotNum + 7].equals("white")&&slotColor[slotNum].equals("white")) {
                legitClick = true;
            }
        }

        catch (ArrayIndexOutOfBoundsException t) {

            if (slotColor[slotNum].equals("white")) {
                legitClick = true;
            }
        }

        /*
         * This variable is used to tell
         * makeSlot that the JButton at
         * this index is pressed. So
         * simply change the Icon for this
         * JButton, instead of adding a new 
         * JButton.
         */
        int index = Integer.parseInt(slotClicked1);

        if (legitClick == true) {
            if (turn == true) {
                slot[index].setIcon(makeSlot("red", index));
                slotColor[slotNum] = "red";
                System.out.println("Put " + slotColor[slotNum] + " checker     in slot number " + slotNum + ".");
            }

            else if (turn == false) {
                slot[index].setIcon(makeSlot("black", index));
                slotColor[slotNum] = "black";
                System.out.println("Put " + slotColor[slotNum] + " checker      in slot number " + slotNum + ".");
            }

            //gamePane.validate();
            GameFrame.changeTurn();
        }
        System.out.println(turn);
    }

}

这篇关于尽管使用validate(),GUI也未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆