【问题标题】:Make a JPanel Change After ActionListener在 ActionListener 之后进行 JPanel 更改
【发布时间】:2015-06-03 23:15:59
【问题描述】:

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

下面是一段代码:

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

这里还有一些程序运行时的照片。

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

然后是下一张卡片:

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

【问题讨论】:

    标签: java swing user-interface actionlistener cardlayout


    【解决方案1】:

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

    一个简单的解决方案是将名称传递给所有面板。当您想要添加新的卡片/面板时,这会成为问题,因为您需要不断更新代码,当然,您可以使用 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
                    }
                }
            });
        }
    
    }
    

    【讨论】:

    • 感谢您的洞察!我对代码非常陌生,所以如果您能指导我学习将名称传递给另一个面板所需的知识吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-30
    • 1970-01-01
    • 2019-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多