0

Why is my repaint method not called here?

package UI;

import Observer.Obs;

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

public class InfoPanel extends JPanel implements Obs
{
    String bTime = "1:00";
    String wTime = "1:00";
    String chessMessage = "黑方先行";
    int i = 1;

    JLabel blackTime = new JLabel("黑方用时:" + bTime, JLabel.LEFT);
    JLabel chessInfo = new JLabel("游戏信息:" + chessMessage, JLabel.CENTER);
    JLabel whiteChess = new JLabel("白方用时:" + wTime, JLabel.RIGHT);

    public InfoPanel() throws InterruptedException
    {
//        this.setSize(1000,30);
//        this.add(blackTime);
//        this.add(chessInfo);
//        this.add(whiteChess);
//        this.paint();
    }

    public void paint(Graphics g)
    {
        System.out.println("1、paint");
        g.drawString("黑方用时:"+bTime,250,10);
        g.drawString(chessMessage,500,10);
        g.drawString("白方用时:"+wTime,750,10);
        System.out.println(chessMessage);
        System.out.println("2、paint");
    }

    public void updateChessMessage() throws InterruptedException
    {
        if (i % 2 == 0)
        {
            chessMessage = "轮到黑方";
        } else
        {
            chessMessage = "轮到白方";
        }
        i++;
//        chessInfo.setText(chessMessage);
//        chessInfo.updateUI();
//        Thread.sleep(1000);
//        System.out.println(chessInfo.getText());
//        System.out.println("开始重绘");
        this.repaint();
//        System.out.println("重绘结束");
    }

    @Override
    public void response() throws InterruptedException
    {
        updateChessMessage();
        System.out.println("开始重绘");
        this.repaint();
        System.out.println("重绘结束");
//        new Thread(() ->
//        {
//            try
//            {
//                updateChessMessage();
//                System.out.println("开始重绘");
//                InfoPanel.this.repaint();
//                System.out.println("重绘结束");
//            }
//            catch (InterruptedException e)
//            {
//                e.printStackTrace();
//            }
//        }).start();
    }

}

my output is 保存成功 1、paint 黑方先行 2、paint 保存成功 开始重绘 重绘结束 保存成功 开始重绘 重绘结束 保存成功 开始重绘 重绘结束

Obviously here, he did not call the repaint method, but his previous output statement did call. I am not sure why, but for some reason my repaint method is not working.I also have println(); statements to help me check.

1 Answers1

1
  • Firstly, you should override method paintComponent and not method paint.
  • Secondly, the first line in your overridden paintComponent method should be:
super.paintComponent(g)
  • Thirdly, the code in your question is not a minimal, reproducible example
  • Fourthly, from the code in your question, I get the impression that you may be calling method repaint from a thread which is not the Event Dispatch Thread (EDT) and which you should not do.

Perhaps the lesson Performing Custom Painting will be of help.

Abra
  • 19,142
  • 7
  • 29
  • 41
  • `repaint()` is thread safe and does not need to be called on the EDT see [here](https://stackoverflow.com/q/9786497/1133011) – David Kroukamp Dec 21 '20 at 07:11
  • I realise those links are obsolete so [here](https://www.oracle.com/java/technologies/painting.html#paint_process) is an updated link. "JComponent.repaint() registers an asynchronous repaint request to the component's RepaintManager, which uses invokeLater() to queue a Runnable to later process the request on the event dispatching thread." – David Kroukamp Dec 21 '20 at 07:22