Cung cấp khoảng trắng trong GUI GUI


161

Một GUI không có khoảng trắng xuất hiện 'đông đúc'. Làm cách nào tôi có thể cung cấp khoảng trắng mà không cần dùng đến việc đặt rõ ràng vị trí hoặc kích thước của các thành phần?



1
sử dụng một Trình quản lý bố cục hỗ trợ các khoảng trống về mặt ngữ nghĩa. Bạn nhìn thấy nó đến, phải không :-) MigLayout để giải cứu: bạn xác định một mạng lưới và những khoảng trống ở giữa như liên quan, không liên quan, đoạn - aftet rằng chỉ cần thêm các thành phần
Kleopatra

Câu trả lời:


111

Sử dụng nhiều LayoutManagersngười có thể cung cấp khoảng cách giữa các thành phần khác nhau.

1.) Biên giới:

2.) Lưu lượng truy cập:

3.) GridLayout:

4.) GridBagLayout:

GridBagConstraint.insets

5.) CardLayout ( ví dụ ):

CardLayout (int hGap, int vGap)

Ví dụ để hiển thị tất cả các hàm tạo đang hoạt động:

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

public class LayoutExample {

    private final int hGap = 5;
    private final int vGap = 5;

    private String[] borderConstraints = {
        BorderLayout.PAGE_START,
        BorderLayout.LINE_START,
        BorderLayout.CENTER,
        BorderLayout.LINE_END,
        BorderLayout.PAGE_END
    };

    private JButton[] buttons;

    private GridBagConstraints gbc;

    private JPanel borderPanel;
    private JPanel flowPanel;
    private JPanel gridPanel;
    private JPanel gridBagPanel;
    private JPanel cardPanel;

    public LayoutExample() {
        buttons = new JButton[16];
        gbc = new GridBagConstraints();
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;   
        gbc.insets = new Insets(hGap, vGap, hGap, vGap);        
    }

    private void displayGUI() {
        JFrame frame = new JFrame("Layout Example");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

        JPanel contentPane = new JPanel(
                        new GridLayout(0, 1, hGap, vGap));
        contentPane.setBorder(
            BorderFactory.createEmptyBorder(hGap, vGap, hGap, vGap));
        borderPanel = new JPanel(new BorderLayout(hGap, vGap));
        borderPanel.setBorder(
            BorderFactory.createTitledBorder("BorderLayout"));
        borderPanel.setOpaque(true);
        borderPanel.setBackground(Color.WHITE);
        for (int i = 0; i < 5; i++) {
            buttons[i] = new JButton(borderConstraints[i]);
            borderPanel.add(buttons[i], borderConstraints[i]);
        }
        contentPane.add(borderPanel);

        flowPanel = new JPanel(new FlowLayout(
                    FlowLayout.CENTER, hGap, vGap));
        flowPanel.setBorder(
            BorderFactory.createTitledBorder("FlowLayout"));
        flowPanel.setOpaque(true);
        flowPanel.setBackground(Color.WHITE);
        for (int i = 5; i < 8; i++) {
            buttons[i] = new JButton(Integer.toString(i));
            flowPanel.add(buttons[i]);
        }
        contentPane.add(flowPanel);

        gridPanel = new JPanel(new GridLayout(2, 2, hGap, vGap));
        gridPanel.setBorder(
            BorderFactory.createTitledBorder("GridLayout"));
        gridPanel.setOpaque(true);
        gridPanel.setBackground(Color.WHITE);
        for (int i = 8; i < 12; i++) {
            buttons[i] = new JButton(Integer.toString(i));
            gridPanel.add(buttons[i]);
        }
        contentPane.add(gridPanel);

        gridBagPanel = new JPanel(new GridBagLayout());
        gridBagPanel.setBorder(
            BorderFactory.createTitledBorder("GridBagLayout"));
        gridBagPanel.setOpaque(true);
        gridBagPanel.setBackground(Color.WHITE);
        buttons[12] = new JButton(Integer.toString(12));
        addComp(gridBagPanel, buttons[12], 0, 0, 1, 1
                            , GridBagConstraints.BOTH, 0.33, 0.5);
        buttons[13] = new JButton(Integer.toString(13));
        addComp(gridBagPanel, buttons[13], 1, 0, 1, 1
                            , GridBagConstraints.BOTH, 0.33, 0.5);
        buttons[14] = new JButton(Integer.toString(14));
        addComp(gridBagPanel, buttons[14], 0, 1, 2, 1
                            , GridBagConstraints.BOTH, 0.66, 0.5);
        buttons[15] = new JButton(Integer.toString(15));
        addComp(gridBagPanel, buttons[15], 2, 0, 1, 2
                            , GridBagConstraints.BOTH, 0.33, 1.0);
        contentPane.add(gridBagPanel);

        cardPanel = new JPanel(new CardLayout(hGap, vGap));
        cardPanel.setBorder(
            BorderFactory.createTitledBorder("CardLayout"));
        cardPanel.setOpaque(true);
        cardPanel.setBackground(Color.WHITE);
        cardPanel.add(getPanel(Color.BLUE));
        cardPanel.add(getPanel(Color.GREEN));
        contentPane.add(cardPanel);

        frame.setContentPane(contentPane);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }

