JPanel组件放置

时间:2014-11-07 07:38:32

标签: java swing user-interface jframe jpanel

enter image description here我正在尝试获得一个基本的GUI程序。它不需要做太多,但底部的按钮必须工作。我无法将组件(文本,组合框等)放置在适当的位置。使用GridBag我可以使用c.gridx和c.gridy更改位置,但是非常奇怪。如果我将网格值0-7与x为0,则一切都在彼此的顶部。我尝试通过更改gridx值将组合框放在文本旁边,一切都搞砸了。在我试图移动之后,组件上的对齐关闭了。我该如何解决?我没有运气试过BorderLayout.DIRECTION。实际的变化根本没有生效(然后移动到底部)。我该如何解决?感谢

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package javaredesign;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;

/**
 *
 * @author 
 */
public class Window extends JFrame {

    //Default global variables
    private JButton submit;
    private JButton cancel;
    private JButton reset;
    private JPanel panel = new JPanel(new GridBagLayout());
    private String searchOutput = "";


    //Default constructor
    public Window() {

        //Title of the window
        super("LIBSYS: Search");

        //Creating the flow layout to which we can work on and adding panel to frame
        setLayout(new FlowLayout());
        add(panel, BorderLayout.SOUTH);

        //Creating the grid to location of the parts
        GridBagConstraints c = new GridBagConstraints();

        //Initializing the buttons
        submit = new JButton("Submit");
        c.insets = new Insets(10, 10, 10, 5);
        c.gridx = 1;
        c.gridy = 20;
        panel.add(submit, c);
        reset = new JButton("Reset");
        c.gridx = 2;
        c.gridy = 20;
        panel.add(reset, c);
        cancel = new JButton("Cancel");
        c.gridx = 3;
        c.gridy = 20;
        panel.add(cancel, c);

        //Handler constructor to do the actionlistening
        Handler handler = new Handler();
        submit.addActionListener(handler);
        reset.addActionListener(handler);
        cancel.addActionListener(handler);

        //Creating the two dropdowns with the words next to them
        JLabel chooseCollection = new JLabel("Choose Collection");
        String[] ccString = {"All", "Mostly", "Some", "Few"};
        JComboBox ccComboBox = new JComboBox(ccString);
        JLabel searchUsing = new JLabel("Search Using");
        String[] suString = {"Title", "Artist", "Arthor", "Type"};
        JComboBox suComboBox = new JComboBox(suString);

        //Adding all the text and dropdown menus to the panel
        c.gridx = 0;
        c.gridy = 24;
        panel.add(chooseCollection, c);
        c.gridx = 0;
        c.gridy = 25;
        panel.add(ccComboBox, c);
        c.gridx = 1;
        c.gridy = 25;
        panel.add(searchUsing, c);
        c.gridx = 0;
        c.gridy = 27;
        panel.add(suComboBox, c);
        c.gridx = 1;
        c.gridy = 27;

        //Setting up the text inputbox
        JLabel keyword = new JLabel("Keyword or phrase");
        JTextField textField = new JTextField(20);

        //Adding lable and text box to the panel
        panel.add(keyword);
        panel.add(textField);
    }

}

4 个答案:

答案 0 :(得分:4)

我不会尝试强制按钮与其他组件的布局相同。它们是独立的,应该是均匀自由浮动的。

按钮面板应位于使用 flowlayout 设置的面板中。然后,应将此面板添加到框架中,并在SOUTH处使用 borderlayout

其他组件应进入带有 gridbaglayout 的面板,并添加到CENTER的框架中。

然后,gridbaglayout面板应将其所有组件设置在图片中列出的坐标处。如果组件覆盖两个以上的单元格(即组合),则将 gridWidth 属性设置为2.

enter image description here

答案 1 :(得分:2)

问题是您需要了解GridBagLayout。您需要将组件布局到适当的网格上:

GridBagLayout

