我有一个自定义Component
,其中Canvas
扩展为ScrollPane
。当我的组件的内部状态发生变化时,我称之为repaint()
方法。但是这会导致完全重新绘制(传递给组件的绘制方法的Graphics对象的边界是组件的大小,而不是视口的大小)。这是一个问题,因为组件可能变得非常大(10,000 + px)并且具有复杂的绘制逻辑。
以下代码举例说明了这个问题:
package main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.ScrollPane;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
public class ScrollPaneTest {
static class MyCanvas extends Canvas {
@Override
public void paint(Graphics g) {
super.paint(g);
Rectangle clipBounds = g.getClipBounds();
System.out.println("paint " + clipBounds.toString());
g.setColor(Color.black);
g.drawString(clipBounds.toString(), 20, 20);
}
// Attempted solution: doesn't work; MyCanvas.paint() doesn't get called at all.
// @Override
// public void repaint(long tm, int x, int y, int width, int height) {
// System.out.println(tm + " " + x + " " + y + " "
// + width + " " + height);
// getParent().repaint();
// }
}
public static void main(String[] args) throws Exception {
JFrame frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
frame.setBounds(0, 0, 400, 200);
frame.setVisible(true);
ScrollPane pane = new ScrollPane();
frame.add(pane);
MyCanvas mc = new MyCanvas();
pane.add(mc);
mc.setBounds(0, 0, 1000, 1000);
mc.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
System.out.println("keypressed");
mc.repaint();
}
});
mc.requestFocus();
}
}
问题:当按下一个键并重新绘制()时,会调用paint(Graphics),打印的clipBounds
始终包含整个MyCanvas:
paint java.awt.Rectangle[x=0,y=0,width=1000,height=1000]
而不仅仅是可见区域(400x200)。我搜索过Google / SO但没有发现任何相关内容;有谁知道如何改变这个或找出paint
方法中的可见区域?