Внесите изменения в JPanel после ActionListener

Мне нужно сделать игру для школьного проекта в 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);
 }

Вот также несколько фотографий программы во время работы.

Вот экран ввода имени после выбора имени и нажатия Enter:

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

А вот и следующая карта:

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

Заранее спасибо за помощь! (Я бы напрямую разместил изображения, но у меня недостаточно репутации)


person BananaCreamDream    schedule 03.06.2015    source источник


Ответы (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
                }
            }
        });
    }

}
person MadProgrammer    schedule 03.06.2015
comment
Спасибо за понимание! Я очень новичок в программировании, поэтому, не могли бы вы указать мне, что мне нужно научиться передавать имя на другую панель? - person BananaCreamDream; 04.06.2015