Java 贾拉贝尔赢得';t显示图像
我正在用Java创建一个Tic-Tac-Toe游戏。现在,当你点击一个按钮时,Java 贾拉贝尔赢得';t显示图像,java,swing,jbutton,jlabel,Java,Swing,Jbutton,Jlabel,我正在用Java创建一个Tic-Tac-Toe游戏。现在,当你点击一个按钮时,JButton将从JPanel中删除,包含X或O图像的JLabel将被添加,并且JPanel将被重新绘制。但是,当我单击按钮时,图像不会显示,但按钮消失 创建按钮和标签/图像: package tictactoe; import javax.swing.*; import java.awt.*; import java.awt.event.*; import javax.swing.ImageIcon; public
JButton
将从JPanel
中删除,包含X或O图像的JLabel
将被添加,并且JPanel
将被重新绘制。但是,当我单击按钮时,图像不会显示,但按钮消失
创建按钮和标签/图像
:
package tictactoe;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.ImageIcon;
public class TicTacToe implements ActionListener
{
private JFrame holder = new JFrame();
private GridLayout layout = new GridLayout(3,3);
private FlowLayout panel = new FlowLayout(FlowLayout.CENTER);
private JPanel p11, p12, p13, p21, p22, p23, p31, p32, p33;
private JButton b1, b2, b3, b4, b5, b6, b7, b8, b9;
private ImageIcon iconX = new ImageIcon("iconX.png");
private JLabel xLabel = new JLabel(iconX);
private ImageIcon iconO = new ImageIcon("iconO.png");
private JLabel oLabel = new JLabel(iconO);
private int turn;
private char s1, s2, s3, s4, s5, s6, s7, s8, s9;
public TicTacToe()
{
paint();
}
private void paint()
{
holder.setLayout(layout);
holder.setSize(300,300);
b1 = new JButton("1");
p11 = new JPanel();
p11.setLayout(panel);
p11.add(b1);
holder.add(p11);
//Same block of code for the next 8 buttons/panels inserted here
holder.setVisible(true);
b1.addActionListener(this);
//Other action listeners inserted here
}
@Override
public void actionPerformed(ActionEvent e)
{
if (e.getSource() == b1)
{
++turn;
p11.remove(b1);
if (turn % 2 == 1) { s1 = 'x'; p11.add(xLabel); }
else if (turn % 2 == 0) { s1 = 'o'; p11.add(oLabel); }
p11.repaint();
}
//Other action events inserted here
}
public static void main(String[] args)
{
TicTacToe game = new TicTacToe();
}
}
尝试调用
revalidate()代码>然后重新绘制()在JPanel
s实例上的code>如下所示:
p11.revalidate();
p11.repaint();
当添加或删除组件时,需要调用revalidate()
此调用是一条指令,指示布局管理器
根据新的组件
列表进行重置revalidate()
将触发对组件认为是“脏区域”的repaint()调用。RepaintManager
显然不会认为JPanel
上的所有区域都脏
repaint()
用于通知组件重新绘制自身。通常情况下,您需要调用此函数来清理像您这样的条件
@Override
public void actionPerformed(final ActionEvent e)
{
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
if (e.getSource() == b1) {
++turn;
p11.remove(b1);
if (turn % 2 == 1) { s1 = 'x'; p11.add(new JLabel(iconX)); }
else { s1 = 'o'; p11.add(new JLabel(iconO)); }
//p11.revalidate();
//p11.repaint();
}
**Other action events inserted here
}
});
}
invokeLater构造的语法有点多,但是让事件处理线程处理按钮单击,然后再进行更改。否则,您不能依赖于立即重新绘制,gui的响应性会降低。(可运行对象只能从外部访问final变量,即:不再分配给的变量。)
像JLabel
这样的组件的父组件只有一个字段。因此,不能重用一个组件。因此,出现了新的JLabel()
关于重新粉刷;请务必先尝试,不要自己触发它。如果您也解释一下为什么这种方法会起作用,可能会很有用。