How to Dynamically Add JButton to JPanel?

后端 未结 3 548
傲寒
傲寒 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 );
            }
          } );
      
        }
      
      }
      
    0 讨论(0)
  • 2020-12-07 00:18

    Some times when you don't see a button it is a layout manager issue (as in you aren't setting the right properties for the layout manager). You can test this by disabling it:

    this.jPanel2.setLayoutManager(null);
    

    And setting bounds for the button (JButton.setBounds()).

    If the above fixes your problem, then you need to look into the requirements set by the LayoutManager you are using (see also the answer by Robin).

    All the calls to validate(), revalidate() and repaint() are not needed to do this.

    0 讨论(0)
  • 2020-12-07 00:19

    Create Dynamic JButton with Image and ActionListener - Java Swing

    Create JButton dynamically with Image and the ActionListener . You will be able to change the button height , width horizontal gap and vertical gap in one place.

    you can find more details from here

    enter image description here

    0 讨论(0)
提交回复
热议问题