Java - How Would I Dynamically Add Swing Component to Gui on Click

java - How would I dynamically add swing component to gui on click?

Sample code to add Buttons on the fly dynamically.

panel.add(new JButton("Button"));
validate();

Full code:

import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JPanel;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import java.awt.FlowLayout;
import java.awt.BorderLayout;

public class AddComponentOnJFrameAtRuntime extends JFrame implements ActionListener {

JPanel panel;

public AddComponentOnJFrameAtRuntime() {
super("Add component on JFrame at runtime");
setLayout(new BorderLayout());
this.panel = new JPanel();
this.panel.setLayout(new FlowLayout());
add(panel, BorderLayout.CENTER);
JButton button = new JButton("CLICK HERE");
add(button, BorderLayout.SOUTH);
button.addActionListener(this);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setVisible(true);
}

public void actionPerformed(ActionEvent evt) {
this.panel.add(new JButton("Button"));
this.panel.revalidate();
validate();
}

public static void main(String[] args) {
AddComponentOnJFrameAtRuntime acojfar = new AddComponentOnJFrameAtRuntime();
}
}
  • Resource

Dynamically add swing component to gui on click?

there are several ways to reach dynamicaly added components to swing tree:

1st approach:

panel.getComponent(n);

returns n'th component in the panel (Container). (n is the order, that component added to its parent (parent is panel here) ) (you need to know component's index) this way you can use ((JComboBox)panel.getComponent(3)).getSelectedIndex()

2nd approach

directly add some listeners when dynamically adding your components;

JButton b1 = new JButton("add");
b1.addActionListener(e -> {

JComboBox<String> color = new JComboBox<String>();
color.addActionListener(x -> { myFormBean.setColor(color.getSelectedItem();) });
panel.add(color);

JTextField name = new JTextField();
name.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
myFormBean.setName(name.getText());
}

@Override
public void insertUpdate(DocumentEvent e) {
myFormBean.setName(name.getText());
}

@Override
public void changedUpdate(DocumentEvent e) {
myFormBean.setName(name.getText());
}
});
panel.add(name);

panel.revalidate();
panel.repaint();

});

this way you do not need to reach your dynamically added components.

3rd approach may be using a framework for data binding,

4rd approach ...

how to dynamically add swing components to gui on click and make it permanent

This has little to do with Swing per se and all to do with persistence: What you are trying to do is set the state of an object (or group of objects) and have it persist when the program exits. There are several ways to do this including serialization, XML serialization (which I favor) using XML beans or JAXB, or properties. I suggest checking out JAXB and persisting your class's state with this by marshalling and unmarshalling the state to XML. Otherwise if you have a lot of information that must persist, then consider using a database.

dynamically add JLabel to UI in java on button click using a single object

Calling revalidate and repaint on the container after adding your JLabel will tell the GUI to position the new component and to repaint the container so that it shows. e.g.,

public void actionPerformed(ActionEvent ae) {
if (!text.getText().equals(defaultMessage)) {
if (!text.getText().isEmpty()) {
label = new JLabel(text.getText());
label.setBounds(10, y, 380, 20);
y = y - 20;
frame.add(label);
frame.revalidate();
frame.repaint();
}
}
}

In your case, the revalidate isn't absolutely necessary since you're not using a layout manager, but still it's a good idea to include it, since you should be using layout managers as null layouts are dangerous and fragile.

Better though to use a JList.

e.g.,

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import javax.swing.*;

@SuppressWarnings("serial")
public class ChatClient2 extends JPanel {
private static final int VISIBLE_ROW_COUNT = 30;
private DefaultListModel<String> listModel = new DefaultListModel<>();
private JList<String> chatList = new JList<>(listModel);
private SendAction sendAction = new SendAction("Send");
private JTextField textField = new JTextField(20);
private JButton sendButton = new JButton(sendAction);

public ChatClient2() {
chatList.setFocusable(false);
chatList.setVisibleRowCount(VISIBLE_ROW_COUNT);
JScrollPane scrollPane = new JScrollPane(chatList);

textField.setAction(sendAction);
JPanel bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.LINE_AXIS));
bottomPanel.add(textField);
bottomPanel.add(sendButton);

setLayout(new BorderLayout());
add(scrollPane);
add(bottomPanel, BorderLayout.PAGE_END);
}

private class SendAction extends AbstractAction {
public SendAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}

