Change the height of a panel at runtime - java

How to change the height of panel at runtime?
I have some panels inside a JFrame, I tried on one of them:
int w = panel.getWidth();
panel.setSize(w, 1000);
But there's no effect. What's wrong?

You may have to validate and repaint your panel. Try following:
int x=panel.getWidth();
panel.setSize(x,1000);
panel.validate();
panel.repaint();

Check out this answer:
set size wont work in java
"In Swing, you have two options for layout: do everything manually or let a LayoutManager handle it for you."
and
"Try calling setPreferredSize() and setMinimumSize()."
If you are using a layout manager (you probably are), the layout decides what to do with the
contained components. setPreferredSize() usually works because the layout usually asks the
contained components what their preferred sizes are, and then arranges the components
based on (among others) that information.

If you put the panel in a LayoutManager (i.e. the parent has a LayoutManager which is BorderLayout by default) that LayoutManager would override the size and thus your call would have no effect.
Try to call setLayoutManager(null) on the parent although I'd recommend using a LayoutManager and use setPreferredSize(), setMinimumSize() and setMaximumSize().

For changing width and height of JPanel use setPreferredSize method.
JPanel folderPanel = new JPanel();
folderPanel.setPreferredSize(new Dimension(245, 450));// width, height

You just set the visibility of this component (JPanel) as follow:
JPanel panel = new JPanel();
//set your custom size in this with=120; height=570;
panel.setSize(120,570);
panel.setVisible(false);
panel.setVisible(true);
//hope this help! :)

Related

Dynamically add JPanel instances to a JScrollPane

I'm trying to add precreated JPanel instances into a bigger JPanel into a JScrollPane, but I can't get it to work.
I'm using NetBeans to create the container, then using the context menu to include it into a scroll panel.
To add the JPanel at runtime I'm doing this:
ActivityPanel actPanel;
for(Reservation r: mainFrame.getKiosko().getReservations()) {
if( r.getUser().equals(user)) {
actPanel = new ActivityPanel(r.getActivity(),mainFrame);
actPanel.setHour(r.getHour());
Dimension actDim = new Dimension(600, 100);
actPanel.setPreferredSize(actDim);
actPanel.setMaximumSize(actDim);
actPanel.setMinimumSize(actDim);
pnlReservations.add(actPanel);
}
}
But it just is not working. Should I create the ScrollPanel at runtime? If so How should I do it?
pnlReservation has a BoxLayout by page axis.
actPanel.setPreferredSize(actDim);
Don't try to manually control the preferred size of a component. The size of the panel should be determined by the components you add to the panel.
Same with your pnlReservation, don't hardcode a preferred size. The layout manager will determine its preferred size based on the preferred size of the components added to it.
Then the scrollbars will appear automatically as the preferred size of the pnlReservation dynamically changes when you add components to it.

How do I get thet components that are in a particular layout location in JFrame

I have a JFrame that uses the BorderLayout. How do I get all the components that are in the left or the right or in any other location of this JFrame?
As #brano suggested, you can access those components via the LayoutManager of your JFrame's contentPane.
For exemple, assuming that you want to get the component that is located on BorderLayout.WEST (and that your JFrame is called frame), you could do:
final BorderLayout layout = (BorderLayout) frame.getContentPane().getLayout();
final Component west = layout.getLayoutComponent(BorderLayout.WEST);
One remark, though: the getLayoutComponent method doesn't belong to LayoutManager: thus, you have to know and be sure that your layout is an actual BorderLayout.

Adding panel with without layout to the NORTH of BorderLayout

Colleagues.
I'm trying to construct simple GUI in Java, where JFrame has Border Layout. I want to put JScrollPane with JTable to CENTER, and JPanel without layout to NORTH.
The problem is that JPanel doesn't visible. There is simple examle of the problem:
JFrame frame = new JFrame("Test frame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Test button");
button.setBounds(10, 10, 40, 20);
JPanel panelN = new JPanel(null); // layout = null, panelN without layout
panelN.add(button);
frame.add(panelN, BorderLayout.NORTH);
JTable table = new JTable(new DefaultTableModel(4, 4));
JScrollPane scrollPane = new JScrollPane(table);
frame.add(scrollPane, BorderLayout.CENTER);
frame.setSize(400, 400);
frame.setVisible(true);
You have to use a LayoutManager. It's totally discouraged not using layoutManager, but if you want this you have to set panel.setBounds(..) to the panel too.
By default JPanel has FlowLayout so if you put
JPanel panelN = new JPanel(); // FlowLayout used
panelN.add(button);
frame.add(panelN, BorderLayout.NORTH);
So your frame will look like this.
Layout Managers determines the size and position of the components within a container. Although components can provide size and alignment hints, a container's layout manager has the final say on the size and position of the components within the container.
It's strongly recommended cause for example if you have to resizes components or show in differentes resolutions you delegate this work to layout managers
I don't know the expected behavior of a null layout, but without further requirements you might as well just instantiate with the zero-arg constructor:
new JPanel();
If you didn't set any layout to the panel, when adding components the panel don't know where to put the component, so baisicly the component don't show until you set a specific location for components one by one by component.setBounds(x,y,width,hieght) method.
Note that it's not a good practice to remove the layout manager because of the different platformes, suppose that your program working on Window and MacOS and Linux, you'v better to use the layout managers instead.
Take a look at this post also and see #Andrew Thompson's comment on my answer:
Java GUIs might have to work on a number of platforms, on different
screen resolutions & using different PLAFs. As such they are not
conducive to exact placement of components. For a robust GUI, instead
use layout managers, or combinations of them, along with layout
padding & borders for white space, to organize the components.
After all:
If you have a requirement or an assignment telling you you must use absolute layout, then use it, otherwise avoid it.
It is OK to use containers with no layout manager because you actually CAN set container's layout to NULL. And it's a nice idea to position your components with setBounds(). But in this case, you just have to consider your container. What size it need to be? A layout manager would calculate this for you, and if you don't have one, you have to set the size of your panel by yourself, according to components you have added to it.
As pointed by others here, the case it that the border-layout manager of your frame needs the preferred size of your NORTH panel (actually, the preferred height). And you have to set it, or values will be zeros and the container will become invisible. Note that for the CENTER panel this is not needed as it gets all space possible.
I had a problem like yours before and have written a fast function to resize a container according to bounds of a given component. It will be as large as needed to show this component, so dimension (w,h) and position (x,y) are considered. There's an "auto-resize" version that can be used once, after all components are added.
public static void updatePreferredSize(Container cont, Component comp) {
int w = cont.getPreferredSize().width;
int h = cont.getPreferredSize().height;
int W = comp.getBounds().x + comp.getBounds().width;
int H = comp.getBounds().y + comp.getBounds().height;
if (W>w||H>h) cont.setPreferredSize(new Dimension(W>w?W:w, H>h?H:h));
}
public static void autoPreferredSize(Container cont) {
for (Component comp : cont.getComponents())
updatePreferredSize(cont, comp);
}
You can use updatePreferredSize() after adding every component to a panel, or use autoPreferredSize() once, after all addings.
// [...]
panelN.add(button);
updatePreferredSize(panelN, button);
// [...]
// or...
// [...]
autoPreferredSize(panelN);
// [...]
frame.setVisible(true);
This way, if you do not set you north panel height with a fixed value, with help of these functions you can expect your button will be visible according the position you set it with setBounds().

