Java Swing边框布局的调整困难

5
我希望将屏幕分成两部分,因此我使用了一个具有东部和西部部分的边框布局(BorderLayout)。但我在调整大小时遇到了问题。最终我在这里找到了答案:http://www.leepoint.net/GUI/layouts/20borderlayout.html。我发现东部和西部面板的宽度不会改变,而北部和南部面板的高度也不会改变,只有中心面板的宽度和高度都会改变。
然而,我希望在调整大小时宽度和高度都能改变,并且将两个面板并排放置。我尝试了各种嵌套级别来尝试让它工作,但我认为它在边框布局中无法实现。
这似乎对于默认的布局管理器来说应该很容易,但也许我应该尝试不同的布局(例如BoxLayout)来实现我想要的效果。
此外,以下是一些代码,可以复制出现我所说的问题(尝试调整窗口大小)。
import java.awt.BorderLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Main extends JFrame {

    public static void main(String[] args) {
        JFrame window = new Main();
        window.setVisible(true);
    }

    public Main() {
        JButton east = new JButton("East");
        JButton west = new JButton("West");

        JPanel content = new JPanel();
        content.setLayout(new BorderLayout());

        content.add(east, BorderLayout.EAST);
        content.add(west, BorderLayout.WEST);

        setContentPane(content);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }

}

编辑:我不希望两边相等,大致的比例是2:1。


1
如果你只想把它分成两部分,为什么不使用GridLayout呢? - Sednus
4个回答

8
你可以在这种情况下使用GridLayout,在这里两个JButtons将会随着JFrame的调整而自动调整大小。
import java.awt.GridLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame window = new Main();
                window.setVisible(true);
            }
        });        
    }

    public Main() {
        JButton east = new JButton("East");
        JButton west = new JButton("West");

        JPanel content = new JPanel();
        content.setLayout(new GridLayout(1, 2));

        content.add(east);
        content.add(west);

        setContentPane(content);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }

}

此外,最好从EDT - 事件分派线程而不是主线程运行与GUI相关的代码。请阅读Swing中的并发性,了解更多信息。 最新编辑:根据请求的评论 使用GridBagLayout指定要提供的大小。
import java.awt.Color;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Main extends JFrame {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                JFrame window = new Main();
                window.setVisible(true);
            }
        });        
    }

    public Main() {
        JPanel east = new JPanel();
        east.setOpaque(true);
        east.setBackground(Color.WHITE);
        JPanel west = new JPanel();
        west.setOpaque(true);
        west.setBackground(Color.BLUE);

        JPanel content = new JPanel();
        content.setLayout(new GridBagLayout());

        GridBagConstraints gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.weightx = 0.3;
        gbc.weighty = 1.0;
        gbc.gridx = 0;
        gbc.gridy = 0;

        content.add(east, gbc);
        gbc.weightx = 0.7;
        gbc.gridx = 1;
        content.add(west, gbc);

        setContentPane(content);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        pack();
    }

}

谢谢您的建议。然而,我之前没有提到的是,我不想让两边相等。GridLayout还能做到吗? - Paul
你需要使用GridBagLayout来实现这个功能,它可以通过约束条件来自由定义JComponents的大小。请稍等,我会给你提供一个例子 :-) - nIcE cOw
现在看这个编辑,我希望这就是你所说的大小不相等。 - nIcE cOw

8

为什么不尝试使用JSplitPane

import javax.swing.*;
import java.awt.*;

public class AppDemo {

    public static void main(String[] args) {

        SwingUtilities.invokeLater(() -> {
            JFrame frame = new JFrame();
            JButton eastButton = new JButton("East");
            JButton westButton = new JButton("West");
            JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, eastButton, westButton);

            JPanel content = new JPanel();
            content.setLayout(new BorderLayout());
            content.add(splitPane, BorderLayout.CENTER);

            frame.setContentPane(content);
            frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            frame.setPreferredSize(new Dimension(500, 400));
            frame.pack();
            frame.setVisible(true);
        });

    }
}

你将会得到这个:

在此输入图片描述


非常欢迎您,保持微笑 :-) - nIcE cOw
谢谢。这也是我在寻找的,但我更喜欢没有中间的条形。虽然我可能仍会使用它。 - Paul
您可以创建2个面板和按钮。然后为这些面板调用setPreferredSize()方法(eastPanel.setPreferredSize(new Dimension(250,400))和westPanel.setPreferredSize(new Dimension(250,400)),并将它们添加到JSplitPane中。 - Branislav Lazic

1
如果您想保留您的BorderLayout布局,可以使用以下对象:

如果你想保持你的BorderLayout你可以使用以下对象:

public class ResizablePanel extends JPanel {

  public ResizablePanel(JComponent body) {

    setLayout(new BorderLayout());
    JButton resize = new JButton();
    resize.setPreferredSize(new Dimension(Integer.MAX_VALUE, 4));
    resize.addMouseMotionListener(new MouseAdapter() {
        public void mouseDragged(MouseEvent e) {
            Dimension preferredSize = ResizablePanel.this.getPreferredSize();
            ResizablePanel.this.setPreferredSize(new Dimension(preferredSize.width, preferredSize.height-e.getY()));
            ResizablePanel.this.revalidate();
        }
    });             
    add(resize, BorderLayout.PAGE_START);
    add(body, BorderLayout.CENTER);
  }
}

现在,将您想要调整大小的部分用 ResizablePanel 的实例包装起来,然后您就可以通过拖动细按钮来调整其大小。
请注意,此代码是用于调整放置在边框布局底部(PAGE_END)部分的面板的高度,但更改宽度应该相当简单。

0
抱歉回复旧帖子。 我的解决方法是仍然使用BorderLayout,但在组件调整大小后加入以下行:
getLayout().layoutContainer(this);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接