![](/img/trans.png)
[英]When I modify a JPanel after it becomes visible, paintComponent gets called before componentResized
[英]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.