Как динамически добавить JButton в JPanel? - PullRequest
1 голос
/ 27 марта 2012

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

Я гуглил всю ночь, но не могу заставить ее работать.

Ответы [ 3 ]

3 голосов
/ 27 марта 2012

Обычно достаточно вызова add.

Примечание: BorderLayout может содержать только один компонент в каждом местоположении.Поэтому, если вы добавите еще один компонент в местоположение NORTH, ваша кнопка не будет видна.

Второе примечание: по умолчанию JPanel не имеет BorderLayout, а FlowLayout.Вы установили BorderLayout на этой конкретной панели?В противном случае ограничение BorderLayout#NORTH является неправильным

Все вызовы validate, revalidate, repaint могут быть удалены

Редактировать

Кажется, все-таки нужна какая-то проверка.У меня сложилось впечатление, что Swing должен быть достаточно умен, чтобы слушать событие, когда что-то добавляется в Container, и обновлять все, что необходимо (немного похоже на обновление TableModel, обновляет JTable на основе событий,без необходимости вызывать repaint или подобные сообщения на JTable).

Однако, пробуя это в 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 );
          }
        } );
    
      }
    
    }
    
3 голосов
/ 27 марта 2012

Иногда, когда вы не видите кнопку, это проблема менеджера макета (так как вы не устанавливаете правильные свойства для менеджера макета).Вы можете проверить это, отключив его:

this.jPanel2.setLayoutManager(null);

И установив границы для кнопки (JButton.setBounds()).

Если вышеперечисленное решает вашу проблему, вам необходимо ознакомиться с требованиями, установленными используемым LayoutManager (см. Также ответ Робина).

Все вызовы validate(), revalidate() и repaint() не нужны для этого.

0 голосов
/ 12 сентября 2013

Создание динамического JButton с помощью Image и ActionListener - Java Swing

Создание JButton динамически с помощью Image и ActionListener.Вы сможете изменить высоту кнопки, ширину горизонтального зазора и вертикальный зазор в одном месте.

более подробную информацию вы можете найти здесь

enter image description here

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...