add a scrollable jpanel to a gridlayout - java

I'm building a grid filled with labels. One of them contains html-text and should resize to maximum format and be scrollable. I found how to add a JScrollPane but it stays one line height, I just can't find how to resize it even when I give it a size of 400x400 ...
Removing getViewport() gives the same result.
JPanel grid = new JPanel(new GridLayout(1,2));
// first cell of the grid
grid.add(new JLabel("title"));
// second cell of the grid, this should be the scrollable one
JScrollPane scroll = new JScrollPane();
scroll.getViewport().setSize(400, 400);
scroll.getViewport().add(new JLabel("<html>long<br>html<br>text</html>"));
grid.add(scrollVersion, BorderLayout.CENTER);
Any ideas ?
Thanks a lot ...

GridLayout does not respect preferred size of the components which it lays out. It aims to make all grid cells the same size. An alternative is to use GridBagLayout, however I personally would recommend ZoneLayout which (in my opinion) is simpler, just as powerful, and much more intuitive. With the cheatsheet you can't go wrong.
As a side note, BorderLayout.CENTER is a constraint used for BorderLayout and is not compatible with GridLayout. When components are added to the owner of a GridLayout, you need not provide constraints. Components are added left to right starting at the top left corner cell using GridLayout.

Replace your GridLayout with a GridBagLayout. With the correct set of constraints, it should work like a charm. And obviously, take a look at some examples, as GridBagLayout seems quite complex, but is rather simple with some examples.

All cells of the GridLayout are designed to have the same size, so if you want one to be bigger than teh othes you must use another LayoutManager, like the GridBagLayout that Riduel suggest.
Also if your JLabel is going to have more than one line i suggest you to replace it by an uneditable JTextPane o JTextArea

Related

Make buttons unresizable

So I was trying to google how to set a default size to JButtons so that they don't grow as the JFrame is resized. I didn't see a setDefaultSize method but the closest one I could find that does a similar job is setMaximumSize(). However, it doesn't seem to work in my situation and I'm guessing it's because I'm using Grid Layout for positioning my buttons in the frame, here's a small piece of my code:
rightPanel.add(ButtonA);
rightPanel.add(ButtonB);
rightPanel.add(ButtonC);
outerPanel.add(leftPanel);
outerPanel.add(rightPanel);
getContentPane().add(outerPanel);
Here's a picture of what happens:
I would also like to have my buttons in the middle of the right panel when I'm resizing (just like they are now but a lot smaller). Any idea of how I can fix this? I'm assuming that I have to use another layout or something.
Thanks
EDIT: I modified my code to use BoxLayout but it does not seem to put the buttons in the middle. The X Alignment is working but Y Alignment is not doing anything:
ButtonA.setAlignmentX(CENTER_ALIGNMENT);
ButtonA.setAlignmentY(CENTER_ALIGNMENT);
ButtonB.setAlignmentX(CENTER_ALIGNMENT);
ButtonB.setAlignmentY(CENTER_ALIGNMENT);
ButtonC.setAlignmentX(CENTER_ALIGNMENT);
ButtonC.setAlignmentY(CENTER_ALIGNMENT);
JPanel rightPanel = new JPanel();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.Y_AXIS));
rightPanel.add(ButtonA);
rightPanel.add(ButtonB);
rightPanel.add(ButtonC);
outerPanel.add(leftPanel);
outerPanel.add(rightPanel);
getContentPane().add(outerPanel);
EDIT2: Fixed with vertical glue.
A GridLayout will always resize the components to fill the space available.
Try using a vertical BoxLayoutinstead. See the section from the Swing tutorial on How to Use Box Layout for more information and examples.
Encapsulate each JButton in a JPanel with a FlowLayout, and then add those FlowLayout JPanels to the rightPanel instead of the JButtons themselves. This will allow you to keep your evenly spaced buttons, but won't make them expand to take up the entire space that the parent container has available.
If you don't want them evenly spaced, but to be three consecutive buttons one after another top down, you can make the right panel have a BorderLayout, add a sub panel to the north area of the BorderLayout with the original GridLayout that the right panel had, and then add those FlowLayout panels containing the JButtons.

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?

Alignment of components in a gui window