@Override
public void actionPerformed(ActionEvent e) {
String text = textField.getText();
listModel.add(0, text);
textField.selectAll();
textField.requestFocusInWindow();
}
}

private static void createAndShowGui() {
JFrame frame = new JFrame("Chat Client2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ChatClient2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}

public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}

Java dynamically create buttons and pass a parameter to action performed

One of the issues you're having is creating a monolithic action listener, and then expecting to delegate actions from that. One nice feature of java are anonymous classes, or since java 7 lambdas.

JButton button = new JButton("Click " + i);
panel.add(button);
int id = i;
button.addActionListener( evt->{
performActionOnId( id );
});

Now instead of having the main class be an action listener, the main class has methods that are descriptive.

public void addUser( User a ){
//just showing delete button.

JButton delete = new JButton("X");
delete.addActionListener( evt ->{
removeUser( a );
//clean up gui.
});
}

This puts some of the steps of delegation at the creation of the user. Otherwise you'll have to delegate in your action performed.

public void actionPerformed( ActionEvent evt ){
//has to be a new class to have id attribute.
CustomButton b = (CustomButton)evt.getSource();
int id = b.getId();
User u = getUserById(id);
removeUser(u);
}

Dynamically adding components to JPanel

Call validate() on the parent container, as shown in the Nested Layout Example. Those labels on the lower left are added dynamically. Note that calling pack() might cause the size of the GUI to change, whereas calling validate() won't. If you need to get the GUI to resize - call pack(), else call validate().

Java dynamically add a button to a panel

Here's a SSCCE that does what you desire.

It uses BoxLayout to ensure that the buttons are displayed in a single row.

It sets each button to the same, particular size.

There is the same size gap between each, adjacent button.

It uses a JScrollPane so that once you add more buttons that can fit into the width of the JScrollPane, you can scroll to see the other buttons. This is instead of increasing the size of the JPanel (or creating a new row) each time you add a button.

More explanations after the code.

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.LayoutManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.WindowConstants;

public class AdButton implements ActionListener, Runnable {
private static final String ADD = "Add";
private static final String EXIT = "Exit";

private int counter;
private JFrame frame;
private JPanel panel;

@Override // java.awt.event.ActionListener
public void actionPerformed(ActionEvent event) {
String actionCommand = event.getActionCommand();
switch (actionCommand) {
case ADD:
addButton();
break;
case EXIT:
System.exit(0);
default:
JOptionPane.showMessageDialog(frame,
actionCommand,
"Unhandled",
JOptionPane.WARNING_MESSAGE);
}
}

@Override // java.lang.Runnable
public void run() {
createGui();
}

private void addButton() {
panel.add(Box.createHorizontalStrut(10));
JButton button = new JButton(String.valueOf(++counter));
Dimension size = new Dimension(50, 30);
button.setMaximumSize(size);
button.setMinimumSize(size);
button.setPreferredSize(size);
panel.add(button);
panel.revalidate();
}

private JButton createButton(String text, int mnemonic, String tooltip) {
JButton button = new JButton(text);
button.setMnemonic(mnemonic);
button.setToolTipText(tooltip);
button.addActionListener(this);
return button;
}

private JPanel createButtonsPanel() {
JPanel buttonsPanel = new JPanel();
buttonsPanel.add(createButton(ADD, KeyEvent.VK_A, "Add button to panel"));
buttonsPanel.add(createButton(EXIT, KeyEvent.VK_X, "Exit the application"));
return buttonsPanel;
}

private void createGui() {
frame = new JFrame("Add Buttons");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(createPanel(), BorderLayout.CENTER);
frame.add(createButtonsPanel(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}

private JScrollPane createPanel() {
panel = new JPanel();
LayoutManager mgr = new BoxLayout(panel, BoxLayout.LINE_AXIS);
panel.setLayout(mgr);
JScrollPane scrollPane = new JScrollPane(panel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane.setPreferredSize(new Dimension(500, 100));
return scrollPane;
}

public static void main(String[] args) {
EventQueue.invokeLater(new AdButton());
}
}

You should use an ActionListener rather than a MouseListener when you want an action to be performed as a result of clicking in a JButton.

The important part in the addButton() method is the call to revalidate() which makes the JPanel layout all its components and draw them on the screen. You need to do this since you have added another component to the JPanel.



Related Topics



Leave a reply



Submit