JViewport 没有定位它的视图?
Posted
技术标签:
【中文标题】JViewport 没有定位它的视图?【英文标题】:JViewport is not positioning its view? 【发布时间】:2013-04-18 12:42:07 【问题描述】:我正在为我的应用程序使用 Java Swing,并且我想利用 JViewport 在端口“后面”显示一些类似画布的面板的片段。但不知何故,视口永远不会定位它的视图,所以我必须做一些事情。我做错了什么,为什么这段代码不起作用?
以下是我在更大、更复杂的规模上所做的示例。
public class MyApp
// THIS IS A TEMPORARY TEST TO GET VIEWPORT WORKING
public static void main(String[] args)
JFrame frame = new JFrame();
JViewport viewport = new JViewport();
viewport.setOpaque(true);
viewport.setBackground(Color.GRAY);
frame.add(viewport, BorderLayout.CENTER);
JPanel canvas = new JPanel(null);
canvas.setBackground(Color.CYAN);
viewport.setView(canvas);
viewport.setViewSize(new Dimension(500, 500));
viewport.setExtentSize(new Dimension(300, 300));
viewport.setPreferredSize(new Dimension(300, 300));
// item one
JLabel label = new JLabel("This is a 32x32 box");
label.setOpaque(true);
label.setBackground(Color.GREEN);
label.setIcon(Sprites.BOX2.getSprite());
label.setBounds(0, 0, 200, 32); // position upper left, 200 wide
label.setHorizontalAlignment(SwingConstants.LEFT);
canvas.add(label);
// item two
JLabel label2 = new JLabel("This is a 32x32 wall");
label2.setOpaque(true);
label2.setBackground(Color.ORANGE);
label2.setIcon(Sprites.WALL1.getSprite());
label2.setBounds(300, 468, 200, 32); // position lower right, 200 wide
label2.setHorizontalAlignment(SwingConstants.RIGHT);
label2.setHorizontalTextPosition(SwingConstants.LEFT);
canvas.add(label2);
// this should scroll the canvas to the left and up, so the box becomes invisible and the wall visible
viewport.setViewPosition(new Point(200, 200));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
结果是“画布”只是停留在 0,0,它永远不会像我使用 setViewPostition() 那样移动到 200,200。无论空布局管理器如何,它的内容都完美定位。为了简单起见,我只是将画布写成 JPanel,但它实际上是一个复杂的 JLayeredPane。
【问题讨论】:
另见ScrollPanePaint
、et al。
【参考方案1】:
你的情况有几个问题:
你使用null
-layout/absolute 定位:停止这样做......永远。这是一种糟糕的做法,一种非常糟糕和令人讨厌的习惯,它总是会导致同一个问题:大量问题。
不要调用setPreferredSize()
:要么使用适当的LayoutManager
,要么覆盖getPreferredSize()
考虑为您的画布实现Scrollable
,getPreferredScrollableViewportSize()
将返回new Dimension(300, 300)
(目标视口范围大小)
调用 setSize()/setExtentSize() 几乎没用,因为这将被 LayoutManager 覆盖。
【讨论】:
+1 最后一点可能是 - 使用 JLayer (Java7) 而不是 JViewport 1) 我知道布局管理器比定位更好,但这并不是真正的问题。画布的内容是完美的,但画布本身的位置不正确。 2&4) 你的意思是我必须在视口中添加一个布局管理器吗?我以为它不需要一个。 3) 我将研究使画布可滚动。 @JackMcKalling 视口有自己的 LayoutManager。视口的首选大小基于 1) 如果视口视图实现 Scrollable,则由 getPreferredScrollableViewPortSize 返回的值 2) 否则,首选大小。视口视图的大小由 getPreferredSize() 的返回值定义 @Guillaume Polet 好的,我现在明白了。我删除了 setViewSize()、setExtendSize() 和 setPreferredSize() 调用,使画布实现 Scrollable 并通过分别覆盖 getPreferredSize() 和 getPreferredScrollableViewportSize() 让它返回画布和视口大小,现在它作品!非常感谢! 在“一段时间”和更大的显示器之后,我发现如果画布变得小于视口的范围大小,问题就会再次出现。视口拒绝偏移视图,它始终保持在最靠近请求视图位置的一侧。在我的情况下,它只发生在水平方向,因为视图只适合水平方向的范围大小。但这是一个真正的痛苦,我希望视图居中,无论它有多大。以上是关于JViewport 没有定位它的视图?的主要内容,如果未能解决你的问题,请参考以下文章