我的目标是当我点击按钮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.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();
}
}
答案 0 :(得分:3)
问题似乎是当你多次按下按钮时,你会多次向面板添加相同的按钮,SpringLayout
无法处理它。
您可以在b1
中执行任何其他操作之前删除actionPerformed
来避免这种情况:
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();
}
这不应该是第一次出现任何问题,因为删除不存在的元素无效!
答案 1 :(得分:1)
使用MigLayout代替SpringLayout。 使用MigLayout,您可以使用 hidemode 约束:
hidemode:设置组件的隐藏模式。如果已在“隐藏”模式中指定了隐藏模式,则可以通过组件约束覆盖此模式。隐藏模式指定了布局管理器应该如何处理a 不可见的组件。模式是:
0 -Default。意味着隐藏组件的处理方式与它们可见的完全相同。
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);
}