Java AWT:滚动窗格中的组件:仅重新绘制视口/可见区域
我有一个扩展画布的自定义组件,我将其放置在滚动窗格中。当我的组件的内部状态改变时,我调用它的重绘方法。但是,这会导致完全重新绘制。传递给组件的绘制方法的图形对象的边界是组件的大小,而不是视口的大小。这是一个问题,因为组件可能变得非常大,10000+px,并且具有复杂的绘制逻辑 以下代码举例说明了此问题:Java AWT:滚动窗格中的组件:仅重新绘制视口/可见区域,java,awt,scrollpane,Java,Awt,Scrollpane,我有一个扩展画布的自定义组件,我将其放置在滚动窗格中。当我的组件的内部状态改变时,我调用它的重绘方法。但是,这会导致完全重新绘制。传递给组件的绘制方法的图形对象的边界是组件的大小,而不是视口的大小。这是一个问题,因为组件可能变得非常大,10000+px,并且具有复杂的绘制逻辑 以下代码举例说明了此问题: package main; import java.awt.Canvas; import java.awt.Color; import java.awt.Graphics; import ja
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();
}
}
问题:当按下一个键并重新绘制时,调用paintGraphics,打印的剪贴簿始终包含整个MyCanvas:
paint java.awt.Rectangle[x=0,y=0,width=1000,height=1000]
而不仅仅是可见区域400x200。我搜索了Google/SO,但没有找到任何相关信息;有人知道如何更改此设置或在绘制方法中计算可见区域吗?如果图形的剪裁边界未设置为视口区域,则需要检查滚动窗格的父对象是什么,然后检查其viewportSizeproperty@MadProgrammer有点像黑客;我想这就是我使用AWT xD所得到的。无论如何,谢谢!很多问题归结为这样一个事实:通常,组件的绘制是由操作系统本身完成的,而不是AWT,因此它的优化方式与Swing不同