我想使用一个ScrollPane在其视口以显示图像,并且还具有一个网格(或盒,或任何其它类型的登记/位置标记的)叠加在图像上。 我需要的叠加滚动时(意为形象似乎移动覆盖“下”),以保持固定。 我将滚动视口中的视图以固定的速率,以提供平滑的运动,并且所述覆盖是提供到视内的特定位置的引用。 从概念上讲,认为大地图在视口中,和视口滚动具有(相对于视口本身)的矩形不移动标志着可以放大到基于某些用户动作的区域的。
我相信(但尚未证实),其将ScrollPane实现高效处理视图的渲染(从后备存储,不必重新绘制整个视图(甚至视区)为每一个新的部分曝光)等不希望有覆盖涂料()方法。
我已经看了LayerPane,虽然没有掌握它,它看来,这是一种强制方法。 将ScrollPane是SplitPane的一个组成部分,并且将被移动/调整大小。 我想到的是我不得不手动维护视口,并使用绝对定位的LayerPane之间的正确关系。 我从GUI设计和实施方面的专家很远,我敢肯定,我错过了机会,从明显模糊和优雅是有经验的人会知道。
我愿意接受任何建议,不只是路我已经开始了。 如果我(我可以)我SplitPane添加的JPanel的一个组成部分,那么LayerPane添加到包含我的ScrollPane上,而在LayerPane不同层覆盖(另一种JPanel的)? 是否有滚动窗格功能,直接支持吗? 我已经看过了的Java Swing教程和API文档,但还没有看到任何迹象。
谢谢。
更新:
感谢您的链接,trashgod。 这是比我预想的要容易得多。 无需LayerPane,玻璃面板,基于XOR的合成...我不知道为什么没有想到要尽量覆盖JViewport.paint()来绘制覆盖我的 - 但我下面的代码验证的概念将给我什么我要找的。 只要使用的JViewport的子类,它做什么,我想(在这种情况下,叠加在视口的同时图像下方滚动中心的矩形)。 我没有GUI专家,Java API的是宽广的; 我不知道你们是如何保持这一切都在你的脑袋 - 但感谢!
class MyViewport extends JViewport {
@Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D)g;
g2.setPaint(Color.BLACK);
g2.drawRect(getWidth()/4,getHeight()/4,getWidth()/2,getHeight()/2);
}
}
通常情况下,“Swing程序应该重写paintComponent()
而不是覆盖paint()
,”在提到在AWT绘画和Swing:该漆方法 。 基于ScrollPanePaint
,吸引滚动内容下面 ,下面的例子将覆盖paint()
来绘制滚动内容的上方 。
import java.awt.*;
import javax.swing.*;
/**
* @see https://stackoverflow.com/a/10097538/230513
* @see https://stackoverflow.com/a/2846497/230513
* @see https://stackoverflow.com/a/3518047/230513
*/
public class ScrollPanePaint extends JFrame {
private static final int TILE = 64;
public ScrollPanePaint() {
JViewport viewport = new MyViewport();
viewport.setView(new MyPanel());
JScrollPane scrollPane = new JScrollPane();
scrollPane.setViewport(viewport);
this.add(scrollPane);
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private static class MyViewport extends JViewport {
public MyViewport() {
this.setOpaque(false);
this.setPreferredSize(new Dimension(6 * TILE, 6 * TILE));
}
@Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.blue);
g.fillRect(TILE, TILE, 3 * TILE, 3 * TILE);
}
}
private static class MyPanel extends JPanel {
public MyPanel() {
this.setOpaque(false);
this.setPreferredSize(new Dimension(9 * TILE, 9 * TILE));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.lightGray);
int w = this.getWidth() / TILE + 1;
int h = this.getHeight() / TILE + 1;
for (int row = 0; row < h; row++) {
for (int col = 0; col < w; col++) {
if ((row + col) % 2 == 0) {
g.fillRect(col * TILE, row * TILE, TILE, TILE);
}
}
}
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new ScrollPanePaint();
}
});
}
}
注意:设置不透明组件(例如JTable中用作滚动窗格会给奇怪的视觉缺陷的视图),例如滚动时移动固定的蓝盒子。 视图组件上使用setOpaque(false)来解决这个问题。