重点在于向外界公开正确的方法和常量字符串,使得该类可以自行切换视图。例如,给你的第一个类一个称为cardlayout的私有CardLayout字段和一个称为cards(卡片持有者JPanel)的私有JPanel字段,并提供一些公共的字符串常量,用于将您的卡片JPanel添加到cards容器中。还要给它一个名为public void swapView(String key)
的公共方法,允许外部类交换卡片...就像这样:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Registration extends JPanel {
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";
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();
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) {
if (registration != null) {
registration.swapView(Registration.USER_AGREEMENT);
}
}
});
}
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));
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();
}
});
}
}