将空布局与卡片布局相结合[java]

将空布局与卡片布局相结合[java],java,swing,layout,cardlayout,Java,Swing,Layout,Cardlayout,我正在尝试将cardlayout函数与空布局结合起来。 但是,当我试图运行该程序时,它不起作用。按钮不会出现在我告诉他们的边界处。是我做错了什么,还是两者都用错了 public class CardLayoutTest extends JFrame { private static final long serialVersionUID = 1L; private JPanel cardPanel, jp1, jp2, buttonPanel; private JLabel jl1, jl2;

我正在尝试将cardlayout函数与空布局结合起来。 但是,当我试图运行该程序时,它不起作用。按钮不会出现在我告诉他们的边界处。是我做错了什么,还是两者都用错了

public class CardLayoutTest extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel cardPanel, jp1, jp2, buttonPanel;
private JLabel jl1, jl2;
private JButton btn1, btn2;
private CardLayout cardLayout = new CardLayout();

public CardLayoutTest() {
    setTitle("Test med CardLayout");
    setSize(400, 300);
    Insets insets = getInsets();
    cardPanel = new JPanel();
    buttonPanel = new JPanel();
    cardPanel.setLayout(cardLayout);
    jp1 = new JPanel();
    jp2 = new JPanel();
    jl1 = new JLabel("Card 1");
    jl2 = new JLabel("Card 2");
    jp1.add(jl1);
    jp2.add(jl2);
    cardPanel.add(jp1, "1");
    cardPanel.add(jp2, "2");
    btn1 = new JButton("Show Card 1");
    btn1.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            cardLayout.show(cardPanel, "1");
        }
    });
    btn2 = new JButton("Show Card 2");
    btn2.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            cardLayout.show(cardPanel, "2");
        }
    });
    buttonPanel.add(btn1);
    buttonPanel.add(btn2);
    add(cardPanel, BorderLayout.NORTH);
    add(buttonPanel, null);

    Dimension size1 = btn1.getPreferredSize();
    btn1.setBounds(100 + insets.left, 100 + insets.top,
                 size1.width, size1.height);

    Dimension size = btn2.getPreferredSize();
    btn2.setBounds(210 + insets.left, 130 + insets.top,
                 size.width, size.height);
}


public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            CardLayoutTest frame = new CardLayoutTest();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    });
}
}

我做错什么了吗

是的,假设
null
布局可以帮助您(但不了解
null
布局是什么,以及您需要从布局管理API接管的工作)

或者两者都使用的整个概念是错误的

public class CardLayoutTest extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel cardPanel, jp1, jp2, buttonPanel;
private JLabel jl1, jl2;
private JButton btn1, btn2;
private CardLayout cardLayout = new CardLayout();

public CardLayoutTest() {
    setTitle("Test med CardLayout");
    setSize(400, 300);
    Insets insets = getInsets();
    cardPanel = new JPanel();
    buttonPanel = new JPanel();
    cardPanel.setLayout(cardLayout);
    jp1 = new JPanel();
    jp2 = new JPanel();
    jl1 = new JLabel("Card 1");
    jl2 = new JLabel("Card 2");
    jp1.add(jl1);
    jp2.add(jl2);
    cardPanel.add(jp1, "1");
    cardPanel.add(jp2, "2");
    btn1 = new JButton("Show Card 1");
    btn1.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            cardLayout.show(cardPanel, "1");
        }
    });
    btn2 = new JButton("Show Card 2");
    btn2.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            cardLayout.show(cardPanel, "2");
        }
    });
    buttonPanel.add(btn1);
    buttonPanel.add(btn2);
    add(cardPanel, BorderLayout.NORTH);
    add(buttonPanel, null);

    Dimension size1 = btn1.getPreferredSize();
    btn1.setBounds(100 + insets.left, 100 + insets.top,
                 size1.width, size1.height);

    Dimension size = btn2.getPreferredSize();
    btn2.setBounds(210 + insets.left, 130 + insets.top,
                 size.width, size.height);
}


public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            CardLayoutTest frame = new CardLayoutTest();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    });
}
简言之,是的。99.99%的时候你认为你需要一个
null
布局,你不需要,甚至在0.01%的时候你“可能”,你可能不需要

那么,答案是什么?令人惊讶的是,使用合适的布局管理器,不要再担心“像素完美”的布局,它们只是一种幻觉。现代计算机系统运行在各种各样的硬件和软件上,这些硬件和软件改变了用户界面的各个方面,从而改变了组件需要交互或调整大小的方式

虽然您可能会考虑仅在一个操作系统上运行此功能,但即使如此,硬件和软件驱动程序以及操作设置也可以更改字体大小、字体度量和DPI,所有这些都会影响组件需要正确渲染的空间量