    private JPanel getPanel(Color bColor) {
        JPanel panel = new JPanel(new FlowLayout(
                    FlowLayout.CENTER, hGap, vGap));
        panel.setOpaque(true);
        panel.setBackground(bColor.darker().darker());
        JButton swapperButton = new JButton("Next");
        swapperButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent ae) {
                CardLayout cardLayout = (CardLayout) cardPanel.getLayout();
                cardLayout.next(cardPanel);
            }
        });

        panel.add(swapperButton);

        return panel;
    }

    private void addComp(JPanel panel, JComponent comp
                                , int x, int y, int gWidth
                                    , int gHeight, int fill
                                        , double weightx, double weighty) {
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = gWidth;
        gbc.gridheight = gHeight;
        gbc.fill = fill;
        gbc.weightx = weightx;
        gbc.weighty = weighty;      

        panel.add(comp, gbc);
    }

    public static void main(String[] args) {
        Runnable runnable = new Runnable(){
            @Override
            public void run() {
                new LayoutExample().displayGUI();
            }
        };
        EventQueue.invokeLater(runnable);
    }
}

ĐẦU RA:

LAYOUTIMAGE


6
+1 Tôi luuuuuv cho tôi một số phần tử GridBagConstraint. Chúng tôi sử dụng GBL rất nhiều, vì vậy tôi đã viết một số lớp trợ giúp thực hiện công việc bẩn thỉu cho tôi để mã GBL khá ngắn gọn và dễ đọc. Giống như mẫu ở đây, tôi sử dụng một Insets mặc định để tôi không phải gõ nó mọi lúc và giao diện kết quả là bố cục "thoải mái" hơn.
bắn tung tóe

63

Có một số cách trong GUI GUI để phân tách giữa các thành phần và khoảng trắng xung quanh các thành phần:

Nhưng nói chung, hãy nhìn vào:

  • Khoảng cách như có thể được xác định trong các nhà xây dựng bố trí.
  • Biên giới.

Dưới đây là một ví dụ về việc sử dụng dấu tách hGap& vGapgiá trị & đường viền bố cục (cụ thể là một EmptyBorder) để cung cấp không gian 'trắng' (thực sự được hiển thị là màu đỏ để làm cho nó rất rõ ràng). Điều chỉnh các spinners để xem kết quả.

Không có khoảng trắng GUI

Với không gian trắng GUI

import java.awt.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.event.*;

public class WhiteSpace {

    private JPanel gui = null;
    private BorderLayout mainLayout = 
        new BorderLayout(0, 0);
    private final FlowLayout buttonLayout = 
            new FlowLayout(FlowLayout.CENTER, 0, 0);
    private final JPanel buttonPanel = new JPanel(buttonLayout);
    private final SpinnerNumberModel hModel = 
            new SpinnerNumberModel(0, 0, 15, 1);
    private final SpinnerNumberModel vModel = 
            new SpinnerNumberModel(0, 0, 15, 1);
    private final SpinnerNumberModel hBorderModel = 
            new SpinnerNumberModel(0, 0, 15, 1);
    private final SpinnerNumberModel vBorderModel = 
            new SpinnerNumberModel(0, 0, 15, 1);
    private ChangeListener changeListener;