所以你应该有5行12列来布局你在图片中描述的方式。不要介意填充(我试图添加它以使其更具说明性)。前三行应各自包含gridwidth = 6元素,第一行应位于gridx = 0,第二行应位于gridx = 6。然后,您的“是”和“否”按钮应分别在gridwidth = 3gridx = 6gridx = 9。最后,您的最后一行(按钮)应分别包含gridwidth = 2gridx = 1gridx = 5gridx = 9。我只使用gbc.anchor = GridBagConstraints.CENTER(对于所有组件)而不是使用填充,以便组件在其网格内居中。

我建议将gbc.fill = GridBagConstraints.HORIZONTAL用于文本字段和组合框,以便它们排列“美观漂亮”,但不要忘记将其设置回gbc.fill = GridBagConstraints.NONE单选按钮和常规按钮(除非你希望它们也拉伸)。

我非常偶然地改变了你的代码(似乎没有逻辑顺序):

// Creating the grid to location of the parts
GridBagConstraints c = new GridBagConstraints();

c.anchor = GridBagConstraints.CENTER;

// Initializing the buttons
submit = new JButton("Submit");
c.insets = new Insets(10, 10, 10, 5);
c.gridx = 1;
c.gridy = 5;
c.gridwidth = 2;
panel.add(submit, c);
reset = new JButton("Reset");
c.gridx = 5;
// c.gridy = 20;
panel.add(reset, c);
cancel = new JButton("Cancel");
c.gridx = 9;
// c.gridy = 20;
panel.add(cancel, c);

// Handler constructor to do the actionlistening
Handler handler = new Handler();
submit.addActionListener(handler);
reset.addActionListener(handler);
cancel.addActionListener(handler);

// Creating the two dropdowns with the words next to them
JLabel chooseCollection = new JLabel("Choose Collection");
String[] ccString = { "All", "Mostly", "Some", "Few" };
JComboBox ccComboBox = new JComboBox(ccString);
JLabel searchUsing = new JLabel("Search Using");
String[] suString = { "Title", "Artist", "Arthor", "Type" };
JComboBox suComboBox = new JComboBox(suString);
// Adding all the text and dropdown menus to the panel
c.gridx = 0;
c.gridy = 0;
c.gridwidth = 6;
c.anchor = GridBagConstraints.WEST;
panel.add(chooseCollection, c);
c.gridx = 6;
// c.gridy = 25;

c.fill = GridBagConstraints.HORIZONTAL;
panel.add(ccComboBox, c);
c.gridx = 0;
c.gridy = 2;
c.fill = GridBagConstraints.NONE;
panel.add(searchUsing, c);
c.gridx = 6;
// c.gridy = 27;
c.fill = GridBagConstraints.HORIZONTAL;
panel.add(suComboBox, c);

// Setting up the text inputbox
JLabel keyword = new JLabel("Keyword or phrase");
JTextField textField = new JTextField(20);
// Adding lable and text box to the panel
c.gridx = 0;
c.gridy = 1;
c.fill = GridBagConstraints.NONE;
panel.add(keyword, c);
c.gridx = 6;

panel.add(textField, c);

其中产生了以下布局:

enter image description here

答案 2 :(得分:2)

我通过外部BorderLayout来做到这一点。对于标签/控制对,CENTER将是GroupLayout。对于按钮,PAGE_END将是FlowLayoutLibSysSearch control

这使用TitledBorder代替JLabel来显示LIBSYS Search。如果它确实需要标签,请将其放在边框布局的PAGE_START中。

import java.awt.*;
import java.util.HashMap;
import java.util.Map;
import javax.swing.*;
import javax.swing.border.*;

public class LibSysSearch {

    private JComponent ui = null;

    LibSysSearch() {
        initUI();
    }