相反,关注UI的工作流程和可用性,以最大限度地提高用户体验

因此,基于我对您问题的(有限)理解,我在
按钮面板上使用了
GridBagLayout
,以“模拟”您的预期结果

布局管理器一开始可能有点难,但它们是非常强大的工具。我整个职业生涯都在使用所有内置的布局管理器、一个第三方布局和两个自定义布局管理器来解决特定问题。我从未觉得有必要回到
null
布局,我发现它们的局限性,它们需要大量的时间和工作来维护,而且通常都很懒惰

我做错什么了吗

是的,假设
null
布局可以帮助您(但不了解
null
布局是什么,以及您需要从布局管理API接管的工作)

或者两者都使用的整个概念是错误的

public class CardLayoutTest extends JFrame {

private static final long serialVersionUID = 1L;
private JPanel cardPanel, jp1, jp2, buttonPanel;
private JLabel jl1, jl2;
private JButton btn1, btn2;
private CardLayout cardLayout = new CardLayout();

public CardLayoutTest() {
    setTitle("Test med CardLayout");
    setSize(400, 300);
    Insets insets = getInsets();
    cardPanel = new JPanel();
    buttonPanel = new JPanel();
    cardPanel.setLayout(cardLayout);
    jp1 = new JPanel();
    jp2 = new JPanel();
    jl1 = new JLabel("Card 1");
    jl2 = new JLabel("Card 2");
    jp1.add(jl1);
    jp2.add(jl2);
    cardPanel.add(jp1, "1");
    cardPanel.add(jp2, "2");
    btn1 = new JButton("Show Card 1");
    btn1.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            cardLayout.show(cardPanel, "1");
        }
    });
    btn2 = new JButton("Show Card 2");
    btn2.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent e) {
            cardLayout.show(cardPanel, "2");
        }
    });
    buttonPanel.add(btn1);
    buttonPanel.add(btn2);
    add(cardPanel, BorderLayout.NORTH);
    add(buttonPanel, null);

    Dimension size1 = btn1.getPreferredSize();
    btn1.setBounds(100 + insets.left, 100 + insets.top,
                 size1.width, size1.height);

    Dimension size = btn2.getPreferredSize();
    btn2.setBounds(210 + insets.left, 130 + insets.top,
                 size.width, size.height);
}


public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {

        @Override
        public void run() {
            CardLayoutTest frame = new CardLayoutTest();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setVisible(true);
        }
    });
}
简言之,是的。99.99%的时候你认为你需要一个
null
布局,你不需要,甚至在0.01%的时候你“可能”,你可能不需要

那么,答案是什么?令人惊讶的是,使用合适的布局管理器,不要再担心“像素完美”的布局,它们只是一种幻觉。现代计算机系统运行在各种各样的硬件和软件上,这些硬件和软件改变了用户界面的各个方面,从而改变了组件需要交互或调整大小的方式

虽然您可能会考虑仅在一个操作系统上运行此功能,但即使如此,硬件和软件驱动程序以及操作设置也可以更改字体大小、字体度量和DPI,所有这些都会影响组件需要正确渲染的空间量

相反,关注UI的工作流程和可用性,以最大限度地提高用户体验

因此,基于我对您问题的(有限)理解,我在
按钮面板上使用了
GridBagLayout
,以“模拟”您的预期结果


布局管理器一开始可能有点难,但它们是非常强大的工具。我整个职业生涯都在使用所有内置的布局管理器、一个第三方布局和两个自定义布局管理器来解决特定问题。我从来没有觉得有必要退回到
null
布局,我发现它们的局限性,它们需要大量的时间和工作来维护,并且通常是懒惰的

Ahh,而不是
add(buttonPanel,null),可以尝试添加(按钮面板,BorderLayout.SOUTH)-在你跳下我的喉咙谈论
null
布局之前,我认为你需要了解
null
布局实际上是什么,因为这不是它,你还必须认识到容器将依赖它的子容器来提供适当的大小提示,而你的代码都没有这样做,因此,
buttonPanel
无法知道它需要多大才能满足孩子们的需求。这就是合适的布局、布局约束和边框的作用,而不是
add(buttonPanel,null),可以尝试添加(按钮面板,BorderLayout.SOUTH)-在你跳下我的喉咙谈论
null
布局之前,我认为你需要了解
null
布局实际上是什么,因为这不是它,你还必须认识到容器将依赖它的子容器来提供适当的大小提示,而你的代码都没有这样做,因此,
buttonPanel
无法知道它需要多大才能满足孩子们的需求。这就是合适的布局、布局约束和边框的作用。感谢您的帮助!然后我会对GridBagLayouts做更多的研究。谢谢你的帮助!然后我会对GridBagLayouts做更多的研究。