【问题标题】:How do I draw over top of a JScrollPane?如何在 JScrollPane 上绘制?
【发布时间】:2013-05-24 18:44:02
【问题描述】:

我有一个JScrollPane,它填充了一个JPanel(这是我的JFrame 的内容窗格)。 JPanel 执行自定义绘图 - 但是,它不会出现在 JScrollPane 之上。我应该覆盖paintComponent以外的其他内容吗?

这是一个演示:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.LayoutManager;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;

public class Test {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                // Create the frame.
                JFrame frame = new JFrame();
                frame.setPreferredSize(new Dimension(1024, 768));
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                JPanel custom = new CustomPanel(new BorderLayout());
                // Add the scroll pane.
                JScrollPane scroll = new JScrollPane();
                scroll.setBorder(BorderFactory.createLineBorder(Color.blue));
                custom.add(scroll, BorderLayout.CENTER);

                // Display the frame.
                frame.setContentPane(custom);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }

        });
    }
}

@SuppressWarnings("serial")
class CustomPanel extends JPanel {

    public CustomPanel(LayoutManager lm) {
        super(lm);
    }

    @Override
    public void paintComponent(Graphics g) {
        g.setColor(Color.red);
        g.drawRect(200, 200, 200, 200);
    }

}

【问题讨论】:

  • 你的意思是在 JScrollPane 中为 JPanel 完成一次绘画,然后在顶部完成第二次绘画???,两个单独的图层
  • @mKorbel 我想让 JPanel 上的油漆超过 JScrollPane 上的油漆。
  • 你在找JViewport
  • @mKorbel 是的,那是完美的。我设置了一个自定义视口!谢谢!
  • 这可能是:stackoverflow.com/questions/8776540/… 的副本,它也可以正常工作。

标签: java swing jframe jscrollpane paint


【解决方案1】:

我想让 JPanel 上的油漆越过 JScrollPane

你可以画到

  • JViewport 可以看到herehere

  • 使用JLayer(Java7) based on JXlayer(Java6)

  • 非常相似(就像今天的 JLayer)正在绘制到 GlassPane,注意 GlassPaneconsume()(默认情况下)MouseEvent 在这种情况下添加了一些 JComponent(s ), GlassPane 可以覆盖整个RootPane 或仅部分可用的矩形,取决于使用的LayoutManagerDimension 从layed JComponent(s) 返回

【讨论】:

  • @sdasdadas note - 使用 RepaintManager 制作动画,在所有情况下使用 setScrollMode
【解决方案2】:

只是一个简单的问题。您正在将滚动窗格添加到隐藏您正在绘制的内容的自定义面板中。相反,请考虑使用 cutsompanel 作为其内容来初始化您的滚动窗格。

例子:

JScrollPane scrlPane = new JScrollPane(customPanel);

【讨论】:

  • 我不确定这是否会提供完全相同的解决方案。在实际问题中(对于演示来说太大了),滚动窗格是第三方的并且包含其他组件。我想在上面叠加图纸 - 但我不确定我是否可以在其中工作。
【解决方案3】:

当您将单个组件添加到 BorderLayout 并指定 BorderLayout.CENTER 时,该组件将扩展以完全填充其父级。如果组件是不透明的,您将无法在父组件中看到任何自定义绘画。

【讨论】:

  • 我知道它会完全填满(这是所希望的),但为什么我的面板不能涂在上面?顺序是 1.孩子,2.你自己,还是 1.你自己 2.孩子?如果是后者,有没有办法扭转这种绘画顺序?
  • 您的面板没有绘画有两个原因:(1)您的JScrollPaneJViewport 是不透明的,它隐藏了下面的内容,以及(2)您的paintComponent 方法绘制了一个未填充的大小为 0 像素的矩形 :) 尝试调用 scroll.getViewport().setOpaque(false); 并修复您的 paintComponent 方法,如果可行,请告诉我。
  • 是的,一个组件在其任何子组件被绘制之前被绘制。如果你想要相反的行为,我想你可以覆盖paintComponent - 让方法的第一行是super.paintComponent();,然后在下面做任何你想做的事情。
  • 我不认为这些建议是正确的:paintComponent 方法确实在下面绘制了一个红色矩形(只是没有填充),并且首先调用 super.paintComponent() 不起作用 - 虽然我明白和你一样……
  • 您对视口的看法部分正确(请参阅我上面的评论)。谢谢!
【解决方案4】:

有效的方式(正如@mKorbel 建议的那样)是使用 JViewport:

scroll.setViewport(new CustomViewPort());

其中CustomViewPort 是一个扩展JViewport 的类,它覆盖paintComponent 方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-04-26
    • 1970-01-01
    • 2012-08-05
    • 1970-01-01
    • 2014-09-18
    • 1970-01-01
    • 2013-11-12
    • 2013-12-13
    相关资源
    最近更新 更多