Miglayout grid constraints custom layout - java

i'm new here so go easy on me.
I've researched all the documentation on miglayout (which is pretty good btw) but I can't seem to properly display the grid that I want.
I need MigLayout() parameters to setup a grid as:
2 rows, being that the bottom row is split in half (or if you will: 1 top row adjacent to 2 bottom columns).
The top row will display the search textfield with an adjancent button.
The bottom left column will display 3 buttons stacked on top of each other.
The bottom right column will display an image label.
Here's some code to start with:
//main window panel setup
JPanel mainPanel = new JPanel();
mainWindow.add(mainPanel);
mainPanel.setLayout(new MigLayout(""));
//components insertion into panel (using MigLayout constraints)
mainPanel.add(searchText);
mainPanel.add(searchBtn, "wrap");
mainPanel.add(addBtn);
mainPanel.add(logoImage, "spany 3 , wrap");
mainPanel.add(randomBtn, "wrap");
mainPanel.add(getFileBtn);
(could not upload image)
With this code, Notice that the logo is being kept below the searchButton (i think it does this due to the layout being default-set as a grid) but I want it to fit adjacent-right to the buttons and below the textfield/searchButton.

First off I would say you are pretty close and you only need to play with both columns number and constraints (plus some missing component constraints). This can be done when you instantiate your layout:
MigLayout layout = new MigLayout("debug, fillx", "[][grow][]");
Note debug and fillx are layout constraints intended to enable debug feature and fill whole width, respectively. See this answer for more details.
Now you can think you need two columns, but you actually need three columns in order to expand the middle one, while first and last columns continue occupying the minimum possible width. That's what [][grow][] constraints mean.
Please consider this snippet:
MigLayout layout = new MigLayout("debug, fillx", "[][grow][]");
JPanel content = new JPanel(layout);
// First row
content.add(new JTextField(20), "spanx 2, growx"); // search text field
content.add(new JButton("Search"), "wrap");
// Second row
content.add(new JButton("Button # 1"), "growx");
content.add(new JLabel("Image here"), "span 2 3, grow, wrap"); // image label
content.add(new JButton("Button # 2"), "growx, wrap");
content.add(new JButton("Button # 3"), "growx, wrap");
This will produce something like this:
Please note that on horizontal resizing both search text field and image label will occupy the maximum available width, while search button and button's stack will occupy just the minimum possible width.

Related

Center JButtons inside a JPanel in a JScrollPane

I am trying to add JButton components to a JPanel that I added to a JScrollPane. I want that they are vertically aligned. I already found the solution with the BoxLayout(panel, BoxLayout.Y_AXIS) in the panel, but after I did that the buttons had different widths.
I also would like to add some space between the buttons.
You need to use a different layout. Grid or GridBag is what you're looking for, although GridBag is overkill for something this simple:
panel.setLayout(new GridLayout(3, 1));
panel.add(new JButton("Button 1"));
panel.add(new JButton("Button 2"));
panel.add(new JButton("Button 3"));
Use a gridbaglayout , and apply vertical spacers at the button of each button. Also the text in button is not equal to the second and third button dats why it has a different size. So you can adjust it using the preferred size tool

Java Swing: SpringLayout within BorderLayout

