wake-up-neo.net

Bereitstellen von Leerzeichen in einer Swing-GUI

Eine GUI ohne Leerzeichen erscheint "überfüllt". Wie kann ich weißen Raum bieten, ohne explizit zurückgreifen, die Position oder Größe der Komponenten einstellen?

150
Andrew Thompson

In einer Swing-Benutzeroberfläche gibt es mehrere Möglichkeiten, eine Trennung zwischen Komponenten und Leerzeichen um Komponenten zu ermöglichen:

Aber allgemeiner betrachtet:

  • Der Abstand kann in den Layout-Konstruktoren definiert werden.
  • Grenzen. 

Hier ist ein Beispiel für die Verwendung des Layouttrennzeichens hGap & vGap values ​​& Rahmen (speziell eine EmptyBorder), um Platz für 'white' (eigentlich als red dargestellt) bereitzustellen. Passen Sie die Spinner an, um das Ergebnis zu sehen.

With no GUI white space

With GUI white space

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;
    private FlowLayout buttonLayout;
    private EmptyBorder border;

    public Container getGui() {
        if (gui==null) {
            mainLayout = new BorderLayout(0,0);
            gui = new JPanel(mainLayout);
            gui.setBackground(Color.RED);
            border = new EmptyBorder(0,0,0,0);

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

            buttonLayout = new FlowLayout(FlowLayout.CENTER,0,0);
            JPanel buttonPanel = new JPanel(buttonLayout);
            gui.add(buttonPanel, BorderLayout.PAGE_START);

            buttonPanel.add(new JLabel("H Gap"));
            final JSpinner hSpinner = 
                    new JSpinner(new SpinnerNumberModel(0,0,15,1));
            buttonPanel.add(hSpinner);

            buttonPanel.add(new JLabel("V Gap"));
            final JSpinner vSpinner = 
                    new JSpinner(new SpinnerNumberModel(0,0,15,1));
            buttonPanel.add(vSpinner);

            buttonPanel.add(new JLabel("H Border"));
            final JSpinner hBorderSpinner = 
                    new JSpinner(new SpinnerNumberModel(0,0,15,1));
            buttonPanel.add(hBorderSpinner);

            buttonPanel.add(new JLabel("V Border"));
            final JSpinner vBorderSpinner = 
                    new JSpinner(new SpinnerNumberModel(0,0,15,1));
            buttonPanel.add(vBorderSpinner);

            ChangeListener changeListener = new ChangeListener() {

                @Override
                public void stateChanged(ChangeEvent e) {
                    int hGap = ((Integer)hSpinner.getValue()).intValue();
                    int vGap = ((Integer)vSpinner.getValue()).intValue();
                    int hBorder = ((Integer)hBorderSpinner.getValue()).intValue();
                    int vBorder = ((Integer)vBorderSpinner.getValue()).intValue();
                    adjustWhiteSpace(hGap,vGap,hBorder,vBorder);
                }
            };

            hSpinner.addChangeListener(changeListener);
            vSpinner.addChangeListener(changeListener);
            hBorderSpinner.addChangeListener(changeListener);
            vBorderSpinner.addChangeListener(changeListener);
        }

        return gui;
    }

    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 = new Runnable() {

            @Override
            public void run() {
                WhiteSpace ws = new WhiteSpace();
                // the GUI as seen by the user (without frame)
                Container gui = ws.getGui();

                JFrame f = new JFrame("White (OK Red) Space");
                f.add(gui);
                // Ensures JVM closes after frame(s) closed and
                // all non-daemon threads are finished
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                // See http://stackoverflow.com/a/7143398/418556 for demo.
                f.setLocationByPlatform(true);

                // ensures the frame is the minimum size it needs to be
                // in order display the components within it
                f.setResizable(false);
                f.pack();
                // should be done last, to avoid flickering, moving,
                // resizing artifacts.
                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
62
Andrew Thompson

Durch die Verwendung verschiedener LayoutManagers kann man den Abstand zwischen verschiedenen Komponenten angeben. 

1.) BorderLayout:

2.) FlowLayout:

3.) GridLayout:

4.) GridBagLayout:

GridBagConstraints.insets

5.) CardLayout ( Beispiel ):

CardLayout (int hGap, int vGap)

Beispiel zum Anzeigen aller Konstruktoren in Aktion:

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

AUSGABE :

LAYOUTIMAGE

101
nIcE cOw

Wenn Sie die BoxLayout-Methode verwenden, können Sie mit der Box.createVerticalGlue()-Methode Leerstellen schaffen.

Eine andere Methode ist BorderFactory.createEmptyBorder(int top, int left, int bottom, int right). Es kann Ihnen helfen, etwas Leerraum um die Komponente herum zu schaffen.

Vielen Dank für die Erinnerung von Andrew Thompson. Ich habe BoxLayout in den letzten Tagen überarbeitet und finde, dass Box.createVerticalGlue() Leerräume hinzufügen kann, die von der Panelgröße abhängen, und Sie können den expliziten Pixelwert der Länge von Leerräumen nicht festlegen Box.createVerticalStrut() kann das. Hier ist ein MCTaRE und zeigt die Wirkung dieser beiden Methoden.

enter image description here

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() und Box.createHorizontalStrut(int height) können ebenfalls verwendet werden. Außerdem hat Box.createRigidArea(Dimension d) die Möglichkeit, auch Leerzeichen zu erzeugen.

19
Gearon

MigLayout hat mehrere Möglichkeiten, um Platz zu schaffen. (Ein Leerzeichen wird in diesem Layout als Lücke bezeichnet.) Lücken können auf der obersten Ebene mit Layoutbeschränkungen erstellt werden. Es ist möglich, Lücken zwischen Zeilen und Spalten zu erstellen. Lücken können auch zwischen einzelnen .__ Komponenten mit Komponenteneinschränkungen. Es gibt auch bestimmte Lücken um die Grenzen Eines Containers, die als Insets bezeichnet werden und deren eigenes Schlüsselwort festgelegt werden muss.

Das folgende Beispiel erstellt alle diese Arten von Lücken:

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

Wir haben vier Panels im Layout. Jedes dieser Panels verfügt über einen MigLayout-Manager.

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

Diese Zeile erstellt Containereinsätze und vertikale Lücken zwischen den Panels.

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

Hier legen wir Lücken für die gesamte Gitterstruktur an und setzen auch Containerlücken.

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

Diese Zeile erzeugt Lücken zwischen den Spalten.

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

Zeilenabstände werden mit diesem Code definiert.

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

Schließlich ist es möglich, Lücken zwischen einzelnen Komponenten zu schaffen.

Gaps

11
Jan Bodnar

JGoodies FormLayout.

Autor Karsten Lentzsch hat eine Sammlung von Präsentationen zum Design der Benutzeroberfläche. Insbesondere this PDF spricht für die Notwendigkeit ästhetischen Whitespace. Indem Sie sinnvollen Platz hinzufügen und gleichzeitig auf Unordnung achten, wird die Spreu vom Weizen getrennt.

7
javajon

Immer wenn ich dieses Problem habe, verwende ich einfach JPanels. Zum Beispiel in einem 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

Hoffe das hat geholfen :)

0
Luke Pasfield