在尝试理解repaint()和paintComponent()的过程中,我在http://docs.oracle.com/javase/tutorial/uiswing/painting/step3.html上看到了这些代码:
import javax.swing.SwingUtilities;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.BorderFactory;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseMotionListener;
import java.awt.event.MouseMotionAdapter;
public class SwingPaintDemo3 {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI() {
System.out.println("Created GUI on EDT? "+
SwingUtilities.isEventDispatchThread());
JFrame f = new JFrame("Swing Paint Demo");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new MyPanel());
f.pack();
f.setVisible(true);
}
}
class MyPanel extends JPanel {
private int squareX = 50;
private int squareY = 50;
private int squareW = 20;
private int squareH = 20;
public MyPanel() {
setBorder(BorderFactory.createLineBorder(Color.black));
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
addMouseMotionListener(new MouseAdapter() {
public void mouseDragged(MouseEvent e) {
moveSquare(e.getX(),e.getY());
}
});
}
private void moveSquare(int x, int y) {
int OFFSET = 1;
if ((squareX!=x) || (squareY!=y)) {
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
squareX=x;
squareY=y;
repaint(squareX,squareY,squareW+OFFSET,squareH+OFFSET);
}
}
public Dimension getPreferredSize() {
return new Dimension(250,200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawString("This is my custom Panel!",10,20);
g.setColor(Color.RED);
g.fillRect(squareX,squareY,squareW,squareH);
g.setColor(Color.BLACK);
g.drawRect(squareX,squareY,squareW,squareH);
}
}
我对这些代码的问题是我不理解这条线"重绘(squareX,squareY,squareW + offset,squareH + offset"。首先,我对repaint()的理解它基本上只是调用paint(Graphics g)或paintComponent(Graphics g),你显然不能像普通程序一样调用它,因为你实际上无法输入图形,比如输入一个int或一个字符串但是,这个程序的paintComponent()没有任何额外的输入(也许它会有paintComponent(Graphics g,int squareX,int squareY,int squareW,int squareH)),所以输入在哪里给予重画去......?它用于什么?
答案 0 :(得分:1)
example cited调用repaint(int x, int y, int width, int height)
以在鼠标处理程序中隐式循环中呈现效率。这种repaint()
变体的实现要求RepaintManager
将由坐标限定的区域添加到其他“应该刷新的组件”的区域。更新区域是两个重绘矩形的 union 。
如上所述here,这可能会导致技术上违反GUI框架(例如Swing)的single-thread rule。由于Runnable
的实例会不断发布到EventQueue
,因此读取失败的风险很小。 Profile两者都接近(练习3)来评估利益与风险。
答案 1 :(得分:1)
我不懂行
"repaint(squareX, squareY, squareW+offset,squareH+offset".
该代码用于重绘面板的小矩形,而不是重新绘制整个面板。画一个小区域显然比画一个小区域更有效。
此外,该语句被调用两次。 repaint()方法使用绘制请求调用RepaintManager
来重绘两个矩形区域。 RepaintManager
将两个请求合并为一个绘制请求,这将再次使代码更有效。
因此,第一个语句用于清除当前位置的Rectangle绘制。然后改变Rectangle的x / y位置并进行第二次repaint()请求,以便可以在其新位置重新绘制Rectangle。
尝试没有第一个重绘(...)语句的代码,你会看到原始的Rectangle没有被完全清除,所以你得到了旧矩形的痕迹。
答案 2 :(得分:0)
Here可以帮助你解决这个问题。
public void repaint(int x, 是的, 整数宽度, int height)重新绘制此组件的指定矩形。
只需调用普通repaint()
即可重新绘制该组件,但使用这些参数即可重新绘制该组件的特定矩形。