How to prevent MigLayout from exceeding a container's bounds - java

I'm trying to construct a simple status panel using MigLayout as follows:
setLayout(new MigLayout("fillx", "[][p]")); // removing constructor args makes no difference
add(createStatusLabel(), "span 2, wrap");
add(createProgressBar(), "growx, pushx");
add(createCancelButton(), "");
This works fine as long as the status message displayed by the status label is short enough to fit within the current panel's size (the cancel button remains right-justified, and the progress bar resizes to take up the remaining space). If the status message is too long, it is not cropped, and causes the area to exceed the bounds of the container, resulting in the cancel button being pushed off screen.
Any suggestions on how to prevent this from happening?
Thanks

Try setting the maximum width of the label to 100%.
You can do this by changing the layout for the label to "span 2, wrap, wmax 100%"
In my tests, I found that it still didn't look quite right, so you may want to subtract a little bit of length (something like wmax 100% - 10px) to bring it away from the edge.

Related

How to limit the amount of scrolling ScrollPane does

When scrolling on my ScrollPane, it leaves a lot of empty space when I reach the bottom, I want this to be limited so it stops allowing scrolling when the bottom item of the ScrollPane becomes visible.
Image 1 - Top of the ScrollPane
Image 2 - Midway down the ScrollPane
As you can see there's a lot of space at the bottom, ideally this would stop being able to scroll after "TestIdleLevel2" becomes visible.
ScrollPane:
ScrollPane itemCollectionScrollPane = new ScrollPane(itemCollection);
itemCollectionScrollPane.setPrefSize(shopInterface.getPrefWidth()*1.55, shopInterface.getPrefHeight());
itemCollectionScrollPane.setHbarPolicy(ScrollBarPolicy.NEVER);
itemCollectionScrollPane.getStylesheets().add(Shop.class.getResource("/cssFolder/TransparentScrollPane.css").toExternalForm());
Transforms for the items within it:
itemBox.getTransforms().add(new Translate(shopInterface.getTranslateX() - itemBox.getPrefWidth() / 8,
shopInterface.getTranslateY() + (counter * shopInterface.getPrefHeight() / 3), 0));
itemCollection.getChildren().addAll(itemBox);
Each transform is separated by a counter to space it out, this stops after the items have been looped through (4).
The preferred height is set to about 300, and should be extended to about 400 due to the ScrollPane. However, the ScrollPane is extending it to around 500-600.
Issue: itemCollection was being initialized as the same size as shopInterface.
Solution: Initialize the height as a smaller instance of shopInterface. (In this case the exact amount was shopInterface.getHeight()/4).
Special thanks to Fabian.

Java How to get JComponent to resize based on frame width

So my calculator program looks good unless I resize it. Then things get all out of whack. Right now I'm using a GridBagLayout to organize my buttons (thought it was best to use GridBag for this situation given a number of buttons). I set the preferredSize to what I would like the size of the buttons to be upon startup. How can I get the buttons to change size upon window resizing?
That's what happens after I resize the app smaller.
When I make it bigger, everything just stays the same and I get a grey emptiness on either side to make up space, instead of enlarging the buttons.
For my buttons dimensions i'm using new Dimension(80, 55)
Then setting the preferredSize to that dimension.
For the memory buttons and jlabels I compute some math to make it as wide as the total buttons across.
Please Note I'm still learning java, as well as the swing library. END NOTE
UPDATE I tried setting the minimum and maximum size when I set the preferred size and still no go END UPDATE
UPDATE 2 I tried setting the size of my main panel to match the size of the app upon start and that didn't work END UPDATE
EDIT 2 My hierarchy is like this:
FRAME
MAINPANEL - Contains all three panels
TOPPANEL - Contains the display
MIDDLEPANEL - Contains memory buttons
BOTTOMPANEL - Contains calculator buttons
END EDIT 2
I recommend using TableLayout from Oracle (you can download it there), because it is more comfortable. Sure it is possible with the GridBagLayout too, but especially when you're new, the TableLayout is much easier to understand and to configure.
double size[][] =
{{0.25, 0.25, 0.25, 0.25}, //Horizontal
{50, TableLayout.FILL, 40, 40, 40}}; //Vertical
frame.setLayout (new TableLayout(size));
It's basically a Grid which is separated into rows and columns. So, each of the cells have an id, for example "0, 0".
The height and width is adjustable with pixels, percentage, and Layout.FILL, which uses the available space. if you are using multiple Layout.FILL, it will separate the available space between them.
To add Buttons or other elements, you will need to know the cell coordinates, if it's bigger than one cell, you can add an end cell to, so you can use the whole place available.
// Add buttons
frame.add (button[0], "1, 1, 4, 1"); // Top
frame.add (button[1], "1, 4, 4, 4"); // Bottom
frame.add (button[2], "1, 3 "); // Left
frame.add (button[3], "4, 3 "); // Right
frame.add (button[4], "3, 3, c, c"); // Center
frame.add (button[5], "3, 3, 3, 4"); // Overlap
Here some useful links:
http://www.oracle.com/technetwork/java/tablelayout-141489.html
http://www.clearthought.info/sun/products/jfc/tsc/articles/tablelayout/Simple.html
http://www.clearthought.info/sun/products/jfc/tsc/articles/tablelayout/Preferred.html

