How to Dynamically Add JButton to JPanel?

后端 未结 3 551
傲寒
傲寒 2020-12-06 23:51

In NetBeans, I have used the GUI editor to make a JFrame and I\'ve put a JPanel in the frame. At the moment, I\'m trying to make a new button in the panel when the class con

3条回答
  •  执笔经年
    2020-12-07 00:04

    Normally the add call is sufficient.

    Note: a BorderLayout can only contain one component in each location. So if you add another component in 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 set a BorderLayout on that specific panel ? Otherwise the BorderLayout#NORTH constraint is incorrect

    All the validate,revalidate,repaint calls can be removed

    Edit

    It seems some sort of validation is needed after all. I was under the impression that Swing should be smart enough to listen for the event when something is added to a Container, and update whatever is necessary (a bit similar to updating a TableModel updates the JTable based on events, without the need to call repaint or the likes on the JTable).

    However, when trying this in an SSCCE, I came to the following code (different versions, only post the most elaborate version)

    • without the scroll-pane, the validate calls seem to have no effect. I actually need to call pack again to make the new labels visible (not included in the SSCCE, but removing the scrollpane from the code is trivial)
    • with the scroll-pane, the validate call 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 );
            }
          } );
      
        }
      
      }
      

提交回复
热议问题