Java的:如何在滚动窗格视口绘制非滚动覆盖?Java的:如何在滚动窗格视口绘制非滚动覆盖?(Jav

2019-05-13 12:11发布

我想使用一个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);
    }
}

Answer 1:

通常情况下,“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)来解决这个问题。



文章来源: Java: How to draw non-scrolling overlay over ScrollPane Viewport?