I'm using Java Swing for my application, and I want to make use of the JViewport to show a fragment of some canvas-like panel 'behind' the port. But somehow the viewport never positions its view, so there must be something I'm doing. What am I doing wrong, why this code is not working?
The following is an example of what I'm doing on a bigger and more complex scale.
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);
}
}
The result is that the 'canvas' is simply sticking at 0,0, it never moves to 200,200 like I do with setViewPostition(). It's contents is perfectly positioned well, regardless of the null layout manager. I just wrote the canvas to be a JPanel for simplicity, but it's really a complex JLayeredPane.
There are several problems in your case:
null
-layout/absolute positionning: stop doing that... forever. It's a bad practice, a very bad and nasty habit which always leads to the same point: tons of problems.setPreferredSize()
: either use an appropriate LayoutManager
or override getPreferredSize()
Scrollable
for your canvas and where getPreferredScrollableViewportSize()
would return new Dimension(300, 300)
(the targetted viewport extent size)