JPanel & components change position automatically

2019-01-02 21:20发布

Hi I am working on swing application but I am facing one problem.

When I first run application JPanel is positioned at proper position where I decided to set with components inside. But problem occur when

I minimize & again maximize frame window jpanel automatically changes it's position.

Below images shows that difference

enter image description here

enter image description here

As we can see on second image components changes it's position automatically.

For this I written below code,

jpanel_addPurchase = new JPanel();
jpanel_addPurchase.setLayout(null);
jpanel_addPurchase.setBounds(400, 0, 500, 500);
jpanel_addPurchase.setBackground(Color.white);
JLabel lbl_title = new JLabel("Purchase Form");
lbl_title.setBounds(90, 20, 100, 100);
jpanel_addPurchase.add(lbl_title);

And added this panel in frame using,

setContentPane(getJPanel());

Where I am going wrong?

1条回答
明月照影归
2楼-- · 2019-01-02 21:52

I think the original (non-broken) layout looks quirky and would make it difficult for the end user to follow the rows and labels/fields. I suggest instead using a GroupLayout to right align the labels, and left align the fields that contain the values. Like this:

enter image description here

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

class TwoColumnLayoutWithHeader {

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

    public static String getProperty(String name) {
        return name + ": \t"
                + System.getProperty(name)
                + System.getProperty("line.separator");
    }

    public static void main(String[] args) {
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JComponent[] components = {
                    new JTextField(15),
                    new JTextField(10),
                    new JTextField(8),
                    new JSpinner(new SpinnerNumberModel(1,0,10,1)),
                    new JSpinner(new SpinnerNumberModel(9.95,0d,100d,.01)),
                    new JSpinner(new SpinnerNumberModel(9.95,0d,1000d,.01)),
                    new JSpinner(new SpinnerNumberModel(9.95,0d,100d,.01)),
                    new JSpinner(new SpinnerNumberModel(9.95,0d,1000d,.01)),
                    new JSpinner(new SpinnerNumberModel(9.95,0d,100d,.01)),
                    new JSpinner(new SpinnerNumberModel(9.95,0d,1000d,.01))
                };

                String[] labels = {
                    "Product Name:",
                    "Product Unit Name:",
                    "Purchase Date:",
                    "Quantity:",
                    "Price Per Unit:",
                    "Total Price:",
                    "Discount:",
                    "Total:",
                    "VAT:",
                    "Grand Total:"
                };

                JComponent labelsAndFields = getTwoColumnLayout(labels,components);
                JComponent orderForm = new JPanel(new BorderLayout(5,5));
                orderForm.add(new JLabel("Purchase Form", SwingConstants.CENTER),
                    BorderLayout.PAGE_START);
                orderForm.add(labelsAndFields, BorderLayout.CENTER);

                JOptionPane.showMessageDialog(null, orderForm);
            }
        };
        // Swing GUIs should be created and updated on the EDT
        // http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
        SwingUtilities.invokeLater(r);
    }
}
查看更多
登录 后发表回答