I am attempting to put a JGoodies panel into a JScrollPane with only a vertical scroll bar; any elements larger than the current JScrollPane width should be truncated. However I can't figure out a way to make this work
Example of the effect I'm going for
What I don't want to happen
My current code is essentially:
FormLayout locationsLayout = new FormLayout("15dlu, pref, 5dlu, pref, 5dlu, pref:grow", "");
locationsBuilder = new DefaultFormBuilder(locationsLayout)
.background(Color.WHITE)
.lineGapSize(Sizes.ZERO);
locationsPane = new JScrollPane(locationsBuilder.getPanel());
locationsPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
locationsPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
//...Sometime later, the user adds a folder...
FormLayout headerLayout = new FormLayout("pref, pref", "pref");
DefaultFormBuilder headerBuilder = new DefaultFormBuilder(headerLayout)
.background(Color.WHITE)
.lineGapSize(Sizes.ZERO);
headerBuilder.add(curContainer.getGuiHeader(), CC.xy(1, 1));
headerBuilder.add(curContainer.getGuiTablePrefix(), CC.xy(2, 1));
locationsBuilder.leadingColumnOffset(0);
locationsBuilder.append(headerBuilder.getPanel(), 6);
Things I've tried
Various permutations of min, pref, grow, fill, etc. Nothing changed this behavior
Passing a custom JPanel that implements Scrollable to the locationsBuilder DefaultFormBuilder constructor as documented here, here, or here
Trying the other vertical scroll bar options on JScrollPane
I don't know what else I can try. Does anybody have any suggestions?
I never could find an exact answer to this specific setup. My guess is that JGoodies dies bit handle nested layouts very well.
I ended up "fixing" this by using only one single panel for the entire locations scroll pane. This made the layout a bit complicated: Multiple cells now had to span columns and I had to manually adjust the column offset. But in the end it works
Related
I am trying to show a scroll bar next to my text pane but I can't find the reason why it doesn't show.
this.setLayout(null);
editorPane = new JTextPane();
size = editorPane.getPreferredSize();
editorPane.setBounds(17, 12, 533, size.height * 3);
editorPane.setBackground(Color.BLACK);
editorPane.setForeground(Color.WHITE);
//editorPane.setEditable(false);
console = editorPane.getStyledDocument();
scrollConsole = new JScrollPane(editorPane);
scrollConsole.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
this.add(editorPane);
this.add(scrollConsole);
Avoid using null layouts, pixel perfect layouts are an illusion within modern ui design. There are too many factors which affect the individual size of components, none of which you can control. Swing was designed to work with layout managers at the core, discarding these will lead to no end of issues and problems that you will spend more and more time trying to rectify
See Why is it frowned upon to use a null layout in SWING? for more details...
You have two basic mistakes...
You've decided to use a null layout, but neglected to set the size of the JScrollPane
You set the JTextPane as the view for the JScrollPane but then add it to the container, along with the JScrollPane. A component can only belong to a single container, by adding it a second time, you've removed it from the JScrollPane
See How to Use Scroll Panes for more details
I'm trying to add a table to my program that has the column names at the top and a scroll bar down the side. For some odd reason everything works, but the column names don't show nor does the scroll bar.
Here's my code, if you need a running program let me know, but you should be able to just add this to an empty JFrame:
String[] columns = {"Sport", "Location", "Date", "Result"};
String[][] data = {{"Football", "AQA Highschool", "12.11.13", "5 - 0"},
{"Tennis", "Wembley", "26.11.14.", "TBC"}};
listTable = new JTable(data, columns);
listTable.setPreferredScrollableViewportSize(new Dimension(450, 750));
listTable.setFillsViewportHeight(false);
listTable.setBounds(25, 100, 450, 640);
JScrollPane scroll = new JScrollPane(listTable);
guestFixturesPanel.add(listTable);
guestFixturesPanel.add(listTable);
is wrong ! you must add the scroll like this:
guestFixturesPanel.add(scroll);
For some odd reason everything works, but the column names don't show
nor does the scroll bar.
First of all you're not adding the scroll pane but the table directly to guestFixturesPanel:
guestFixturesPanel.add(listTable);
Second, you must avoid the use of setBounds() method and use a suitable LayoutManager instead. Take a look to A visual guide to Layout Managers. You might also consider third party options suggested here. As #AndrewThompson always says:
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. To organize the components
for a robust GUI, instead use layout managers, or combinations of
them, along with layout padding & borders for white space.
This is what I've layed out using a GridBagLayout:
But, when I select a file a couple of labels are supposed to be populated. This is what it looks like after I make a file selection using those small "..." buttons:
As you can see , the entire layout gets messed up. All I am doing in the actionlistener is this:
fileTxt = fileChooser.getSelectedFile();
fileTxtField.setText(fileTxt.getAbsolutePath());
labels = getLabels();
lbl1.setText(labels[0].toUpperCase());
Dimension size = lbl1.getPreferredSize();
lbl1.setMinimumSize(size);
lbl1.setPreferredSize(size);
lbl2.setText(labels[1]);
lbl2.setToolTipText(longLbl);
size = lbl2.getPreferredSize();
lbl2.setMinimumSize(size);
lbl2.setPreferredSize(size);
button1.setPreferredSize(new Dimension(20,25));
button2.setPreferredSize(new Dimension(20,25));
So, basically, the buttons are going to their original sizes and not preferred sizes.and that messes up the entire layout. How do I fix this? All components are set not to fill with the gridbagconstraint of gridBagConstraints.fill set to GridBagConstraints.NONE - however, the layout still gets messed up :(
UPDATE
As per your suggestions, I removed the code that was calling setPreferredSize() method, and this is what I get:
Obviously, this is what I want to avoid - a button, that is bigger than its text, that was reason for setting setPreferredSize on the button. Now what do I do?
Don't call setPreferredSize(). Let LayoutManager do this.
In your GridBagConstraints define fill and weightx parameters to define how extra space should be distributed.
There is a simple solution to this. The extra width of the buttons is due to the default margins on the left and right of the button text. By default it is 14
you can set btn.setMargin(new Insets(2, 0, 2, 0)); and that extra gap will go.
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.
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