    public Container getGui() {
        if (gui == null) {
            gui = new JPanel(mainLayout);
            gui.setBackground(Color.RED);

            JTree tree = new JTree();
            tree.setVisibleRowCount(10);
            for (int ii = tree.getRowCount(); ii > -1; ii--) {
                tree.expandRow(ii);
            }
            gui.add(new JScrollPane(
                    tree,
                    JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                    JScrollPane.HORIZONTAL_SCROLLBAR_NEVER),
                    BorderLayout.LINE_START);
            gui.add(new JScrollPane(new JTextArea(10, 30)));

            gui.add(buttonPanel, BorderLayout.PAGE_START);

            changeListener = (ChangeEvent e) -> {
                int hGap = hModel.getNumber().intValue();
                int vGap = vModel.getNumber().intValue();
                int hBorder = hBorderModel.getNumber().intValue();
                int vBorder = vBorderModel.getNumber().intValue();
                adjustWhiteSpace(hGap, vGap, hBorder, vBorder);
            };

            addModel("H Gap", hModel);
            addModel("V Gap", vModel);
            addModel("H Border", hBorderModel);
            addModel("V Border", vBorderModel);
        }

        return gui;
    }

    private void addModel(String label, SpinnerNumberModel model) {
        buttonPanel.add(new JLabel(label));
        final JSpinner spinner = new JSpinner(model);
        spinner.addChangeListener(changeListener);
        buttonPanel.add(spinner);
    }

    private void adjustWhiteSpace(
            int hGap, int vGap, int hBorder, int vBorder) {
        mainLayout.setHgap(hGap);
        mainLayout.setVgap(vGap);
        buttonLayout.setHgap(hGap);
        gui.setBorder(new EmptyBorder
                (vBorder, hBorder, vBorder, hBorder));
        Container c = gui.getTopLevelAncestor();
        if (c instanceof Window) {
            Window w = (Window) c;
            w.pack();
        }
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            WhiteSpace ws = new WhiteSpace();
            Container gui1 = ws.getGui();
            JFrame f = new JFrame("White (OK Red) Space");
            f.add(gui1);
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setLocationByPlatform(true);
            f.setResizable(false);
            f.pack();
            f.setVisible(true);
        };
        SwingUtilities.invokeLater(r);
    }
}

20

Khi bạn sử dụng BoxLayout, Box.createVerticalGlue()phương thức có thể giúp bạn tạo một số khoảng trắng.

Một phương pháp khác là BorderFactory.createEmptyBorder(int top, int left, int bottom, int right). Nó có thể giúp bạn tạo một số khoảng trắng xung quanh thành phần.

Cảm ơn lời nhắc của Andrew Thompson. Tôi đã sửa đổi BoxLayout trong những ngày gần đây và tôi thấy rằng Box.createVerticalGlue()có thể thêm một số khoảng trắng tùy thuộc vào kích thước của bảng điều khiển và bạn không thể đặt giá trị pixel rõ ràng về độ dài của khoảng trắng. Nhưng Box.createVerticalStrut()có thể làm điều đó. Dưới đây là một MCTaRE và cho thấy hiệu quả của hai phương pháp đó.

nhập mô tả hình ảnh ở đây

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

public class WhiteSpace extends JFrame{
    static WhiteSpace whiteSpace;
    DemoPanel demoPanel;
    boolean withGlue;
    JSpinner spinner;

    public WhiteSpace(){
        initialWindow();
        demoPanel = new DemoPanel();
        ActionPanel actionPanel = new ActionPanel();

        setLayout(new BorderLayout());

        getContentPane().add(actionPanel,BorderLayout.NORTH);
        getContentPane().add(demoPanel,BorderLayout.CENTER);
            setVisible(true);
    }

