Reputation: 47
I have a JFframe form in NetBeans 8 / Java 7.
It has a bunch of labels, textboxes, dropdowns, etc. These are a column on the left size, all staked up on top of each other.
Here's a screenshot:
How can I prevent all those components from sticking to the right and resizing along with the window and at the same time have the preview frame at the far right resize along?
I'm new to Java, and the gridbaglayout was the only I found to align everything properly. I just want the left side to have its components well aligned and not moving around. And I just want the right side, the panel, to resize according to the window resize.
Thank you,
Upvotes: 2
Views: 9586
Reputation: 11647
the gridbaglayout was the only I found to align everything properly.
The MigLayout
manager can do that easily. It also provides much better portability.
Notice the usage of related gaps (r), dialog insets (dialog) and logical pixels (lp).
These units are translated to pixels accordingly. On the other hand, GridbagLayout
sets spaces directly in pixels which is inadequate, e.g. changing font or resolution
will affect the layout.
See to following code example:
package com.zetcode;
import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSeparator;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;
public class MigLayoutPreview2 extends JFrame {
public MigLayoutPreview2() {
initUI();
setTitle("Design preview");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
}
private void initUI() {
JPanel pnl = new JPanel(new MigLayout("ins dialog, wrap"));
pnl.add(new JLabel("Source PDF file..."), "pad 0 -5lp 0 0");
pnl.add(new JButton("Browse"), "growx");
pnl.add(new JLabel("Height (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JLabel("Width (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JButton("More PDF attributes"), "growx");
pnl.add(new JSeparator(), "pad 0 -5lp 0 0, gaptop r, growx");
pnl.add(new JLabel("Set bounding box..."), "pad 0 -5lp 0 0");
pnl.add(new JComboBox(), "growx");
pnl.add(new JSeparator(), "pad 0 -5lp 0 0, gaptop r, growx");
pnl.add(new JLabel("Sheet size..."), "pad 0 -5lp 0 0");
pnl.add(new JComboBox(), "growx");
pnl.add(new JLabel("Height (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JLabel("Width (inches):"), "sgx, split 2");
pnl.add(new JTextField(10), "growx");
pnl.add(new JSeparator(), "pad 0 -5lp 0 0, gaptop r, growx");
JPanel rpnl = new JPanel();
rpnl.setBorder(BorderFactory.createEtchedBorder());
pnl.add(rpnl, "cell 2 0, w 90, spany, pushx, grow");
add(pnl);
pack();
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MigLayoutPreview2 ex = new MigLayoutPreview2();
ex.setVisible(true);
}
});
}
}
I have reproduced part of your screenshot and have also kept the indents. Horizontal separators do not stretch completly, since I believe this is not optimal design. The design is also improved by eliminating the huge spaces between labels and text fields.
Upvotes: 0
Reputation: 5415
You need to set the fill constraint to NONE.
Tutorial: How to Use GridBagLayout:
When you add each Component to the panel, it would look something like this (from the tutorial):
JPanel pane = new JPanel(new GridBagLayout());
GridBagConstraints c = new GridBagConstraints();
//For each component to be added to this container:
//...Create the component...
//...Set instance variables in the GridBagConstraints instance...
pane.add(theComponent, c);
you need to ensure that you call:
c.fill = GridBagConstraints.NONE;
for every constraints object for each Component that you add to the panel that you don't want to stretch horizontally.
If you're resusing the same constraints object for each component, you can simply set it once for all if that's you're desired result.
EDIT:
As some others have pointed out, the OP may want the fields to stretch, but only up to a certain limit (which is still not clear at this point). In that case, you would use a combination of
c.fill = GridBagConstraints.HORIZONTAL;
c.weightx = 0;
as already pointed out. Example:
import java.awt.*;
import javax.swing.*;
public class GridBagDemo implements Runnable
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new GridBagDemo());
}
public void run()
{
// 4 components that all have different widths
JButton btnBrowse = new JButton("Browse");
JTextField txfHeight = new JTextField(4);
JTextField txfWidth = new JTextField(10);
JButton btnMore = new JButton("More PDF Attributes");
// the preview pane?
JTextArea txaPreview = new JTextArea(8, 20);
JScrollPane scrPreview = new JScrollPane(txaPreview);
scrPreview.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
GridBagConstraints gbc = new GridBagConstraints();
// we'll use these constraints for all components
gbc.anchor = GridBagConstraints.NORTHWEST;
gbc.insets = new Insets(2,4,2,4);
JPanel panel = new JPanel(new GridBagLayout());
gbc.gridx = 0;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
panel.add(new JLabel("Source PDF size..."), gbc);
gbc.gridx = 0;
gbc.gridy = 1;
gbc.gridwidth = 2;
gbc.gridheight = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(btnBrowse, gbc);
gbc.gridx = 0;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
panel.add(new JLabel("Height (in inches):"), gbc);
gbc.gridx = 1;
gbc.gridy = 2;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(txfHeight, gbc);
gbc.gridx = 0;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
panel.add(new JLabel("Width (in inches):"), gbc);
gbc.gridx = 1;
gbc.gridy = 3;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(txfWidth, gbc);
gbc.gridx = 0;
gbc.gridy = 4;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.HORIZONTAL;
panel.add(btnMore, gbc);
gbc.gridx = 0;
gbc.gridy = 5;
gbc.gridwidth = 2;
gbc.fill = GridBagConstraints.VERTICAL;
gbc.weighty = 1;
panel.add(Box.createVerticalGlue(), gbc);
gbc.gridx = 2;
gbc.gridy = 0;
gbc.gridwidth = 1;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
gbc.weighty = 0;
panel.add(new JLabel("Preview"), gbc);
gbc.gridx = 2;
gbc.gridy = 1;
gbc.gridwidth = 1;
gbc.gridheight = 8; // some number that's > the number of entry rows
gbc.fill = GridBagConstraints.BOTH;
gbc.weightx = 1;
gbc.weighty = 1;
panel.add(scrPreview, gbc);
JFrame frame = new JFrame("GrigBag Demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new JScrollPane(panel), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
Upvotes: 1
Reputation: 46841
I just want the right side, the panel, to resize according to the window resize.
By default all the columns are divided in equal percentage in each row.
To force the second (right side) column to take the more space, assign it a higher percentage using GridBagConstraints#weightx
gc.weightx = 0.75; // 75%
Don't forget to fill the horizontal space completely using GridBagConstraints#fill
gc.fill = GridBagConstraints.HORIZONTAL;
If you want fixed width for first column then set the preferred size for the left side panel by overriding getPreferredSize()
method and assign 100% width to the right side panel.
JPanel leftSidePanel = new JPanel() {
@Override
public Dimension getPreferredSize() {
return new Dimension(..., ...);
}
}
Have a look at my another post GridBagLayout: How to set fixed column width? that explain it better.
It;s worth reading Swing Tutorial on Solving Common Layout Problems
Upvotes: 1