Java-Swing: A problem using layout managers!
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.setTex开发者_C百科t("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.
精彩评论