here's an SSCCE:
import java.awt.Color;
import java.awt.Dimension;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BoxLayoutTest extends JFrame {
public BoxLayoutTest(){
JPanel main = new JPanel();
main.setLayout(new BoxLayout(main, BoxLayout.Y_AXIS));
main.setBackground(Color.red);
this.add(main);
JPanel northPanel = new JPanel();
JPanel middle = new JPanel();
middle.setLayout(new BoxLayout(middle, BoxLayout.X_AXIS));
middle.add(new JButton("FOO"));
middle.add(Box.createHorizontalGlue());
JPanel aPanel = new JPanel();
aPanel.setBackground(Color.black);
JComboBox b = new JComboBox();
//b.setPreferredSize(new Dimension(100,16)); //uncomment this to see the layout I would like to achieve
//b.setMaximumSize(new Dimension(100,16));
//middle.add(b); //uncomment this line
middle.setBackground(Color.green);
northPanel.setBackground(Color.blue);
main.add(northPanel);
main.add(middle);
main.add(Box.createVerticalGlue());
this.setSize(800,600);
this.setResizable(true);
this.setVisible(true);
}
public static void main(String[] args) {
new BoxLayoutTest();
}
}
I'm trying to refactor some classes I wrote some time ago, when I didn't know that using setXXXSize methods on components is wrong. Using a resizable frame ,the result I want to achieve is the following:
- The northPanel should stay on top and change it's size accordingly to the frame size modifications (seems to work fine)
- The green panel where I put the JButton should keep the maximum dimension of the JButton and stay just below the blue panel above (this works fine if I only put JButtons inside that panel).
The problem arise if I put a JComboBox inside the green panel (try to uncomment the line in the SSCCE). I guess JComboBox hasn't a maximum size specified, so it stretches with the frame. In the previous wrong version of my code I was using setxxxSize methods on the JComboBox to limit it's dimension(try to uncomment the line on setXXXSize methods to see it).
My question are:
- Is it possible to achieve the same result using BoxLayout without invoking setXXXSize() methods?
- If yes, how?
- Is there any other LayoutManager that can I use to get that effect?
Please put me in the right direction
JComboBox is misbehaving (the same as JTextField) in reporting an unbounded max height: should never show more than a single line. Remedy is the same: subclass and return a reasonable height
JComboBox b = new JComboBox() {
/**
* @inherited <p>
*/
@Override
public Dimension getMaximumSize() {
Dimension max = super.getMaximumSize();
max.height = getPreferredSize().height;
return max;
}
};
just for fun, here's a snippet using MigLayout (which is my personal favorite currently :-)
// two panels as placeholders
JPanel northPanel = new JPanel();
northPanel.setBackground(Color.YELLOW);
JPanel southPanel = new JPanel();
southPanel.setBackground(Color.YELLOW);
// layout with two content columns
LC layoutContraints = new LC().wrapAfter(2)
.debug(1000);
AC columnContraints = new AC()
// first column pref, followed by greedy gap
.size("pref").gap("push")
// second
.size("pref");
// three rows, top/bottom growing, middle pref
AC rowContraints = new AC()
.grow().gap().size("pref").gap().grow();
MigLayout layout = new MigLayout(layoutContraints, columnContraints,
rowContraints);
JPanel main = new JPanel(layout);
main.setBackground(Color.WHITE);
// add top spanning columns and growing
main.add(northPanel, "spanx, grow");
main.add(new JButton("FOO"));
// well-behaved combo: max height == pref height
JComboBox combo = new JComboBox() {
@Override
public Dimension getMaximumSize() {
Dimension max = super.getMaximumSize();
max.height = getPreferredSize().height;
return max;
}
};
// set a prototype to keep it from constantly adjusting
combo.setPrototypeDisplayValue("somethingaslongasIwant");
main.add(combo);
// add top spanning columns and growing
main.add(southPanel, "spanx, grow");
I have always seen using the layout managers in the jdk are not easy. They are either too simple and inflexible or the gridbaglayout is just too much trouble. Instead I started using the jgoodies form layout and never looked back since.. Have a look at it. Its very simple and easy to use. Here's a link:
http://www.jgoodies.com/freeware/forms/
Make sure you go through the white paper.
And now, we also have google providing us a WYSISWG editor for the formlayout as a plugin for eclipse. This just makes life a lot lot easier.
http://code.google.com/javadevtools/wbpro/palettes/swing_palette.html
来源:https://stackoverflow.com/questions/7581846/swing-boxlayout-problem-with-jcombobox-without-using-setxxxsize