添加新组件时(每当按下按钮时)是否有更简单的方法将 'older' 组件向下移动?
Is there an easier way to shift 'older' components down when adding newer components (whenever a button is pressed)?
我尝试寻找我的问题的答案,但找不到任何类似的答案。如果已经有人问过,请 link。提前致谢。
主面板mainPanel的布局为GridBagLayout。它有三个按钮。其中两个是哑弹(出于这个问题的目的)。每次按下 butt2 时,中间按钮 butt2 都会创建一个包含其他组件的 JPanel。
因为butt2在中间,而butt3在它的正下方,我有一个int变量tracker2,它跟踪butt2的网格。每次按下 butt2 时,我都会在 butt2 下创建一个新的 JPanel,增加 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 );
}
}
是否有更简单的方法或自动为我执行此操作的布局?
是的,有更简单的方法。不要将新文本字段添加到 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
用作新文本字段的容器。
我尝试寻找我的问题的答案,但找不到任何类似的答案。如果已经有人问过,请 link。提前致谢。
主面板mainPanel的布局为GridBagLayout。它有三个按钮。其中两个是哑弹(出于这个问题的目的)。每次按下 butt2 时,中间按钮 butt2 都会创建一个包含其他组件的 JPanel。
因为butt2在中间,而butt3在它的正下方,我有一个int变量tracker2,它跟踪butt2的网格。每次按下 butt2 时,我都会在 butt2 下创建一个新的 JPanel,增加 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 );
}
}
是否有更简单的方法或自动为我执行此操作的布局?
是的,有更简单的方法。不要将新文本字段添加到 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
用作新文本字段的容器。