Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Swing应用程序中的动态按钮放置问题_Java_Swing - Fatal编程技术网

Java Swing应用程序中的动态按钮放置问题

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.

我的目标是,当我单击按钮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();
  }

}

问题似乎在于,当您多次按下按钮时,会将同一按钮多次添加到面板中,
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也能完成任务,我建议您使用它。。。