JPanel对MouseEvents没有反应?

时间:2015-11-22 15:35:59

标签: java swing jpanel mouseevent mouselistener

我正在尝试创建一个“Tic Tac Toe”游戏。我选择创建一个JPanel变体来代表每个方块。下面的类代表了9个面板中的一个,这些面板组成了我的游戏板。
现在我遇到的问题是,当我点击面板时,应该在面板内部显示“X”,但没有任何反应。如果有人引导我朝着正确的方向前进,我将非常感激。

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

public class TicTacToePanel extends JPanel implements MouseListener {
    private boolean isPlayer1Turn = true;
    private boolean isUsed = false;
    private JLabel ticTacLbl = new JLabel();

    public TicTacToePanel() {
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        addMouseListener(this);
    }

    public void mouseClicked(MouseEvent e) {
        if (!isUsed) {
            if (isPlayer1Turn) {
                ticTacLbl.setForeground(Color.red);
                ticTacLbl.setText("X");
                add(ticTacLbl, 0);
                isUsed = true;
            } else {
                ticTacLbl.setForeground(Color.blue);
                ticTacLbl.setText("O");
                add(ticTacLbl, 0);
                isUsed = true;
            }

        } else {

        }
    }

    public void mousePressed(MouseEvent e) {

    }

    public void mouseReleased(MouseEvent e) {

    }

    public void mouseEntered(MouseEvent e) {

    }

    public void mouseExited(MouseEvent e) {

    }

    public static void main(String[] args) {
        JOptionPane.showMessageDialog(null, new TicTacToePanel());
    }

}

编辑: 我只是在我的TicTacToePanel的构造函数中添加了我的标签组件,这样我就不必再调用revalidate()了,而且我不会在运行时添加组件。

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

public class TicTacToePanel extends JPanel implements MouseListener{
    private boolean isPlayer1Turn = true;
    private boolean isUsed = false;
    private JLabel ticTacLbl = new JLabel();

    public TicTacToePanel(){
        add(ticTacLbl, 0);
        setBorder(BorderFactory.createLineBorder(Color.BLACK));
        addMouseListener(this);
    }

    public void mouseClicked(MouseEvent e){

    }

    public void mousePressed(MouseEvent e){
        if (!isUsed) {
            if (isPlayer1Turn) {
                ticTacLbl.setForeground(Color.red);
                ticTacLbl.setText("X");
                isUsed = true;
            } else {
                ticTacLbl.setForeground(Color.blue);
                ticTacLbl.setText("O");
                isUsed = true;
            }

        }
        else{

        }

    }

     public void mouseReleased(MouseEvent e){

    }

    public void mouseEntered(MouseEvent e){

    }

    public void mouseExited(MouseEvent e){

    }   

     public static void main(String[] args){
        JOptionPane.showMessageDialog(null, new TicTacToePanel());
    }
}

GUI构造函数:

     public TicTacToeGUI(int gameMode){
        if(gameMode == 0){
            amountOfPanels = 9;
            TicTacToePanel[] panelArr = new TicTacToePanel[amountOfPanels];
            add(gamePanel, new GridLayout(3, 3));
            setPreferredSize(new Dimension(100, 100));
            for(int i = 0; i < amountOfPanels; i++){
                panelArr[i] = new TicTacToePanel();
                gamePanel.add(panelArr[i]);
            }   
        }
        else if(gameMode == 1){
            amountOfPanels = 225;
            TicTacToePanel[] panelArr = new TicTacToePanel[amountOfPanels];
            add(gamePanel, new GridLayout(15, 15));
            setPreferredSize(new Dimension(500, 500));
            for(int i = 0; i < amountOfPanels; i++){
                panelArr[i] = new TicTacToePanel();
                gamePanel.add(panelArr[i]);
            }
        }

    }

    public static void main(String[] args){
        JOptionPane.showMessageDialog(null, new TicTacToeGUI(0));
    }
}

2 个答案:

答案 0 :(得分:2)

在运行时添加/删除组件时,请务必在之后调用revalidate()revalidate()使组件刷新/重新布局。

所以只需在添加标签后调用revalidate()即可。

答案 1 :(得分:2)

如果你的目标是创建一个Tic Tac Toe游戏,那么你可能希望重新考虑你当前在GUI中添加组件的策略。更好的是创建一个组件网格,比如JLabel,并在程序启动时将它们放在JPanel上。通过这种方式,您可以更改按下的JLabel文本和颜色,甚至可以更改其图标,如果您希望在程序运行期间不必添加或删除组件。例如:

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

@SuppressWarnings("serial")
public class TicTacToePanel extends JPanel {
    private static final int ROWS = 3;
    private static final int MY_C = 240;
    private static final Color BG = new Color(MY_C, MY_C, MY_C);
    private static final int PTS = 60;
    private static final Font FONT = new Font(Font.SANS_SERIF, Font.BOLD, PTS);
    public static final Color X_COLOR = Color.BLUE;
    public static final Color O_COLOR = Color.RED;
    private JLabel[][] labels = new JLabel[ROWS][ROWS];
    private boolean xTurn = true;

    public TicTacToePanel() {
        setLayout(new GridLayout(ROWS, ROWS, 2, 2));
        setBackground(Color.black);

        MyMouse myMouse = new MyMouse();
        for (int row = 0; row < labels.length; row++) {
            for (int col = 0; col < labels[row].length; col++) {
                JLabel label = new JLabel("     ", SwingConstants.CENTER);
                label.setOpaque(true);
                label.setBackground(BG);
                label.setFont(FONT);
                add(label);
                label.addMouseListener(myMouse);
            }
        }
    }

    private class MyMouse extends MouseAdapter {
        @Override // override mousePressed not mouseClicked
        public void mousePressed(MouseEvent e) {
            JLabel label = (JLabel) e.getSource();
            String text = label.getText().trim();
            if (!text.isEmpty()) {
                return;
            }
            if (xTurn) {
                label.setForeground(X_COLOR);
                label.setText("X");
            } else {
                label.setForeground(O_COLOR);
                label.setText("O");
            }

            // information to help check for win
            int chosenX = -1;
            int chosenY = -1;
            for (int x = 0; x < labels.length; x++) {
                for (int y = 0; y < labels[x].length; y++) {
                    if (labels[x][y] == label) {
                        chosenX = x;
                        chosenY = y;
                    }
                }
            }
            // TODO: check for win here
            xTurn = !xTurn;
        }
    }

    private static void createAndShowGui() {
        TicTacToePanel mainPanel = new TicTacToePanel();

        JFrame frame = new JFrame("Tic Tac Toe");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.getContentPane().add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                createAndShowGui();
            }
        });
    }
}