之前我问过这个问题,但理论上只是在没有SSCCE的情况下问过。现在,我创建了一个,问题仍然存在。我想知道为什么paintComponent
未在repaint(x, y, w, h)
上调用,而是在repaint()
上调用。
两个班级:
SANDBOX
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
public class Sandbox {
public static void main(String[] args) {
JFrame f = new JFrame();
f.setMinimumSize(new Dimension(800, 600));
f.setLocationRelativeTo(null);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLayout(new FlowLayout());
// Add label
f.getContentPane().add(new TLabel());
f.setVisible(true);
}
}
和 TLabel (带有一点造型):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.border.LineBorder;
@SuppressWarnings("serial")
public class TLabel extends JLabel {
public TLabel() {
super("TEST LABEL, NON-STATIC");
this.setHorizontalAlignment(SwingConstants.CENTER);
TLabel.this.setPreferredSize(new Dimension(200, 50));
TLabel.this.setMaximumSize(new Dimension(200, 50));
TLabel.this.setMinimumSize(new Dimension(200, 50));
TLabel.this.setOpaque(true);
TLabel.this.setBackground(Color.cyan.darker().darker());
TLabel.this.setForeground(Color.white);
TLabel.this.setBorder(new LineBorder(Color.orange, 2));
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
// EXPECTED BEHAVIOR HERE: This line will call paint and paintComponent.
//repaint();
// PROBLEM HERE: This line will not call paint or paintComponent.
repaint(TLabel.this.getBounds());
}
});
}
@Override
public void paint(Graphics g) {
// Note: This is called once when the label is realised.
// Note: This is called when the mouse enters the frame.
System.out.println("PAINT.");
super.paint(g);
}
@Override
public void paintComponent(Graphics g) {
// Note: This is called once when the label is realised.
// Note: This is called when the mouse enters the frame.
System.out.println("REPAINT.");
super.paintComponent(g);
}
}
答案 0 :(得分:4)
你在说这个
repaint(TLabel.this.getBounds());
TLabel对象内部。因此重绘将尝试在Bounds位置绘制相对于其自身的矩形,但getBounds()返回相对于此组件包含对象位置的矩形,而重绘期望相对于组件本身的边界。因此,您尝试绘制一个矩形,该矩形具有JLabel的宽度和高度,但相对于JLabel 位于x = 292和y = 5 时相反,你希望x和y都为0.本质上你试图在这个组件之外绘制方式。
而是试试这个:
//!! repaint(TLabel.this.getBounds());
Dimension d = TLabel.this.getSize();
repaint(new Rectangle(0, 0, d.width, d.height));