【发布时间】:2014-05-27 05:30:56
【问题描述】:
好吧,我在每张卡上制作了不同尺寸的 CardLayout 时遇到了一些麻烦。
在阅读The Use of Multiple JFrames: Good or Bad Practice? 之后,我注意到我做事的方式不合时宜,所以我决定开始学习如何使用CardLayout
我尝试过来自@HovercraftFullOfEels 的this answer
This one 来自@mKorbel
最后是@Kleopatra 的answer
所有这些都是基于 Hovercraft 的答案,但有一些变化。我能够创建 CardLayout(但仍然对此感到困惑),并且我(以某种方式)可以实现 Kleopatra 的方法,它调整了框架的大小,但不是应该的,当复制和粘贴代码时,你会注意到它减少了框架的大小只有几毫米(或像素)。
我不确定这是否与我正在使用的布局管理器有关,或者是因为我没有以正确的方式使用 Kleopatra 的方法,因为我也不知道 @Override 方法是如何工作的全部或何时使用,何时不使用。
这是一个 MCVE(我能做的最短的)。
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
public class PageViewer extends CardLayout{
private static final String loginCard = "login";
private static final String userCard = "createUser";
JFrame frame;
JPanel contentPane;
CardLayout cardLayout;
@Override
public Dimension preferredLayoutSize(Container parent) {
Component current = findCurrentComponent(parent);
if (current != null) {
Insets insets = parent.getInsets();
Dimension pref = current.getPreferredSize();
pref.width += insets.left + insets.right;
pref.height += insets.top + insets.bottom;
return pref;
}
return super.preferredLayoutSize(parent);
}
public Component findCurrentComponent(Container parent) {
for (Component comp : parent.getComponents()) {
if (comp.isVisible()) {
return comp;
}
}
return null;
}
public void createAndShowUI() {
frame = new JFrame("Welcome");
cardLayout = new CardLayout();
contentPane = new JPanel(cardLayout);
LoginPage lp = new LoginPage();
CreateUser cu = new CreateUser();
lp.register.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e){
createNewUser();
frame.pack();
}
});
contentPane.add(lp, loginCard);
contentPane.add(cu, userCard);
frame.add(contentPane, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocation(150, 150);
frame.pack();
frame.setResizable(false);
frame.setVisible(true);
}
PageViewer() {
createAndShowUI();
}
public void createNewUser() {
cardLayout.show(contentPane, userCard);
}
public static void main(String[] args) {
new PageViewer();
}
public class LoginPage extends JPanel {
Image image;
ImageIcon imageIcon;
JPanel userPanel;
JPanel passwordPanel;
JPanel buttonsPanel;
JPanel fieldsPanel;
JFrame frame;
JLabel usernameLabel;
JLabel passwordLabel;
JLabel logo;
JTextField usernameField;
JPasswordField passwordField;
JButton login;
JButton register;
public LoginPage() {
image = Toolkit.getDefaultToolkit().getImage("image.jpg");
imageIcon = new ImageIcon("image.jpg");
userPanel = new JPanel();
passwordPanel = new JPanel();
buttonsPanel = new JPanel();
fieldsPanel = new JPanel();
usernameLabel = new JLabel("username:");
passwordLabel = new JLabel("password:");
logo = new JLabel(imageIcon);
usernameField = new JTextField();
passwordField = new JPasswordField();
login = new JButton("Login");
register = new JButton("Register");
this.setLayout(new BorderLayout(10, 15));
this.setBorder(new EmptyBorder(10, 10, 10, 10));
fieldsPanel.setLayout(new BorderLayout());
usernameField.setColumns(8);
passwordField.setColumns(8);
userPanel.add(usernameLabel);
userPanel.add(usernameField);
passwordPanel.add(passwordLabel);
passwordPanel.add(passwordField);
fieldsPanel.add(userPanel, BorderLayout.CENTER);
fieldsPanel.add(passwordPanel, BorderLayout.SOUTH);
buttonsPanel.add(login);
buttonsPanel.add(register);
this.add(logo, BorderLayout.NORTH);
this.add(fieldsPanel, BorderLayout.CENTER);
this.add(buttonsPanel, BorderLayout.SOUTH);
}
}
public class CreateUser extends JPanel {
JPanel userPanel;
JPanel passPanel;
JPanel repPassPanel;
JPanel buttonsPanel;
JPanel fieldsPanel;
JLabel username;
JLabel password;
JLabel repPassword;
JTextField userField;
JPasswordField passField;
JPasswordField repPassField;
JButton acceptButton;
JButton cancelButton;
public CreateUser() {
userPanel = new JPanel();
passPanel = new JPanel();
repPassPanel = new JPanel();
buttonsPanel = new JPanel();
fieldsPanel = new JPanel();
username = new JLabel("username: ");
password = new JLabel("password: ");
repPassword = new JLabel("repeat password: ");
userField = new JTextField();
passField = new JPasswordField();
repPassField = new JPasswordField();
acceptButton = new JButton("Accept");
cancelButton = new JButton("Cancel");
userField.setColumns(8);
passField.setColumns(8);
repPassField.setColumns(8);
userPanel.add(username);
userPanel.add(userField);
passPanel.add(password);
passPanel.add(passField);
repPassPanel.add(repPassword);
repPassPanel.add(repPassField);
buttonsPanel.add(acceptButton);
buttonsPanel.add(cancelButton);
fieldsPanel.setLayout(new BoxLayout(fieldsPanel, BoxLayout.Y_AXIS));
this.setLayout(new BorderLayout(10, 15));
this.setBorder(new EmptyBorder(10, 10, 10, 10));
fieldsPanel.add(userPanel);
fieldsPanel.add(passPanel);
fieldsPanel.add(repPassPanel);
this.add(fieldsPanel, BorderLayout.CENTER);
this.add(buttonsPanel, BorderLayout.SOUTH);
}
}
}
所以,继续(并添加了一些我在进行 MCVE 时想到的问题):
- 为什么框架没有按预期调整大小?
- 我是否使用了正确的布局管理器?
-
是我的
lp.register.addActionListener(...还是我这样做 难吗?
提前致谢:)
【问题讨论】:
-
尝试颠倒调用
frame.pack();、frame.setResizable(false);,以便首先调用setResizable...无需扩展CardLayout -
@MadProgrammer 好的,我会成功并返回结果,顺便说一句,我扩展它只是为了能够使用 Kleopatra 的方法,因为我无法称它为超级方法。但感谢您的建议。
-
@MadProgrammer 即使通过反向调用仍然无法解决问题。
-
你确实知道你在调用时实际上并没有使用
PageViewer布局,所以preferredLayoutSize没有被调用
标签: java swing layout layout-manager cardlayout