How to set only the preferred width of Panel with flow layout?

I have a panel with flow layout, and it can contain a variable number of items - from 1 to 2000. I want to put it inside a scroll pane, scrollable in vertical direction, and with fixed width. The problem is, when I set preferred size of panel to something like (800,600), some items are missing, and there is no scroll. If I set up preferred size of scroll pane, then all elements in flow pane are put on one very long line.
Setting maximum size on any element seems to do nothing at all - layout managers ignore it.
How can I fix this?
I want to put it inside a scroll pane, scrollable in vertical direction, and with fixed width
You can use the Wrap Layout for this.
Don't set the preferred size of the panel. But you can set the preferred size of the scroll pane so the frame.pack() method will work.
You could use BoxLayout to do this:
JPanel verticalPane = new JPanel();
verticalPane.setLayout(new BoxLayout(verticalPane, BoxLayout.Y_AXIS));
JScrollPane pane = new JScrollPane(verticalPane);
//add what you want to verticalPane
verticalPane.add(new JButton("foo"));
verticalPane.add(new JButton("bar"));
This of course will use the preferred size of each component added. If you want to modify the preferred size for example of a JPanel, extend it and override getPreferredSize:
class MyPanel extends JPanel(){
public Dimension getPreferredSize(){
return new Dimension(100,100);
}
}
A note: BoxLayout will take in consideration getPreferredSize, other LayoutManager may not.
Please criticize my answer, I'm not sure it's completely correct and I'm curious to hear objections in order to know if I understood the problem.

Problem with FlowLayout

public class MyFrame extends JFrame
{
public MyFrame(String title)
{
setSize(200, 200);
setTitle(Integer.toString(super.getSize().width));
setLayout(new FlowLayout());
for (int i = 0; i < 5; ++i)
{
JButton b = new JButton();
b.setSize(90,50);
b.setText(Integer.toString(b.getSize().width));
this.add(b);![alt text][1]
}
this.setVisible(true);
}
}
why if having button widht 90 I'm getting window where three buttons are in one row instead of two?
FlowLayout will lay out Components left-to-right (or right-to-left) wrapping them if required. If you wish to explicitly set the size of each JButton you should use setPreferredSize rather than setSize as layout managers typically make use of the minimum, preferred and maximum sizes when performing a layout.
Size properties are quite confusing - There is an interesting article here. In particular, note:
Are the size properties always
honored?
Some layout managers, such as
GridLayout, completely ignore the size
properties.
FlowLayout, attempts to honor both
dimensions of preferredSize, and
possibly has no need to honor either
minimumSize or maximumSize.
The FlowLayout just places component one beside the other in a left-to-right order. When the width reaches the one of the container that has that layout it simply wraps on the other line.
If you want to arrange them in a grid-style layout (like it seems you want) you can use the GridLayout that allows you to specify the number of columns and rows:
component.setLayout(new GridLayout(2,2))
The only downside of GridLayout is that every cell of the grid will be of the same size (which is usually good if you just have JButtons or JLabels but when you mix things it will be visually bad).
If you really need more power go with the GridBagLayout, very customizable but with a steeper learning curve at the beginning.
Probably your size problem is related to the fact that you are using setSize but in Swing these things have strange behaviours, you should try by setting setPreferredSize(200,200) instead of setSize. But don't ask me why!
NOTE: you should ALWAYS refer to the frame's content pane and not to the frame it self. When you set layout you should do getContentPane().setLayout(..), when you add items you should do getContentPane().add(..) and so on.
Errata: now every JFrame add, remove, setLayout automatically forward to the content pane.
For one thing, you're not using JFrame correctly: you don't add components directly to the frame, you add them to a JPanel that you then pass to the frame with setContentPane().
Also: it's not very elegant to directly subclass JFrame just to add components. Instead, create your frame as a separate object.

Categories