如何动态添加JButton到JPanel?

在NetBeans中,我使用GUI编辑器制作JFrame,并在框架中放置了JPanel。 目前,我正在尝试在类构造时在面板中创建一个新按钮。 这是我的代码,但我似乎无法让它工作。 (第一行显示按钮,其他行尝试显示它。)

this.jPanel2.add(new JButton("Test"),BorderLayout.NORTH); this.jPanel2.validate(); this.jPanel2.revalidate(); this.jPanel2.repaint(); this.jPanel2.setVisible(true); this.revalidate(); this.setVisible(true); this.repaint(); 

我一直在谷歌上搜索,但似乎无法让它工作。

有时,当您没有看到按钮时,它是布局管理器问题(因为您没有为布局管理器设置正确的属性)。 您可以通过禁用它来测试它:

 this.jPanel2.setLayoutManager(null); 

并设置按钮的边界( JButton.setBounds() )。

如果以上解决了您的问题,那么您需要查看您正在使用的LayoutManager设置的要求(另请参阅Robin的答案)。

执行此操作不需要对validate()revalidate()repaint()所有调用。

通常, add调用就足够了。

注意: BorderLayout只能在每个位置包含一个组件。 因此,如果您在NORTH位置添加其他组件,则您的按钮将不可见。

第二个注释:默认情况下, JPanel没有BorderLayout而是FlowLayout 。 您是否在该特定面板上设置了BorderLayout ? 否则BorderLayout#NORTH约束不正确

可以删除所有validaterevalidaterepaint调用的调用

编辑

毕竟,似乎需要进行某种validation。 我的印象是Swing应该足够聪明,可以在将某些内容添加到Container时监听事件,并更新任何必要的内容(有点类似于更新TableModel根据事件更新JTable ,而无需调用repaintJTable上的喜欢)。

但是,在SSCCE中尝试这个时,我得到了以下代码(不同的版本,只发布最精细的版本)

  • 没有滚动窗格, validate调用似乎没有任何效果。 我实际上需要再次调用pack以使新标签可见(不包括在SSCCE中,但从代码中删除滚动窗格是微不足道的)
  • 使用滚动窗格, validate调用具有效果

     import javax.swing.BoxLayout; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; public class AddLabelsAtRuntime { private int fLabelCounter = 0; private JPanel fLabelPanel; private final JFrame fTestFrame; public AddLabelsAtRuntime() { fLabelPanel = new JPanel( ); BoxLayout boxLayout = new BoxLayout( fLabelPanel, BoxLayout.PAGE_AXIS ); fLabelPanel.setLayout( boxLayout ); fTestFrame = new JFrame( "Dynamically add labels" ); } private JFrame createUI(){ Container contentPane = fTestFrame.getContentPane(); contentPane.setLayout( new BorderLayout() ); JScrollPane scrollPane = new JScrollPane( fLabelPanel ); scrollPane.setPreferredSize( new Dimension( 200, 200 ) ); contentPane.add( scrollPane, BorderLayout.CENTER ); contentPane.add( createButtonPanel(), BorderLayout.SOUTH ); fTestFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); fTestFrame.pack(); return fTestFrame; } private void addLabel(){ fLabelPanel.add( new JLabel( "Label " + ++fLabelCounter ) ); } private JPanel createButtonPanel(){ JPanel buttonPanel = new JPanel( ); BoxLayout boxLayout = new BoxLayout( buttonPanel, BoxLayout.LINE_AXIS ); buttonPanel.setLayout( boxLayout ); JButton validateButton = new JButton( "Add + validate" ); validateButton.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { addLabel(); fLabelPanel.validate(); fTestFrame.validate(); } } ); buttonPanel.add( validateButton ); JButton noValidateButton = new JButton( "Add" ); noValidateButton.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { addLabel(); } } ); buttonPanel.add( noValidateButton ); JButton packButton = new JButton( "Add + pack" ); packButton.addActionListener( new ActionListener() { @Override public void actionPerformed( ActionEvent e ) { addLabel(); fTestFrame.pack(); } } ); buttonPanel.add( packButton ); return buttonPanel; } public static void main( String[] args ) { EventQueue.invokeLater( new Runnable() { @Override public void run() { AddLabelsAtRuntime addLabelsAtRuntime = new AddLabelsAtRuntime(); addLabelsAtRuntime.createUI().setVisible( true ); } } ); } } 

使用Image和ActionListener创建动态JButton – Java Swing

使用Image和ActionListener动态创建JButton。 您可以在一个位置更改按钮高度,宽度水平间隙和垂直间隙。

你可以在这里找到更多细节

在此处输入图像描述