在ActionListener之后进行JPanel更改

时间:2015-06-03 23:16:00

标签: java swing user-interface actionlistener cardlayout

我必须为CS的学校项目制作游戏。我想这样做,以便一个人可以输入他们的名字,所有后续的小组都会在上面写上他们的名字。我使用的是卡片布局,大部分都可以使用。当我运行游戏并输入名称时,它专门用于该卡。但是,当我转到下一张卡片时,应该出现String名称,它显示为null。我怀疑该程序在有机会接受名称输入之前创建了所有卡片,因此失败了。我的老师也不知道该怎么做。

以下是代码的一部分:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class NovelCards extends JFrame {
   private String name;
   private CardLayout cards;
   private JTextField txt = new JTextField(10);
   private JLabel label = new JLabel();
   public NovelCards() {
      super("Novel");
      masterPanel = new JPanel();
      cards = new CardLayout();
      txt.addActionListener( new ActionListener(){
          public void actionPerformed(ActionEvent e){
            name = txt.getText();
            label.setText(name);
          }
      });      
      button2 = new JButton("Next");
      button2.addActionListener(new NextListener());
      JPanel card2 = new JPanel();
      card2.add(button2);
      card2.add(txt);
      card2.add(label);
      card2.add(new JLabel(" Enter your name "));

      JButton button3 = new JButton("Next");
      button3.addActionListener(new NextListener());
      JPanel card3 = new JPanel();
      card3.add(new JLabel("Hello there, " + name + "!"));
      card3.add(button3);

      masterPanel.setLayout(cards); 
      masterPanel.add("2",card2);
      masterPanel.add("3",card3);
      this.setContentPane(masterPanel);
      cards.show(masterPanel, "1");
 }

 public class NextListener implements ActionListener{
  public void actionPerformed(ActionEvent event){
     cards.next(masterPanel);
 }

以下是运行时程序的一些照片。

选择姓名并点击输入后,这是输入屏幕的名称:

http://i.stack.imgur.com/AC446.png

然后这是随后的卡片:

http://i.stack.imgur.com/Z1Jin.png

提前感谢您的帮助! (我会直接发布图片,但我没有足够的声誉)

1 个答案:

答案 0 :(得分:4)

您需要问自己的问题是,所有其他卡/面板如何知道该名称的价值是多少?

一个简单的解决方案是将名称传递给所有面板。当您想要添加新卡/面板时,这会成为问题,因为您需要不断更新代码,当然,您可以使用List或数组,并让所有卡/面板实现一个通用接口......

或者你可以简单地使用某种类型的“模型”,所有的牌/面板共享参考。这样可以让您更简单地在它们之间共享数据,而不必乱用很多

  

所以,如果你能指导我学习将名字传递给另一个小组,我可能会这么做吗?

创建一个类,最好从一个接口开始,它充当数据的容器,这就成了你的模型......

public interface NovelCardsModel {
    public String getName();
    public void setName(String name);

    public void addPropertyChangeListener(PropertyChangeListener listener);
    public void removePropertyChangeListener(PropertyChangeListener listener);

    // Add accessors to any other data you might think
    // you need to share
}

现在,创建模型的实现

public class DefaultNovelCardsModel implements NovelCardsModel {
    private PropertyChangeSupport propertyChangeSupport;
    private String name;

    public DefaultNovelCardsModel() {
        propertyChangeSupport = new PropertyChangeSupport(this);
    }

    @Override
    public String getName() {
        return name;
    }

    @Override
    public void setName(String value) {
        if (value == null || !value.equals(name)) {
            String old = name;
            name = value;
            propertyChangeSupport.firePropertyChange("name", old, name);
        }
    }

    @Override
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }

    @Override
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }


}

对于需要知道名称的每个小组,您需要将相同的模型实例传递给它...

DefaultNovelCardsModel model = new DefaultNovelCardsModel();
masterPanel = new MasterPane(model);
// All the other cards.

每个小组想知道姓名何时更改,他们需要注册PropertyChangeListener并监控name属性的更改

public class MasterPanel extends JPanel {

    private NovelCardsModel model;

    public MasterPanel(NovelCardsModel model) {
        this.model = model;
        this.model.addPropertyChangeListener(new PropertyChangeListener() {
            @Override
            public void propertyChange(PropertyChangeEvent evt) {
                if ("name".equals(evt.getPropertyName())) {
                    // Name has changed
                }
            }
        });
    }

}