I don't really have example code for this (so I'll try to explain it), but I'm wondering if there is a way to stop JSplitPane from mashing my layouts?
I have two panels that I add into a JSplitpane which both have GridBagLayout on them. On the left pane I have a table. On the right pane I have a JPanel that displays information when the user interacts with the table. However, when the information is displayed on the right pane, the table gets mashed. (unable to display unless the divider is dragged all the way to the right).
I would think with a GridBagLayout that my table should still be visible no matter what. Even if it squished the columns and rows in.
I'm just wondering if this is a common problem, if so, is there a fix?
My issue was that when the table was clicked I reset the constraints to the JSplitPane. This caused the constraints to disappear and leave the GUI to do what is pleased.
Pseudo:
//set constraints for panel that contains table and random components
//if table clicked add data (with GridBagLayout) in other side of splitpane <-- this is where I accidentally reset the layout
So as soon as that line of code was removed, it functioned as expected.
Related
Disclaimer: I am new to swing.
TLDR:
I am dynamically adding JPanels to an "enclosing" JPanel with a button. All panels use MiGLayout. The outer panel contains one cell only, and more rows are created as inner panels are added, top to bottom ("flowy" constraint). The inner panels are made of two rows --but the second one is revealed dynamically ("hidemode 3" layout constraint, with setVisible(false) until a condition is met.)
What's happening, is when adding an inner panel, and causing its second row to be visible, it overlaps with the panel below it. I have tried to call revalidate and repaint everywhere possible. To me, it would seem that the outer/enclosing panel simply has to revalidate its child components, but this doesn't seem to be happening.
Background
I am using MiGLayout and Swing to create a GUI for importing to my database.
Users should be able to hit a button which adds panels to an enclosing panel.
Specifically, the [portion of the] GUI [in question] is made of...
an enclosing JPanel(black), containing a:
JToolbar(blue) and
JScrollPane(red), which has as its Viewport
another JPanel(green)
this last JPanel, #4, is a container for dynamically added panels via a button (see the second picture below).
The bottom most JPanel, #4, uses MiGLayout. Itself, and the scroll pane that contains it, are hidden from view until a user hits that button next to the "File" comboBox. (not shown in picture above, as that wasn't runtime).
Once pressed, a subclass of JPanel is added to this panel:
(runtime screenshot)
The panels are stacked on top of eachother as more are added.
This inner panel is made of two rows, but the second one is invisible and does not affect the layout until it is visible. It is made visible via listeners once a condition is met within the text field..
The issue
If the second row of an inner panel becomes visible, it overlaps the panel in the row under it. Here's what I mean....
User adds three panels:
Second panel triggers setVisible(true), so now is made of two rows, but hides the third panel:
For dramatic effect (same runtime):
The problem is obvious. How do I prevent this overlap?
Ideally, I'd want the out panel to reorganize itself appropriately to account for the larger size.
Say I add one panel, then trigger the hidden row, THEN add another panel --- there is still overlap. It was my understanding that revalidate() should take care of these things but I have called it every place possible (perhaps too much, if possible??) to no avail..
I have tried many different constraints on the enclosing panel as well as the inner panels, with no luck. I have tried both creating the second row and show/hiding it dynamically, or simply creating it dynamically, with no luck. It consistently overlaps the same way, and I cannot get it to re-layout these inner panels.
I can think of some work arounds, but this seems like it should be possible!
My longest question ever, sorry for that. Any help is appreciated.
Thanks.
It turns out that setting row constraints on the (green) outer panel was what was causing the issue.
I had set min/preferred row size to 30 pixels, with a maxiumum size of 60 pixels (60 being the size of a two row inner panel). Clearly this did not do what I thought it should.
I had heard to be wary using pref/max/min bounds in swing---but I ignored it and this is what happened!
By removing the row constraints completely, the outer (green) panel shifts the rows and what not appropriately.
jframe.getContentPane().revalidate();
I just recently started using Swing to create GUIs for programs, and it's been pretty fun to mess around with so far. However, I'm having an issue with a JPanel with the layout set to gridLayout. Right now it looks like this:
The grid on the right is a JPanel set to a GridLayout, with each cell being a bordered JLabel. The options on the left are also inside a JPanel, and the left JPanel and right JPanel are nested in a GridBagLayout set on a JFrame.
Essentially, my problem is that I want to "scale" the grid on the right so that each cell is a certain height and width. The grid itself will have a variable number of rows and columns, which are set when the program first starts up. Eventually, I plan to have the right JPanel in a JScrollPane (if that's how that works...), so I'm not really concerned about whether or not all of the grid shows up onScreen.
I tried setting the fill value for the gridLayout to "BOTH" and it gave me the following result:
This is closer to my intention, but I wanted the actual ImageIcon in the JLabels to fill the entire JLabel. Additionally, I would want the JLabels to be the same height and width. However, I don't know exactly how to do that. I've been messing around with it for a while now, and I'm not sure if I'm just too much of a noob with Swing, or if I'm missing something in the documentation.
In the end, I'd like the grid cells to be a fixed height and width, no matter the number of cells, and no matter whether it goes offscreen or doesn't fill it.
(Also, I just thought, maybe it's not the best idea to code this and then shove it in a JScrollPane later and expect it to perform the same.... I guess I'll just see what happens.)
but I wanted the actual ImageIcon in the JLabels to fill the entire JLabel.
Check out Darryl's Stretch Icon which will allow the icon to resize to file the space available for the JLabel.
I created a JFrame initialized with a BorderLayout and a JScrollPane as its CENTER element.
The scroll pane is set with VERTICAL_SCROLLBAR_ALWAYS and HORIZONTAL_SCROLLBAR_NEVER policies. The intent of my frame is to have a controlled width, while the height should grow/shrink as data is added/removed.
Inside my scroll pane, I added a simple JPanel (lets call it the content panel) which is initialized with a FlowLayout (and LEADING policy).
In order to test this, I simply populate my content panel with 20 JLabel("Item " + n) components where n is the loop counter.
I would expect to see my labels shown on a single row if the frame is large enough and the labels wrap to other lines when I shrink the width. But instead, there is only a single line displayed with no wrapping... ever.
Does anyone know why the flow layout does not wrap when a scroll pane is involved?
If I remove the scroll pane all together and put the content panel directly in the frame, the desired wrapping effect occurs, but if the frame height is shrunk smaller than the content panel height it just disappears.
The idea is that I want my labels to be wrapped when necessary but also always be visible if it means having to scroll up/down.
Any suggestions on how to fix this?
Thanks.
Wrap Layout gives an explanation and a solution.
If you work with the designer, you have to set the prefferedSize property to null (delete what is set) then set the preferred size by clicking the triple dots [...] button next to the prefferedsize property name and put your preferred value.
I encountered the same problem and it works for me.
Been developing a game for a while, and currently re working the GUI, or at least trying to. Had the massive problem of not being able to resize the frame (without issues), as I didn't understand layout managers very well. A few projects later, and time to come back and do some more on the game, and I hit a problem...
The basic layout of the main frame is, mainPane, containing one gameScrollPane and one controlPanel. The scroll pane is a scroll pane, and the control panel a normal panel. The scroll pane contains the main game panel.
As I wanted the scroll pane to take up most of the screen, with the control panel taking up a small lower area, much the same as many Sim like games, so chose the Border layout for the mainPane. I added the scroll pane and set the constraints CENTER and the control panel added and constriants SOUTH. This didn't show the scroll pane, so I played around trying different constraints, and it seems that only when I set the scroll pane constraint to North, does it display at all.
To demonstrate this, I have created a quick video...
http://screenjel.ly/q5RjczwZjH8
As you can see, when I change the value of NORTH to CENTER and re run, it's like its not there!
Bonus points for anyone who can see a clear second problem which I may start another question for after this issue is solved!
I thank you for your time to read this.
Thanks in advance for any ideas or thoughts :)
Rel
If you'd posted some code to start with then you might have gotten a really quick answer. Luckily, you posted a link in the comments to the other response.
The setContentPane() stuff is weird, especially after doing some things to it that will then get wiped out. However, that's not your problem.
The issue is that you are adding levelMaker and personMover right to mainPane without any constraints. These will then be blowing away anything you set for CENTER... in this case the previously set gameScrollPane.
That's why you see it for NORTH and not for CENTER.
I can't get the video to show. It's been buffering for ages.
My guess would be that the scrollpane is in fact filling the center; it's just your game panel that's not being shown.
Your game panel needs to return reasonable values for getPreferredSize().
Update
Another thing you may want to do is have your game panel implement the Scrollable interface. You can then override getScrollableTracksViewportWidth and ...height to return true so your panel will be forced to the scrollpane's dimensions.
I need to layout a panel on the top of my Dialog so that it has two buttons (Save and Cancel).
I want the save to be on the left and Cancel to be on the right side.
I've created a JPanel using the MigLayout and docked it to the north of the content pane, and can't for the life of me figure out how to add the two buttons to it so that they appear as I want them. Docking them within the panel seems to get rid of all padding in the dialog (which looks terrible).
Any help would be greatly appreciated.
As an aside, you should probably not be dictating which button is on the left or right. That's one of the way cool things about MiGLayout (platform independence, even on things such as where the cancel button should go).
p.add(cancelButton, "tag cancel");
p.add(okButton, "tag ok");
Now the buttons will appear in the correct order, based on platform.
Here's an article with code doing what you are going for. I strongly recommend avoiding trying to force the size of components like buttons (these really should come from the platform look and feel). Also, docking is fine if it makes sense to do so, but I rarely find it to be necessary. Instead of building a totally separate panel for your buttons, just span the row that contains the buttons - much cleaner, and you don't wind up with all of the nested panels.
It's hard to break from the border layout technique of nested panels, but once you get the hang of it, MigLayout is a dream. BTW - I understand that there are times where you might want to build up the button panel in a library - if that's the case, then separate panels may make sense (although you could also have the library add a button row to an existing panel, instead of returning a panel that you then add to the layout).
Doh, always happens as soon as you ask a question, the answer pops out:
JPanel buttonPanel = new JPanel(new MigLayout("fill","[50][50]",""));
buttonPanel.add(saveChangesButton);
buttonPanel.add(cancelButton, "align right");
getContentPane().add(buttonPanel, "dock north");
Note that the content pane is using the MigLayout too.