JButton的ActionListener响应但代码显然没有被执行,但是当我直接调用方法时,它就是。很奇怪的行为?

时间:2014-10-15 00:48:29

标签: java swing actionlistener

当我添加ActionListener并将代码放入调用方法的actionPerformed时,该方法被调用得很好,但是其中的代码,它应该动态添加各种​​Swing组件,似乎没有回应。但是,当我在ActionListener之外添加该行时,会运行相同的代码并且正在添加组件。这很奇怪,我不确定问题是什么。

当我在动作执行方法中添加类似System.out.println语句的内容来添加设备时,显然正在调用它,但没有任何内容添加到JPanel。当我将System.out.println放在addAppliance()方法中时,它也被称为正常。就像我说的,一个非常奇怪的问题。到目前为止,这是我的整个计划:

package Main;    
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;

import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

@SuppressWarnings("serial")
public class ElectricPanel extends JPanel
{
  private static final int WIDTH = 360;
  private static final int HEIGHT = 600;
  private ArrayList<JTextField> description;
  private ArrayList<JTextField> volts;
  private ArrayList<JTextField> current;
  private ArrayList<JTextField> power;
  private JButton addButton;
  private JButton subtractButton;
  private JLabel[] labels;
  private int numOfAppliances;
  public ElectricPanel()
  {
    setPreferredSize(new Dimension(WIDTH, HEIGHT));  
    setFocusable(true);
    requestFocus();
    setLayout(null);
    description = new ArrayList<JTextField>();
    volts = new ArrayList<JTextField>();
    current = new ArrayList<JTextField>();
    power = new ArrayList<JTextField>();
    labels = new JLabel[]{new JLabel("Description"),
        new JLabel("Volts"),
        new JLabel("Current"),
        new JLabel("Power")};
    Dimension size = labels[0].getPreferredSize();
    labels[0].setBounds(10, 10, size.width, size.height);
    size = labels[1].getPreferredSize();
    labels[1].setBounds(125, 10, size.width, size.height);
    size = labels[2].getPreferredSize();
    labels[2].setBounds(185, 10, size.width, size.height);
    size = labels[3].getPreferredSize();
    labels[3].setBounds(245, 10, size.width, size.height);
    for (int i = 0; i < 4; i++)
    {
      add(labels[i]);
    }
    numOfAppliances = 0;
    addAppliance();
    setupAddAndSubtractButtons();
  }
  private void setupAddAndSubtractButtons()
  {
    Insets insets = new Insets(0, 0, 0, 0);
    addButton = new JButton("+");
    subtractButton = new JButton("-");
    addButton.setBounds(305, 30, 24, 18);
    subtractButton.setBounds(305, 50, 24, 18);
    subtractButton.setVisible(false);
    addButton.setMargin(insets);
    subtractButton.setMargin(insets);
    addButton.addActionListener(new ActionListener()
    {
      @Override
      public void actionPerformed(ActionEvent e)
      {
        addAppliance();
      }
    });
    subtractButton.addActionListener(new ActionListener()
    {
      @Override
      public void actionPerformed(ActionEvent arg0)
      {
        subtractAppliance();
      }
    });
    add(addButton);
    add(subtractButton);
    addAppliance();
  }
  private void tryToAdd()
  {
    addAppliance();
  }
  private void addAppliance()
  {
    description.add(new JTextField(10));
    volts.add(new JTextField(5));
    current.add(new JTextField(5));
    power.add(new JTextField(5));

    Dimension size = description.get(numOfAppliances).getPreferredSize();
    description.get(numOfAppliances).setBounds(10, 30 + 20 * numOfAppliances, size.width, size.height);
    size = volts.get(numOfAppliances).getPreferredSize();
    volts.get(numOfAppliances).setBounds(125, 30 + 20 * numOfAppliances, size.width, size.height);
    size = current.get(numOfAppliances).getPreferredSize();
    current.get(numOfAppliances).setBounds(185, 30 + 20 * numOfAppliances, size.width, size.height);
    size = power.get(numOfAppliances).getPreferredSize();
    power.get(numOfAppliances).setBounds(245, 30 + 20 * numOfAppliances, size.width, size.height);

    add(description.get(numOfAppliances));
    add(volts.get(numOfAppliances));
    add(current.get(numOfAppliances));
    add(power.get(numOfAppliances));

    numOfAppliances++;
  }
  private void subtractAppliance()
  {
    int index = numOfAppliances - 1;
    description.remove(index);
    volts.remove(index);
    current.remove(index);
    power.remove(index);
  }
}

感谢所有的帮助和建议!

1 个答案:

答案 0 :(得分:2)

如果您在单击按钮后调整窗口大小(如果它可以调整大小),您会注意到按钮单击正在生效。发生的事情是您正在添加组件,但不重新绘制面板。只需在repaint()方法中添加actionPerformed()电话,您的更改就会显示出来。

方法在动作侦听器之外工作的原因是方法调用是在首次绘制面板之前进行的。然而,当方法调用在动作侦听器内部时,在绘制面板后单击按钮时,它们就会被执行。

除此之外,您绝对不应该使用空布局,这将使您的GUI仅限于您正在使用的计算机。另外,请阅读Java Swing