I'm having problems with my GridLayout whereby a JTextField widens to fit an entry longer than the initial size. Another poster with this problem was told SpringLayout was the easiest solution, so that's what I'm trying. However I'm having problems getting this panel to even display.
I've top, bottom, left, and right panels each with different layouts that are set in a top-level panel (the only one in this frame). This SpringLayout I'm trying is to be in the right panel (added to the top panel as topPanel.add(springPanel, BorderLayout.EAST - this was how I did it when this panel was a GridLayout). The code below is modeled after the SpringLayout Oracle tutorial. Sorry I'm new to this layout and am only using it to use fixed widths for JTextFields.
JPanel testPanel = new JPanel();
SpringLayout layout = new SpringLayout();
testPanel.setLayout(layout);
JLabel label = new JLabel("First field: ");
JTextField field = new JTextField("enter text");
testPanel.add(label);
testPanel.add(field);
layout.putConstraint(SpringLayout.WEST, label, 5, SpringLayout.WEST, testPanel);
layout.putConstraint(SpringLayout.NORTH, label, 5, SpringLayout.NORTH, testPanel);
layout.putConstraint(SpringLayout.WEST, field, 5, SpringLayout.EAST, label);
layout.putConstraint(SpringLayout.NORTH, field, 5, SpringLayout.NORTH, testPanel);
...
topPanel.add(testPanel, BorderLayout.EAST);
Any guidance would be appreciated. Thanks.
EDIT: Adding the cols argument doesn't seem to work, but I'll keep trying. The same problem exists with GridBagLayout. Tabbing to the next field doesn't re-size the previous field, but clicking outside those fields elsewhere in the frame causes it to expand the length of its containing text which is what I need to avoid. And I don't have enough rep pts to post images of what I'm doing
EDIT2: Adding cols works - I tried that at some point. Not entirely sure how it's working, but any value (1, 10, 15 tested) seems to fix the length so leaving that panel's focus no longer causes a size change. Thanks!
#Andrew Thompson's answer worked - use col arg to specify # of columns (any number seems to work). Thank you!

Grow table larger than growx

I have configured my layout like that:
panel.add(addButtons(), "wrap");
panel.add(showTable(), "growx, wrap");
So at first I am adding a button group and then I would like to grow my table as large as it can and then wrap the next component in the next "line".
However, my gui looks like that:
Here you clearly cannot see any values from the table. Therefore, how to grow the table so that each value can be seen?
I appreciate your answer!
Here you clearly cannot see any values from the table. Therefore, how to grow the table so that each value can be seen?
As I've said in my comment, I don't think your problem is about columns (preferred | min | max) sizes but the default behavior of your layout manager: MigLayout. As stated in this answer by default rows in MigLayout doesn't fill all available width but just the necessary to display the longest row (based on components width). You can see this fact if you enable "debug" feature when you instantiate your layout:
MigLayout layout = new MigLayout("debug");
As I understand your question you need a combination of both growx and fillx constraint. The first one is a component constraint and the other one is a layout constraint.
That being said, pelase consider the following progression.
1. Adding scroll pane without "growx" constraint
Snippet
MigLayout layout = new MigLayout("debug");
JPanel panel = new JPanel(layout);
panel.add(buttonsPanel, "wrap");
panel.add(scrollPane);
Screenshot
2. Adding scroll pane with "growx" constraint
Snippet
MigLayout layout = new MigLayout("debug");
JPanel panel = new JPanel(layout);
panel.add(buttonsPanel, "wrap");
panel.add(scrollPane, "growx"); // Note "growx" here
Screenshot
3. Adding scroll pane with "growx" and "fillx" contraints
Snippet
MigLayout layout = new MigLayout("debug, fillx"); // Note "fillx" here
JPanel panel = new JPanel(layout);
panel.add(buttonsPanel, "wrap");
panel.add(scrollPane, "growx"); // Note "growx" here
Screenshot
You can use javax.swing.table.TableColumn;
TableColumn custom_column = yourTable.getColumnModel().getColumn(1); // 1 means column 1
custom_column.setPreferredWidth(500);
As you want to widen all columns you can use loop :
TableColumn custom_column ;
int numberOfColumns = yourTable.getColumnModel().getColumnCount();
for(int y= 0;y<numberOfColumns;y++){
custom_column=table.getColumnModel().getColumn(y);
custom_column.setMinWidth(500);
}

Prevent JLabels from Growing in MigLayout

I am trying to create a form in MigLayout. I want for any text fields to be labeled with a small JLabel preceding it, with the text field growing as space is available. I am successfully able to do this in the following code:
JFrame frame = new JFrame("Test");
JPanel panel = new JPanel(new MigLayout("", "fill", ""));
panel.add(new JLabel("Testing"));
panel.add(new JTextField(), "growx, pushx, wrap");
frame.setContentPane(panel);
frame.pack();
frame.setMinimumSize(new Dimension(400, 100));
frame.setPreferredSize(new Dimension(400, 100));
frame.setVisible(true);
The result looks like this, which is as expected (the JLabel is the minimum necessary size, the JTextField takes up the rest of the area):
However, if I put a JEditorPane below this and have it span the length of the whole window, the JLabel becomes larger and grows if I enlarge the window. The code change looks like this:
...
panel.add(new JTextField(), "growx, pushx, wrap");
//New line of code here:
panel.add(new JEditorPane(), "growx, pushx, span");
frame.setContentPane(panel);
...
Which causes a result that I do not expect (the JLabel has grown):
I've tried to fix this by adding MigLayout parameters for the JLabel, like "growx 0" and "shrink", but this doesn't seem to have any effect on the size of the label.
How can I prevent the JLabels from growing in a situation like this?
I figured it out! The problem is with the parameter on the JEditorPane:
panel.add(new JEditorPane(), "growx, pushx, span");
It turns out that when using span, growx, pushx is unnecessary (because it already grows in size) and when used in conjunction with this, it creates the effect shown above. My guess is that growx applies to all cells marked by span, but pushx only applies to the first cell.
So span makes the component take up multiple cells, they all were assigned the default growx weight, but pushx only makes the first cell grow.
So the proper way to fix the line is simply:
panel.add(new JEditorPane(), "span");

MigLayout: unexpected layout beside a vertical spanning component

While playing a bit to demonstrate how to easily fulfil a layout requirment with MigLayout, I was surprised by the outcome of:
MigLayout layout = new MigLayout("wrap 3, debug");
JComponent content = new JPanel(layout);
content.add(new JLabel("First:"));
content.add(new JScrollPane(new JTextArea(10, 20)), "skip, spany");
content.add(new JLabel("Second"));
content.add(new JTextField(10));
content.add(new JLabel("third"));
content.add(new JTextField(10));
//content.add(new JLabel());
The layout idea is simple enough:
three columns
last column spanning all rows
first two columns a bunch of label/component pairs
The unexpected is that the last row of the first two columns takes all the available vertical space which leads to positioning the last pair in its middle (top align is not an option, as they must be baseline aligned to each other)
uncommenting the last line above (adding a virtually invisible dummy) shows the expected layout, but a hack which shouldn't go into production code
The question is: how to achieve the expected layout without hacking?
might be a bug:
a less hacky way to workaround (applicable if number of rows is known at creation time of the form) is to explicitly define the row constraints
MigLayout layout = new MigLayout("wrap 3, debug", "", "[][][][]");
that is define one row more than actually needed for the components at the side of the spanning component

Categories

Resources