I need to add components dynamically. Moreover, I need to alter the layout dynamically.
To dynamically change layouts after each menu action, set the new layout with its constraints and call the revalidate() method.
Swing in Java is a lightweight GUI toolkit which has a wide variety of widgets for building optimized window based applications. It is a part of the JFC( Java Foundation Classes). It is build on top of the AWT API and entirely written in java. It is platform independent unlike AWT and has lightweight components.
JavaFX new fixes will continue to be supported on Java SE 8 through March 2022 and removed from Java SE 11. Swing and AWT will continue to be supported on Java SE 8 through at least March 2025, and on Java SE 11 (18.9 LTS) through at least September 2026.
For reference, here's an sscce that shows the essential method, validate()
. This more elaborate example shows both requirements: it changes the layout and adds components dynamically.
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();
}
});
}
}
Example of changing the layout Dynamically :
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();
}
}
One thing remember is you set new layout on panel don't forgot call the method validate()
on panel.If you don't call this method you don't see the effect of change in layout. If you want to see the effect with out call the method you must resize the frame.
Also you can set same layout very easily like FlowLayout
,GridLayout
and BoxLayout
, but when set BorderLayout
it required constraints for adding element, so we first remove all component from panel by remove(Component comp)
method then add the component in panel by constraint
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With