Java swing GroupLayout - 如何交换组件的位置



我在GroupLayout中布局了一个JFrame。我想在用户单击按钮时交换此 JFrame 中两个组件的位置。我使用GroupLayout中replace()的方法将一个替换为另一个。这是我想交换两个按钮位置的代码:buttons[0]buttons[1]

groupLayout.replace(buttons[1], buttons[2]);
groupLayout.replace(buttons[2], buttons[1]);

但是,当我运行它时,该程序会NullPointerException。该异常不提供任何有用的信息:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at javax.swing.GroupLayout$ComponentInfo.setBounds(Unknown Source)
    at javax.swing.GroupLayout.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.validate(Unknown Source)
    at javax.swing.RepaintManager$2.run(Unknown Source)
    at javax.swing.RepaintManager$2.run(Unknown Source)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
    at javax.swing.RepaintManager.validateInvalidComponents(Unknown Source)
    at javax.swing.RepaintManager$ProcessingRunnable.run(Unknown Source)
    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)

(起初,我以为这是因为按钮[2]已经被移除了。但是当我尝试replace(buttons[1],buttons[3])之前没有将按钮[3]添加到groupLayout时,没有任何问题。所以我仍然无法弄清楚发生了什么问题。

然后,我想出了一个想法,即维护对组的引用,该引用仅包含我要更改的组件,以便以后对其进行操作。这是我的代码:

if(count % 2 == 1) {
    groupLayout.replace(buttons[1], buttons[2]);
    button2HorizontalGroup.addComponent(buttons[1]);
    button2VerticalGroup.addComponent(buttons[1]);
}else {
    groupLayout.replace(buttons[2], buttons[1]);
    button2HorizontalGroup.addComponent(buttons[2]);
    button2VerticalGroup.addComponent(buttons[2]);
}

但这可能更像是一种黑客攻击,而不是解决方案。另外,如果要更换大量组件,可能会很麻烦。有没有更好的解决方案来交换组式布局中的组件?(其他布局中的解决方案也欢迎:))

谢谢。


更新:

@user1803551:这是我的代码(GroupLayoutTest是一个扩展JFrame的类):

public GroupLayoutTest() {
    // Allow group layout to automatically creat the gap between components and containers.
    groupLayout.setAutoCreateGaps(true);
    groupLayout.setAutoCreateContainerGaps(true);
    setLayout(groupLayout);

    buttons = new JButton[4];
    buttons[0] = new JButton("small 1");
    buttons[1] = new JButton("medium 2");
    buttons[2] = new JButton("big 3");
    buttons[1].addActionListener(replaceHandler);
    buttons[2].addActionListener(replaceHandler);
    button1HorizontalGroup.addComponent(buttons[1]);
    button1VerticalGroup.addComponent(buttons[1]);
    button2HorizontalGroup.addComponent(buttons[2]);
    button2VerticalGroup.addComponent(buttons[2]);
    groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup()
            .addGroup(groupLayout.createSequentialGroup()
                    .addGap(39)
                    .addComponent(buttons[0])
                    // Make it like a Spring
                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGap(10)
                    .addGroup(button1HorizontalGroup)
                    .addGap(52))
            .addGroup(groupLayout.createSequentialGroup()
                    .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGap(0)
                    .addGroup(button2HorizontalGroup)
                    .addContainerGap(GroupLayout.DEFAULT_SIZE, 160))
    );
    groupLayout.setVerticalGroup(
            groupLayout.createSequentialGroup()
            .addContainerGap(50, 50)
            .addGroup(groupLayout.createParallelGroup()
                    .addComponent(buttons[0])
                    .addGroup(button1VerticalGroup) )
            .addGap(10)
            .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addGroup(button2VerticalGroup)
            .addContainerGap(168, 168));
    groupLayout.linkSize(SwingConstants.HORIZONTAL, buttons[1],buttons[2]);
    pack();
    setLocationRelativeTo(null);
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
private class ReplaceHandler implements ActionListener {
    private int count = 0;
    @Override
    public void actionPerformed(ActionEvent e) {
        count += 1;
        if(count % 2 == 1) {
            groupLayout.replace(buttons[1], buttons[2]);
            button2HorizontalGroup.addComponent(buttons[1]);
            button2VerticalGroup.addComponent(buttons[1]);
        }else {
            groupLayout.replace(buttons[2], buttons[1]);
            button2HorizontalGroup.addComponent(buttons[2]);
            button2VerticalGroup.addComponent(buttons[2]);
        }
        groupLayout.linkSize(SwingConstants.HORIZONTAL, buttons[1],buttons[2]);
    }
}

@camickr:从上面的代码中可以看出,我只是在第一次体验 GroupLayout 时玩得很开心。我想在单击一个按钮("中"和"小")时相互交换。毕竟,感谢您的建议。:)

我只是在第一次体验GroupLayout时玩得很开心。

好吧,您应该先学习其他布局管理器

我想在单击一个按钮("中"和"小")时相互交换。

创建一个 JPanel 以包含您的两个按钮并将面板添加到布局中。

使一个按钮可见,另一个按钮不可见。当您单击该按钮时,您可以切换两个按钮的可见性状态。

相关内容

  • 没有找到相关文章

最新更新