ให้พื้นที่สีขาวใน Swing GUI


161

GUI ที่ไม่มีพื้นที่ปรากฏเป็นสีขาว 'แออัด' ฉันจะให้พื้นที่สีขาวโดยไม่หันไปใช้การกำหนดตำแหน่งหรือขนาดของส่วนประกอบอย่างชัดเจนได้อย่างไร



1
ใช้ LayoutManager ที่รองรับช่องว่างในแง่ความหมาย คุณเห็นว่ามันกำลังมาใช่ไหม :-) MigLayout เพื่อช่วยเหลือ: คุณกำหนดกริดและช่องว่างระหว่างความเกี่ยวข้องไม่เกี่ยวข้องย่อหน้า - aftet ที่เพิ่งเพิ่มส่วนประกอบ
kleopatra

คำตอบ:


111

ใช้ต่าง ๆLayoutManagersหนึ่งสามารถให้ระยะห่างระหว่างส่วนประกอบต่างๆ

1. ) BorderLayout:

2. ) FlowLayout:

3. ) GridLayout:

4. ) GridBagLayout:

GridBagConstraints.insets

5. ) CardLayout ( ตัวอย่าง ):

CardLayout (int hGap, int vGap)

ตัวอย่างที่จะแสดงการก่อสร้างทั้งหมดในการดำเนินการ:

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

เอาท์พุท:

LAYOUTIMAGE


6
+1 ผม luuuuuv ฉันบางขุ่น GridBagConstraints เราใช้ GBL บ่อยครั้งดังนั้นฉันจึงเขียนคลาสผู้ช่วยที่ทำงานสกปรกสำหรับฉันเพื่อให้รหัส GBL ค่อนข้างสั้นและอ่านง่าย เช่นเดียวกับตัวอย่างที่นี่ฉันใช้ Insets ที่เป็นค่าเริ่มต้นเพื่อที่ฉันจะได้ไม่ต้องพิมพ์ในทุกครั้งและผลลัพธ์ที่ได้คือรูปแบบที่ "ผ่อนคลาย" มากกว่า
splungebob

63

มีหลายวิธีในการสวิง GUI เพื่อให้แยกระหว่างส่วนประกอบและพื้นที่สีขาวรอบส่วนประกอบคือ:

  • JToolBarมีวิธีการaddSeparator()& addSeparator(Dimension).
  • JMenuaddSeparator()ใช้องค์ประกอบระยะห่างที่เหมาะสมดีกว่าที่จะเมนูผ่านใช้ได้

แต่โดยทั่วไปแล้วมองไปที่:

  • ระยะห่างที่สามารถกำหนดได้ในตัวสร้างโครงร่าง
  • พรมแดน

นี่คือตัวอย่างของการใช้ตัวคั่นเลย์เอาต์hGap& vGapค่าและเส้นขอบ (โดยเฉพาะEmptyBorder) เพื่อให้มีพื้นที่ 'สีขาว' (แสดงเป็นสีแดงจริง ๆเพื่อให้ชัดเจน) ปรับสปินเนอร์เพื่อดูผลลัพธ์

ไม่มีพื้นที่สีขาว GUI

ด้วย 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

เมื่อคุณใช้BoxLayout, Box.createVerticalGlue()วิธีการช่วยให้คุณสามารถที่จะทำให้พื้นที่สีขาวบาง

BorderFactory.createEmptyBorder(int top, int left, int bottom, int right)อีกวิธีหนึ่งคือ มันสามารถช่วยคุณสร้างพื้นที่สีขาวรอบ ๆ องค์ประกอบ

ขอบคุณสำหรับการเตือนของ Andrew Thompson ฉันได้ทำการแก้ไข BoxLayout ในช่วงไม่กี่วันที่ผ่านมาและฉันพบว่าBox.createVerticalGlue()สามารถเพิ่มพื้นที่สีขาวขึ้นอยู่กับขนาดของแผงและคุณไม่สามารถตั้งค่าพิกเซลที่ชัดเจนของความยาวของพื้นที่สีขาวBox.createVerticalStrut()ได้ นี่คือ MCTaRE และแสดงผลกระทบของทั้งสองวิธี

ป้อนคำอธิบายรูปภาพที่นี่

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)สามารถใช้ได้เช่นกัน นอกจากนี้Box.createRigidArea(Dimension d)ยังมีความสามารถในการสร้างพื้นที่สีขาวด้วย


12

MigLayoutมีหลายวิธีในการสร้างพื้นที่ (ช่องว่างเรียกว่าช่องว่างในเลย์เอาต์นี้) สามารถสร้างช่องว่างในระดับสูงสุดด้วยข้อ จำกัด ของเลย์เอาต์สามารถสร้างช่องว่างระหว่างแถวกับคอลัมน์และช่องว่างได้ด้วย นอกจากนี้ยังมีช่องว่างเฉพาะรอบ ๆ ขอบของคอนเทนเนอร์ที่เรียกว่า insets ซึ่งมีคำหลักเฉพาะของตนเองที่จะตั้งค่า

ตัวอย่างต่อไปนี้สร้างช่องว่างทุกประเภทเหล่านี้:

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

เรามีสี่แผงในเค้าโครง แต่ละพาเนลนี้มีMigLayoutผู้จัดการ

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

บรรทัดนี้สร้างสิ่งที่ใส่ในภาชนะและช่องว่างในแนวตั้งระหว่างแผงควบคุม

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

ที่นี่เราใช้ช่องว่างสำหรับโครงสร้างกริดทั้งหมดและตั้งช่องว่างของคอนเทนเนอร์

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

บรรทัดนี้สร้างช่องว่างระหว่างคอลัมน์

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

ช่องว่างแถวถูกกำหนดด้วยรหัสนี้

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

ในที่สุดมันเป็นไปได้ที่จะสร้างช่องว่างระหว่างแต่ละองค์ประกอบ

ช่องว่าง


7

JGoodies FormLayout

ผู้แต่ง Karsten Lentzsch มีชุดของงานนำเสนอในการออกแบบ UI โดยเฉพาะอย่างยิ่งPDF นี้พูดถึงความต้องการช่องว่างความงาม การเพิ่มพื้นที่ที่มีความหมายในขณะเดียวกันก็ให้ความสนใจกับความยุ่งเหยิงที่แยกข้าวสาลีออกจากแกลบ


0

เมื่อใดก็ตามที่ฉันมีปัญหานี้ฉันแค่ใช้ JPanels ตัวอย่างเช่นใน 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

หวังว่านี่จะช่วยได้ :)

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.