我有一个使用SwingLayout的Swing程序。Swing组件的结构如下所示。
JFrame
JPanel (Cardlayout)
JPanel (Miglayout) - Main panel
Jpanel (Flowlayout) - Checkbox Panel
JPanel (Flowlayout) - Option Panel
我现在的问题是,我不知道如何防止复选框面板增长。我不希望它"推"出它在右边的栏。我希望Wraplayout(在选项面板上运行良好)在复选框面板变得太大时包装它的内容。
这是Eclipse内部Windowsbuilder GUI中的视图。带有标签"sites"的面板是复选框面板。复选框面板右侧是选项面板。包含这两者的大面板是主面板。https://i.stack.imgur.com/K7Gp1.png
当我添加太多复选框时,就会发生这种情况https://i.stack.imgur.com/0aJM7.png
我的主要问题是,我不明白为什么当我在站点面板中添加新的复选框时,在主面板中第一列的列约束上设置"grow 0"并不能阻止它的增长(站点面板可以有任意数量的复选框)。
这是我的主面板miglayout。
mainPanel.setLayout(new MigLayout("", "[][grow]", "[][][][][][][][grow]"));
以下是我添加复选框面板时的组件限制
siteCheckBoxPanel = new JPanel();
mainPanel.add(siteCheckBoxPanel, "cell 0 0,alignx left,gapx 0px,aligny center");
siteCheckBoxPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
我也尝试过不使用流布局,但这并不能解决任何问题。你能提供的任何见解都会很棒!如果人们有疑问,我也很乐意提供更多信息。仅供参考,我还尝试过在复选框面板所在单元格的列和行约束上"增长0"。
这是SSCCE。你可以在下面找到来源。您唯一需要的依赖项是miglayout。您可以单击按钮添加复选框。
https://dl.dropbox.com/u/20614368/Test.java
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import net.miginfocom.swing.MigLayout;
public class Test extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
private Test frame;
public void run() {
try {
frame = new Test();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private JPanel contentPane;
private JPanel mainPanel;
private JPanel optionPanel;
private JButton btnUploadImages;
private JLabel thumbnailLabel;
private JTextArea textArea;
private JPanel checkboxPanel;
private final Action action = new SwingAction();
/**
* Create the frame.
*/
public Test() {
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 1098, 846);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(new CardLayout(0, 0));
mainPanel = new JPanel();
mainPanel.setName("");
contentPane.add(mainPanel, "name_329556913535654");
mainPanel.setLayout(new MigLayout("", "[][grow]", "[][][][][][][][grow]"));
JLabel lblPicture = new JLabel("Picture");
mainPanel.add(lblPicture, "cell 0 1");
optionPanel = new JPanel();
optionPanel.setBackground(Color.red);
mainPanel.add(optionPanel, "cell 1 0 1 5,grow");
btnUploadImages = new JButton("Upload Images");
btnUploadImages.setAction(action);
thumbnailLabel = new JLabel("");
mainPanel.add(thumbnailLabel, "cell 0 4");
textArea = new JTextArea();
mainPanel.add(btnUploadImages, "cell 0 6");
checkboxPanel = new JPanel();
checkboxPanel.setBackground(Color.green);
mainPanel.add(checkboxPanel, "flowx,cell 0 0");
JLabel lblSites = new JLabel("Sites");
checkboxPanel.add(lblSites);
}
private class SwingAction extends AbstractAction {
public SwingAction() {
putValue(NAME, "Add checkbox");
putValue(SHORT_DESCRIPTION, "Some short description");
}
public void actionPerformed(ActionEvent e) {
JCheckBox box = new JCheckBox();
box.setName("Foobar!");
checkboxPanel.add(box);
contentPane.validate();
contentPane.repaint();
}
}
}
理论上,如果您告诉布局,您的设置应该如您所期望的那样工作
- 通过将最大值设置为百分比,使第一列不超过最大值
- 通过在列约束中将最小值设置为pref,使optionPanel列不收缩到其pref下
列约束示例:
// first column - restrict max
"[grow, fill, n:pref:30%]" +
// second column - restrict min
"[grow, pref:pref:n]"
实际上,无论受到什么限制,我都无法使FlowLayout和MigLayout很好地配合使用:甚至初始布局也被破坏了(例如,optionPanel被推离了框架宽度)。用Rob的WrapLayout替换FlowLayout看起来更好,但并不完全是最优的,因为盒子之间没有完全对齐。
/*
* Created on 12.09.2012
*
*/
package layout;
import java.awt.CardLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import net.miginfocom.swing.MigLayout;
public class MigLayoutNested extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
private MigLayoutNested frame;
public void run() {
try {
frame = new MigLayoutNested();
frame.pack();
// frame.setSize(frame.getWidth(), frame.getHeight()* 2);
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
private JPanel contentPane;
private JPanel mainPanel;
private JPanel optionPanel;
private JButton btnUploadImages;
private JLabel thumbnailLabel;
private JTextArea textArea;
private JPanel checkboxPanel;
private final Action action = new SwingAction();
/**
* Create the frame.
*/
public MigLayoutNested() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
contentPane = (JPanel) getContentPane(); //new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new CardLayout(0, 0));
mainPanel = new JPanel();
contentPane.add(mainPanel, "name_329556913535654");
mainPanel.setLayout(new MigLayout("debug",
"[grow, fill][grow, pref:pref:n]"
, "[grow, fill][][][][][][][grow]"
));
// stand-in to simulate a row-spanning all-growing component
optionPanel = new JPanel();
((FlowLayout) optionPanel.getLayout()).setAlignment(JLabel.RIGHT);
JLabel option = new JLabel("just some label so we see the trailing corner, long enough");
optionPanel.add(option);
optionPanel.setBackground(Color.YELLOW);
mainPanel.add(optionPanel, "cell 1 0 1 5, grow");
// the panel to dynamically add components to
// expected behaviour is to wrap on revalidate if needed
// not working with FlowLayout, but looks half-way fine
// with Rob's WrapLayout
checkboxPanel = new JPanel(new WrapLayout());
checkboxPanel.setBackground(Color.green);
JLabel lblSites = new JLabel("Sites");
checkboxPanel.add(lblSites);
mainPanel.add(checkboxPanel, "cell 0 0");
JLabel lblPicture = new JLabel("Picture");
mainPanel.add(lblPicture, "cell 0 1");
thumbnailLabel = new JLabel("thumb");
mainPanel.add(thumbnailLabel, "cell 0 3");
textArea = new JTextArea(10, 10);
mainPanel.add(textArea, "cell 0 4");
btnUploadImages = new JButton("Upload Images");
btnUploadImages.setAction(action);
mainPanel.add(btnUploadImages, "cell 0 6");
}
private class SwingAction extends AbstractAction {
public SwingAction() {
putValue(NAME, "Add checkbox");
putValue(SHORT_DESCRIPTION, "Some short description");
}
@Override
public void actionPerformed(ActionEvent e) {
JCheckBox box = new JCheckBox();
box.setName("Foobar!");
checkboxPanel.add(box);
checkboxPanel.revalidate();
}
}
}