Java Swing应用程序中的动态按钮放置问题
我的目标是,当我单击按钮b1(“显示”)时,按钮b2(“按钮2”)应显示在按钮b1右侧10px处。当我第一次单击按钮b1时,它按预期工作,但从第二次开始,按钮b2被置于(0,0)位置。为什么Java Swing应用程序中的动态按钮放置问题,java,swing,Java,Swing,我的目标是,当我单击按钮b1(“显示”)时,按钮b2(“按钮2”)应显示在按钮b1右侧10px处。当我第一次单击按钮b1时,它按预期工作,但从第二次开始,按钮b2被置于(0,0)位置。为什么 import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.JButton; import javax.swing.Spring; import javax.swing.SpringLayout; import java.
import javax.swing.JPanel;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.Spring;
import javax.swing.SpringLayout;
import java.awt.event.*;
import javax.swing.*;
class DynamicSpring implements ActionListener
{
JPanel jp;
JFrame jf;
JButton b1,b2;
SpringLayout sl;
DynamicSpring()
{
jf=new JFrame("DynamicSpring");
jf.setSize(500,500);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
sl=new SpringLayout();
jp=new JPanel(sl);
b1=new JButton("SHOW");
b1.setSize(100,100);
sl.putConstraint(SpringLayout.WEST,b1,10,SpringLayout.WEST,jp);
sl.putConstraint(SpringLayout.NORTH,b1,10,SpringLayout.NORTH,jp);
b1.addActionListener(this);
jp.add(b1);
b2=new JButton("Button 2");
b2.setSize(100,100);
jf.setContentPane(jp);
jf.setVisible(true);
}
public void actionPerformed(ActionEvent ae)
{
sl.putConstraint(SpringLayout.WEST,b2,10,SpringLayout.EAST,b1);
jp.add(b2);
jp.repaint();
jp.validate();
}
public static void main(String... s)
{
new DynamicSpring();
}
}
问题似乎在于,当您多次按下按钮时,会将同一按钮多次添加到面板中,
SpringLayout
无法处理该按钮
您可以在执行操作之前删除b1
,以避免此问题:
public void actionPerformed(ActionEvent ae)
{
jp.remove(b2); /* remove the button first! */
sl.putConstraint(SpringLayout.WEST,b2,10,SpringLayout.EAST,b1);
jp.add(b2);
jp.repaint();
jp.validate();
}
第一次删除不存在的元素不会产生任何问题 问题似乎在于,当您多次按下按钮时,会将同一按钮多次添加到面板中,而SpringLayout
无法处理该按钮
您可以在执行操作之前删除b1
,以避免此问题:
public void actionPerformed(ActionEvent ae)
{
jp.remove(b2); /* remove the button first! */
sl.putConstraint(SpringLayout.WEST,b2,10,SpringLayout.EAST,b1);
jp.add(b2);
jp.repaint();
jp.validate();
}
第一次删除不存在的元素不会产生任何问题 使用而不是SpringLayout。
使用MigLayout,可以使用隐藏模式约束:
隐藏模式:设置组件的隐藏模式。如果在中指定了隐藏模式,则此隐藏模式可以由零部件约束替代。隐藏模式指定布局管理器应如何处理
不可见的组件。这些模式包括:
0-默认值。这意味着不可见组件的处理方式将与可见组件完全相同
1-组件的大小(如果不可见)将设置为0,0
2-组件的大小(如果不可见)将设置为0,0,并且其周围的间隙也将设置为0
3-不可见组件根本不会参与布局,例如,它不会占用网格单元
您的代码将成为:
DynamicString() {
jp=new JPanel(sl);
b1=new JButton("SHOW");
b1.addActionListener(this);
jp.add(b1,"newline, w 100!, h 100!");
b2=new JButton("Button 2");
jp.add(b2,"w 100!, h 100!, hidemode 0"); // use whatever hidemode mode that's the more convenient for you
b2.setVisible(false);
jf.setContentPane(jp);
jf.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
b2.setVisible(true);
}
使用而不是SpringLayout。
使用MigLayout,可以使用隐藏模式约束:
隐藏模式:设置组件的隐藏模式。如果在中指定了隐藏模式,则此隐藏模式可以由零部件约束替代。隐藏模式指定布局管理器应如何处理
不可见的组件。这些模式包括:
0-默认值。这意味着不可见组件的处理方式将与可见组件完全相同
1-组件的大小(如果不可见)将设置为0,0
2-组件的大小(如果不可见)将设置为0,0,并且其周围的间隙也将设置为0
3-不可见组件根本不会参与布局,例如,它不会占用网格单元
您的代码将成为:
DynamicString() {
jp=new JPanel(sl);
b1=new JButton("SHOW");
b1.addActionListener(this);
jp.add(b1,"newline, w 100!, h 100!");
b2=new JButton("Button 2");
jp.add(b2,"w 100!, h 100!, hidemode 0"); // use whatever hidemode mode that's the more convenient for you
b2.setVisible(false);
jf.setContentPane(jp);
jf.setVisible(true);
}
public void actionPerformed(ActionEvent ae) {
b2.setVisible(true);
}
删除第二个问题。无论如何,这是离题的。请调用revalidate
,然后调用repaint
,仍然得到相同的结果。删除第二个问题。不管怎样,这都是离题的。调用revalidate
,然后再调用repaint
仍然会得到相同的结果这很有效!!!但我可以理解为什么我必须在添加按钮b2之前删除它???根据规则,如果组件添加到另一个容器中,则任何组件都会从其以前的容器中删除…因此,当我第二次单击按钮b1时,按钮b2应自动从其容器中移除,然后添加到同一容器中……如果有效,请将答案标记为正确。如果多次添加按钮,则按钮不会出现两次,但是SpringLayout
无法正确处理它。我假设这是因为当您第二次添加约束时,约束仍然属于按钮的“旧实例”,并且没有用于“新实例”,即使它是同一个对象。好的……但是当我第一次单击按钮b1时,它不应该给出任何错误,因为它必须删除容器中不存在的b2吗???不,删除不存在的元素没有任何效果。如果用JLabelt替换按钮b2,则上述方法无效。此方法有效!!!但我可以理解为什么我必须在添加按钮b2之前删除它???根据规则,如果组件添加到另一个容器中,则任何组件都会从其以前的容器中删除…因此,当我第二次单击按钮b1时,按钮b2应自动从其容器中移除,然后添加到同一容器中……如果有效,请将答案标记为正确。如果多次添加按钮,则按钮不会出现两次,但是SpringLayout
无法正确处理它。我假设这是因为当您第二次添加约束时,约束仍然属于按钮的“旧实例”,并且没有用于“新实例”,即使它是同一个对象。好的……但是当我第一次单击按钮b1时,它不应该给出任何错误,因为它必须删除容器中不存在的b2吗???不,删除不存在的元素没有任何效果。如果用JLabelI替换按钮b2,则上述方法不起作用。不建议使用MigLayout。它不是Java API的一部分,它可能会给商业应用程序带来一些许可问题(它是GPL),如果其他人参与该项目,他们必须首先习惯它。。。如果Java API也能完成任务,我建议使用它……我不建议使用MigLayout。它不是Java API的一部分,它可能会给商业应用程序带来一些许可问题(它是GPL),如果其他人参与该项目,他们必须首先习惯它。。。如果Java API也能完成任务,我建议您使用它。。。