Adding panel to BorderLayout region, elements not wrapping as they should - java

So I have some code like this inside init() for an applet:
layout = new BorderLayout();
setLayout(layout);
northPanel = new JPanel(new FlowLayout());
northPanel.add(inputDropDown);
northPanel.add(lowBoundLabel);
northPanel.add(lowBoundField);
northPanel.add(highBoundLabel);
northPanel.add(highBoundField);
northPanel.add(new JLabel("using"));
northPanel.add(categoriesField);
northPanel.add(new JLabel("categories"));
northPanel.add(showTotalsBox);
northPanel.add(refreshButton);
add(northPanel, BorderLayout.NORTH);
Now when I test it, all of the elements are in a straight line and do not wrap around when there is not enough space. I even made sure to specify that the panel is FlowLayout (even though it's the default) and it didn't change anything.
Shouldn't they wrap instead of just going off the screen? What's going on? I came up with a temporary solution by changing the northPanel to BorderLayout, splitting up these elements into to separate panels and adding them to North and South. However, the elements just disappear off the screen without the necessary space in this method so I'd rather have them wrap around.

This is actually exactly how FlowLayout works, annoying isn't it...
Take a look at WrapLayout instead...

Related

Placing components on Jpanel

Can i combine Java layouts in same JPanel. I'm stuck with with placing my components on JPanel. It shoudl be like this: JLabel, JButton, JButton , JLabel and new line and same. I used BorderLayout but it wont go to the next row, keep adding components to same row and I need a new row. Ideal sit combined with cardlayout or some other good solution.
EDIT: Solved with GridLayout (0,4) It will do the job till i learn to use GridBaglayout. Thank you for trying to help me.
Yes you can combine layouts.
Using a JPanel you are able to embed other JPanels:
JPanel back = new JPanel(new BorderLayout());
JPanel rows = new JPabel(new GridLayout(3,3));
back.add(rows, BorderLayout.CENTER);
Without seeing your code though it's difficult to know exactly what you are trying to achieve!
Yes you can combine java layouts.
A common pattern I use is BorderLayout first on a frame. The central component expands out, while the other components shrink in. Inside these panels I might have a Flowlayout to show buttons evenly spaced horizontally on top.
Another common approach for forms is using a Gridbaglayout, then adding all the form elements at gridX and gridY positions. I then later can stretch and teak these cells using other constraints in the Gridbaglayout repetoire.
Can you add a screenshot so that we can see what you want to do?

Glue Equivalent in MigLayout

I am using MigLayout and I would like to create an effect like using BoxLayout's "glue" to create an invisible space that will flexibly fill the area between two components. From the tutorial:
I understand that in MigLayout, gaps are used to create spaces between components. I can create a rigid space with "gap 10". The MiG Layout Cheatsheet says that I can append push to a bound size with a gap to "make that gap "greedy" and take any left over space" (e.g. "gap rel:push"), but that doesn't seem to work in the following code that I've tried:
JFrame frame = new JFrame("Test");
JPanel panel = new JPanel(new MigLayout());
JLabel label1 = new JLabel("Testing");
label1.setBorder(BorderFactory.createLineBorder(Color.black)); //Border to clearly show JLabel boundaries
panel.add(label1, "");
JLabel label2 = new JLabel("Testing Once Again");
label2.setBorder(BorderFactory.createLineBorder(Color.black)); //Border to clearly show JLabel boundaries
panel.add(label2, "gap rel:push");
frame.setContentPane(panel);
frame.pack();
frame.setMinimumSize(new Dimension(400, 100));
frame.setPreferredSize(new Dimension(400, 100));
frame.setVisible(true);
Which displays a window like this:
I would expect for the "gap rel:push" parameter to work like horizontal glue in the picture above and thus push the JLabel on the right all the way to the right edge of the window, but it doesn't.
How can I get the same effect as BoxLayout's glue using MigLayout? Am I misusing the "gap" parameter or is there some other way to accomplish it?
Also, I realize that I could use docking in the example given, but I'd like an answer without that because it won't work in a more complex layout I'm creating.
Save yourself some sanity points and enable debug borders on the MiGLayout: new MigLayout("debug").
It's possible that the gap is indeed pushing the components apart, but the layout isn't using all of the available space. This should be obvious if you turn on debug borders. Try making the layout use all available space: new MigLayout("debug, fill").
Instead of placing a gap between your label and the cell edge, you may want to place a gap between the two columns: new MigLayout("debug, fill", "[]rel:push[]"). The difference should become clear when using a multi-row layout. In this case, you may not need the fill constraint: new MigLayout("debug", "[]rel:push[]").
I don't have a compiler handy to run this against, but I hope I've given you something to work with.

Automatic wrapping using MigLayout

I'm looking to wrap a JPanel when it reaches the 'edge' of the screen using MigLayout. At the moment I have a JScrollPane (which I only want to be enabled vertically). The JScrollPane contains any number of JPanels which are arranged horizontally - when a panel is added so that the JPanel would go off the edge I want it to add to the next line. Is this possible?
This is the code:
public void setupPanels(){
JScrollPane scrollPane = new JScrollPane();
JPanel mainPanel = new JPanel(new MigLayout("insets 2"));
for (Object object : objects){
JPanel subPanel = new JPanel(new MigLayout("insets 0"));
mainPanel.add(subPanel, "alignx left, gapx 2px 5px, gapy 2px 2px, top");
}
scrollPane.setViewportView(mainPanel);
}
Also, to add an extra factor, every time it reaches the edge I need to add a new/different panel (a timeline) - so is there a way of finding out when it is going to wrap onto a new line?
Thanks
MigLayout does not have such a feature. It is based on a grid and while you can use the nogrid option to flow components horizontally or vertically in a cell span, you cannot make them flow into the next row or column.
The java.awt.FlowLayout contained in the JDK wraps the contained components automatically:
JPanel mainPanel = new JPanel(new FlowLayout());
mainPanel.add(subPanel1);
mainPanel.add(subPanel2);
mainPanel.add(subPanel3);
...
The preferred height is off, but there are ways to fix this, see WrapLayout.
As for the second requirement:
Also, to add an extra factor, everytime it reaches the edge I need to
add a new/different panel (A timeline) - so is there a way of finding
out when it is going to wrap onto a new line?
A layout manager should layout components that have already been added to a container, not add new components based on the results of the layout. Adding invisible placeholder components for the timeline after each subpanel that are made visible by the layout manager on demand might work.
You definitely need a custom layout manager to do this. To get started I would recommend to take the source of FlowLayout. In the layoutContainer implementation there is a loop that iterates over all components. After a line wrap, check if the next component is a timeline placeholder component, make it visible and wrap again.

Why am I not getting a functioning JScrollPane?

I have a JFrame window, and I'd like to add a scrollable JTable towards the middle of it. I have a method, called collectionTableScrollPane() that generates the JScrollPane (and I know this is guaranteed to work).
I then proceed to add it to my mainPanel panel. However, I'd like there to be some forced 30px padding on the left and right of the JScrollPane. Logically, I would create a holding JPanel with a centred FlowLayout, and add Box.createHorizontalStrut(30) either side of the JScrollPane.
JPanel tableHolderPanel = new JPanel(new FlowLayout());
mainPanel.add(tableHolderPanel);
tableHolderPanel.add(Box.createHorizontalStrut(30));
tableHolderPanel.add(collectionTableScrollPane());
tableHolderPanel.add(Box.createHorizontalStrut(30));
However, I'm getting a strange result, where the JScrollPane in the middle of the window (denoted by the arrows) sort of becomes ineffectual.
Does anyone know what the problem is?
Note that the JTable contains four rows, of which only two are visible.
I had some issues in the past when i used a JScrollPane inside a panel with a FlowLayout. The behaviour could be tricky, when the content grow, the horizontal scrollbar may appear or the FlowLayout should add a new line.
In your case, i will replace the FlowLayout by a BorderLayout :
JPanel tableHolderPanel = new JPanel(new BorderLayout());
mainPanel.add(tableHolderPanel);
tableHolderPanel.add(Box.createHorizontalStrut(30), BorderLayout.WEST);
tableHolderPanel.add(collectionTableScrollPane(), BorderLayout.CENTER);
tableHolderPanel.add(Box.createHorizontalStrut(30), BorderLayout.EAST);
As far as I'm aware, Box is suppose to be used with the BoxLayout, this may be causing you some issues. Instead, why not use a EmptyBorder on the tableHolderPane
BoxLayout accepting size that came from JComponents, the same issue with default FlowLayout pre_implemented for JPanel
you have to returns PreferredSize by overrode JPanel nested JScrollPane,
use another LayoutManager, e.g. GridBagLayout or todays MigLayout
use NestedLayout, by using BorderLayout where you put two JLabels (e.i. that returns PreferredSize) to the EAST and WEST area
everything depends if you really to want to create the empty area and if shoud be resiziable or not

How do I add space to a JPanel, so that JScrollPane doesn't sit on top of my components?

I have a JScrollPane and when I load my application the bar is sitting on top of one of my buttons. What I would like to do is add some space to the side of my button so that the scroll bar draws over the space and not my button.
Example code that I tried:
JPanel eButton = new JPanel(new BorderLayout());
JPanel spaceFiller = new JPanel();
spaceFiller.setSize(30, 10);
eButton.add(editButton, BorderLayout.EAST);
eButton.add(spaceFiller, BorderLayout.WEST);
The problem with this code is that it still overwrites my button and no space is added. What is the best way to make sure that JScrollPane doesn't overlap the components in my JFrame?
Thanks
To ensure that the size of the JPanel is respected you should use setPreferredSize() instead of setSize().
In your sample code, didn't you reverse EAST and WEST? Shouldn't it be like:
eButton.add(editButton, BorderLayout.WEST);
eButton.add(spaceFiller, BorderLayout.EAST);
That would make more sense, sicne the scrollbar will appear on the right side (EAST).
Please note that the solution you suggest, even though it may work (after exchanging EAST and WEST) looks more like a hack than a real solution.

Categories