gridbaglayout将第二个项目放在中心

时间:2016-12-25 20:59:01

标签: java swing layout-manager gridbaglayout

正在创建一个应用程序,我想在其中使用GridBagLayout向滚动窗格添加文本字段,遇到的问题是我添加的第一个文本字段是添加到面板顶部的滚动窗格,但是,从第二个开始,它们被添加到中心,这是我的代码:

public class main extends javax.swing.JFrame {
private static HashMap<String, Integer> anch_codes = new HashMap<String, Integer>();
private static List<Component> items = new ArrayList<>();
/**
 * Creates new form main

 */
public main() {
    initComponents();
}
/**
 * This method is called from within the constructor to initialize the form.
 * WARNING: Do NOT modify this code. The content of this method is always
 * regenerated by the Form Editor.
 */
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">                          
private void initComponents() {

    jMenuBar1 = new javax.swing.JMenuBar();
    jMenu1 = new javax.swing.JMenu();
    jMenuItem1 = new javax.swing.JMenuItem();
    jMenu2 = new javax.swing.JMenu();

    setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

    jMenu1.setText("File");

    jMenuItem1.setAccelerator(javax.swing.KeyStroke.getKeyStroke(java.awt.event.KeyEvent.VK_S, java.awt.event.InputEvent.CTRL_MASK));
    jMenuItem1.setLabel("Save");
    jMenu1.add(jMenuItem1);
    jMenuItem1.getAccessibleContext().setAccessibleName("save_opt");

    jMenuBar1.add(jMenu1);

    jMenu2.setText("Edit");
    jMenuBar1.add(jMenu2);

    setJMenuBar(jMenuBar1);

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 1282, Short.MAX_VALUE)
    );
    layout.setVerticalGroup(
        layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
        .addGap(0, 703, Short.MAX_VALUE)
    );

    pack();
}// </editor-fold>                        

/**
 * @param args the command line arguments
 */
public static void main(String args[]) {
    /* Set the Nimbus look and feel */
    //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
    /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
     * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
     */
    try {
        for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                javax.swing.UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException ex) {
        java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (InstantiationException ex) {
        java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (IllegalAccessException ex) {
        java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    } catch (javax.swing.UnsupportedLookAndFeelException ex) {
        java.util.logging.Logger.getLogger(main.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
    }
    //</editor-fold>

    /* Create and display the form */
    java.awt.EventQueue.invokeLater(new Runnable() {
        public void run() {
            setAnchCodes();
            JFrame fmain = new main();

            fmain.setLayout(new GridBagLayout());
            GridBagConstraints c = new GridBagConstraints();

            fmain.setExtendedState(JFrame.MAXIMIZED_BOTH); 

            JTextField maintext = new JTextField();
            addToGrid(c, fmain, maintext, 0, 0, 0.9, 1.0, anch_codes.get("FIRST_LINE_START"));

            JButton add_btn =  new JButton("Add");
            addToGrid(c, fmain, add_btn, 1, 0, 0.1, 1.0, anch_codes.get("FIRST_LINE_START"));

            JPanel scrpanel = new JPanel(new GridBagLayout());
            scrpanel.setBackground(Color.WHITE);
            JScrollPane display_area = new JScrollPane(scrpanel);
            display_area.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            display_area.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
            addToGrid(c, fmain, display_area, 0, 1, 1.0, 1000, anch_codes.get("FIRST_LINE_START"), 2);

            GridBagConstraints an_c = new GridBagConstraints();
            eventAddNew(an_c, add_btn,maintext,scrpanel,fmain,display_area);

            fmain.setVisible(true);

        }
    });
}

public static void eventAddNew(GridBagConstraints c, Component ... comp) {
    JButton add_btn = (JButton) comp[0];
    JTextField maintext = (JTextField) comp[1];
    JPanel scrpanel = (JPanel) comp[2];
    JFrame fmain = (JFrame) comp[3];
    JScrollPane display_area = (JScrollPane) comp[4];
    add_btn.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            JTextField item = new JTextField(maintext.getText());
            item.setEnabled(false);
            item.setEditable(false);
            addToGrid(c, scrpanel, item, 0, items.size(), 1.0, 1.0, anch_codes.get("FIRST_LINE_START"));
            items.add(item);
            fmain.repaint();
            fmain.revalidate();
            display_area.repaint();
            display_area.revalidate();
        }
    });
}

public static void addToGrid(GridBagConstraints c, Component parent, Component child, int x, int y, double weightx, double weighty, int anchor){

    String fcls = parent.getClass().toString();
    String cls = fcls.substring(fcls.lastIndexOf(".")+1);

    c.fill = GridBagConstraints.HORIZONTAL;
    c.anchor = anchor;
    c.weightx = weightx;
    c.weighty = weighty;
    c.gridx = x;
    c.gridy = y;

    if ("JFrame".equals(cls) || "main".equals(cls)) {
        JFrame frame = (JFrame) parent;
        frame.add(child,c);
    } else if ("JPanel".equals(cls)) {
        JPanel panel = (JPanel) parent;
        panel.add(child, c);
    }
}

