JPanel Resize

Hi,

I am writing a swing based application which appends rows of components to a JPanel.

The JPanel is within a JScrollPane.

Currently I have set the components up like this:

private Dimension mainPanelSize =new Dimension(780,3500);

//....

panelMain = createNewMainPanel();

panelMain.setPreferredSize(mainPanelSize);

//...........

jsp =new JScrollPane(panelMain, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

jsp.setPreferredSize(new Dimension(800,690 - adjustment));

container.add(jsp);

This setup means that the main panel is a fixed size (it is quite large but you can't scroll down forever). If I remove the line setting a preferred size of panelMain, when a new row of components is added it goes off the side of the panel (the panel increases horizontally), rather than being added below (increasing vertically).

What I would like to do is set a preferred width of panelMain, but allow the height to grow when new rows are added. Is this possible?

[1271 byte] By [jjdevinea] at [2007-11-27 11:31:27]
# 1

if you're adding rows, set the layout as a BoxLayout(Y_AXIS), or a GridLayout(0,1)

Michael_Dunna at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 2

Hi, im not sure if I explained the problem well in the first post so ive made an example app to demonstrate:

import java.awt.Color;

import java.awt.Container;

import java.awt.Dimension;

import java.awt.FlowLayout;

import java.awt.Toolkit;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import javax.swing.*;

import javax.swing.border.LineBorder;

public class JPanelTest extends JFrame implements ActionListener

{

JPanel panel;

public JPanelTest()

{

super("Example Panel App");//form heading

//create container to place components in:

Container container = getContentPane();

container.setLayout(new FlowLayout());//set flow layout

/*

* add menu bar

*/

JButton button = new JButton("press");

button.addActionListener(this);

button.setPreferredSize(new Dimension(400,50));

container.add(button);

panel = new JPanel();

panel.setPreferredSize(new Dimension(430,800));

panel.setBorder(new LineBorder(Color.BLACK));

JScrollPane jsp = new JScrollPane(panel, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);

jsp.setPreferredSize(new Dimension(450,570));

container.add(jsp);

Dimension d = Toolkit.getDefaultToolkit().getScreenSize();//get screen resoloution

setLocation((d.width-500)/2, (d.height-700)/2);//centre form

setSize(500,700);//set form size

setVisible(true);//display screen

}

public void actionPerformed(ActionEvent arg0)

{

JPanel newPanel = new JPanel();

newPanel.setPreferredSize(new Dimension(400,60));

newPanel.setBorder(new LineBorder(Color.BLACK));

panel.add(newPanel);

panel.validate();

}

public static void main(String [] args)

{

new JPanelTest();

}

}

I would like the main scrolling jpanel to stay at a fixed horizontal size and grow vertically with each new JPanel added inside, rather than having a fixed horizontal AND vertical size so that only so many Jpanels fit inside.

jjdevinea at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 3

> would like the main scrolling jpanel to stay at a fixed horizontal size

> and grow vertically with each new JPanel added inside

And that is the solution Michael gave you.

When you use a FlowLayout components are added horizontally in a single line. If you set the preferred size of the panel, then the components will wrap, but the preferred size of the panel will never change even when you add new rows to the container. Since the preferred size never changes the scroll pane doesn't know that the size of the panel is increasing and never displays the scroll bars.

So, the solution is to use a different layout manager and to not set the preferred size of the panel.

camickra at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 4

It almost sounds like you're looking for something like this:

http://forum.java.sun.com/thread.jspa?forumID=57&threadID=701797&start=2

JayDSa at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 5

Thanks Jay that looks like pretty much exactly the sort of component I need, I will have a go at understanding and incorporating it into my project tommorow.

I have tried using Grid, Box and other layouts in the existing panel but the don't seem to give the application the look it needs - the components are spaced out evenly throughout the whole panel until it is full as opposed to neatly stacking on each other as the current flowlayout is doing.

jjdevinea at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 6

I would highly recommend using SpringLayout. I used to use the other layouts, mostly GridLayout, then I learned how to do SpringLayout and I have not gone back to using the other ones. It allows you to space your components out in relation to each other and even to the panel itself.

Check it out:

http://java.sun.com/docs/books/tutorial/uiswing/layout/spring.html

Scuba_Stevea at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 7

> I have tried using Grid, Box and other layouts in the existing panel but

> they don't seem to give the application the look it needs

Then you don't understand the concept of using the Layout managers. Remember your original requirement was:

I am writing a swing based application which appends rows of components to a JPanel.

So the easiest way to do this would be to create a panel and add your components to the panel using a FlowLayout. Then you add the panel to your main panel which is using the BoxLayout or GridLayout (depending on your requirement).

No need for custom code (unless your ac\tual requirement is different from your stated requirement).

Using the suggestion Michael and I gave you your components will always be displayed on a single row no matter how the frame is resized.

Using the custom panel the components will shift position as the frame is resized.

camickra at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 8

> So the easiest way to do this would be to create a

> panel and add your components to the panel using a

> FlowLayout. Then you add the panel to your main panel

> which is using the BoxLayout or GridLayout (depending

> on your requirement).

I'll admit im no expert in using layoutmanagers, but this is what I tried to do. I'm sorry it wasn't clear in the original post, but the rows of components are in a JPanel already. I've tried using grid and box layouts on the main JPanel but as I said before, the rows (ie smaller JPanels) dont stack neatly until the viewable area is full, before that they space themselves out over the whole viewable area.

Springlayout sounds like it could have the functionality so I will have a look at that.

jjdevinea at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 9

SpringLayout seems to have the functionality I need, still had a bit of a problem with the JScrollPane not recognising when it needs to provide a scroll bar but it seems to work now - thanks.

jjdevinea at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...
# 10

> the rows (ie smaller JPanels) dont stack neatly until the viewable area is full

The basic logic should be:

a) rowPanel = ....

b) mainPanel.add( rowPanel );

c) mainPanel.revalidate();

Using FlowLayout and BoxLayout or GridLayout is far simpler than using a SpringLayout. You should be learning how to use the basic layout managers first before attempting the more compliated managers.

If you need further help then you need to create a "Short, Self Contained, Compilable and Executable, Example Program (SSCCE)",

see http://homepage1.nifty.com/algafield/sscce.html,

that demonstrates the incorrect behaviour, because I can't guess exactly what you are doing based on the information provided.

Don't forget to use the "Code Formatting Tags",

see http://forum.java.sun.com/help.jspa?sec=formatting,

so the posted code retains its original formatting.

camickra at 2007-7-29 16:39:48 > top of Java-index,Desktop,Core GUI APIs...