Waiting for the GUI to fully update?

I have some tabs with scrollable panels that contain a series of labels. The labels may be "focused", in which case they are to remain perfectly centered, as tabs are switched, the window is resized, or font size is changed. I have all the math for that done. The only issue is when the code runs. The following function...
public void fixMargins() {
//Top margin:
final int top = (this.getHeight() - this.getVerseBlock(1).getHeight()) / 2;
//Bottom margin:
final int bottom = (this.getHeight() -this.getVerseBlock(this.view.getComponentCount()).getHeight()) / 2;
this.view.setBorder(new EmptyBorder(top, 0, bottom, 0));
//Set scroll bar accordingly:
this.jumpCenter(this.focused);
}
... will work sometimes. Seemingly every time when the window resizes, because dragging it causes an update every pixel. On maximizing, or on switching tabs after a redraw, it is not properly focused because it's using outdated numbers. I've confirmed this with console output.
I know exactly what needs to happen, but I only know an easy way in Node.js, which this certainly is not. Basically:
External value updates - resize, font change, etc;
Wait for layout to be 100% complete, all labels and parents settled into new size;
Apply margins according to new size;
Wait for layout to update 100% again, scrollable range finalized;
Move scroll bar to determined position using current numbers.
The following do not wait for the UI to fully update, for reasons I am unsure of:
revalidate()
doLayout()
SwingUtilities.invokeLater()
I'm about to just throw in a hack job that pauses a thread for one millisecond before running the code, but I figured I'd ask and see if there is any sort of convenient waitForLayoutUpdate() function that I just haven't found yet.
Upon further research, I have discovered that the JLabels specifically are not reporting a correct height at the time that it is checked. This is a known issue with them, but I have yet to find a work-around.

Java swing GridLayout adjusting cellsize

After starting a JPanel using GridLayout(4,4) i insert a JLabel (and attach an imageicon to it) inside every grid cell with size of (150,150).
when i resize the JLabel to size (100,100) the image get cropped (which is perfectly fine by me), but i get a wierd looking grid (imaged added at the end).
if this helps: i dont actually resize the window, i just need to make sure the the size of the JLabel is set to (100,100) always, no metter what is the original image size.
before:
http://postimg.org/image/iolyeb8e7/
after:
http://postimg.org/image/5j6g87ein/
thanks
Unfortunately you did not say what you expect the grid to look like. I assume you don't want the cells to be so far apart from each other.
The GridLayout documentation states that...
The container is divided into equal-sized rectangles, and one component is placed in each rectangle.
If you shrink the size of each JLabel (i.e. the components in each of those rectangles) you just do that. You shrink the size of the component, not that of the rectangle. The grid does not care if the component is to small to fill the whole rectangle. At the moment you add the component to the grid1, the grid tries to set the components size to best fit the available space. But if you later change the labels size, the grid does not care.
What you probably want is to change the size of the whole grid: If you set the grids size to 400 by 400 it should evenly divide it to all 4 rows and 4 columns, so you get rectangles of size 100 by 100. All labels should automatically be sized accordingly.
1 Probably it is not exactly while adding the labels but while validating the container, but I don't know all the internal details about how and when layouts do there magic.

Borders around ImageIcons appear to have zero border, hgap and vgap are zero, still empty space between ImageIcons

There is a persistent empty space around the ImageIcons. I created new empty borders on all the objects like so:
array[i].setBorder(BorderFactory.createEmptyBorder());
set the hgap and vgap to zero on two diffrent layouts:
frame.getContentPane().setLayout(new FlowLayout(FlowLayout.CENTER, 0, 0));
//frame.getContentPane().setLayout(new GridLayout(screenSize.height/15,screenSize.width/15,0,0));
and tried setting the gaps negative, on advice from another post on here. None of these seem to work, any suggestions?
Look at the all of settings of your GridLayout By default it has some margins and such. Though I might be wrong, it occurs to me this is Swing and not SWT.
Works fine for me when I use a JLabel. You don't even need to use an EmptyBorder.
Maybe the problem is that your images have a transparent border. Or maybe the problem is that you are using another component.
If you need more help than post your SSCCE that demonstrates the problem.

Categories