public static void addToGrid(GridBagConstraints c, JFrame frame, Component element, int x, int y, double weightx, double weighty, int anchor, int gridwidth){

    String fcls = element.getClass().toString();
    String cls = fcls.substring(fcls.lastIndexOf(".")+1);


    c.anchor = anchor;
    c.weightx = weightx;
    c.weighty = weighty;
    c.gridx = x;
    c.gridy = y;
    c.gridwidth = gridwidth;
    if ("JScrollPane".equals(cls)) {
        c.fill = GridBagConstraints.BOTH;
    } else {
        c.fill = GridBagConstraints.HORIZONTAL;
    }
    frame.add(element,c);
}

private static void setAnchCodes() {
    anch_codes.put("FIRST_LINE_START", 23);
    anch_codes.put("FIRST_LINE_END", 24);
}

// Variables declaration - do not modify                     
private javax.swing.JMenu jMenu1;
private javax.swing.JMenu jMenu2;
private javax.swing.JMenuBar jMenuBar1;
private javax.swing.JMenuItem jMenuItem1;
// End of variables declaration                   
}

我对外框也有同样的问题,也有网格袋布局,但我通过将重量设置为高值来解决它,但这不适用于有问题的情况,可能不是正确的方法去做吧。如果任何人可以提供任何建议,那将会有很大的帮助。

1 个答案:

答案 0 :(得分:2)

你不需要使用GridBagLayout,我建议你不要这样做。而是为具有1列和任意行数的Grid创建一个使用GridLayout(0, 1)的JPanel。然后 - 这是关键 - 将此JPanel放入另一个使用BorderLayout的JPanel,进入BorderLayout.PAGE_START位置,以便它始终位于顶部。然后将此边框布局 - 使用JPanel放入JScrollPane。

例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;

import javax.swing.*;

public class AddComponents extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = 450;
    private JTextField inputField = new JTextField(20);
    private AddAction addAction = new AddAction("Add");
    private JButton addButton = new JButton(addAction);
    private JPanel innerPanel = new JPanel(new GridLayout(0, 1)); // 1 column, any number of rows

    public AddComponents() {
        JPanel borderLayoutPanel = new JPanel(new BorderLayout());
        borderLayoutPanel.add(innerPanel, BorderLayout.PAGE_START);
        JScrollPane scrollPane = new JScrollPane(borderLayoutPanel);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        inputField.setAction(addAction);
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
        topPanel.add(inputField);
        topPanel.add(addButton);

        setLayout(new BorderLayout());
        add(scrollPane);
        add(topPanel, BorderLayout.PAGE_START);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension prefSize = super.getPreferredSize();
        if (isPreferredSizeSet()) {
            return prefSize;
        } else {
            int w = Math.max(PREF_W, prefSize.width);
            int h = Math.max(PREF_H, prefSize.height);
            return new Dimension(w, h);
        }
    }

    private class AddAction extends AbstractAction {
        public AddAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String text = inputField.getText();
            JTextField innerTextField = new JTextField(text);
            innerPanel.add(innerTextField);
            revalidate();
            repaint();
            inputField.selectAll();
            inputField.requestFocusInWindow();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        AddComponents mainPanel = new AddComponents();
        JFrame frame = new JFrame("Add Components");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }
}

但是,如果你想显示这个,那么根据你的需要,你可以显示JTextField的等价物,可以编辑或不编辑,然后使用简单的JTable。

例如:

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;

public class AddItems extends JPanel {
    private static final int PREF_W = 600;
    private static final int PREF_H = 450;
    private JTextField inputField = new JTextField(20);
    private AddToTableAction addAction = new AddToTableAction("Add");
    private JButton addButton = new JButton(addAction);
    private DefaultTableModel tableModel = new DefaultTableModel(new String[]{"A"}, 0);
    private JTable table = new JTable(tableModel){
        public boolean isCellEditable(int row, int column) {
            return false;
        };
    };

    public AddItems() {
        table.setTableHeader(null);
        JScrollPane scrollPane = new JScrollPane(table);
        scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);

        inputField.setAction(addAction);
        JPanel topPanel = new JPanel();
        topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.LINE_AXIS));
        topPanel.add(inputField);
        topPanel.add(addButton);

        setLayout(new BorderLayout());
        add(scrollPane);
        add(topPanel, BorderLayout.PAGE_START);
    }

    @Override
    public Dimension getPreferredSize() {
        Dimension prefSize = super.getPreferredSize();
        if (isPreferredSizeSet()) {
            return prefSize;
        } else {
            int w = Math.max(PREF_W, prefSize.width);
            int h = Math.max(PREF_H, prefSize.height);
            return new Dimension(w, h);
        }
    }

    private class AddToTableAction extends AbstractAction {
        public AddToTableAction(String name) {
            super(name);
        }

        @Override
        public void actionPerformed(ActionEvent e) {
            String text = inputField.getText();
            tableModel.addRow(new String[] {text});
            inputField.selectAll();
            inputField.requestFocusInWindow();
        }
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }

    private static void createAndShowGui() {
        AddItems mainPanel = new AddItems();
        JFrame frame = new JFrame("AddItems");
        frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
        frame.add(mainPanel);
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
}