Is there a way to set, when specifying height and width of a component in Swing, that a given object should fill the available vertical/horizontal space? I.e. I would like to say setSize(*, 100) to allow horizontal fill.
You can call setSize with whatever you want, but in the end it is the LayoutManager of the parent Container which decides what position and what size each component gets.
So by using the correct LayoutManager you can typically succeed in letting a component take all the available width.
As you can see in the BorderLayout part of the Visual guide to LayoutManagers tutorial the PAGE_START and PAGE_END take all the available width.
By specifying the height as preferred size you will obtain the desired result
A BorderLayout is probably what you'll want to use, it allows you to set components to North, West, South, East and center.
So for horizontal fill use NORTH, for vertical fill use WEST and for both CENTER.
Related
I have a program in which I use BorderLayout and the EAST and WEST positions are not filled, though the CENTER one is. As a result, the center component extends to the space where the east and west components would be.
How can I prevent this? I know I could just use a blank JPanel in the east and west positions, but that seems hacky.
If what you want is empty space around your center panel, you can add a border to it:
panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10);
You said:
I know I could just use a blank JPanel in the east and west positions, but that seems hacky.
Why is that hacky? How else would you control the amount of size of the visible space? What if you only want it to be a narrow (say, 10 pixels) blank space? What if you want it to be 100 pixels? What if you want the border to grow and shrink based on the size of the corresponding frame?
Adding some sort of component there (it doesn't have to be a JPanel, though that's not a bad choice) allows you to specify the size of it more effectively, and there's nothing inherently wrong with doing so.
What you need is Box.Filler. It is used to create empty components to fill areas.
See https://docs.oracle.com/javase/tutorial/uiswing/layout/box.html#filler
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 have a horizontal scrollbar that controls a large panel (with a very large width, and a very small height, thus an horizontal panel).
I want the start of the scrollbar (when the knob is at max left) NOT to start at the beggining of the panel it is scrolling, but rather in a specific place that I dictate. The same for the end of the scrollbar (when the knob is at max right).
I find that the scrollbar is always bound to the panel it is scrolling, and I can't figure out how to change its behaviour.
EDIT:
As an example, picture a normal web-page: when at the top of the page, the scrollbar knob is also at the top. When at the bottom, the scrollbar knob is at the bottom. I want to define new limits for the content, such that when the scrollbar knob reaches the top or bottom, the page is showing the limit I defined, instead of the real top and bottom.
As shown in How to Use Scroll Panes, you can use the component's scrollRectToVisible() method to scroll to an arbitrary Rectangle. There's an example here.
Addendum: As a Container, a JPanel is fairly fungible even if it has considerable nested content. One reliable way to swap content at a given level is via CardLayout, shown here, here and here.
I solved the problem by using the JScrollbar method setValues(), which allows me to set at the same time the maximum, minimum, value and extent of the scrollbar. By setting the maximum and minimum to the values I want, the scrollbar behaves as I wanted/expected.
The problem was that I was only setting maximum and minimum values (setMaximum, setMinimum), and since there is a strict policy at the model that minimum <= value <= value+extent <= maximum, that estrategy did not work.
Would it be possible to keep the large panel as a backing store and copy the region of interest into a panel which is actually realized in the scrollpane. This way you don't have to fight the behavior of the scrollpane.
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.
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.