Usually just calling add
enough.
Note: a BorderLayout
can contain only one component in each location. Therefore, if you add another component to the NORTH
location, your button will not be visible.
Second note: by default, a JPanel
does not have a BorderLayout
, but a FlowLayout
. Have you installed BorderLayout
on this particular panel? Otherwise, the BorderLayout#NORTH
constraint is incorrect.
All calls to validate
, revalidate
, repaint
can be removed
Edit
It seems that some kind of validation is needed in the end. I got the impression that Swing should be smart enough to listen to the event when something is added to the Container
and update everything it needs (a bit like updating TableModel
updates JTable
based on events, without the need to call repaint
or JTable
on JTable
) .
However, when you try to do this in SSCCE, I came to the following code (different versions, only publish the most complex version)
- without a scroll pane,
validate
calls seem ineffective. I really need to call pack
again to make the new shortcuts visible (not included in SSCCE, but removing scroll from code is trivial) using the scroll pane, calling validate
has an effect
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 ); } } ); } }
source share