Как изменить панели компоновки карты с другой панели?

#java #swing #layout #cardlayout

#java #качать #макет #cardlayout

Вопрос:

Я долго гуглил, но никаких решений не нашел. Я думаю, что должны быть мастера Java, которые помогут мне…

Это мой метод инициализации:


 private void initialize() {
    this.setSize(750, 480);
    this.setContentPane(getJContentPane());
    this.setTitle("Registration");
    JPanel topPane = new TopPane();
    this.getContentPane().add(topPane,BorderLayout.PAGE_START);
    cards=new JPanel(new CardLayout());
    cards.add(step0(),"step0");
    cards.add(step1(),"step1");
    cards.add(step2(),"step2");
    this.getContentPane().add(cards,BorderLayout.CENTER);
}

public JPanel step2(){
    EnumMap<DPFPFingerIndex,DPFPTemplate> template = new EnumMap<DPFPFingerIndex, DPFPTemplate>(DPFPFingerIndex.class); 
    JPanel enrol = new Enrollment(template,2);
    return enrol;
}

public JPanel step0(){
    JPanel userAgree = new UserAgreement();
    return userAgree;
}

public JPanel step1(){
    JPanel userInfo = new UserInformation();
    return userInfo;
}

public JPanel getCards(){
    return cards;
}
  


Это метод на другом step0 JPanel:

 jButtonAgree.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent e) {
                Registration reg = new Registration();
                LayoutManager cards = reg.getCards().getLayout();
                ((CardLayout) cards).show(reg.getCards(),"step1");
            }
        });
  

Вообще никаких изменений, я пробовал повторную проверку, перекрашивание и другой персонал … не работает… у кого-нибудь есть какие-либо предложения здесь!

Комментарии:

1. Дело в том, чтобы не вызывать методы в соответствующем экземпляре регистрации. В приведенном выше коде вы создаете новый экземпляр регистрации, который совершенно не связан с тем, который отображается в графическом интерфейсе. Вместо этого вам нужно получить ссылку на видимый объект регистрации. Пожалуйста, смотрите мой ответ ниже…

Ответ №1:

Все дело в том, чтобы предоставить правильные методы и постоянные строки внешнему миру, чтобы позволить классу самому менять представления. Например, присвойте вашему первому классу закрытое поле CardLayout с именем cardlayout и закрытое поле JPanel с именем cards (JPanel держателя карты), а также некоторые общедоступные строковые константы, которые используются для добавления ваших карточек JPanels в контейнер cards. Также дайте ему открытый метод, скажем, called public void swapView(String key) , который позволяет внешним классам менять карты местами … что-то вроде этого:

 // code corrected
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class Registration extends JPanel {
   // use these same constants as button texts later
   private static final Dimension PREF_SIZE = new Dimension(450, 300);
   public static final String USER_AGREEMENT = "User Agreement";
   public static final String USER_INFO = "User Information";
   public static final String ENROLLMENT = "Enrollment";
   // we'll extract them from this array
   public static final String[] KEY_TEXTS = {USER_AGREEMENT, USER_INFO, ENROLLMENT};
   private CardLayout cardlayout = new CardLayout();
   private JPanel cards = new JPanel(cardlayout);

   public Registration() {
      cards.add(createUserAgreePanel(), USER_AGREEMENT);
      cards.add(createUserInfoPanel(), USER_INFO);
      cards.add(createEnrollmentPanel(), ENROLLMENT);
      setLayout(new BorderLayout());
      add(cards, BorderLayout.CENTER);
   }

   @Override
   public Dimension getPreferredSize() {
      return PREF_SIZE;
   }

   private JPanel createEnrollmentPanel() {
      JPanel enrol = new JPanel();
      enrol.add(new JLabel("Enrollment"));
      return enrol;
   }

   private JPanel createUserAgreePanel() {
      JPanel userAgree = new JPanel();
      userAgree.add(new JLabel("User Agreement"));
      return userAgree;
   }

   private JPanel createUserInfoPanel() {
      JPanel userInfo = new JPanel();
      userInfo.add(new JLabel("User Information"));
      return userInfo;
   }

   public void swapView(String key) {
      cardlayout.show(cards, key);
   }

}
  

Затем внешний класс может поменять местами представления, просто вызвав swapView для визуализированного экземпляра этого класса, передав соответствующую ключевую строку, такую как в данном случае CardTest.USER_INFO, чтобы показать информацию о пользователе JPanel.

Теперь у вас проблема с этим фрагментом кода, на который я указываю с помощью комментария:

     jButtonAgree.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent e) {
            Registration reg = new Registration(); // **** HERE *****
            LayoutManager cards = reg.getCards().getLayout();
            ((CardLayout) cards).show(reg.getCards(),"step1");
        }
    });
  

В этой строке вы создаете новый объект регистрации, вероятно, тот, который совершенно не связан с тем, который визуализируется в графическом интерфейсе, и поэтому вызов методов для этого нового объекта не окажет абсолютно никакого влияния на просматриваемый в данный момент графический интерфейс. Вместо этого вам нужно получить ссылку на просматриваемый объект регистрации, возможно, предоставив этому классу метод getRegistration, а затем вызвать его методы, например:

 class OutsideClass {
   private Registration registration;
   private JButton jButtonAgree = new JButton("Agree");

   public OutsideClass() {
      jButtonAgree.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
            // make sure registration reference has been obtained first!
            if (registration != null) { 
               registration.swapView(Registration.USER_AGREEMENT);
            }
         }
      });
   }

   // here I allow the calling class to pass a reference to the visualized
   // Registration instance.
   public void setRegistration(Registration registration) {
      this.registration = registration;
   }
}
  

Например:

 @SuppressWarnings("serial")
class ButtonPanel extends JPanel {
   private Registration registration;

   public ButtonPanel() {
      setLayout(new GridLayout(1, 0, 10, 0));
      // go through String array making buttons
      for (final String keyText : Registration.KEY_TEXTS) {
         JButton btn = new JButton(keyText);
         btn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
               if (registration != null) {
                  registration.swapView(keyText);
               }
            }
         });
         add(btn);
      }
   }

   public void setRegistration(Registration registration) {
      this.registration = registration;
   }
}
  

и основной класс, который управляет всем этим

 class MainClass extends JPanel {
   public MainClass() {
      Registration registration = new Registration();
      ButtonPanel buttonPanel = new ButtonPanel();
      buttonPanel.setRegistration(registration);

      buttonPanel.setBorder(BorderFactory.createTitledBorder("Button Panel"));
      registration.setBorder(BorderFactory.createTitledBorder("Registration Panel"));

      setLayout(new BorderLayout());
      add(registration, BorderLayout.CENTER);
      add(buttonPanel, BorderLayout.SOUTH);
   }

   private static void createAndShowUI() {
      JFrame frame = new JFrame("Registration");
      frame.getContentPane().add(new MainClass());
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.pack();
      frame.setLocationRelativeTo(null);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      java.awt.EventQueue.invokeLater(new Runnable() {
         public void run() {
            createAndShowUI();
         }
      });
   }
}
  

Комментарии:

1. Это очень полезно! Большое вам спасибо! Эта проблема вызывала у меня сомнения уже много дней… ха-ха…

2. Хотелось бы, чтобы этому сообщению можно было дать больше баллов

3. Но что, если у меня есть моя JPanel, которая является отдельным файлом? Означает ли это, что я должен передавать cardsLayout или cards JPanel каждый раз, когда я создаю объект JPanel?