Java 重新绘制未调用paintComponent

Java 重新绘制未调用paintComponent,java,swing,Java,Swing,重新绘制未调用PaintComponent。 我也试图从Try类的另一个方法调用它,但并没有成功 import java.awt.*; import java.awt.event.*; import javax.swing.*; import java.util.*; public class Try extends JPanel { int i =0; @Override public void paintComponent(Graphics g){

重新绘制未调用PaintComponent。
我也试图从Try类的另一个方法调用它,但并没有成功

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

public class Try extends JPanel {
    int i =0;

    @Override
    public void paintComponent(Graphics g){
       //super.paintComponent(g);
       System.out.println("hey");
   }

    public static void main(String[] args) {
       JFrame f=new JFrame();
       Try t = new Try();
       f.setSize(500,600);//400 width and 500 height

       Container contentPane = f.getContentPane();
       contentPane.add(new PaintComponent());
       f.setVisible(true);//making the frame visible

       while(true){
          t.repaint();
       }
    }
 }

有多个问题,@trashgood在评论中提到了其中一些问题

  • 您正在对未添加到内容窗格中的实例调用Repain-您在那里有一个不同的实例(实际上,您在那里有完全不同的内容-
    new PaintComponent()

  • 不要移除
    super.paintComponent(g)除非您自己清理该区域(如果不透明,则几乎填充整个组件背景),否则在重新绘制时,这些组件将出现视觉故障

  • 您正在滥发重新绘制操作,这是非常糟糕的,请在重新绘制之间至少进行一些延迟,以提供执行重新绘制的Swing时间。最好的情况是,仅当组件实际在视觉上显示不同的内容时,才重新绘制组件。如果需要始终更新视图,请至少将其限制为每秒30-60帧(重新绘制)。此外,一些内部Swing优化可能会“吃掉”一些重绘调用,因此您可能不会看到像在组件上调用的大量重绘那样多的
    paintComponent
    调用

  • 您正在事件分派线程(简称EDT)之外使用Swing组件,这可能会导致问题。确保始终使用它来创建Swing组件,并对其调用任何方法<代码>SwingUtilities有助于实现这一点

  • 任何需要很长时间(或未知时间)才能完成的繁重操作都应该在EDT之外执行,否则,您的UI将在等待该操作完成时挂起,因为所有UI更新都是在EDT上执行的,而不是在其他任何地方

  • 考虑到我上面所说的,您的示例应该是这样的:

    public class Try extends JPanel
    {
        @Override
        public void paintComponent ( final Graphics g )
        {
            super.paintComponent ( g );
    
            final Graphics2D g2d = ( Graphics2D ) g;
            g2d.drawString ( Long.toString ( System.currentTimeMillis () ), 25, 35 );
    
            System.out.println ( "repainted" );
        }
    
        public static void main ( final String[] args )
        {
            SwingUtilities.invokeLater ( new Runnable ()
            {
                @Override
                public void run ()
                {
                    final JFrame f = new JFrame ();
    
                    final Try t = new Try ();
                    f.getContentPane ().add ( t );
    
                    f.setSize ( 500, 600 );
                    f.setVisible ( true );
    
                    new Thread ( new Runnable ()
                    {
                        @Override
                        public void run ()
                        {
                            try
                            {
                                while ( true )
                                {
                                    t.repaint ();
                                    Thread.sleep ( 25 );
                                }
                            }
                            catch ( final InterruptedException e )
                            {
                                //
                            }
                        }
                    } ).start ();
                }
            } );
        }
    }
    
    希望这能为你澄清一点

    还有一个
    SwingWorker
    类可以帮助在Swing中执行长时间运行的任务,但我在这里使用它并不是为了使示例尽可能简单


    还有一个附带说明-您不需要在EDT中调用
    repaint()
    ,因为它自己会将重新绘制请求发送给EDT,所以该方法可以安全地在任何线程上使用(就像我在示例中所做的那样)。

    也许您的意思是
    contentPane.add(new Try())
    。另外,不要阻塞EDT;请务必查看和。并且不要删除
    super.paintComponent()
    行,请按照了解其工作原理感谢@Mikle示例