Scrollable JPanel having GridLayout.

S

Shuaib

I have been trying to solve this problem for some time but haven't
found a solution yet.

Here is what I wanna do: A scrollable JPanel having GridLayout to
which I add images of any size which are also in JPanel(s). The image
size should be maintained and when I need to see the part not visible
in the screen I can use the scrollbar.

Here is the simplified form of what I am currently doing:

JPanel p = new JPanel();
JScrollPane sp = new JScrollPane(p);
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
p.setLayout(new GridLayout(1,2));

JPanel p1 = new JPanel();
ImageIcon icon1 = new ImageIcon(url1);
JLabel image1 = new JLabel(icon1);
p1.add(image1, BorderLayout.CENTER);
p.add(p1);

JPanel p2 = new JPanel();
ImageIcon icon2 = new ImageIcon(url2);
JLabel image2 = new JLabel(icon2);
p2.add(image2, BorderLayout.CENTER);
p.add(p2);

For single image, it does appear in the panel but its top and bottom
are chopped off if it is in portrait orientation with no vertical
scrollbar. For two images, it tries to fit both by chopping them off
from the sides too. Both appear together in the viewport without
horizontal and vertical scrollbars.
Any help will be highly appreciated.

-SA
 
B

Babu Kalakrishnan

Shuaib said:
I have been trying to solve this problem for some time but haven't
found a solution yet.

Here is what I wanna do: A scrollable JPanel having GridLayout to
which I add images of any size which are also in JPanel(s). The image
size should be maintained and when I need to see the part not visible
in the screen I can use the scrollbar.

Here is the simplified form of what I am currently doing:

JPanel p = new JPanel();
JScrollPane sp = new JScrollPane(p);
sp.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
p.setLayout(new GridLayout(1,2));

JPanel p1 = new JPanel();
ImageIcon icon1 = new ImageIcon(url1);
JLabel image1 = new JLabel(icon1);
p1.add(image1, BorderLayout.CENTER);
p.add(p1);

JPanel p2 = new JPanel();
ImageIcon icon2 = new ImageIcon(url2);
JLabel image2 = new JLabel(icon2);
p2.add(image2, BorderLayout.CENTER);
p.add(p2);

For single image, it does appear in the panel but its top and bottom
are chopped off if it is in portrait orientation with no vertical
scrollbar. For two images, it tries to fit both by chopping them off
from the sides too. Both appear together in the viewport without
horizontal and vertical scrollbars.
Any help will be highly appreciated.

Cannot reproduce this on my machine. As far as I can see from the code,
the JScrollPane should display the panel properly with scrollbars as
appropriate to scroll the images fully.

Couple of comments about your code though :

When creating a GridLayout, never specify the rows and column values.
Only one of them will be honored, and the second parameter will only
confuse someone who reads your code. The arguments (1,2) will give you a
layout that will always create a GridLayout with 1 row - and as many
number of columns as required - not 2. If you want 2 columns, specify
the constructor arguments as (0,2).

You're adding the JLabels to the panel using a constraint
BorderLayout.CENTER. This is incorrect because you never set a
BorderLayout as the JPanel's layoutmanager. A constraint of
specification of BorderLayout.CENTER will not make any sense to a
FlowLayout which is the default layout manager for a JPanel.

Also in the example code above, the intermediate panels (to which you're
adding the JLabels) aren't really required. You can add the JLabels
directly to the outer panel instead.

BK
 
S

sanjay manohar

Your problem is that GridLayouts always try and shrink to the size of
their container.

The solution is to create _another_ panel in the hierarchy, that
contains the gridlayout panel, but is the View of the scrollpane. this
new panel should have a flowlayout, which instructs the gridlayout
panel to take up as much space as it needs.
 
B

Babu Kalakrishnan

sanjay said:
Your problem is that GridLayouts always try and shrink to the size of
their container.

This is applicable only if the size of the container is set to a value
that is lower than its preferredSize. In the code snippet that the OP
had posted, the panel was placed as the view for the JScrollPane, and I
don't see any reason why the scrollpane should set it to a size smaller
than its preferredSize. For a container controlled by a Gridlayout, the
preferredSize will be equal to the (preferred width of the _widest_
child component * no or columns in the grid) by (preferred height of the
_tallest_ child component * no of rows). (Plus of course the insets /
gaps as applicable). This means that each grid will be capable of
holding the biggest child component at its preferred size - no question
of "shrinking" arises.
The solution is to create _another_ panel in the hierarchy, that
contains the gridlayout panel, but is the View of the scrollpane. this
new panel should have a flowlayout, which instructs the gridlayout
panel to take up as much space as it needs.

I cannot see how this can solve the problem either. All layoutmanagers
that I have seen try to give its children its preferredSize if possible.
And adding another panel to the hierarchy will do nothing to change this
behaviour.

I would suspect that the OP has some thing else in his actual code (over
and above what was posted) that is causing this behaviour. For instance
he might have called setPreferredSize on the panel with some fixed value
which is a very common error.

BK
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,982
Messages
2,570,185
Members
46,736
Latest member
AdolphBig6

Latest Threads

Top