[英]JPanel gets paintComponent gets called when child is entered
Some previous entries here address paintComponent() being called repeatedly, but the answers hinged on paintComponent itself calling repaint(). 此处以前的一些条目解决了反复调用paintComponent()的问题,但答案取决于paintComponent本身调用的repaint()。
Using Nimbus L&F, if I subclass JPanel and add a JButton or JTextField, then my JPanel's paintComponent() method gets called whenever I enter or leave a child. 使用Nimbus L&F,如果我继承了JPanel并添加JButton或JTextField,则无论何时进入或离开子级,都会调用JPanel的paintComponent()方法。 In addition, if the JTextField gets focus, my panel's paintComponent() method gets called for every flash of the text field's position cursor.
另外,如果JTextField获得焦点,则文本字段位置光标的每次闪烁都会调用面板的paintComponent()方法。 My paintComponent() method does nothing other than print that it is being called.
我的paintComponent()方法除了打印正在调用的东西外没有做其他事情。 Here's an example:
这是一个例子:
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 );
}
} );
}
}
When you click in the first text field (nested inside another JPanel), you do not get continual calls to paintComponent(). 当您单击第一个文本字段(嵌套在另一个JPanel中)时,不会连续调用paintComponent()。 But if you click in the second one, you continually get calls.
但是,如果您单击第二个,则将不断收到呼叫。 If you comment out the setting of Nimbus L&F, the paintComponent() doesn't get repeated calls.
如果注释掉Nimbus L&F的设置,则paintComponent()不会重复调用。 The Nimbus implementation of JTextField and JButton act like their paintComponent method calls parent.repaint().
JTextField和JButton的Nimbus实现就像它们的paintComponent方法调用parent.repaint()一样。 Is this a bug in Nimbus, or is it that way by design?
这是Nimbus中的bug,还是设计使然?
This seems to be a design choice of Nimbus. 这似乎是Nimbus的设计选择。
If you inspect the result of JTextField#isOpaque
, it returns false
(making it transparent). 如果检查
JTextField#isOpaque
的结果,则返回false
(使其透明)。 This means that when ever the component is repainted, the parent container must first be repainted as well. 这意味着,无论何时重新绘制组件,都必须首先重新绘制父容器。
The JTextField
is triggering a repaint each time the caret is updated (blinks on and off) 每次插入符号更新时,
JTextField
都会触发重新绘制(打开和关闭闪烁)
The reason why your first JTextField
doesn't cause a repaint on the Tester
is because it's sitting inside a opaque container, so only it's immediate parent container will be repainted. 您的第一个
JTextField
不会在Tester
上引起重新绘制的原因是因为它位于不透明的容器内,因此只有其直接父容器会被重新绘制。
Try making the JTextField
opaque ( t2.setOpaque(true);
) and see what happens 尝试使
JTextField
不透明( t2.setOpaque(true);
),看看会发生什么
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.