如何阻止 JTextField 和 JTextLabel 在 JPanel 上截断

How to stop JTextField and JTextLabel from truncating on JPanel

每次按下 JButton 时,我都会将 JTextFieldsJLabels 添加到我的 JPanel(从左到右)。但是,每添加一个新的 JTextFieldJLabel 就会变得越来越小。我该如何解决这个问题?

另外,我想在 JPanel 中添加一个 JScrollPane,但这样做有问题。

     public class MyExample 
{
    // Field members
    static JPanel panel = new JPanel();
    static Integer indexer = 1;
    static List<JLabel> listOfLabels = new ArrayList<JLabel>();
    static List<JTextField> listOfTextFields = new ArrayList<JTextField>();
    static JScrollPane scrollPane = new JScrollPane( panel );

    public static void main(String[] args)
    {       
        // Construct frame
        JFrame frame = new JFrame();
        frame.setLayout(new GridBagLayout());
        frame.setPreferredSize(new Dimension(2000, 2000));
        frame.setTitle("My Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        frame.getContentPane().add(scrollPane);

        // Frame constraints
        GridBagConstraints frameConstraints = new GridBagConstraints();

        // Construct button
        JButton addButton = new JButton("Add");
        addButton.addActionListener(new ButtonListener());

        // Add button to frame
        frameConstraints.gridx = 0;
        frameConstraints.gridy = 0;
        frame.add(addButton, frameConstraints);

        // Construct panel
        panel.setPreferredSize(new Dimension(1000, 1000));
        panel.setLayout(new GridBagLayout());
        panel.setBorder(LineBorder.createBlackLineBorder());

        // Add panel to frame
        frameConstraints.gridx = 0;
        frameConstraints.gridy = 1;
        frameConstraints.weighty = 1;
        frame.add(panel, frameConstraints);

        // Pack frame
        frame.pack();

        // Make frame visible
        frame.setVisible(true);
    }

    static class ButtonListener implements ActionListener
    {
        @Override
        public void actionPerformed(ActionEvent arg0) 
        {       
            // Clear panel
            panel.removeAll();

            // Create label and text field
            JTextField jTextField = new JTextField();
            jTextField.setSize(100, 200);
            listOfTextFields.add(jTextField);
            listOfLabels.add(new JLabel("Label " + indexer));

            // Create constraints
            GridBagConstraints textFieldConstraints = new GridBagConstraints();
            GridBagConstraints labelConstraints = new GridBagConstraints();

            // Add labels and text fields
            for(int i = 0; i < indexer; i++)
            {
                // Text field constraints
                textFieldConstraints.gridx = i;
                textFieldConstraints.fill = GridBagConstraints.HORIZONTAL;
                textFieldConstraints.weightx = 0.5;
                textFieldConstraints.insets = new Insets(10, 10, 10, 10);
                textFieldConstraints.gridy = 1;

                // Label constraints
                labelConstraints.gridx = i;
                labelConstraints.gridy = 0;
                labelConstraints.insets = new Insets(10, 10, 10, 10);

                // Add them to panel
                panel.add(listOfLabels.get(i), labelConstraints);
                panel.add(listOfTextFields.get(i), textFieldConstraints);
            }

            // Align components
            GridBagConstraints c = new GridBagConstraints();
            c.gridx = 0;
            c.gridy = indexer;
            c.weighty = 1;
            panel.add(new JLabel(), c);

            // Increment indexer
            indexer++;
            panel.updateUI();
        }
    }
}

至于以 panel 作为视口的 JScrollPane,您根本不应该将面板添加到框架 - 将其设置为视口(就像您在 JScrollPane 构造函数中所做的那样)并添加JScrollPane 就足够了。添加面板本身可能是您遇到问题的原因。

至于缩小的问题,我仍在尝试理解您的布局代码 - 您对 GridBagLayout 的使用对我来说似乎有点过于复杂。也许你可以画一个简单的草图,说明你想要的布局外观?

However, every new JTextField and JLabelthat is added becomes smaller and smaller. How do I fix this?

panel.setPreferredSize(new Dimension(1000, 1000));

不要设置首选尺寸。如果大小是固定的,那么当您添加更多组件时,它们需要缩小以适应允许的 space.

不要尝试设置任何组件的大小。让布局管理器完成它的工作并确定面板的首选大小。

创建 JTextField 时,代码应类似于:

//JTextField jTextField = new JTextField();
JTextField jTextField = new JTextField(10);

这将允许文本字段确定自己的首选大小以显示大约 10 个字符。

panel.updateUI();

不要使用 updateUI()。当您更改 LAF 时,Swing 会在内部使用它。当您 remove/add 组件时,您应该使用:

panel.revalidate();
panel.repaint();