我需要动态添加组件。而且,我需要动态地改变布局。
答案 0 :(得分:13)
作为参考,这里有一个显示基本方法sscce的validate()
。这个更精细的example显示了两个要求:它更改布局并动态添加组件。
import java.awt.*;
import java.awt.event.ActionEvent;
import javax.swing.*;
/** @see http://stackoverflow.com/questions/5750068 */
public class DynamicLayout extends JPanel {
private static final LayoutManager H = new GridLayout(1, 0);
private static final LayoutManager V = new GridLayout(0, 1);
public DynamicLayout() {
this.setLayout(H);
this.setPreferredSize(new Dimension(320, 240));
for (int i = 0; i < 3; i++) {
this.add(new JLabel("Label " + String.valueOf(i), JLabel.CENTER));
}
}
private void display() {
JFrame f = new JFrame("DynamicLayout");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
JPanel p = new JPanel();
p.add(new JButton(new AbstractAction("Horizontal") {
@Override
public void actionPerformed(ActionEvent e) {
DynamicLayout.this.setLayout(H);
DynamicLayout.this.validate();
}
}));
p.add(new JButton(new AbstractAction("Vertical") {
@Override
public void actionPerformed(ActionEvent e) {
DynamicLayout.this.setLayout(V);
DynamicLayout.this.validate();
}
}));
f.add(p, BorderLayout.SOUTH);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new DynamicLayout().display();
}
});
}
}
答案 1 :(得分:1)
动态更改布局的示例:
package swinglayout;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class LayoutChanger implements ActionListener{
JButton b1;
JButton b2;
JButton b3;
JButton b4;
JButton b5;
JButton b6;
/** This button set the flowlayout on panel2 with left orientation */
JButton flowLayout;
/** This button set the Gridlayout of 2,3 grid on panel2 */
JButton gridLayout;
/** This button set the Borderlayout on panel2*/
JButton borderLayout;
/**
* This panel is control panel where we use button to change
* layout of another panel
*/
JPanel panel;
/** This panel contain multiple button from b1 to b6 */
JPanel panel2;
JFrame frame;
public LayoutChanger() {
//set Default Look and Feel on frame
JFrame.setDefaultLookAndFeelDecorated(true);
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = frame.getContentPane();
con.setLayout(new BorderLayout());
panel = new JPanel();
panel2 = new JPanel();
//This button are used to only showing the layout effect
b1 = new JButton("HelloButton1");
b2 = new JButton("HelloButton2");
b3 = new JButton("HelloButton3");
b4 = new JButton("HelloButton4");
b5 = new JButton("HelloButton5");
b6 = new JButton("HelloButton6");
// By default panel have layout
panel2.add(b1);
panel2.add(b2);
panel2.add(b3);
panel2.add(b4);
panel2.add(b5);
panel2.add(b6);
// Layout changer button
flowLayout = new JButton("FlowLayout");
gridLayout = new JButton("GridLayout");
borderLayout = new JButton("BorderLayout");
//call Action listener on every layout changer button
flowLayout.addActionListener(this);
gridLayout.addActionListener(this);
borderLayout.addActionListener(this);
panel.add(flowLayout);
panel.add(gridLayout);
panel.add(borderLayout);
// add layout changer button panel at a top
//button panel at the center of container
con.add(panel, BorderLayout.PAGE_START);
con.add(panel2, BorderLayout.CENTER);
frame.setVisible(true);
frame.pack();
}
public void actionPerformed(ActionEvent e) {
//set the flowlayout on panel2
if(e.getSource() == flowLayout) {
FlowLayout flow = new FlowLayout(FlowLayout.LEFT);
panel2.setLayout(flow);
panel2.validate();
}
//set the gridlayout on panel2
if(e.getSource() == gridLayout) {
GridLayout grid = new GridLayout(2,3);
panel2.setLayout(grid);
panel2.validate();
}
//set the gridlayout but the problem if we don't set the constraint
//all button are set on center. So you remove the all button from panel
//Then set grid layout on panel and add them with constraints.
if(e.getSource() == borderLayout) {
panel2.remove(b1);
panel2.remove(b2);
panel2.remove(b3);
panel2.remove(b4);
panel2.remove(b5);
panel2.remove(b6);
BorderLayout border = new BorderLayout();
panel2.setLayout(border);
panel2.add(b1,BorderLayout.NORTH);
panel2.add(b2,BorderLayout.SOUTH);
panel2.add(b3,BorderLayout.EAST);
panel2.add(b4,BorderLayout.WEST);
panel2.add(b5,BorderLayout.CENTER);
panel2.add(b6,BorderLayout.BEFORE_FIRST_LINE);
panel2.validate();
}
}
public static void main(String args[]) {
new LayoutChanger();
}
}
有一点需要记住,你在面板上设置了新的布局,不要忘记在面板上调用方法validate()
。如果你不调用这个方法,你就不会看到布局变化的影响。如果要在不调用方法的情况下查看效果,则必须调整框架的大小。
您也可以非常轻松地设置相同的布局,例如FlowLayout
,GridLayout
和BoxLayout
,但是当设置BorderLayout
时,它需要添加元素的约束,因此我们首先从面板中删除所有组件通过remove(Component comp)
方法,然后按约束