    public void initialWindow(){
        setSize(220, 300);
        setTitle("White Space");
        setResizable(false);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        //Show the window in the middle of the screen
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        Runnable runnable = new Runnable() {
            @Override
            public void run() {
                whiteSpace = new WhiteSpace();
            }
        };
        SwingUtilities.invokeLater(runnable);
    }

    class DemoPanel extends JPanel{
        //Show the vertical white space between label1 and label2
        JLabel label1;
        JLabel label2;
        public void initialDemoPanel(){
            setBorder(BorderFactory.createTitledBorder(getBorder(), "DemoPanel", TitledBorder.LEADING, TitledBorder.TOP, new Font("Default",Font.PLAIN,10), Color.gray));
            setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

            label1 = new JLabel("This is first line");
            label2 = new JLabel("This is second line");
        }

        public DemoPanel(){
            initialDemoPanel();
            add(label1);
            if(withGlue){
                add(Box.createVerticalGlue());
            }
            add(label2);
        }

        public DemoPanel(int strutValue){
            initialDemoPanel();
            add(label1);
            add(Box.createVerticalStrut(strutValue));
            add(label2);
        }
    }

    class ActionPanel extends JPanel{
        public ActionPanel(){
            setBorder(BorderFactory.createTitledBorder(getBorder(), "ActionPanel", TitledBorder.LEADING, TitledBorder.TOP, new Font("Default",Font.PLAIN,10), Color.gray));

            setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
            JRadioButton glueButton = new JRadioButton("With Glue");
            glueButton.addActionListener(new glueButtonListener());
            add(glueButton);

            add(Box.createHorizontalStrut(10));
            //To create horizontal white space
            JLabel strutLabel = new JLabel("Strut Value");
            add(strutLabel);
            spinner = new JSpinner(new SpinnerNumberModel(0,0,50,1));
            spinner.addChangeListener(new spinnerListener());
            add(spinner);
            //public SpinnerNumberModel(Number value,Comparable minimum,Comparable maximum,Number stepSize)
        }
    }

    class glueButtonListener implements ActionListener{
        @Override
        public void actionPerformed(ActionEvent e) {
            spinner.setValue(new Integer(0));
            withGlue = (withGlue == true ? false:true);
            whiteSpace.getContentPane().remove(demoPanel);
            demoPanel = new DemoPanel();
            whiteSpace.getContentPane().add(demoPanel,BorderLayout.CENTER);
            whiteSpace.getContentPane().validate();
        }
    }

    class spinnerListener implements ChangeListener{

        @Override
        public void stateChanged(ChangeEvent e) {
            int strutValue = (Integer) spinner.getValue();
            whiteSpace.getContentPane().remove(demoPanel);
            demoPanel = new DemoPanel(strutValue);
            whiteSpace.getContentPane().add(demoPanel,BorderLayout.CENTER);
            whiteSpace.getContentPane().validate();
        }
    }
}

Box.createHorizontalGlue()Box.createHorizontalStrut(int height)có thể được sử dụng quá. Bên cạnh đó, Box.createRigidArea(Dimension d)có khả năng tạo không gian trắng quá.


12

MigLayoutcó nhiều cách tạo không gian. (Một khoảng trắng được gọi là khoảng trống trong bố cục này.) Các khoảng trống có thể được tạo ở mức cao nhất với các ràng buộc bố cục, có thể tạo các khoảng trống giữa các hàng và cột và các khoảng trống cũng có thể được đặt giữa các thành phần riêng lẻ với các ràng buộc thành phần. Cũng có những khoảng trống cụ thể xung quanh đường viền của một container được gọi là insets có từ khóa cụ thể của riêng chúng được đặt.

Ví dụ sau đây tạo ra tất cả các loại khoảng trống:

package com.zetcode;

import java.awt.EventQueue;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import net.miginfocom.swing.MigLayout;


public class MigLayoutGaps2 extends JFrame {

    public MigLayoutGaps2() {

        initUI();

        setTitle("Gaps");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
    }

