【问题标题】:CardLayout with different sizes不同尺寸的 CardLayout
【发布时间】: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 时想到的问题):

  1. 为什么框架没有按预期调整大小?
  2. 我是否使用了正确的布局管理器?
  3. 是我的 lp.register.addActionListener(... 还是我这样做 难吗?

提前致谢:)

【问题讨论】:

  • 尝试颠倒调用frame.pack();frame.setResizable(false);,以便首先调用setResizable...无需扩展CardLayout
  • @MadProgrammer 好的,我会成功并返回结果,顺便说一句,我扩展它只是为了能够使用 Kleopatra 的方法,因为我无法称它为超级方法。但感谢您的建议。
  • @MadProgrammer 即使通过反向调用仍然无法解决问题。
  • 你确实知道你在调用时实际上并没有使用PageViewer布局,所以preferredLayoutSize没有被调用

标签: java swing layout layout-manager cardlayout


【解决方案1】:

切换packsetResizable 调用。 setResizable 会在某些系统上改变框架的边框大小,所以而不是

frame.setResizable(false);
frame.pack();

你应该使用...

frame.pack();
frame.setResizable(false);

调用之间的区别示例...

您可能还想实际使用PageViewer 布局管理器...

cardLayout = new PageViewer();

现在,UI 不应像您拥有的那样包含在布局管理器中,它们应该分开,例如...

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Image;
import java.awt.Insets;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;

public class CardLayoutTest {

    private static final String loginCard = "login";
    private static final String userCard = "createUser";

    private JFrame frame;
    private CardLayout cardLayout;
    private JPanel contentPane;

    public static void main(String[] args) {
        new CardLayoutTest();
    }

    public CardLayoutTest() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                }

                createAndShowUI();
            }
        });
    }

    public void createAndShowUI() {
        frame = new JFrame("Welcome");
        cardLayout = new PageViewer();
        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.setResizable(false);
        frame.pack();
        frame.setVisible(true);
    }

    public void createNewUser() {
        cardLayout.show(contentPane, userCard);
    }

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

    public class PageViewer extends 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;
        }
    }
}

【讨论】:

  • 其实问题是在单击“注册按钮”时出现的。该页面应该有上面的图像,因此问题更加明显。尝试使用image.jpg 名称复制 jpg 图像,它应该让您更好地了解我在说什么。确实,我也会将 SS 附加到问题中。
  • @Frakcool ps- 作为用户,突然的帧大小变化真的会让我很烦,只是说;)
  • 是的,我正在看。
  • 我正在调整框架的大小,因为它会在用户登录后有一个菜单窗口,以及一个JTable,它就像一个比登录页面大的 LOOOOOT。它的大小是1350 x 700,所以它是一个巨大的东西。这就是我使用框架调整大小的原因。无论如何谢谢你:) 我会检查更新的代码
  • 您可以考虑在登录屏幕上使用JDialogJOptionPane,但无论如何它都适合您 ;)
猜你喜欢
  • 2020-12-26
  • 2015-02-28
  • 1970-01-01
  • 2016-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-09
相关资源
最近更新 更多