    public void initUI() {
        if (ui != null) {
            return;
        }
        ui = new JPanel(new BorderLayout(4, 4));
        ui.setBorder(new EmptyBorder(4, 4, 4, 4));

        // Here is our control.  This puts a titled border around it, 
        // instead of using a label in the PAGE_START
        JPanel libSysSearchControl = new JPanel(new BorderLayout());
        ui.add(libSysSearchControl);

        JPanel actionPanel = new JPanel(
                new FlowLayout(FlowLayout.CENTER, 15, 15));
        libSysSearchControl.add(actionPanel, BorderLayout.PAGE_END);

        String[] actionNames = {"Search", "Reset", "Cancel"};
        for (String name : actionNames) {
            actionPanel.add(new JButton(name));
        }

        // Use GroupLayout for the label/cotrnl combos.
        // make the arrays for the factory method
        String[] labels = {
            "Choose Collection", "Search Using", 
            "Keyword or phrase", "Adjacent words"
        };
        String[] ccString = {"All", "Mostly", "Some", "Few"};
        String[] suString = {"Title", "Artist", "Arthor", "Type"};

        JPanel confirmAdjacent = new JPanel(new FlowLayout(FlowLayout.LEADING,5,0));
        confirmAdjacent.add(new JRadioButton("Yes", true));
        confirmAdjacent.add(new JRadioButton("No"));

        JComponent[] controls = {
            new JComboBox(ccString),
            new JTextField(20),
            new JComboBox(suString),
            confirmAdjacent
        };

        libSysSearchControl.add(getTwoColumnLayout(labels, controls));

        // throw in a few borders for white space
        Border border = new CompoundBorder(
                new EmptyBorder(10, 10, 10, 10),
                new TitledBorder("LIBSYS Search"));
        border = new CompoundBorder(
                border,
                new EmptyBorder(10, 10, 10, 10));
        libSysSearchControl.setBorder(border);
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (Exception useDefault) {
                }
                LibSysSearch o = new LibSysSearch();

                JFrame f = new JFrame("Library System Search");
                f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                f.setLocationByPlatform(true);

                f.setContentPane(o.getUI());
                f.pack();
                f.setMinimumSize(f.getSize());

                f.setVisible(true);
            }
        };
        SwingUtilities.invokeLater(r);
    }

    /**
     * Provides a JPanel with two columns (labels & fields) laid out using
     * GroupLayout. The arrays must be of equal size.
     *
     * Typical fields would be single line textual/input components such as
     * JTextField, JPasswordField, JFormattedTextField, JSpinner, JComboBox,
     * JCheckBox.. & the multi-line components wrapped in a JScrollPane -
     * JTextArea or (at a stretch) JList or JTable.
     *
     * @param labels The first column contains labels.
     * @param fields The last column contains fields.
     * @param addMnemonics Add mnemonic by next available letter in label text.
     * @return JComponent A JPanel with two columns of the components provided.
     */
    public static JComponent getTwoColumnLayout(
            JLabel[] labels,
            JComponent[] fields,
            boolean addMnemonics) {
        if (labels.length != fields.length) {
            String s = labels.length + " labels supplied for "
                    + fields.length + " fields!";
            throw new IllegalArgumentException(s);
        }
        JComponent panel = new JPanel();
        GroupLayout layout = new GroupLayout(panel);
        panel.setLayout(layout);
        // Turn on automatically adding gaps between components
        layout.setAutoCreateGaps(true);
        // Create a sequential group for the horizontal axis.
        GroupLayout.SequentialGroup hGroup = layout.createSequentialGroup();
        GroupLayout.Group yLabelGroup = layout.createParallelGroup(GroupLayout.Alignment.TRAILING);
        hGroup.addGroup(yLabelGroup);
        GroupLayout.Group yFieldGroup = layout.createParallelGroup();
        hGroup.addGroup(yFieldGroup);
        layout.setHorizontalGroup(hGroup);
        // Create a sequential group for the vertical axis.
        GroupLayout.SequentialGroup vGroup = layout.createSequentialGroup();
        layout.setVerticalGroup(vGroup);

        int p = GroupLayout.PREFERRED_SIZE;
        // add the components to the groups
        for (JLabel label : labels) {
            yLabelGroup.addComponent(label);
        }
        for (Component field : fields) {
            yFieldGroup.addComponent(field, p, p, p);
        }
        for (int ii = 0; ii < labels.length; ii++) {
            vGroup.addGroup(layout.createParallelGroup().
                    addComponent(labels[ii]).
                    addComponent(fields[ii], p, p, p));
        }

        if (addMnemonics) {
            addMnemonics(labels, fields);
        }

        return panel;
    }

    private final static void addMnemonics(
            JLabel[] labels,
            JComponent[] fields) {
        Map<Character, Object> m = new HashMap<Character, Object>();
        for (int ii = 0; ii < labels.length; ii++) {
            labels[ii].setLabelFor(fields[ii]);
            String lwr = labels[ii].getText().toLowerCase();
            for (int jj = 0; jj < lwr.length(); jj++) {
                char ch = lwr.charAt(jj);
                if (m.get(ch) == null && Character.isLetterOrDigit(ch)) {
                    m.put(ch, ch);
                    labels[ii].setDisplayedMnemonic(ch);
                    break;
                }
            }
        }
    }

    /**
     * Provides a JPanel with two columns (labels & fields) laid out using
     * GroupLayout. The arrays must be of equal size.
     *
     * @param labelStrings Strings that will be used for labels.
     * @param fields The corresponding fields.
     * @return JComponent A JPanel with two columns of the components provided.
     */
    public static JComponent getTwoColumnLayout(
            String[] labelStrings,
            JComponent[] fields) {
        JLabel[] labels = new JLabel[labelStrings.length];
        for (int ii = 0; ii < labels.length; ii++) {
            labels[ii] = new JLabel(labelStrings[ii]);
        }
        return getTwoColumnLayout(labels, fields);
    }

    /**
     * Provides a JPanel with two columns (labels & fields) laid out using
     * GroupLayout. The arrays must be of equal size.
     *
     * @param labels The first column contains labels.
     * @param fields The last column contains fields.
     * @return JComponent A JPanel with two columns of the components provided.
     */
    public static JComponent getTwoColumnLayout(
            JLabel[] labels,
            JComponent[] fields) {
        return getTwoColumnLayout(labels, fields, true);
    }
}

