【问题标题】:How can I align elements in JPanels / JFrames?如何对齐 JPanels / JFrames 中的元素?
【发布时间】:2013-02-02 06:56:51
【问题描述】:

我对在 java 中使用 GUI 完全陌生,所以在弄清楚如何对齐我需要的所有内容时遇到了一些麻烦。我必须在我的 JFrame 中对齐需要对齐的面板(一个向左,一个向右)和一个面板中的几个按钮,我需要在面板中居中。这是我的代码。

package application;

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.io.*;
import java.nio.*;
import java.util.*;

public class Main extends JPanel 
{
    public static void main(String[] args)
    { 
        //set the ui to the native OS
        try
        { 
            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        }catch(ClassNotFoundException | InstantiationException | IllegalAccessException 
        | UnsupportedLookAndFeelException e)                                   
        {
        }

        JFrame frame = new JFrame("Application Name");
        Menu menu = new Menu();
        JPanel iconPanel = new JPanel();
        final JPanel grid = new JPanel(new FlowLayout());
        JButton firewallButton = new JButton("Firewall");
        JButton networkButton = new JButton("Network");
        JButton printerButton = new JButton("Printer");

        int iconPanelSizeX;
        int iconPanelSizeY;
        int gridSizeX;
        int gridSizeY;
        int gridPosition;

        //frame setting
        frame.setSize(800, 600);
        frame.setMinimumSize(new Dimension(800, 600));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);

        //add grid and iconPanel JPanels to the frame
        frame.add(iconPanel);
        iconPanel.add(firewallButton);
        iconPanel.add(networkButton);
        iconPanel.add(printerButton);
        frame.add(grid);        

        //iconPanel settings
        iconPanel.setBorder(BorderFactory.createLoweredSoftBevelBorder());
        iconPanel.setBackground(Color.gray);
        iconPanel.setLayout(new FlowLayout());
        iconPanel.setSize(new Dimension(100, 600));
        iconPanel.setVisible(true);

        //grid setting
        grid.setBackground(Color.red);
        grid.setSize(new Dimension(700, 600));
        grid.setVisible(true);

        //this is for resizing components when the user resizes the window
        int counter = 0;
        while(counter == 0)
        {
            firewallButton.setSize(new Dimension(iconPanel.getWidth(), 50));
            networkButton.setSize(new Dimension(iconPanel.getWidth(), 50));
            printerButton.setSize(new Dimension(iconPanel.getWidth(), 50));
            iconPanelSizeX = frame.getWidth() / 10;
            iconPanelSizeY = frame.getHeight();
            gridSizeX = (frame.getWidth() / 10) * 9;
            gridSizeY = frame.getHeight();
            iconPanel.setSize(new Dimension(iconPanelSizeX, iconPanelSizeY));
            grid.setSize(new Dimension(gridSizeX, gridSizeY));
        }
    }
}

如您所见,第二个 JPanel(网格)没有与框架的右侧对齐,并且 iconTray 内的按钮也不居中。我意识到这些可能都是简单的布局修复,但我不知道从哪里开始。

【问题讨论】:

    标签: java swing jframe jpanel layout-manager


    【解决方案1】:

    对于JFrame 的简单拆分,您可以使用GridLayout 1 行和2 列。

    frame.setLayout(new GridLayout(1,2,3,3)); //3,3 are gaps
    frame.add(grid);
    frame.add(iconPanel);
    

    为了使面板中的组件居中,您可以使用FlowLayout,默认情况下设置为JPanels

    手动操作:

    grid.setLayout(new FlowLayout()); //Centered components
    
    grid.setLayout(new FlowLayout(FlowLayout.LEFT,3,3)); //Components aligned to left
    
    grid.setLayout(new FlowLayout(FlowLayout.RIGHT,3,3)); //Components aligned to right
    

    看起来是这样的:

    另外,很少有观察:

    • 永远不要为您的组件调用 setXXXSize() 方法;

    • 尽量避免为JFrame调用setSize();,而是调用pack();

    • 在代码末尾调用setVisible(true);

    你所有的大代码都可以“剥离”到这个:

    import javax.swing.*;
    import java.awt.*;
    
    
    public class Main extends JPanel
    {
        public static void main(String[] args)
        {
            JFrame frame = new JFrame("Application Name");
            JPanel iconPanel = new JPanel();
            JPanel grid = new JPanel(new FlowLayout());
            JButton firewallButton = new JButton("Firewall");
            JButton networkButton = new JButton("Network");
            JButton printerButton = new JButton("Printer");
    
    
            frame.add(iconPanel);
            iconPanel.add(firewallButton);
            iconPanel.add(networkButton);
            iconPanel.add(printerButton);
            grid.setBackground(Color.GREEN);
    
            frame.setLayout(new GridLayout(1,2,3,3));
            frame.add(grid);
            frame.add(iconPanel);
    
    
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    【讨论】:

    • 谢谢,这帮助很大。实际上有一件事我忘了问,那就是如何垂直对齐按钮 - 我必须稍后添加一些。
    • 您将不得不使用其他一些布局管理器。对于非常基本的对齐方式,您可以使用GridLayoutBoxLayout,但对于更复杂的情况,我建议使用GridBadLayoutMiGLayout。谷歌一下。
    【解决方案2】:

    如何垂直对齐按钮?

    此示例在框架默认BorderLayoutWEST 区域中使用垂直Box

    import java.awt.*;
    import javax.swing.*;
    
    /** @see http://stackoverflow.com/a/14927280/230513 */
    public class Main {
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    display();
                }
            });
        }
    
        private static void display() throws HeadlessException {
            JFrame frame = new JFrame("Application Name");
            JButton firewallButton = new JButton("Firewall");
            JButton networkButton = new JButton("Network");
            JButton printerButton = new JButton("Printer");
    
            //iconPanel settings
            Box iconPanel = new Box(BoxLayout.Y_AXIS);
            iconPanel.add(firewallButton);
            iconPanel.add(networkButton);
            iconPanel.add(printerButton);
            iconPanel.setBackground(Color.gray);
            iconPanel.setVisible(true);
            frame.add(iconPanel, BorderLayout.WEST);
    
            //grid setting
            JPanel grid = new JPanel() {
    
                @Override
                // arbitrary placeholder size
                public Dimension getPreferredSize() {
                    return new Dimension(320, 230);
                }
            };
            grid.setBackground(Color.red);
            frame.add(grid, BorderLayout.CENTER);
    
            //frame setting
            frame.pack();
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    

    【讨论】:

    【解决方案3】:

    我建议您花点时间浏览一下A Visual Guide to Layout Managers。这将帮助您熟悉标准 API 提供的布局管理器。需要一些经验和努力才能确定其中哪一个是获得您想要的确切外观的正确工具。一旦您对标准 API 提供的功能感到满意后,您还应该四处寻找提供其他选项的第三方布局管理器 API。

    【讨论】:

      【解决方案4】:

      我必须在我的 JFrame 中对齐需要对齐的面板(一个向左, 一个到右边)和我需要的面板之一中的几个按钮 在面板中居中。这是我的代码。

      我意识到这些可能都是简单的布局修复,但我没有 提示从哪里开始。

      使用比您实际使用的简单FlowLayout 更复杂的布局。我建议你使用

      • GridBagLayout
      • BoxLayout

      查看references here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-07-31
        • 2021-01-03
        • 1970-01-01
        • 2021-09-18
        • 2023-01-30
        相关资源
        最近更新 更多