    private void initUI() {

        JPanel base = new JPanel(new MigLayout("flowy, ins 30, gap 15"));
        setContentPane(base);

        JPanel pnl1 = new JPanel();
        pnl1.setBorder(
                BorderFactory.createTitledBorder("Grid gaps")
        );

        pnl1.setLayout(new MigLayout("gap 5 5, ins 10, wrap 3"));

        pnl1.add(new JButton("1"));
        pnl1.add(new JButton("2"));
        pnl1.add(new JButton("3"));
        pnl1.add(new JButton("4"));
        pnl1.add(new JButton("5"));
        pnl1.add(new JButton("6"));

        JPanel pnl2 = new JPanel();
        pnl2.setBorder(
                BorderFactory.createTitledBorder("Column gaps")
        );

        pnl2.setLayout(new MigLayout("wrap 3", "[]10[]"));

        JLabel lbl1 = new JLabel();
        lbl1.setBorder(
            BorderFactory.createEtchedBorder()
        );

        JLabel lbl2 = new JLabel();
        lbl2.setBorder(
            BorderFactory.createEtchedBorder()
        );

        JLabel lbl3 = new JLabel();
        lbl3.setBorder(
            BorderFactory.createEtchedBorder()
        );        

        pnl2.add(lbl1, "w 40, h 110");
        pnl2.add(lbl2, "w 40, h 110");
        pnl2.add(lbl3, "w 40, h 110");

        JPanel pnl3 = new JPanel();
        pnl3.setBorder(
                BorderFactory.createTitledBorder("Row gaps")
        );

        pnl3.setLayout(new MigLayout("wrap", "", "[]15[]"));

        JLabel lbl4 = new JLabel();
        lbl4.setBorder(
            BorderFactory.createEtchedBorder()
        );

        JLabel lbl5 = new JLabel();
        lbl5.setBorder(
            BorderFactory.createEtchedBorder()
        );

        JLabel lbl6 = new JLabel();
        lbl6.setBorder(
            BorderFactory.createEtchedBorder()
        );        

        pnl3.add(lbl4, "w 150, h 20");
        pnl3.add(lbl5, "w 150, h 20");
        pnl3.add(lbl6, "w 150, h 20");        

        JPanel pnl4 = new JPanel();
        pnl4.setBorder(
                BorderFactory.createTitledBorder("Component gaps")
        );

        pnl4.setLayout(new MigLayout());

        pnl4.add(new JLabel("Name:"), "gapright 5");
        pnl4.add(new JTextField(10), "gapbottom 20, gaptop 20");

        base.add(pnl1);
        base.add(pnl2);
        base.add(pnl3);
        base.add(pnl4);

        pack();
    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                MigLayoutGaps2 ex = new MigLayoutGaps2();
                ex.setVisible(true);
            }
        });
    }
}

Chúng tôi có bốn bảng trong bố trí. Mỗi bảng này có một MigLayoutngười quản lý.

JPanel base = new JPanel(new MigLayout("flowy, ins 30, gap 15"));

Dòng này tạo ra các thùng chứa và khoảng cách dọc giữa các bảng.

pnl1.setLayout(new MigLayout("gap 5 5, ins 10, wrap 3"));

Ở đây chúng tôi áp dụng các khoảng trống cho toàn bộ cấu trúc lưới và cũng đặt các khoảng trống chứa.

pnl2.setLayout(new MigLayout("wrap 3", "[]10[]"));

Dòng này tạo ra khoảng cách giữa các cột.

pnl3.setLayout(new MigLayout("wrap", "", "[]15[]"));

Khoảng cách hàng được xác định với mã này.

pnl4.add(new JLabel("Name:"), "gapright 5");
pnl4.add(new JTextField(10), "gapbottom 20, gaptop 20");

Cuối cùng, có thể tạo ra khoảng cách giữa các thành phần riêng lẻ.

Khoảng trống



0

Bất cứ khi nào tôi gặp vấn đề này, tôi chỉ cần sử dụng JPanels. Ví dụ: trong GridLayout:

JFrame frame = new JFrame;
frame.setLayout(new GridLayout(2, 0));

//We want the bottom left to be blank
frame.add(new JLabel("Top Left"));
frame.add(new JLabel("Top Right"));

//This is the position we want empty
frame.add(new JPanel());

//Now we can continue with the rest of the script

Hy vọng điều này sẽ giúp :)

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.