添加新组件时(每当按下按钮时),有没有更简单的方法可以将“旧”组件下移?

时间:2018-07-17 09:00:10

标签: java swing layout-manager gridbaglayout

我尝试寻找问题的答案,但找不到类似的内容。如果已经被询问,请链接。预先感谢。

主面板mainPanel的布局是GridBagLayout。它具有三个按钮。其中两个是哑音(出于本问题的目的)。每次按下butt2时,中间的按钮butt2会创建一个包含其他组件的JPanel。

因为butt2在中间,而butt3在它的正下方,所以我有一个int变量tracker2,它跟踪butt2的网格。每次按下butt2时,我都会创建一个新的JPanel,它位于butt2下,递增tracker2,然后删除butt3并将其添加到较新的组件下方。

import java.util.List;
import java.util.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.*;

 public class Demo implements ActionListener 
     public static void main(String[] args) {
         Demo demo = new Demo();
     }

     private JFrame frame;
     private JPanel mainPanel;
     private JButton butt1, butt2, butt3;
     private GridBagConstraints gb;
     private List<JTextField> list;
     private int count, tracker2;

     public Demo() {
         frame = new JFrame("Demo");
         frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         frame.setResizable(true);
         frame.setBounds(0, 0, 800, 800);
         list = new ArrayList<JTextField>();
         count = 0;
         tracker2 = 0;

         commence();
     }

     private void commence() {
         gb = new GridBagConstraints();
         gb.anchor = GridBagConstraints.FIRST_LINE_START;
         gb.weightx = 1;
         gb.insets = new Insets(50, 5, 0, 20);

         mainPanel = new JPanel();
         mainPanel.setBackground(Color.white);
         mainPanel.setLayout( new GridBagLayout() );

         butt1 = new JButton("One");
         butt1.setPreferredSize( new Dimension(100, 50) );
         // Add to panel
         gb.gridx = 0;
         gb.gridy = 0;
         mainPanel.add( butt1, gb);

         butt2 = new JButton("Two");
         butt2.setPreferredSize( new Dimension(100, 50) );
         butt2.addActionListener(this);
         // Add to panel
         gb.gridy++;
         tracker2 = gb.gridy;
         mainPanel.add( butt2, gb );

         butt3 = new JButton("Three");
         butt3.setPreferredSize( new Dimension(100, 50) );
         // Add to panel
         gb.gridy++;
         mainPanel.add( butt3, gb );

         frame.add(mainPanel);
         frame.setVisible(true);
         frame.repaint();
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource().equals( butt2 )) {
            commence2();
        }
    }

    private void commence2() {
        gb.insets = new Insets( 0, 0, 0, 0 );
        list.add( new JTextField(30) );

        JLabel label = new JLabel("LABEL 2   ");
        label.setDisplayedMnemonic( KeyEvent.VK_N );
        label.setLabelFor( list.get(count) );

        JPanel panel = new JPanel( new FlowLayout(FlowLayout.LEFT, 10, 3));
        panel.setBackground( Color.white );
        panel.add(label);
        panel.add(list.get( count ));
        // Add to mainPanel
        tracker2++;
        gb.gridy = tracker2;
        mainPanel.add( panel, gb );
        updateFrame();
        // Increment count
        count++;

        frame.revalidate();
        frame.repaint();
    }

    private void updateFrame() {
        mainPanel.remove( butt3 );
        gb.insets = new Insets(50, 5, 0, 20);
        gb.gridy = tracker2 + 1;
        mainPanel.add( butt3, gb );
    }
}

是否有更简单的方法或自动为我执行此操作的布局?

1 个答案:

答案 0 :(得分:2)

是的,有一种更简单的方法。不必将新的文本字段添加到您的mainPanel中,而是使用附加的Container。例如

public class Demo2 implements ActionListener {
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override
      public void run() {
        new Demo2();
      }
    });
  }

  private JFrame frame;
  private JPanel textPanel;
  private JButton butt1, butt2, butt3;

  public Demo2() {
    frame = new JFrame("Demo");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setResizable(true);
    frame.setBounds(0, 0, 800, 800);

    commence();
  }

  private void commence() {
    GridBagConstraints gb = new GridBagConstraints();
    gb.anchor = GridBagConstraints.FIRST_LINE_START;
    gb.weightx = 1;
    gb.insets = new Insets(50, 5, 0, 20);

    JPanel mainPanel = new JPanel();
    mainPanel.setBackground(Color.white);
    mainPanel.setLayout( new GridBagLayout() );

    butt1 = new JButton("One");
    butt1.setPreferredSize( new Dimension(100, 50) );
    // Add to panel
    gb.gridx = 0;
    gb.gridy = 0;
    mainPanel.add( butt1, gb);

    butt2 = new JButton("Two");
    butt2.setPreferredSize( new Dimension(100, 50) );
    butt2.addActionListener(this);
    // Add to panel
    gb.gridy++;
    gb.insets = new Insets(50, 5, 0, 0);
    mainPanel.add( butt2, gb );

    textPanel = new JPanel(new GridLayout(0, 1));
    // Add to panel
    gb.gridy++;
    gb.insets = new Insets(0, 5, 0, 20);
    mainPanel.add( textPanel, gb );

    butt3 = new JButton("Three");
    butt3.setPreferredSize( new Dimension(100, 50) );
    // Add to panel
    gb.gridy++;
    gb.insets = new Insets(50, 5, 0, 20);
    mainPanel.add( butt3, gb );

    frame.add(mainPanel);
    frame.setVisible(true);
    frame.repaint();
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    if(e.getSource().equals( butt2 )) {
      commence2();
    }
  }

  private void commence2() {
    JTextField jtf = new JTextField(30);

    JLabel label = new JLabel("LABEL 2   ");
    label.setDisplayedMnemonic(KeyEvent.VK_N );
    label.setLabelFor( jtf );

    JPanel panel = new JPanel( new FlowLayout(FlowLayout.LEFT, 10, 3));
    panel.setBackground( Color.white );
    panel.add(label);
    panel.add( jtf );

    // Add to mainPanel
    textPanel.add( panel );
    textPanel.revalidate();

    frame.revalidate();
    frame.repaint();
  }
}

在上面的代码中,textPanel用作新文本字段的容器。