使用组布局时出错

时间:2014-10-14 14:22:45

标签: java swing layout-manager grouplayout

代码:添加名称和描述(desc的名称和文本字段的组合框)

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.io.IOException;
import java.util.ArrayList;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.BoxLayout;


public class Sample extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JTextField textField_1;

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                Sample frame = new Sample();
                frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}

/**
 * Create the frame.
 */
public Sample() {
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    JPanel panel = new JPanel();
    contentPane.add(panel, BorderLayout.CENTER);
    panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));

    JPanel panel_1 = new JPanel();
    panel.add(panel_1);

    GroupLayout group1 = new GroupLayout(panel_1);
    panel_1.setLayout(group1);
    group1.setAutoCreateGaps(true);
    GroupLayout.SequentialGroup hseq1 = group1.createSequentialGroup();
    GroupLayout.Group hg1 = group1.createParallelGroup(Alignment.TRAILING);
    GroupLayout.Group hg2 = group1.createParallelGroup();
    hseq1.addGroup(hg1);
    hseq1.addGroup(hg2);

    GroupLayout.SequentialGroup vseq1 = group1.createSequentialGroup();

    ArrayList<JLabel> labels = new ArrayList<>();
    ArrayList fields = new ArrayList();

    JLabel labelC = new JLabel("Name : ");
    labels.add(labelC);
    JComboBox<String> box = new JComboBox<>();
    fields.add(box);

    JLabel desc = new JLabel("Desc : ");
    labels.add(desc);

    JTextField descfield = new JTextField(20);
    fields.add(descfield);


    //Adding to the group
    for(int i=0; i<labels.size(); i++){
        hg1.addComponent(labels.get(i));
    }

    for(int i=0; i<fields.size(); i++){
        if(i==0){
            hg2.addComponent((JComboBox)fields.get(i));
        }
        else{
            hg2.addComponent((JTextField)fields.get(i));
        }
    }

    for(int i=0; i<labels.size(); i++){
        if(i==0){
            vseq1.addGroup(group1.createParallelGroup().addComponent(labels.get(i)).addComponent((JComboBox)fields.get(i)));
        }
        else{
            vseq1.addGroup(group1.createParallelGroup().addComponent(labels.get(i)).addComponent((JTextField)fields.get(i)));
        }
    }
}

}

例外:

java.lang.IllegalStateException: javax.swing.JTextField[,0,0,0x0,invalid,layout=javax.swing.plaf.basic.BasicTextUI$UpdateHandler,alignmentX=0.0,alignmentY=0.0,border=javax.swing.plaf.BorderUIResource$CompoundBorderUIResource@46faf015,flags=296,maximumSize=,minimumSize=,preferredSize=,caretColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],disabledTextColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],editable=true,margin=javax.swing.plaf.InsetsUIResource[top=0,left=0,bottom=0,right=0],selectedTextColor=sun.swing.PrintColorUIResource[r=51,g=51,b=51],selectionColor=javax.swing.plaf.ColorUIResource[r=184,g=207,b=229],columns=20,columnWidth=0,command=,horizontalAlignment=LEADING] is not attached to a horizontal group
at javax.swing.GroupLayout.checkComponents(Unknown Source)
at javax.swing.GroupLayout.prepare(Unknown Source)
at javax.swing.GroupLayout.minimumLayoutSize(Unknown Source)
at java.awt.Container.minimumSize(Unknown Source)
at java.awt.Container.getMinimumSize(Unknown Source)
at javax.swing.JComponent.getMinimumSize(Unknown Source)
at javax.swing.BoxLayout.checkRequests(Unknown Source)
at javax.swing.BoxLayout.layoutContainer(Unknown Source)
at java.awt.Container.layout(Unknown Source)
at java.awt.Container.doLayout(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validateTree(Unknown Source)
at java.awt.Container.validate(Unknown Source)
at java.awt.Container.validateUnconditionally(Unknown Source)
at java.awt.Window.show(Unknown Source)
at java.awt.Component.show(Unknown Source)
at java.awt.Component.setVisible(Unknown Source)
at java.awt.Window.setVisible(Unknown Source)
at main.Sample$1.run(Sample.java:34)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$200(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at javax.swing.SizeRequirements.calculateAlignedPositions(Unknown Source)
    at javax.swing.BoxLayout.layoutContainer(Unknown Source)
    at java.awt.Container.layout(Unknown Source)
    at java.awt.Container.doLayout(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validateTree(Unknown Source)
    at java.awt.Container.validate(Unknown Source)
    at java.awt.Window.dispatchEventImpl(Unknown Source)
    at java.awt.Component.dispatchEvent(Unknown Source)
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
    at java.awt.EventQueue.access$200(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.awt.EventQueue$3.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.awt.EventQueue$4.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at java.awt.EventQueue.dispatchEvent(Unknown Source)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
    at java.awt.EventDispatchThread.run(Unknown Source)

1 个答案:

答案 0 :(得分:4)

关于您的代码的一些提示:

  • 不要弄乱框架的内容窗格,明确设置JPanelsetContentPane(contentPane)。将此面板添加到内容窗格中:add(contentPane)。这样您就可以利用框架的默认布局管理器:BorderLayout

  • 将布局管理器与setBounds(...)混合起来并不是一个好主意。在将组件添加到其内容窗格之后并使其可见之前,只需pack()框架。

  • 虽然您可以完美地使用GroupLayout来手动编写GUI,但它可以由GUI构建器使用。请参阅this question的答案。拐角处有更好的选择。

  • 如果您不想使用任何第三方布局管理器,那么Nested Layout approach也是一个不错的选择。

关于此例外:

java.lang.IllegalStateException: javax.swing.JTextField[...] is not attached to a horizontal group

很难说出问题出在哪里,因为创建的组太多了。出于某种原因,布局管理器无法解析此文本字段(我猜是descfield)附加到的水平组。预期布局的图片可能有助于追踪问题所在。

更新

在最小化(删除数组迭代)并测试代码之后,问题是您创建了几个组但是从未将水平或垂直组设置为group1,从而导致IllegalStateException。要解决此问题,您只需要像这样设置两个组:

    group1.setHorizontalGroup(hseq1);
    group1.setVerticalGroup(vseq1);

以下是我用来解决问题的固定代码。请注意变量的名称:它们必须有意义。

import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;

public class Demo {

    private void createAndShowGUI() {

        JPanel groupLayoutPanel = new JPanel();        
        GroupLayout groupLayout = new GroupLayout(groupLayoutPanel);
        groupLayout.setAutoCreateGaps(true);        
        groupLayoutPanel.setLayout(groupLayout);

        GroupLayout.Group hg1 = groupLayout.createParallelGroup(Alignment.TRAILING);
        GroupLayout.Group hg2 = groupLayout.createParallelGroup();

        GroupLayout.Group vg1 = groupLayout.createParallelGroup();
        GroupLayout.Group vg2 = groupLayout.createParallelGroup();

        JLabel nameLabel = new JLabel("Name : ");
        hg1.addComponent(nameLabel);
        vg1.addComponent(nameLabel);

        JComboBox<String> nameComboBox = new JComboBox<>();
        hg2.addComponent(nameComboBox);
        vg1.addComponent(nameComboBox);

        JLabel descriptionLabel = new JLabel("Desc : ");
        hg1.addComponent(descriptionLabel);
        vg2.addComponent(descriptionLabel);

        JTextField descriptionTextField = new JTextField(20);
        hg2.addComponent(descriptionTextField);
        vg2.addComponent(descriptionTextField);

        // Horizontal group
        GroupLayout.SequentialGroup hseq1 = groupLayout.createSequentialGroup();
        hseq1.addGroup(hg1);
        hseq1.addGroup(hg2);

        // Vertical group
        GroupLayout.SequentialGroup vseq1 = groupLayout.createSequentialGroup();
        vseq1.addGroup(vg1);
        vseq1.addGroup(vg2);

        groupLayout.setHorizontalGroup(hseq1);
        groupLayout.setVerticalGroup(vseq1);

        JPanel contentPane = new JPanel(new BorderLayout(4, 4));
        contentPane.setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
        contentPane.add(groupLayoutPanel);

        JFrame frame = new JFrame("Demo");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);

    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Demo().createAndShowGUI();
            }
        });
    }
}

截图

enter image description here

相关问题