我之前问过这个问题,但只是理论上的,没有 SSCCE。现在,我创建了一个,但问题仍然存在。我想知道为什么 paintComponent
不是在 repaint(x, y, w, h)
上调用,而是在 repaint()
上调用>.
两个类:
沙盒
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);
}
}
最佳答案
你在调用这个
repaint(TLabel.this.getBounds());
在 TLabel 对象内部。所以 repaint 将尝试在 Bounds 位置绘制一个相对于自身的矩形,但是 getBounds() 返回一个相对于此组件定位的矩形包含对象的位置,而 repaint 期望相对于组件本身的边界。因此,您尝试绘制一个具有 JLabel 宽度和高度但位于 x = 292 和 y = 5 相对于 JLabel 的矩形,当相反,您希望 x 和 y 都为 0。本质上,您试图在该组件之外进行绘制。
试试这个:
//!! repaint(TLabel.this.getBounds());
Dimension d = TLabel.this.getSize();
repaint(new Rectangle(0, 0, d.width, d.height));
关于Java - repaint(x, y, w, h) 不调用 paintComponent? (与SSCCE),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9288127/