The problem
I have a JPanel with the GridBagLayout as a layout manager. I want the columns of the layout to have certain widths. Sometimes the width of a column might be lower than the preferred width of a component inside. In this case, the column should force a component to take only the available space of the column.
But, for now, a component inside a cell doesn't shrink if the column width constraint is less than the component's preferred width.
Example
Below is the demo with 4x4 grid. I want the JLabel in the top-left corner to shrink in accordance with the min widths I have set when initialized GridBagLayout (10 px)
As I run the example below, the following result is obtained:
The cell in the top-left takes more space than it was allowed initially by the GridBagLayout
public class ResizeDemo extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
ResizeDemo resizeDemo = new ResizeDemo();
resizeDemo.pack();
resizeDemo.setDefaultCloseOperation(EXIT_ON_CLOSE);
resizeDemo.setVisible(true);
});
}
public ResizeDemo() {
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[]{0, 0};
gridBagLayout.rowHeights = new int[]{0, 0};
gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE};
gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE};
getContentPane().setLayout(gridBagLayout);
JPanel panel = new JPanel();
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.fill = GridBagConstraints.BOTH;
gbc_panel.gridx = 0;
gbc_panel.gridy = 0;
getContentPane().add(panel, gbc_panel);
GridBagLayout gbl_panel = new GridBagLayout();
// ============ Set the column widths here ============
// Note that the width of the first column is 10 px
gbl_panel.columnWidths = new int[] {10, 150, 0};
// =====================================================
gbl_panel.rowHeights = new int[]{0, 0, 0};
gbl_panel.columnWeights = new double[]{0.0, 0.0, 0.0};
gbl_panel.rowWeights = new double[]{0.0, 0.0, Double.MIN_VALUE};
panel.setLayout(gbl_panel);
JLabel label1 = new JLabel("A very long string here");
label1.setHorizontalAlignment(SwingConstants.CENTER);
GridBagConstraints gbc_label1 = new GridBagConstraints();
gbc_label1.fill = GridBagConstraints.HORIZONTAL;
gbc_label1.gridx = 0;
gbc_label1.gridy = 0;
panel.add(label1, gbc_label1);
JLabel label2 = new JLabel("Label");
GridBagConstraints gbc_label2 = new GridBagConstraints();
gbc_label2.gridx = 1;
gbc_label2.gridy = 0;
panel.add(label2, gbc_label2);
JLabel label3 = new JLabel("Label");
GridBagConstraints gbc_label3 = new GridBagConstraints();
gbc_label3.fill = GridBagConstraints.HORIZONTAL;
gbc_label3.gridx = 0;
gbc_label3.gridy = 1;
panel.add(label3, gbc_label3);
JLabel label4 = new JLabel("Label");
GridBagConstraints gbc_label4 = new GridBagConstraints();
gbc_label4.gridx = 1;
gbc_label4.gridy = 1;
panel.add(label4, gbc_label4);
}
}
Question:
How can I force the JLabel inside a GridBagLayout cell to shrink itself?
The GridBagLayout sizes each column based on the largest "preferred size" of any component added to the column.
The "columnWidths" is used to set the minimum value for any column. This is used when you resize the frame. If there is not enough space to display the component at it preferred size and you have set a resize weight for the component, then the component will shrink in size from its preferred size to its minimum size.
How can I force the JLabel inside a GridBagLayout cell to shrink itself?
One possibility is to wrap the label in a panel using a BoxLayout. The BoxLayout will respect the maximum size of size of the component. The basic logic would be:
//panel.add(label1, gbc_label1);
Dimension max = label1.getPreferredSize();
max.width = 10;
label1.setMaximumSize(max);
Box wrapper = Box.createHorizontalBox();
wrapper.add(label1);
panel.add(wrapper, gbc_label1);
Don't know what your real application is, but if you are only using labels, then maybe you can use a JTable. With a JTable you can control the actual column width.
This is the piece in your code that is setting the widths. Lack of setting the column width defaults shrinking to fit the enclosed component.
gbl_panel.columnWidths = new int[] {10, 150, 0};
Related
I've implemented a JPanel using a GridBagLayout as follows:
fileSelectionDetails = new JPanel();
fileSelectionGridBagLayout = new GridBagLayout();
fileSelectionDetails.setLayout(fileSelectionGridBagLayout);
JLabel lblFile1 = new JLabel("File 1:");
JTextField txtFile1Path = new JTextField();
JButton btnBrowseFile1 = new JButton("Browse...");
addComponentToFileSelectionGrid(lblFile1, 0, 0, 1, 1, 20, 100, GridBagConstraints.NONE, GridBagConstraints.WEST);
addComponentToFileSelectionGrid(txtFile1Path, 1, 0, 3, 1, 60, 100, GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST);
addComponentToFileSelectionGrid(btnBrowseFile1, 2, 0, 1, 1, 20, 100, GridBagConstraints.HORIZONTAL, GridBagConstraints.WEST);
private void addComponentToFileSelectionGrid(Component component, int gridX, int gridY,
int gridWidth, int gridHeight, int weightX,
int weightY, int fill, int anchor) {
GridBagConstraints constraint = new GridBagConstraints();
constraint.gridx = gridX;
constraint.gridy = gridY;
constraint.gridwidth = gridWidth;
constraint.gridheight = gridHeight;
constraint.weightx = weightX;
constraint.weighty = weightY;
constraint.fill = fill;
constraint.anchor = anchor;
fileSelectionGridBagLayout.setConstraints(component, constraint);
fileSelectionDetails.add(component);
}
I want to see my components laid out as follows:
However, what I'm actually seeing is:
i.e. the 'Browse...' button is missing! Why is this?
From your drawing, I’m guessing you don’t want relative widths at all. It appears you want the label and button to be their preferred sizes, and the JTextField to stretch to take up all of the width not used by the label and button.
As camickr suggested, you should give the JTextField a meaningful preferred size by initializing it with a column count, like new JTextField(20).
You can then take advantage of some useful aspects of GridBagLayout and GridBagConstraints:
The default value of gridx and gridy is RELATIVE, which means each component you add is placed to the right of the last one added. Which just happens to be exactly what you want. Therefore, you should not set gridx or gridy at all.
The default value of gridwidth and gridheight is 1. This is what you want. GridBagLayout cells are flexible, so setting one component’s gridwidth to 3 does not make it three times wider than a component whose gridwidth is 1. The width of a cell, or span of cells, depends entirely on what it contains.
When you add a component to a GridBagLayout, the GridBagConstraints object is cloned inside the GridBagLayout. This means you can safely reuse the same GridBagConstraints object over and over, changing just the fields that need to change.
With this knowledge, your code can be simplified to:
fileSelectionDetails = new JPanel(new GridBagLayout());
JLabel lblFile1 = new JLabel("File 1:");
JTextField txtFile1Path = new JTextField(20);
JButton btnBrowseFile1 = new JButton("Browse\u2026");
txtFile1Path.setMinimumSize(txtFile1Path.getPreferredSize());
GridBagConstraints constraints = new GridBagConstraints();
constraints.fill = GridBagConstraints.HORIZONTAL;
constraints.weight = 0;
fileSelectionDetails.add(lblFile1, constraints);
constraints.weight = 1;
fileSelectionDetails.add(txtFile1Path, constraints);
constraints.weight = 0;
fileSelectionDetails.add(btnBrowseFile1, constraints);
You define gridWidth=3 for txtFile1Path but add btnBrowseFile1 at gridX=2. You must set addComponentToFileSelectionGrid(btnBrowseFile1, 4 ...etc.
I need to format my multiple panels into my main panel, however I'm troubled with which layout to use and more so on how to do it with a specific layout.
The layout I need is like this
So far the code I have is this:
public TDPanel(){
this.setPreferredSize(new Dimension(1150,800));
this.setBackground(Color.gray);
this.tdWorld = towerOfDefenses;
this.setLayout(new FlowLayout());
game = new JPanel();
game.setBackground(Color.blue);
game.setPreferredSize(new Dimension(300,300));
textBox = new JTextField();
textBox.setBackground(Color.ORANGE);
textBox.setPreferredSize(new Dimension(400,300));
menuPanel = new JPanel();
menuPanel.setPreferredSize(new Dimension(100,800));
menuPanel.setBackground(Color.red);
this.add(game);
this.add(textBox);
this.add(menuPanel);
}
I would appreciate any help given!
I would combine at least 3 BorderLayouts. Why? Because the component you put in CENTER will be maximized and for the others you can set a static width (or height) and don't have to do further configuration to get the desired behaviour.
+-------------------------+-----------------------+
| BorderLayout.CENTER (1) | BorderLayout.EAST (2) |
+-------------------------+-----------------------+
In (1) you put the game panel (3) and the "game controls" (4):
+-------------------------+
| BorderLayout.CENTER (3) |
+-------------------------+
| BorderLayout.SOUTH (4) |
+-------------------------+
If you want the text field and the button in (4) to have the same size and maximized (width) then use a GridLayout, othewise you can use FlowLayout to have them layed out with some space after it. But what I recommend doing here is the same as for the game and menu panel in (2): use a BorderLayout and put the component you want to be maximized in the center.
You could use more sophisticated LayoutManagers like BoxLayout or GridBagLayout but it is not really needed for this simple layout (guess it's a matter of taste).
First,I recommend you use Swing Desinger,it's a plug-in unit to visualize your operation.
I'm using GridBagLayout to format these panel,and here is an example.
This is the effect drawing adress
public test() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 685, 485);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
GridBagLayout gbl_contentPane = new GridBagLayout();
gbl_contentPane.columnWidths = new int[]{175, 40, 180, 217, 0};
gbl_contentPane.rowHeights = new int[]{15, 58, 220, 49, 55, 0};
gbl_contentPane.columnWeights = new double[]{0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
gbl_contentPane.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, Double.MIN_VALUE};
contentPane.setLayout(gbl_contentPane);
JPanel gamepanel = new JPanel();
GridBagConstraints gbc_gamepanel = new GridBagConstraints();
gbc_gamepanel.fill = GridBagConstraints.BOTH;
gbc_gamepanel.insets = new Insets(0, 0, 5, 5);
gbc_gamepanel.gridheight = 2;
gbc_gamepanel.gridwidth = 3;
gbc_gamepanel.gridx = 0;
gbc_gamepanel.gridy = 1;
contentPane.add(gamepanel, gbc_gamepanel);
gamepanel.setLayout(null);
JScrollPane scrollPane = new JScrollPane();
GridBagConstraints gbc_scrollPane = new GridBagConstraints();
gbc_scrollPane.fill = GridBagConstraints.BOTH;
gbc_scrollPane.insets = new Insets(0, 0, 5, 0);
gbc_scrollPane.gridx = 3;
gbc_scrollPane.gridy = 1;
contentPane.add(scrollPane, gbc_scrollPane);
JPanel panel = new JPanel();
GridBagConstraints gbc_panel = new GridBagConstraints();
gbc_panel.fill = GridBagConstraints.BOTH;
gbc_panel.gridheight = 3;
gbc_panel.gridx = 3;
gbc_panel.gridy = 2;
contentPane.add(panel, gbc_panel);
panel.setLayout(null);
textField = new JTextField();
GridBagConstraints gbc_textField = new GridBagConstraints();
gbc_textField.fill = GridBagConstraints.BOTH;
gbc_textField.insets = new Insets(0, 0, 0, 5);
gbc_textField.gridx = 0;
gbc_textField.gridy = 4;
contentPane.add(textField, gbc_textField);
textField.setColumns(10);
JButton btnNewButton = new JButton("New button");
GridBagConstraints gbc_btnNewButton = new GridBagConstraints();
gbc_btnNewButton.fill = GridBagConstraints.BOTH;
gbc_btnNewButton.insets = new Insets(0, 0, 0, 5);
gbc_btnNewButton.gridx = 2;
gbc_btnNewButton.gridy = 4;
contentPane.add(btnNewButton, gbc_btnNewButton);
}
If you want the GUI can be resizable,you can set the weghitx and weghity properties.
I'm having a little bit of trouble getting Java's Swing layout managers to behave. This is my first time trying to create a GUI of my own, so it's likely I've just missed something fairly simple, however I would appreciate any advice that can be offered up.
What I am trying to create is a custom JPanel that contains JLabels and JTextFields to allow the user to enter an IP address (so four JTextFields interspaced with three JLabels containing a '.')
I am finding really difficult to find a layout manager that will set this up as I would like; I have tried a Flow and a Box layout and as neither of these worked I have also tried a GridBag, which I thought was perhaps overkill, but even that doesn't work right.
Here is my code that starts the class:
public class PingPanel extends JPanel {
private JLabel[] dotLabels;
private JTextField[] pingFields;
public PingPanel() {
Dimension dim = getPreferredSize();
dim.width = 400;
setPreferredSize(dim);
dotLabels = new JLabel[3];
for (int i = 0; i < dotLabels.length; i++) {
dotLabels[i] = new JLabel(".");
}
pingFields = new JTextField[4];
for (int i = 0; i < pingFields.length; i++) {
pingFields[i] = new JTextField(3);
}
Border panelBorder = BorderFactory.createLineBorder(Color.BLACK);
setBorder(panelBorder);
//setupFlow();
//setupBox();
//setupGridBag();
I've only set the panel's width to 400 to try and get everything to display (as you'll see in a moment I'm not having much luck with that either.) I understand that some of the managers ignore preferred sizes anyway, which is probably why this doesn't work. I've created three methods to try the different layout managers; here they are with the effect that they produce:
public void setupFlow() {
for (int p = 0; p < pingFields.length; p++) {
if (p == dotLabels.length) {
add(pingFields[p]);
System.out.println(p + " (Final Column)");
}
else {
add(pingFields[p]);
add(dotLabels[p]);
System.out.println(p);
}
}
}
The FlowLayout produces this:
This is the closest to what I want it to look like, but I'm not sure why I only get one JTextField and one Label.
public void setupBox() {
Container pingBox = Box.createHorizontalBox();
for (int p = 0; p < pingFields.length; p++) {
if (p == dotLabels.length) {
pingBox.add(pingFields[p]);
System.out.println(p + " (Final Column)");
}
else {
pingBox.add(pingFields[p]);
pingBox.add(dotLabels[p]);
System.out.println(p);
}
}
}
This is what BoxLayout gives me. I literally have no idea how I've messed this one up so badly!
public void setupGridBag() {
setLayout(new GridBagLayout());
GridBagConstraints gc = new GridBagConstraints();
gc.gridy = 0;
gc.gridx = 0;
gc.weightx = 1.0;
gc.weighty = 1.0;
gc.fill = GridBagConstraints.HORIZONTAL;
add(pingFields[0], gc);
gc.gridx++;
add(dotLabels[0], gc);
gc.gridx++;
add(pingFields[1], gc);
gc.gridx++;
add(dotLabels[1], gc);
gc.gridx++;
add(pingFields[2], gc);
gc.gridx++;
add(dotLabels[2], gc);
gc.gridx++;
add(pingFields[3], gc);
}
The GridBagLayout at least gives me the layout I'm looking for, but I've not been able to work out how to make the JTextFields wider.
So there we are - I'm sure my green-ness has just caused me to miss something obvious, but I would be really grateful if anyone had any ideas.
Usually GridBagLayout is what you'd after. Think it as a grid based layout with custom alignment for each component; also each component can occupy multiple columns and rows, enabling quite custom set up.
I got a bit sample code as below:
GridBagLayout gridBagLayout = new GridBagLayout();
gridBagLayout.columnWidths = new int[] {30, 30, 60, 60, 60, 30, 30};
gridBagLayout.rowHeights = new int[] {18, 18, 18, 18, 18, 18, 18, 18, 18};
gridBagLayout.columnWeights = new double[] {0.1, 0.1, 0.2, 0.2, 0.2, 0.1, 0.1};
gridBagLayout.rowWeights = new double[] {0.125, 0.125, 0.1, 0.1, 0.1, 0.1, 0.1, 0.125, 0.125};
setLayout(gridBagLayout);
JLabel labelLong = new JLabel("Long");
labelLong.setForeground(Color.DARK_GRAY);
labelLong.setFont(DisplayConstants.FONT_PANEL_LABEL_BOLD);
GridBagConstraints gbc_labelLong = new GridBagConstraints();
gbc_labelLong.insets = new Insets(0, 0, 5, 5);
gbc_labelLong.gridx = 0;
gbc_labelLong.gridy = 0;
add(labelLong, gbc_labelLong);
JLabel labelShort = new JLabel("Short");
labelShort.setForeground(Color.DARK_GRAY);
labelShort.setFont(DisplayConstants.FONT_PANEL_LABEL_BOLD);
GridBagConstraints gbc_labelShort = new GridBagConstraints();
gbc_labelShort.insets = new Insets(0, 0, 5, 0);
gbc_labelShort.gridx = 6;
gbc_labelShort.gridy = 0;
add(labelShort, gbc_labelShort);
If you are just after a simple layout, then the BorderLayout is what you'd do. Place the fixed size component at side and the major component at center.
Also, it's worthy to mention that Java uses the setPreferredSize() for each component to specify additional size parameters, so the GUI layout would try its best to satisfy the preferred size for each component. Call JFrame.pack() after your construction is finished to arrange component, too.
I'm learning how to use GridBagLayout. I created two buttons in a JFrame. I tried making it that one of them occupies one collumn (the default), and the other two collumns, thus being twice the size of the first one (I know I can acheive this using setPrefferredSize, but my intention is to learn how to use gridwidth and gridheight).
What's the problem? Thanks
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame {
Main(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500,500);
JPanel panel1 = new JPanel(new GridBagLayout());
JButton b1,b2;
b1 = new JButton("button 1");
b2 = new JButton("button 2");
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridwidth = 1;
panel1.add(b1);
gbc.gridx = 2;
gbc.gridwidth = 2;
panel1.add(b2);
add(panel1);
setVisible(true);
}
public static void main(String[]args){
Main m = new Main();
}
}
It doesn't matter how many columns the second button's width.
Actually both buttons will be asked for their preferred width and the width will be set to them if it's enough space for them.
If it's less space then min width is used.
If there is extra space it's distributed between controls according to weights proportions.
You can try to set iPadX=100 for the first and iPadx=200 and set proportion iPadX=1 for the first and iPadx=2 for the second.
The problem is that all the columns of a GridBagLayout don't have the same width. The widths are computed based on the preferred size of the components they contain. So, you could use 3, 4 or 100 as the gridwidth for the second button, it wouldn't change anything.
You need to use fillx and weightx to change the way the buttons resize.
Try using GridBagConstraint in this way, hope this will help you.
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame {
Main(){
setDefaultCloseOperation(EXIT_ON_CLOSE);
setSize(500,500);
JPanel panel1 = new JPanel(new GridBagLayout());
JButton b1,b2;
b1 = new JButton("button 1");
b2 = new JButton("button 2");
panel1.add(b1, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
panel1.add(b2, new GridBagConstraints(1, 0, 1, 1, 2.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
add(panel1);
setVisible(true);
}
public static void main(String[]args){
Main m = new Main();
}
}
EDIT
Or change in your code Like this below:
gbc.gridx = 1;
gbc.gridwidth = 1;
panel1.add(b1, gbc);
gbc.gridx = 2;
gbc.gridwidth = 2;
gbc.fill = gbc.HORIZONTAL; //set fill property to HORIZONTAL
gbc.weightx= 2.0;
panel1.add(b2, gbc); //While adding button also add it with gbc
I'm working on a JDialog (by hand, no GUI builders) and I'm having a problem doing the layout.
I have this:
My problem is that I don't know what how to tell that JList (within a JScrollPane) to have a Maximum width, I used the setSize, setMaximumSize and nothing works! I need that JList's width to be the half of the picture's size.
Explain the layouts:
The "Gene Information" is a GridLayout 2x4, it's contained by a JPanel with BoxLayout, the +/- JButtons is a BoxLayout also, all what I said before is within a BoxLayout.
Now, the "Genes" JPanel is a GridBagLayout.
What can I do?
Thanks in advance!
PD: The other borders are just for seeign the boundaries of the components.
Source Code:
scpGenesList.setViewportView(lstGenesList);
pnlGeneInfo.setLayout(new GridLayout(4, 2, 10, 10));
pnlGeneInfo.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Gene Information"),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
lblGeneSymbol.setText("Symbol:");
lblGeneSymbol.setHorizontalAlignment(SwingConstants.RIGHT);
lblGeneChromosome.setText("Chromosome:");
lblGeneChromosome.setHorizontalAlignment(SwingConstants.RIGHT);
lblGeneStartPosition.setText("Start Position:");
lblGeneStartPosition.setHorizontalAlignment(SwingConstants.RIGHT);
lblGeneStopPosition.setText("Stop Position:");
lblGeneStopPosition.setHorizontalAlignment(SwingConstants.RIGHT);
pnlGeneInfo.add(lblGeneSymbol);
pnlGeneInfo.add(lblGeneSymbolValue);
pnlGeneInfo.add(lblGeneChromosome);
pnlGeneInfo.add(lblGeneChromosomeValue);
pnlGeneInfo.add(lblGeneStartPosition);
pnlGeneInfo.add(lblGeneStartPositionValue);
pnlGeneInfo.add(lblGeneStopPosition);
pnlGeneInfo.add(lblGeneStopPositionValue);
pnlGWASAddRemoveButtons.setLayout(new BoxLayout(pnlGWASAddRemoveButtons, BoxLayout.X_AXIS));
pnlGWASAddRemoveButtons.add(Box.createHorizontalGlue());
pnlGWASAddRemoveButtons.add(cmdGenesAdd);
pnlGWASAddRemoveButtons.add(Box.createHorizontalStrut(10));
pnlGWASAddRemoveButtons.add(cmdGenesRemove);
pnlGWASAddRemoveButtons.add(Box.createHorizontalGlue());
pnlGeneInfoButtons.setLayout(new BoxLayout(pnlGeneInfoButtons, BoxLayout.Y_AXIS));
pnlGeneInfoButtons.add(pnlGeneInfo);
pnlGeneInfoButtons.add(Box.createVerticalStrut(10));
pnlGeneInfoButtons.add(pnlGWASAddRemoveButtons);
pnlGenesPanel.setLayout(new GridBagLayout());
pnlGenesPanel.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Genes"),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
GridBagConstraints ctrGenes = new GridBagConstraints();
ctrGenes.fill = GridBagConstraints.BOTH;
ctrGenes.gridx = 0;
ctrGenes.gridy = 0;
ctrGenes.gridwidth = 1;
ctrGenes.gridheight = 1;
ctrGenes.weighty = 1.0;
ctrGenes.weightx = 1.0;
ctrGenes.insets = new Insets(0, 0, 0, 10);
pnlGenesPanel.add(scpGenesList, ctrGenes);
GridBagConstraints ctrGenesInfoButton = new GridBagConstraints();
ctrGenesInfoButton.fill = GridBagConstraints.BOTH;
ctrGenesInfoButton.gridx = 1;
ctrGenesInfoButton.gridy = 0;
ctrGenesInfoButton.gridwidth = 1;
ctrGenesInfoButton.gridheight = 1;
ctrGenesInfoButton.weighty = 1.0;
ctrGenesInfoButton.weightx = 1.0;
pnlGenesPanel.add(pnlGeneInfoButtons, ctrGenesInfoButton);
contentPane.add(pnlGenesPanel);
pack();
Why not give the "Genes" panel a 2x1 GridLayout? That should ensure that both sides have the same size.
But actually, it would make more sense to me to give the list all space not taken by the controls, since those require a fixed amount of space while the list may benefit from all additional space it can get, if there are wide entries.
To that end, I would give the "Genes" panel a BorderLayout, put the list in the CENTER slot and the controls in the EAST slot.
Following #Michael Borgwardt's suggestion to let the list grow, you can use setVisibleRowCount() to produce a convenient initial panel size. If necessary, you can also examine the Dimension returned by getPreferredScrollableViewportSize(), which "computes the size of viewport needed to display visibleRowCount rows."
Without seeing all the code here it may be impossible to tell you what is wrong. One thing I would suggest if you have time is to take a look at MigLayout. You can use it with Swing & SWT and once you learn it is a pretty powerful layout manager IMHO.
Hope this helps, good luck.
It doesn't answer your question - but I've found that the JGoodies FormLayout to be more intuitive than the GridBagLayout. The library, as well as some examples, can be found here:
http://jgoodies.com/freeware/forms/index.html
I think the earlier solutions are all valid, and it is more of a coding preference in terms of which layout managers to use. Based on your requirement, here is a working one with standard layout managers only (Grid, GridBag and Border). Have fun, - MS.
import java.awt.;
import javax.swing.;
import javax.swing.border.*;
public class GeneDialog extends JDialog {
private String[] plusMinus = {"+","-"}, tfNames = {
"Symbol", "Chromosome", "Start position", "Stop position"},
listData = {"Gene01", "Gene02", "Gene03", "Gene04", "Gene05", "Gene06",
"Gene07", "Gene08", "Gene09", "Gene10", "Gene11", "Gene12"};
private JTextField[] gtField= new JTextField[tfNames.length];
private JList list = new JList (new DefaultListModel());
public GeneDialog (Frame f, String title) {
super (f, title, true);
Container cp = getContentPane();
cp.setLayout (new GridLayout(1,2));
JScrollPane listScrollPane = new JScrollPane (list);
listScrollPane.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createTitledBorder("Genes"),
BorderFactory.createEmptyBorder(10, 10, 10, 10)));
DefaultListModel lm = (DefaultListModel) list.getModel();
for (int k = 0 ; k < listData.length ; k++)
lm.addElement (listData[k]);
cp.add (listScrollPane);
cp.add (controlPanel());
pack();
}
private GridBagConstraints makeGBC (int inset) {
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets (inset, inset, inset, inset);
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.gridx = 0;
gbc.gridy = GridBagConstraints.RELATIVE;
return gbc;
}
private JPanel controlPanel() {
JPanel cp = new JPanel (new BorderLayout()),
bp = new JPanel (new GridBagLayout()),
tp = new JPanel (new GridBagLayout());
GridBagConstraints gbc = makeGBC (10);
for (int i = 0 ; i < tfNames.length ; i++) {
JLabel label = new JLabel (tfNames[i], JLabel.TRAILING);
tp.add (label, gbc);
}
gbc.gridx++; gbc.weightx = 1.0f;
for (int i = 0 ; i < tfNames.length ; i++) {
gtField[i] = new JTextField(12);
tp.add (gtField[i], gbc);
}
gbc = makeGBC (10);
for (int i = 0 ; i < plusMinus.length ; i++) {
JButton b = new JButton (plusMinus[i]);
bp.add (b, gbc);
gbc.gridx++;
}
cp.add (tp, "Center");
cp.add (bp, "South");
return cp;
}
public static void main (String[] args) {
new GeneDialog (null, "Genes").setVisible (true);
}}
Try setting the maximum width for both the JScrollPane and the JList that is within it.
I just want to tell that I share the same opinion as javamonkey79. Take a look at MigLayout, you'll love it, and from Java 7 on it will be standart java-onboard layout.