繁体   English   中英

当输入子级时,JPanel获取paintComponent被调用

[英]JPanel gets paintComponent gets called when child is entered

此处以前的一些条目解决了反复调用paintComponent()的问题,但答案取决于paintComponent本身调用的repaint()。

使用Nimbus L&F,如果我继承了JPanel并添加JButton或JTextField,则无论何时进入或离开子级,都会调用JPanel的paintComponent()方法。 另外,如果JTextField获得焦点,则文本字段位置光标的每次闪烁都会调用面板的paintComponent()方法。 我的paintComponent()方法除了打印正在调用的东西外没有做其他事情。 这是一个例子:

import java.awt.Dimension;
import java.awt.Graphics;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Tester extends JPanel {

   public Tester() {
      JPanel p = new JPanel();
      JTextField t1 = new JTextField( "text in nested panel" );
      p.add( t1 );
      this.add( p );

      JTextField t2 = new JTextField( "text" );
      this.add( t2 );

      JButton b = new JButton( "button" );
      this.add( b );
      setPreferredSize( new Dimension( 400, 200 ) );
   }

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

   public static void main( final String[] args ) {
      SwingUtilities.invokeLater( new Runnable() {
         @Override
            try {
               for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
                  if ( "Nimbus".equals( info.getName() ) ) {
                     UIManager.setLookAndFeel( info.getClassName() );
                     break;
                  }
               }
            } catch (Exception ex) {
               System.out.println( "No Nimbus" );
            }

            final String name = new String( "GuiViewer" );
            final JFrame jf = new JFrame( name );
            jf.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
            final Tester comp = new Tester();

            jf.add( comp );
            jf.pack();
            jf.setVisible( true );
         }
      } );
   }

}

当您单击第一个文本字段(嵌套在另一个JPanel中)时,不会连续调用paintComponent()。 但是,如果您单击第二个,则将不断收到呼叫。 如果注释掉Nimbus L&F的设置,则paintComponent()不会重复调用。 JTextField和JButton的Nimbus实现就像它们的paintComponent方法调用parent.repaint()一样。 这是Nimbus中的bug,还是设计使然?

这似乎是Nimbus的设计选择。

如果检查JTextField#isOpaque的结果,则返回false (使其透明)。 这意味着,无论何时重新绘制组件,都必须首先重新绘制父容器。

每次插入符号更新时, JTextField都会触发重新绘制(打开和关闭闪烁)

您的第一个JTextField不会在Tester上引起重新绘制的原因是因为它位于不透明的容器内,因此只有其直接父容器会被重新绘制。

尝试使JTextField不透明( t2.setOpaque(true); ),看看会发生什么

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM