在ActionListener之后进行JPanel更改 [英] Make a JPanel Change After ActionListener

查看:86
本文介绍了在ActionListener之后进行JPanel更改的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have to make a game for a school project in CS. I want to make it so that a person may input their name and all subsequent panels will have their name on it. I am using a card layout, which works for the most part. When I run the game and input the name, it works specifically on that card. However, when I go to the next card, where the String name is supposed to appear, it appears as null. My suspicion is that the program creates all of the cards before given the chance to accept the name input and is therefore failing. My teacher doesn't really know how to do it either.

这是代码的一部分:

    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);
 }

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

Here are also some photos of the program when running.

在这里是选择名称并按回车后的名称输入屏幕:

Here is the name enter screen after picking a name and hitting enter:

然后是下面的卡片:

在此先感谢您的帮助! (我会直接发布图像,但我的信誉不高)

Thanks in advance for the help! (I would have directly posted the images but I don't have enough reputation)

推荐答案

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

The question you need to ask yourself is, how would all the other cards/panels know what the value of the name is?

一个简单的解决方案是将名称传递给所有面板。当您要添加新的卡/面板时,这变得很麻烦,因为您需要不断更新代码,当然,您可以使用 List 或数组并拥有所有卡/ panels实现一个公共接口...

A simple solution would be to pass the name to all the panels. This becomes problematic when you want to add new cards/panels in, as you need to constantly update the code, sure, you could use a List or array and have all the cards/panels implement a common interface...

或者您可以简单地使用某种模型,所有卡/面板都共享一个引用。这样一来,您就可以更轻松地在它们之间共享数据,而不必花太多时间

Or you could simply use a "model" of some kind, which all the cards/panels shared a reference to. This would allow you more simply share data between them without having to mess around to much


所以如果您可以将我引向我需要的地方学会将名称传递给另一个面板?

so if you could perhaps direct me to what I need to learn to pass name to another panel?

创建一个类,最好从一个接口开始,该接口充当数据的容器,这将成为您的模型...

Make a class, preferably starting with an interface, which acts as a container for the data, this becomes your model...

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);
    }


}

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

For each panel who is going to need to know the name, you need to pass the same instance of the model to it...

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

每个想知道名称更改的小组都需要注册 PropertyChangeListener 并监视 name 属性的更改

Each panel which wants to know when the name changes, they need to register a PropertyChangeListener and monitor for changes to the name property

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
                }
            }
        });
    }

}

这篇关于在ActionListener之后进行JPanel更改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