如何动态地向JPanel添加JLabel?

12

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

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

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

panel.add(new JLabel(stringName));

但这样我无法设置它的边界。stringName来自JTextField。


4
通常我会这样创建一个JLabel:.. lblNewLabel.setBounds(0, 0, 135, 14); 通常你这样做是错误的。使用布局管理器! - Andrew Thompson
3个回答

14

首先,使用布局。如果正确使用布局,它将按您想要的方式放置组件。其次,在动态添加组件到布局时,需要告诉布局进行更新。以下是一个示例,每次按下按钮都会添加一个标签:

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

3
Swing 组件应该在 EDT 上创建,并且不要使用 setSize,而是使用正确的 LayoutManager,在设置可见性之前在 JFrame 上调用 pack() 方法。 - David Kroukamp
1
@DavidKroukamp:在实现之前(在这种情况下是setVisible(true)),不需要在EDT上执行它,关于pack(),此示例需要更多的空间来证明这一点。 - dacwe
1
我不明白你的意思?我没有看到任何invokeLater块会导致在EDT上运行JFrame#setVisible(true);。至于空间,这就是在添加组件后使用pack()来调整JFrame大小的地方,如果必须使用setSize,那么最好重写getPrefferedSize()并返回适当的尺寸。 - David Kroukamp

4

如@AndrewThompson所说,使用正确的LayoutManager,不应该去操作setBounds等方法。

这里有一个我制作的例子(每次点击JButton时,简单地向JPanel添加一个JLabel):

enter image description here

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();
            }
        });
    }
}

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接