#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?