如何从另一个面板更改卡布局面板?

时间:2011-05-30 11:50:02

标签: java swing layout cardlayout

我用Google搜索了很多内容,但未找到任何解决方案。我想应该有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;
}


这是另一个步骤0 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 个答案:

答案 0 :(得分:19)

所有这些都是关于将正确的方法和常量字符串暴露给外部世界以允许类交换视图本身。例如,为您的第一个类提供一个名为cardlayout的私有CardLayout字段和一个名为cards的私有JPanel字段(持卡人JPanel),以及一些用于将您的卡JPanel添加到卡容器的公共String常量。同时给它一个公共方法,比如称为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");
        }
    });

在那一行你要创建一个新的Registration对象,可能与GUI上可视化的对象完全无关,因此对这个新对象的调用方法对当前查看的gui完全没有影响。你需要获得对查看的Registration对象的引用,可能是给这个类一个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;
   }
}

和驱动这一切的MainClass

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