Java JViewport未定位其视图?

Java JViewport未定位其视图?,java,swing,view,jviewport,Java,Swing,View,Jviewport,我正在为我的应用程序使用JavaSwing,我想利用JViewport来显示端口“后面”的一些类似画布的面板的片段。但不知何故,视口从未定位其视图,因此一定有我正在做的事情。我做错了什么,为什么这个代码不起作用 下面是我在更大更复杂的范围内所做的一个例子 public class MyApp { // THIS IS A TEMPORARY TEST TO GET VIEWPORT WORKING public static void main(String[] args) {

我正在为我的应用程序使用JavaSwing,我想利用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);
  }
}

结果是“canvas”只是停留在0,0,它永远不会像我使用setViewPosition()那样移动到200200。无论布局管理器为空,它的内容都被完美地定位。为了简单起见,我刚刚将canvas编写为一个JPanel,但它实际上是一个复杂的JLayeredPane。

在您的案例中有几个问题:

  • 使用
    null
    -layout/absolute positioning:停止这样做。。。永远。这是一个坏习惯,一个非常坏的坏习惯,总是导致同一点:成吨的问题
  • 不要调用
    setPreferredSize()
    :使用适当的
    LayoutManager
    或覆盖
    getPreferredSize()
  • 考虑为画布实现
    Scrollable
    ,其中
    getPreferredScrollableViewportSize()
    将返回
    新维度(300,300)
    (目标视口范围大小)
  • 调用setSize()/setExtentSize()几乎毫无用处,因为这将被LayoutManager覆盖

您的案例中有几个问题:

  • 使用
    null
    -layout/absolute positioning:停止这样做。。。永远。这是一个坏习惯,一个非常坏的坏习惯,总是导致同一点:成吨的问题
  • 不要调用
    setPreferredSize()
    :使用适当的
    LayoutManager
    或覆盖
    getPreferredSize()
  • 考虑为画布实现
    Scrollable
    ,其中
    getPreferredScrollableViewportSize()
    将返回
    新维度(300,300)
    (目标视口范围大小)
  • 调用setSize()/setExtentSize()几乎毫无用处,因为这将被LayoutManager覆盖

+1最后一点可能是-使用JLayer(Java7)而不是JViewport1)我知道布局管理器比定位更好,但这并不是真正的问题。画布的内容非常完美,但画布本身的位置不正确。2和4)您的意思是我必须向视口添加布局管理器吗?我以为它不需要。3) 我将研究如何使画布可滚动。@JackMcCalling视口有自己的LayoutManager。视口的首选大小基于1)如果视口视图实现可滚动,则为getPreferredScrollableViewPortSize返回的值2)否则为首选大小。视口视图获取由getPreferredSize()@Guillaume Polet返回的值定义的大小。好的,我现在明白了。我删除了setViewSize()、setExtendSize()和setPreferredSize()调用,使画布实现可滚动,并通过分别覆盖getPreferredSize()和getPreferredScrollableViewportSize()返回画布和视口大小,现在它可以工作了!非常感谢+最后一点可能是-使用JLayer(Java7)而不是JViewport1)我知道布局管理器比定位更好,但这并不是真正的问题。画布的内容非常完美,但画布本身的位置不正确。2和4)您的意思是我必须向视口添加布局管理器吗?我以为它不需要。3) 我将研究如何使画布可滚动。@JackMcCalling视口有自己的LayoutManager。视口的首选大小基于1)如果视口视图实现可滚动,则为getPreferredScrollableViewPortSize返回的值2)否则为首选大小。视口视图获取由getPreferredSize()@Guillaume Polet返回的值定义的大小。好的,我现在明白了。我删除了setViewSize()、setExtendSize()和setPreferredSize()调用,使画布实现可滚动,并通过分别覆盖getPreferredSize()和getPreferredScrollableViewportSize()返回画布和视口大小,现在它可以工作了!谢谢!另请参见,。另请参见。