我在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]);
}
但这可能更像是一种破解而非解决方案。另外,如果要交换大量组件,可能会很麻烦。在GroupLayout中交换组件有没有更好的解决方案? (也欢迎其他布局的解决方案:))
感谢。
更新
@ 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感到非常开心。我点击它时,我想要一个按钮("媒体"和#34;小")互相交换。毕竟,谢谢你的建议。 :)
答案 0 :(得分:0)
我正在玩我的第一次GroupLayout体验。
嗯,你应该先学习其他布局管理员
当我点击它时,我想让一个按钮(“中”和“小”)相互交换。
创建一个JPanel以包含两个按钮,并将面板添加到布局中。
使一个按钮可见,另一个按钮不可见。当您单击该按钮时,您可以切换两个按钮的可见性状态。