答案 3 :(得分:1)

我可能会这样做:

public class Test {

    public Test() {

        JFrame frame = new JFrame();
        JPanel mainPanel = new JPanel(new GridLayout(0, 1));
        JPanel chooseCollectionPanel = new JPanel(new BorderLayout());
        JPanel keywordPanel = new JPanel(new BorderLayout());
        JPanel searchCategoryPanel = new JPanel(new BorderLayout());
        // ...
        mainPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
        chooseCollectionPanel.setBorder(BorderFactory.createEmptyBorder(5, 0,
                5, 0));
        keywordPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5, 0));
        searchCategoryPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 5,
                0));

        JLabel chooseCollectionLabel = new JLabel("Choose Collection: ");
        JComboBox<String> chooseCollectionCB = new JComboBox<String>();
        chooseCollectionCB.addItem("All");
        chooseCollectionPanel.add(chooseCollectionLabel, BorderLayout.WEST);
        chooseCollectionPanel.add(chooseCollectionCB, BorderLayout.CENTER);

        JLabel chooseCollectionkeywordLabel = new JLabel("Choose Collection: ");
        JTextField keywordCB = new JTextField(10);
        keywordPanel.add(chooseCollectionkeywordLabel, BorderLayout.WEST);
        keywordPanel.add(keywordCB, BorderLayout.CENTER);
        // ...

        mainPanel.add(chooseCollectionPanel);
        mainPanel.add(keywordPanel);
        mainPanel.add(searchCategoryPanel);
        // ...
        frame.add(mainPanel);
        frame.setSize(400, 400);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        new Test();
    }
}