I have got a window that looks like window1 and I would like it to look like window2:
This is my code:
String q = "Have you used GUI before?";
JLabel textLabel2 = new JLabel(
"<html><div style=\"text-align: center;\">" + q + "</html>", SwingConstants.CENTER);
add(textLabel2, BorderLayout.NORTH);
JPanel radioPanel = new JPanel();
add(radioPanel, BorderLayout.CENTER);
JPanel btnPanel = new JPanel();
add(btnPanel, BorderLayout.SOUTH);
For the radio-buttons, I tried to use GridLayout, but it broke the position of "Yes" and "No". And for the "back" and "next" buttons, horizontal alignment did not work (btnPanel.setAlignmentX(RIGHT_ALIGNMENT);), apparently. Any solutions will be highly appreciated, I'm stuck with this bit way too long. Thanks
--EDIT--
That is working perfectly fine:
btnPanel.setLayout(new BoxLayout(btnPanel, BoxLayout.LINE_AXIS));
btnPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10));
btnPanel.add(Box.createHorizontalGlue());
so the buttons problem is solved.
However, still can't get the radio-buttons fixed.
--EDIT 2--
Fixed the background for the radio-buttons using setOpaque(false);
What do you mean by it "broke" the position of "yes" and "no" as a GridLayout should work just fine. I'd give it 1 column and 2 (or 0 for variable number of) rows via new GridLayout(0, 1). Be sure that its opaque property is set as false by doing radioPanel.setOpaque(false);. This way it will show the background color of the container that it sits in. You may need to make the JRadioButtons non-opaque as well, I'm not sure.
Your btnPanel could use a BoxLayout and use Box.createGlue() to push the buttons over to the right side.
Most importantly -- if you haven't yet done so, please read the tutorials on use of the Swing layout managers which you can find here.
A couple of things you can do about this. You need to change your LayoutManager. This is not a great task for BorderLayout. You could do nested BoxLayouts. A vertical box that has the vertical fixed height strut, label, vertical fixed height strut, yes radio, vertical fixed strut, no radio, Vertical glue, and the final button panel. Then use your edit in the button panel to horizontally align them. That's one option, but the nesting of the panels is annoying.
Another option go get TableLayout and learn how to use it. TableLayout is one of the best LayoutManagers. It's easy to use, solidly tested, and it makes Swing fun again. You'll never use GridBagLayout ever ever ever again.
http://java.sun.com/products/jfc/tsc/articles/tablelayout/
The final option is use the new GroupLayout. I'm not terribly familiar with it, but it looks pretty easy. And, it doesn't take as much code or nesting unnecessary panels like Box does.

Problems with my GridLayout

I have a GridLayout 2 rows by 5 columns, and I want to make the height of the first row to something like 50, and the second row to 200. I know GridLayout creates equally-sized cells, so this didn't work out. I also tried splitting the two rows into two GridLayouts setting their desired heights and adding them to a FlowLayout, but the columns didn't align the way I wanted it to. My code went something like this:
row1.setSize(WIDTH, 50); //GridLayout
row2.setSize(WIDTH, 200); //GridLayout
panel.add(row1);
panel.add(row2); //panel is a FlowLayout
The columns aligning are very important and I can't seem to get this right.
I'd look into GridBagLayout. Although, almost everyone I've talked seems to dislike it. I like it, though.
You can't do this with a GridLayout.
You should be able to use either a GridBagLayout or a SpringLayout. Check out the Swing tutorial on Layout Managers for some examples to get you started.
Also you don't add individual rows to the layout. You need to add all 10 components individually to the same panel using whatever layout manager you choose.
Each cell in a GridLayout is exactly the same size, so you'll have to use a different layout manager, e.g. GridBagLayout.

How do I force JScrollPane to only scroll vertical?

Guys, I need to put some buttons in a jscrollpanel, but the JScrollPane won't create a scroll vertically. I'm using a JPanel inside the JScrollPane which is using the simple FlowLayout layout. How can I make the JScrollPanel to scroll only in the vertical??
Problem:
Desired Solution:
Check out the Wrap Layout
The fact you use a JScrollPane changes quite a few things concerning the internal FlowLayout. indeed, when the FlowLayout tries to layout contained JButtons, it use for that the available space. In your case, you don't have limits to the space in the "scrollable client" of your JScrollPane. As a consequence, considering your FlowLayout has infinite space, it uses this space to display items according to it.
So the solution would be to change your scrollable client in order to limit its viewable area to the same than your JScrollPane's JViewport.
However, you would not even in this case have your line returns, as FlowLayout don't really well handle this case.
Were I to be you, I would of course choose an other layout. As GridLayout don't really well handles borders, i think the only reasonible standard layout you can use is GridBagLayout, althgough I fear your dynamic content constraints may require you something even more customizable.
JTextArea c = new JTextArea();
c.setLineWrap(true);
c.setWrapStyleWord(false);
This will wrap anything in a text area to the next line without creating a Horizontal Scroll.
Use the modified Flow Layout that I posted in this answer: How can I let JToolBars wrap to the next line (FlowLayout) without them being hidden ty the JPanel below them?
It will wrap to the next line and your scrollbar should scroll vertically.
scrollbar = new Scrollbar(Scrollbar.VERTICAL);
Or you could use a JList.
See this site for more info: http://docs.oracle.com/javase/tutorial/uiswing/components/list.html
the example class: ListDialog uses only a vertical scrollbar, when the window is resized or the elements don't fit the view.

Categories