【问题标题】:How to dynamically add JLabels to JPanel?如何将 JLabels 动态添加到 JPanel?
【发布时间】:2012-12-11 09:27:20
【问题描述】:

我遇到了这个问题。我有一个 JPanel,通常我会像这样创建一个 JLabel:

JLabel lblNewLabel = new JLabel("New label");
lblNewLabel.setBounds(0, 0, 135, 14);
panel.add(lblNewLabel);

但我希望每次单击按钮时,在该面板中创建一个大小相同但高度位置不同的新 JLabel。我试过了:

panel.add(new JLabel(stringName));

但这样我就无法设置它的界限。我从 JTextField 获得的字符串名称。

【问题讨论】:

  • "通常我会像这样创建一个 JLabel:..lblNewLabel.setBounds(0, 0, 135, 14);" 通常你做错了。 使用布局!

标签: java swing dynamic jlabel setbounds


【解决方案1】:

尝试交换命令的顺序,先添加面板,然后设置位置。

【讨论】:

    【解决方案2】:

    首先,使用layout。正确完成布局将按照您的意愿放置组件。其次,在将组件动态添加到布局时,您需要告诉布局进行更新。这是一个例子,每次按下按钮时都会添加一个标签:

    public static void main(String[] args) {
    
        final JFrame frame = new JFrame("Test");
        frame.setLayout(new GridLayout(0, 1));
    
        frame.add(new JButton(new AbstractAction("Click to add") {
            @Override
            public void actionPerformed(ActionEvent e) {
    
                SwingUtilities.invokeLater(new Runnable() {
                    @Override
                    public void run() {
                        frame.add(new JLabel("Bla"));
                        frame.validate();
                        frame.repaint();
                    }
                });
            }
        }));
    
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(400, 300);
        SwingUtilities.invokeLater(new Runnable() {
            @Override public void run() {
                frame.setVisible(true);
            }
        });
    }
    

    【讨论】:

    • Swing 组件也应该在 EDT 上创建,setSize 是真正的不可用,正确的LayoutManager 并在设置为可见之前在JFrame 上调用pack()
    • @DavidKroukamp:在实现之前无需在 EDT 上执行(在本例中为 setVisible(true)),并且关于 pack() 这个示例需要更多空间来证明这一点。
    • 我不明白你的意思?我没有看到 invokeLater 块会导致 JFrame#setVisible(true); 在 EDT 上运行?至于pack()在添加组件以调整JFrame大小后会派上用场的空间,如果setSize是必须的,而必须覆盖getPrefferedSize()并返回适当的尺寸
    【解决方案3】:

    正如@AndrewThompson 所说,使用正确的LayoutManager,您不应该乱用setBounds 等。

    这是我做的一个例子(每次点击JButton 时,只需在JPanel 中添加一个JLabel):

    import java.awt.BorderLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.*;
    
    public class Test {
    
        public Test() {
            createAndShowUI();
        }
    
        private void createAndShowUI() {
            JFrame frame = new JFrame("Test");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
            initComponents(frame);
    
            frame.setResizable(false);
            frame.pack();
            frame.setVisible(true);
        }
    
        private void initComponents(final JFrame frame) {
    
            final JPanel panel = new JPanel();
    
            JButton button = new JButton("Add label");
    
            button.addActionListener(new ActionListener() {
                int count = 1;
    
                @Override
                public void actionPerformed(ActionEvent e) {
                    JLabel _lbl = new JLabel("Label " + count);//make label and assign text in 1 line
    
                    panel.add(_lbl);//add label we made
    
                    panel.revalidate();
                    panel.repaint();
    
                    frame.pack();//so our frame resizes to compensate for new components
    
                    count++;
                }
            });
    
            frame.add(panel, BorderLayout.CENTER);
            frame.add(button, BorderLayout.SOUTH);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                @Override
                public void run() {
                    new Test();
                }
            });
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2023-03-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      相关资源
      最近更新 更多