In which Swing layout manager it is possible to change layout areas programmatically? And how to do this with lowest cost?
I have to create component with functionality similar to JSplitPane but with three panels from scratch. One of the moments is to Expand/Collapse one of the panels after clicking oneTouchExpandable button on the divider. But the problem is that I don't know how to implement this collapse action. I tried just setting panels width to 0, but the layout area which contains this panel doesn't shrink after the component. I tried to do this in all Layout Managers, but effect is the same.
Thanks.
When making a change that affects the layout of a panel after the GUI is visible you need to revalidate() the panel which essentially invoke the layout on the panel. In your case it might be easier to simply make the component invisible:
component.setVisible(false);
panel.revalidate();
panel.repaint(); // this is only required sometimes
All layout managers resize dynamically. However, the width and height properties are the result of the layouting, and will be overwritten.
The properties you should look at are preferredSize, minimumSize, and maximumSize - the layout managers base their calculations on those properties, though the exact effect depends on the layout manager (e.g. BorderLayout will give the NORTH, SOUTH, WEST and EAST components their preferred size if possibe and assign the remainder to the CENTER component).
Once you've changed the size properties, you have to call revalidate() on the container, then you should see the changes.
I'm with the revalidate()/preferredSize answers but just wanted to suggest this: don't re-invent the wheel! Use the JideSplitPane (part of JIDE's free "Common Layer") - it supports more than two splits.
Thanks to all for the answers. Finally I ended up with combining solutions from several answers.
My final solution is following:
I use BorderLayout, set West, Center and East panels and then manipulate their sizes by setting PreferredSize to West and East panels. The scheme of rendering is following: while laying out the components BorderLayout gives East and West panels their PreferredSize and rest of the space to Center panel. So with a bit of easy calculations I can manipulate size of each of three panels painlessly.
I also added dividers(originally just JPanel components with fixed size) to West and East panels(their size is also considered while calculating). For dynamic resize I handle dragging events on this dividers and recalculate panel sizes.
Refreshing is done with following snippet:
container.setVisible(false);
container.revalidate();
container.repaint();
container.setVisible(true);
I'd like to put this code somewhere to be available for others, but don't know where exactly to do this. So if you know such place, please point me to it in the comments.
Related
I have two JPanel instances in a JLayeredPane, on different z-orders. I want both of my child JPanels to always fill the space of the LayeredPane.
The idea is for me to toggle the display of a 2nd panel over top of the first to display a modal-like dialog. Yes, I could just use a JDialog, but I thought it would be fun to try and create some transparancy overtop of the covered JPanel for a nice effect.
I find that using a layout manager on the JLayeredPane, like BorderLayout, and trying to set both children to CENTER conflicts since both panels can't be in the Center.
Is there a trick that I'm not seeing?
The idea is for me to toggle the display of a 2nd panel over top of the first
The easiest way to do this is to use a Glass Pane.
Check out the Disabled Glass Pane for an example of this approach.
There are two ways to create some "Glass Panel like" overlay for JPanels with JLayeredPane:
Add a ComponentListener to the JLayeredPane and update the sizes of all child components whenever the size of the JLayeredPane changes
Create a simple FillLayout, which expands the size of its child Components to the size of the Layout Container (In our case the JLayeredPane). You need to keep a list of children Components. During layoutContainer you copy the dimensions of the Container to these child Components. I wrote this and its really simple, but unfortunately I can't post it, since it's corporate. But if anyone is interested just ask in the comments. The implementation basically consists of one-liners.
For both solutions you need to make sure, that the panels on top are transparent, by setting setOpaque to false. This ensures that underlying panels render their content.
I have a Java Swing GUI where the top level layout manager is BorderLayout. I'd like it so that when the user resizes my GUI below the preferred size the center region can't be resized any smaller (or at least takes precedence in resizing) and the north/south regions become smaller.
The way it's working right now is my north and south panels are taking precedence and blowing away my center region first. I've tried setting a minimum size on the center panel once it has all of its components added to it
centerPanel.setMinimumSize(centerPanel.getPreferredSize());
but that isn't working for me. It's still the first region to minimize on a resize.
Maybe a BoxLayout will work. Box layout will respect the minimum size of a component. See the section from the Swing tutorial on How to Use Box Layout for more information.
I don't think anything simpler than GridBagLayout will serve. BorderLayout is not good about honoring minimum sizes.
I've got an arbitrary number of JPanels being created based on user input (like 1-8 panels). Right now, I'm putting all the panels in a larger panel using FlowLayout, and then adding that panel to my main window which is using BoxLayout. I want the panels to fit the width of the main window but right now they are very small. Should I use a different layout or is there a way to do this?
You have to choose GridLayout or GridBagLayout.
Yes, you should use a different layout manager. Use BorderLayout (tutorial here), which streches all the contents to fit the container.
Also, BorderLayout doesn't allow more than one component in each area, thus you will need another sub-panel to hold your panels. Don't use FlowLayout for that sub-panel, as it will not have the streching behaviour your are looking for.
I have a JTabbedPane and a JTextArea, I want the Textareas/Panes to resize to fit the window when the window is resized. How do I do this? I'm also fuzzy on if it's the right text component to use.
Really Muddled.
EDIT: I was setting explicit size as a dumb dumb. I've got it all worked out. What I did is set the viewport of a JScrollPane as the JTextArea and remove all explicit sizing.
Thanks chaps!
You can use whatever components you like. All JComponents can resize with a resizing parent container. You simply need to choose the correct LayoutManager.
Depending on how you want everything set up, I assume you will want to add your JTabbedPane to your JFrame like so:
JTabbedPane jtp;
JFrame frame;
// JFrame's default layour is border layout.
frame.add(jtp, BorderLayout.CENTER);
This will cause the JTabbed pane to take up all of the space of the JFrame.
You will also need to set your JTabbedPane's layout manager to BorderLayout, and also any tab you add to the JTabbedPane will need to have a BorderLayout.
To set the layout of your components, do:
JComponent anyComponent;
anyComponent.setLayout(new BorderLayout());
Have a look at the Java LayoutManager tutorials for more information.
I should mention that the reason I suggest BorderLayout is because any component added to the CENTER of a BorderLayout will automatically take up any space not taken up by any of the borders. And, since you aren't adding anything to any of the other borders (NORTH, SOUTH, EAST, WEST) the component in the center will take up the entire space.
Every JComponent is resized automatically when the container it resides in, is resized.
It's not a matter of the right component but more a matter of which LayoutManager to use.
When adding a Component to a container, you can set the minimum size, default size and maximum size.
On resizing the container, the component will scale automatically until reaching the desired maximum size.
If you need code snippets, tell me and I will fire up my IDE later.
cheers
EDIT: jjnguy beat me to it.. nvm then :p
How would I go about making the length of the tabs automatically resize based on how much room is left in that row of tabs.
Picture:
As you can see the tab's width is based off the text in the tab.
If you need me to explain what I want better then just ask me because I don't know if I made it clear enough.
You can use a custom component and set it's preferred size. For example, in ButtonTabComponent of TabComponentsDemo:
label.setPreferredSize(new Dimension(...));
You have to choose an appropriate dimension based on other aspects of your layout, so it won't be automatic.
I want to define a size for the actual tabbed pan.
The size of the JTabbedPane is a function of the dimensions and LayoutManager of the Container to which it has been added. In the example cited, the default layout of the frame's content pane is BorderLayout, and add(pane) adds it to the center by default.
To accomplish your goal, I see two approaches:
Divide the current width of the enclosing Container among the existing tabs and repaint the tabbed pane, as shown in this example.
Develop your own implementation of TabbedPaneUI and interpret SCROLL_TAB_LAYOUT accordingly.