![](/img/trans.png)
[英]Why JLabel isn't refreshing when setText() method is called within jpanel.paintComponent()?
[英]Why isn't setText updating the JLabel?
我在这里检查了其他线程,但没有找到解决方案。
1)JFrame是setVisible(true)。
2)这意味着什么:“我想知道您的问题是否是并发问题,您正在Swing事件线程上运行一个长时间运行的进程,并且这阻止了标签更新其文本。” 我在其他地方读过。
3)我没有多次初始化包含标签的JPanel。
编辑:4)从包含TrackingPanel
(即gamePanel
)的JPanel调用gamePanel
。 我称方法changeTurns();
这是该代码:
public void changeTurns() {
if(turnPlayer == playerX)
turnPlayer = playerO;
else
turnPlayer = playerX;
trackingPanel.updateTurn();
}
这是完整的相关代码:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TrackingPanel extends JPanel{
/*TURN STUFF*/
private JPanel turnPanel; //turns panel to keep track of whose turn it is
private JLabel turnLabel;
private String turn;
/*OTHER*/
private GamePanel gamePanel;
public TrackingPanel( GamePanel gamePan ) {
setLayout( new GridLayout(1,4) );
setBorder(BorderFactory.createMatteBorder(2,2,4,2,Color.BLACK));
gamePanel = gamePan;
/*THIS PANEL DISPLAYS THE TEXT*/
turnPanel = new JPanel( new GridLayout(2,1) );
turn = gamePanel.getPlayerTurn().getLetter();
turnLabel = new JLabel(" Player " + turn + "'s turn");
add( turnPanel);
}//end constructor
/*THIS IS WHERE THINGS GO WRONG*/
public void updateTurn() {
turn = gamePanel.getPlayerTurn().getLetter();
turnLabel.setText( " Player" + turn + "'s turn" );
System.out.println(turn);
}
}
在updateTurn()
之前, turnLabel
说“ PlayerX的转弯”。 之后,应该说“ PlayerO轮到我了”。 通过打印turn
牌(我得到的是字符串'O'而不是'X'),我知道所显示的内容(“ PlayerX的转弯”)不是应该显示的内容(“ PlayerO的转弯”)。
在此先感谢您的支持!
编辑。 尝试提供SSCCE,但不知道如何包含图像文件。 抱歉!
尝试使用此:
private void setText(final JLabel label, final String text){
label.setText(text);
label.paintImmediately(label.getVisibleRect());
}
我将确保您的方法updateTurn()使用SwingUtilities.invokeLater(new Runnable())方法在Swing的线程中调用其代码。
我已经更改了您的代码,使其不需要图像,现在添加了turnLabel。 它仍然太大,但是可以运行并显示一些行为:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import javax.swing.*;
public class GameFrame extends JFrame {
public static void main(String[] args) {
JFrame gameFrame = new JFrame("MyGame");
gameFrame.setResizable(false);
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameFrame.add(new GamePanel());
gameFrame.pack();
gameFrame.setVisible(true);
}
}
class GamePanel extends JPanel implements ActionListener {
private BoardPanel boardPanel; // comprised of 9 mini panels
/* RELEVANT */
private static TrackingPanel trackingPanel; // keeps track of score, turn,
// and stuff
private static Player playerX, playerO, turnPlayer;
private ArrayList<MiniGame> miniGames;
private Graphics graphics;
private Graphics2D graphics2D;
// constructor
public GamePanel() {
super(new BorderLayout());
setFocusable(true);
// create 2 new players, and make it X's turn
playerX = new Player(true, "X");
turnPlayer = playerX;
playerO = new Player(true, "O");
// create tracking panel that will keep track of turns and stuff
trackingPanel = new TrackingPanel(this);
trackingPanel.setBorder(BorderFactory.createLineBorder(Color.red)); //!!
System.out.println("line border added");
// create panel that will hold the 9 mini games
boardPanel = new BoardPanel(this);
// add actionListeners to each button
miniGames = boardPanel.getMiniGames();
for (MiniGame mini : miniGames) {
for (SquareButton button : mini.getSquares())
button.addActionListener(this);
}
// add the tracking and board panels
add(trackingPanel, BorderLayout.NORTH);
add(boardPanel, BorderLayout.CENTER);
}// end constructor
public void actionPerformed(ActionEvent e) {
// loop through mini games
miniGameLoop: for (int gameNum = 0; gameNum < 9; gameNum++) {
MiniGame mini = miniGames.get(gameNum);
SquareButton[] buttons = mini.getSquares();
// loop through buttons of each mini game
for (int buttonNum = 0; buttonNum < 9; buttonNum++) {
SquareButton button = buttons[buttonNum];
// if user clicked on one of the squares on the board
if (e.getSource() == button) {
// if the space isn't already taken
if (button.isEmpty()) {
// mark the space with the player's letter
// !! removed
// ImageIcon icon = new ImageIcon(getClass().getResource(
// "/Images/" + turnPlayer.getLetter() + ".PNG"));
// button.setIcon(icon);
button.setText(turnPlayer.getLetter()); //!! added
button.setEmpty(false);
// change turns
changeTurns();
// exit loops
break miniGameLoop;
}
}
}// end loop through squares
}// end loop through minigames
}// end actionPerformed method
public static Player getPlayer(String letter) {
if (letter == "X")
return playerX;
else
return playerO;
}
public Player getPlayerTurn() {
return turnPlayer;
}
public TrackingPanel getTrackingPanel() {
return trackingPanel;
}
/* RELEVANT */
public void changeTurns() {
if (turnPlayer == playerX)
turnPlayer = playerO;
else
turnPlayer = playerX;
trackingPanel.updateTurn();
}
}// end class GamePanel
class BoardPanel extends JPanel {
private ArrayList<MiniGame> miniGames;
// constructs main panel and places all 9 mini games inside
public BoardPanel(GamePanel gp) {
super(new GridLayout(3, 3));
// add miniGames to arrayList
miniGames = new ArrayList<MiniGame>(9);
for (int i = 1; i <= 9; i++)
miniGames.add(new MiniGame(gp, i));
// add minigames to board
for (MiniGame mini : miniGames)
add(mini);
}
public void reset() {
for (MiniGame mini : miniGames)
mini.clear();
}
public ArrayList<MiniGame> getMiniGames() {
return miniGames;
}
}
@SuppressWarnings("serial")
class TrackingPanel extends JPanel {
/* TURN STUFF */
private JPanel turnPanel; // turns panel to keep track of whose turn it is
private JLabel turnLabel;
private String turn;
/* OTHER */
private GamePanel gamePanel;
public TrackingPanel(GamePanel gamePan) {
setLayout(new GridLayout(1, 4));
setBorder(BorderFactory.createMatteBorder(2, 2, 4, 2, Color.BLACK));
gamePanel = gamePan;
/* THIS PANEL DISPLAYS THE TEXT */
turnPanel = new JPanel(new GridLayout(2, 1));
turn = gamePanel.getPlayerTurn().getLetter();
turnLabel = new JLabel(" Player " + turn + "'s turn");
turnPanel.add(turnLabel);
add(turnPanel);
}// end constructor
/* THIS IS WHERE THINGS GO WRONG */
public void updateTurn() {
turn = gamePanel.getPlayerTurn().getLetter();
turnLabel.setText(" Player" + turn + "'s turn");
System.out.println(turn);
}
}
class MiniGame extends JPanel {
private SquareButton[] squares;
private SquareButton[] line1, line2, line3, line4, line5, line6, line7,
line8;
private ArrayList<SquareButton[]> lines;
private int ThreeinARowButtonCount;
private int panelNum;
private TrackingPanel trackingPanel;
private int[] winningLine;
private Player winner;
private boolean gameIsOver;
private Image gameOverIcon;
public MiniGame(GamePanel gp, int num) {
// setlayout of the mini games
super(new GridLayout(3, 3));
setFocusable(true);
setPreferredSize(new Dimension(220, 220));
// setPreferredSize(new Dimension(100,100));
trackingPanel = gp.getTrackingPanel();
panelNum = num;
if (panelNum == 1)
setBorder(BorderFactory.createMatteBorder(0, 0, 2, 2, Color.BLACK));
else if (panelNum == 2)
setBorder(BorderFactory.createMatteBorder(0, 2, 2, 2, Color.BLACK));
else if (panelNum == 3)
setBorder(BorderFactory.createMatteBorder(0, 2, 2, 0, Color.BLACK));
else if (panelNum == 4)
setBorder(BorderFactory.createMatteBorder(2, 0, 2, 2, Color.BLACK));
else if (panelNum == 5)
setBorder(BorderFactory.createMatteBorder(2, 2, 2, 2, Color.BLACK));
else if (panelNum == 6)
setBorder(BorderFactory.createMatteBorder(2, 2, 2, 0, Color.BLACK));
else if (panelNum == 7)
setBorder(BorderFactory.createMatteBorder(2, 0, 0, 2, Color.BLACK));
else if (panelNum == 8)
setBorder(BorderFactory.createMatteBorder(2, 2, 0, 2, Color.BLACK));
else
setBorder(BorderFactory.createMatteBorder(2, 2, 0, 0, Color.BLACK));
// create list of buttons (each square)
squares = new SquareButton[9];
// create squares and add squares to mini game
for (int i = 0; i < squares.length; i++) {
squares[i] = new SquareButton(i);
add(squares[i]);
}
}// end constructor
public void clear() {
// TODO this method was not present!!!!! Trying to reconstruct it
}
public int getPanelNum() {
return panelNum;
}
public SquareButton[] getSquares() {
return squares;
}
public boolean isOver() {
return gameIsOver;
}
}
class SquareButton extends JButton {
private boolean empty;
private String letter;
private int squareNum;
public SquareButton(int num) {
empty = true;
squareNum = num;
if (num == 0)
setBorder(BorderFactory.createMatteBorder(0, 0, 1, 1, Color.BLACK));
else if (num == 1)
setBorder(BorderFactory.createMatteBorder(0, 1, 1, 1, Color.BLACK));
else if (num == 2)
setBorder(BorderFactory.createMatteBorder(0, 1, 1, 0, Color.BLACK));
else if (num == 3)
setBorder(BorderFactory.createMatteBorder(1, 0, 1, 1, Color.BLACK));
else if (num == 4)
setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, Color.BLACK));
else if (num == 5)
setBorder(BorderFactory.createMatteBorder(1, 1, 1, 0, Color.BLACK));
else if (num == 6)
setBorder(BorderFactory.createMatteBorder(1, 0, 0, 1, Color.BLACK));
else if (num == 7)
setBorder(BorderFactory.createMatteBorder(1, 1, 0, 1, Color.BLACK));
else
setBorder(BorderFactory.createMatteBorder(1, 1, 0, 0, Color.BLACK));
}
public String getLetter() {
return letter;
}
public boolean isEmpty() {
return empty;
}
public void setEmpty(boolean em) {
empty = em;
}
public int getSquareNum() {
return squareNum;
}
}
class Player {
private boolean human; // indicates if player is human or cpu
private int score;
private String letter;
// constructor
public Player(boolean hum, String let) {
// player is human or computer
human = hum;
letter = let;
}
/* PLAYER METHODS */
public boolean isHuman() {
return human;
}
public void setHuman(boolean h) {
human = h;
}
public String getLetter() {
return letter;
}
}
但有趣的是,turnLabel会像上面的示例一样更改其文本。 因此,现在您必须尝试隔离错误,因为它可能在遗漏的代码中。 就像您在问题中提到的那样,这可能与并发有关:
2)这意味着什么:“我想知道您的问题是否是并发问题,您正在Swing事件线程上运行一个长时间运行的进程,并且这阻止了标签更新其文本。” 我在其他地方读过。
因此,也许您的运行过程很漫长,而您没有在上面的代码中向我们展示。
另外,您的代码过度使用了静态字段反模式。 大部分都是静态字段不应该是一成不变的。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.