how to use a template dialog panel for multiple buttons? - java

I'm writing a GUI in java. I have a JXTable in which I currently only have static data, but I want allow the user to input data by using a template panel that I have created.
import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Window;
import java.awt.Dialog.ModalityType;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.border.TitledBorder;
import javax.swing.table.DefaultTableModel;
public class Template_StackOverflowExample extends JPanel{
private JPanel diagPanel = new dialogTemplate();
Object[] columnIdentifiers = {
"id",
"imei",
};
Object[][] data = {
{"1", "123"},
{"2", "123"},
{"3", "123"}
};
private JDialog dialog;
private static DefaultTableModel model;
public Template_StackOverflowExample(){
setLayout(new BorderLayout());
JPanel pane = new JPanel(new BorderLayout());
JButton addRow = new JButton("Add Row");
addRow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
openRowPane("Add Row");
}
});
JButton editRow = new JButton("Edit Row");
editRow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
openRowPane("Edit Row");
}
});
JPanel buttonPane = new JPanel(new GridLayout(0, 1));
TitledBorder buttonBorder = new TitledBorder("Buttons");
buttonPane.setBorder(buttonBorder);
buttonPane.add(addRow);
buttonPane.add(editRow);
model = new DefaultTableModel();
model.setColumnIdentifiers(columnIdentifiers);
JTable table = new JTable(model);
for(int i = 0; i < data.length; i++){
model.insertRow(i, data[i]);
}
JScrollPane scrollPane = new JScrollPane(table);
pane.add(buttonPane, BorderLayout.LINE_END);
pane.add(scrollPane, BorderLayout.CENTER);
add(pane, BorderLayout.CENTER);
}
public void openRowPane(String name){
if(dialog == null){
Window win = SwingUtilities.getWindowAncestor(this);
if(win != null){
dialog = new JDialog(win, name, ModalityType.APPLICATION_MODAL);
dialog.getContentPane().add(diagPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
}
dialog.setVisible(true);
}
public static void createAndShowGUI(){
JFrame frame = new JFrame("MCVE");
Template_StackOverflowExample mainPanel = new Template_StackOverflowExample();
frame.add(mainPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createAndShowGUI();
}
});
}
}
class dialogTemplate extends JPanel{
private JComponent[] content;
private String[] labelHeaders = {
"ID:",
"IMEI:",
};
public dialogTemplate(){
JPanel diagTemplate = new JPanel();
diagTemplate.setLayout(new BorderLayout());
JPanel rowContent = new JPanel(new GridLayout(0, 2));
JLabel idLabel = null;
JLabel imeiLabel = null;
JLabel[] labels = {
idLabel,
imeiLabel,
};
JTextField idTextField = new JTextField(20);
JTextField imeiTextField = new JTextField(20);
content = new JComponent[] {
idTextField,
imeiTextField,
};
for(int i = 0; i < labels.length; i++){
labels[i] = new JLabel(labelHeaders[i]);
rowContent.add(labels[i]);
rowContent.add(content[i]);
labels[i].setLabelFor(content[i]);
}
JButton save = new JButton("Save");
save.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
closeWindow();
}
});
JButton cancel = new JButton("Cancel");
cancel.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
closeWindow();
}
});
JPanel buttonPane = new JPanel(new GridLayout(0, 1, 5, 5));
buttonPane.add(save);
buttonPane.add(cancel);
buttonPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
diagTemplate.add(buttonPane, BorderLayout.PAGE_END);
diagTemplate.add(rowContent, BorderLayout.CENTER);
add(diagTemplate);
}
public void closeWindow(){
Window win = SwingUtilities.getWindowAncestor(this);
if(win != null) {
win.dispose();
}
}
}
As you might see both of the buttons in the pane creates the dialog that is created first ("Add Row" or "Edit Row"). I want them to create different dialogs so that the editing of data doesn't conflict with the addition of data.
Thanks in advance.

Assign a different dialog-creating method to each button so you can open two dialogs:
public void openRowPane(String name){
if(dialog == null){
Window win = SwingUtilities.getWindowAncestor(this);
//change modality
dialog = new JDialog(win, name, ModalityType.MODELESS);
dialog.getContentPane().add(diagPanel);
dialog.pack();
dialog.setLocationRelativeTo(null);
}
dialog.setVisible(true);
}
public void openRowPane2(String name){
if(dialog2 == null){
Window win = SwingUtilities.getWindowAncestor(this);
//change modality
dialog2 = new JDialog(win, name, ModalityType.MODELESS);
dialog2.getContentPane().add(diagPanel2);
dialog2.pack();
dialog2.setLocationRelativeTo(null);
}
dialog2.setVisible(true);
}

Related

Why getSelectedRow( ) method don't return the index of the selected row?

I use the method getSelectedRow() to get the index of the selected row in the first table. When I use it again to get the index of the selected row in the second table it still returns the index of the selected row in the first table. I can't figure out why!
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
public class Selection extends JFrame {
int row;
String actualArray;
JPanel panel = new JPanel();
JPanel dialogPanel = new JPanel();
DefaultTableModel model1 = new DefaultTableModel();
DefaultTableModel model2 = new DefaultTableModel();
JTable table1 = new JTable(model1);
JTable table2 = new JTable(model2);
JScrollPane scrollPane1 = new JScrollPane(table1);
JScrollPane scrollPane2 = new JScrollPane(table2);
JButton showSelectedRow = new JButton("Show");
JButton switchTable = new JButton("switch");
JDialog dialog = new JDialog();
JLabel label = new JLabel();
String [] columns = {"ID","Name"};
String [][] array1 = {{"0001","Alice"},{"0002","Evanka"},{"0003","Steve"}};
String [][] array2 = {{"0004","David"},{"0005","Mario"},{"0006","Marry"}};
public Selection() {
createAndShowGUI();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Selection();
}
});
}
private void createAndShowGUI() {
model1.setDataVector(array1,columns);
model2.setDataVector(array2,columns);
panel.setBounds(15,20,500,480);
scrollPane1.setBounds(20,25,50,50);
scrollPane2.setBounds(20,25,50,50);
showSelectedRow.setBounds(40,160,60,25);
switchTable.setBounds(120,160,60,25);
actions();
panel.add(scrollPane1);
actualArray="array1";
panel.add(showSelectedRow);
panel.add(switchTable);
add(panel);
setSize(550, 500);
setLocation(230, 70);
setLayout(null);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void actions() {
showSelectedRow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (actualArray.equals("array1")) {
row =table1.getSelectedRow();
} else {
row =table2.getSelectedRow();
}
showDialog();
}
});
switchTable.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (actualArray.equals("array1")) {
panel.removeAll();
panel.add(scrollPane1);
actualArray = "array2";
panel.add(showSelectedRow);
panel.add(switchTable);
add(panel);
repaint();
} else {
panel.removeAll();
panel.add(scrollPane2);
actualArray = "array1";
panel.add(showSelectedRow);
panel.add(switchTable);
add(panel);
repaint();
}
}
});
}
private void showDialog() {
dialogPanel.setBounds(5,5,50,30);
label.setText(String.valueOf(row));
label.setBounds(10,10,180,20);
dialogPanel.add(label);
dialog.add(dialogPanel);
dialog.setSize(60, 50);
dialog.setLocation(450, 250);
dialog.setLayout(null);
dialog.setResizable(false);
dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
dialog.setVisible(true);
}
}
I think your logic is backwards here...
When actualArray equals "array1", you're adding scrollPane1 and setting actualArray to "array2" ... shouldn't you be adding scrollPane2?
if (actualArray.equals("array1")) {
panel.removeAll();
panel.add(scrollPane1);
actualArray = "array2";
panel.add(showSelectedRow);
panel.add(switchTable);
add(panel);
repaint();
} else {
panel.removeAll();
panel.add(scrollPane2);
actualArray = "array1";
panel.add(showSelectedRow);
panel.add(switchTable);
add(panel);
repaint();
}
Having said that, I "accidentally" fixed you code trying to repair the null layout issues.
This example makes use of a CardLayout to switch between the tables instead...
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.border.EmptyBorder;
import javax.swing.table.DefaultTableModel;
public class FixMe extends JFrame {
int row;
String actualArray;
JPanel panel = new JPanel();
JPanel dialogPanel = new JPanel();
DefaultTableModel model1 = new DefaultTableModel();
DefaultTableModel model2 = new DefaultTableModel();
JTable table1 = new JTable(model1);
JTable table2 = new JTable(model2);
JScrollPane scrollPane1 = new JScrollPane(table1);
JScrollPane scrollPane2 = new JScrollPane(table2);
JButton showSelectedRow = new JButton("Show");
JButton switchTable = new JButton("switch");
JDialog dialog = new JDialog();
JLabel label = new JLabel();
String[] columns = {"ID", "Name"};
String[][] array1 = {{"0001", "Alice"}, {"0002", "Evanka"}, {"0003", "Steve"}};
String[][] array2 = {{"0004", "David"}, {"0005", "Mario"}, {"0006", "Marry"}};
public FixMe() {
createAndShowGUI();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new FixMe();
}
});
}
private CardLayout cardLayout;
private void createAndShowGUI() {
setLayout(new BorderLayout());
label.setBorder(new EmptyBorder(16, 16, 16, 16));
label.setHorizontalAlignment(JLabel.CENTER);
dialog.add(label);
cardLayout = new CardLayout();
panel.setLayout(cardLayout);
model1.setDataVector(array1, columns);
model2.setDataVector(array2, columns);
actions();
actualArray = "array1";
panel.add(scrollPane1, "array1");
panel.add(scrollPane2, "array2");
JPanel actions = new JPanel(new GridBagLayout());
actions.add(showSelectedRow);
actions.add(switchTable);
// panel.add(showSelectedRow);
// panel.add(switchTable);
add(panel);
add(actions, BorderLayout.SOUTH);
pack();
setLocationRelativeTo(null);
// setSize(550, 500);
// setLocation(230, 70);
// setLayout(null);
// setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
private void actions() {
showSelectedRow.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (actualArray.equals("array1")) {
row = table1.getSelectedRow();
} else {
row = table2.getSelectedRow();
}
showDialog();
}
});
switchTable.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (actualArray.equals("array1")) {
// panel.removeAll();
// panel.add(scrollPane1);
actualArray = "array2";
cardLayout.show(panel, actualArray);
// panel.add(showSelectedRow);
// panel.add(switchTable);
// add(panel);
// repaint();
} else {
// panel.removeAll();
// panel.add(scrollPane2);
actualArray = "array1";
cardLayout.show(panel, actualArray);
// panel.add(showSelectedRow);
// panel.add(switchTable);
// add(panel);
// repaint();
}
}
});
}
private void showDialog() {
label.setText(String.valueOf(row));
dialog.pack();
dialog.setLocationRelativeTo(panel);
dialog.setVisible(true);
// label.setBounds(10, 10, 180, 20);
// dialogPanel.add(label);
// dialog.add(dialogPanel);
// dialog.setSize(60, 50);
// dialog.setLocation(450, 250);
// dialog.setLayout(null);
// dialog.setResizable(false);
// dialog.setDefaultCloseOperation(JDialog.HIDE_ON_CLOSE);
// dialog.setVisible(true);
}
}
I recommend having a read through of Laying Out Components Within a Container
Now, having said all that, I would recommend just switching the models...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
String[] columns = {"ID", "Name"};
String[][] array1 = {{"0001", "Alice"}, {"0002", "Evanka"}, {"0003", "Steve"}};
String[][] array2 = {{"0004", "David"}, {"0005", "Mario"}, {"0006", "Marry"}};
TableModel model1 = new DefaultTableModel(array1, columns);
TableModel model2 = new DefaultTableModel(array2, columns);
JFrame frame = new JFrame();
frame.add(new TestPane(new TableModel[]{model1, model2}));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTable table;
private TableModel[] models;
private int currentModel = 0;
private JLabel selectedRowLabel;
public TestPane(TableModel[] models) {
setLayout(new BorderLayout());
table = new JTable();
this.models = models;
table.setModel(models[0]);
setLayout(new BorderLayout());
add(new JScrollPane(table));
selectedRowLabel = new JLabel("...");
JButton switchButton = new JButton("Switch");
switchButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
currentModel += 1;
if (currentModel >= models.length) {
currentModel = 0;
}
table.setModel(models[currentModel]);
updateSelectionInformation();
}
});
JPanel infoPane = new JPanel(new GridBagLayout());
infoPane.add(switchButton);
infoPane.add(selectedRowLabel);
add(infoPane, BorderLayout.SOUTH);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
updateSelectionInformation();
}
});
}
protected void updateSelectionInformation() {
if (table.getSelectedRow() > -1) {
selectedRowLabel.setText(Integer.toString(table.getSelectedRow()));
} else {
selectedRowLabel.setText("---");
}
}
}
}
Now, if the previously selected row is important, simply keep track of it when you switch and re-apply it, for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
String[] columns = {"ID", "Name"};
String[][] array1 = {{"0001", "Alice"}, {"0002", "Evanka"}, {"0003", "Steve"}};
String[][] array2 = {{"0004", "David"}, {"0005", "Mario"}, {"0006", "Marry"}};
TableModel model1 = new DefaultTableModel(array1, columns);
TableModel model2 = new DefaultTableModel(array2, columns);
JFrame frame = new JFrame();
frame.add(new TestPane(new TableModel[]{model1, model2}));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private JTable table;
private TableModel[] models;
private int[] lastSelectedRow;
private int currentModel = 0;
private JLabel selectedRowLabel;
public TestPane(TableModel[] models) {
setLayout(new BorderLayout());
table = new JTable();
lastSelectedRow = new int[models.length];
Arrays.fill(lastSelectedRow, -1);
this.models = models;
table.setModel(models[0]);
setLayout(new BorderLayout());
add(new JScrollPane(table));
selectedRowLabel = new JLabel("...");
JButton switchButton = new JButton("Switch");
switchButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
lastSelectedRow[currentModel] = table.getSelectedRow();
currentModel += 1;
if (currentModel >= models.length) {
currentModel = 0;
}
table.setModel(models[currentModel]);
if (lastSelectedRow[currentModel] > -1) {
table.setRowSelectionInterval(lastSelectedRow[currentModel], lastSelectedRow[currentModel]);
}
updateSelectionInformation();
}
});
JPanel infoPane = new JPanel(new GridBagLayout());
infoPane.add(switchButton);
infoPane.add(selectedRowLabel);
add(infoPane, BorderLayout.SOUTH);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
updateSelectionInformation();
}
});
}
protected void updateSelectionInformation() {
if (table.getSelectedRow() > -1) {
selectedRowLabel.setText(Integer.toString(table.getSelectedRow()));
} else {
selectedRowLabel.setText("---");
}
}
}
}

JList Swing adding description to List Item

I am trying to create a JList with a small arrow next to it. When clicked, I want some content associated with the list item shown in the same List/Panel. The picture, I hope, gives a clear idea of what I am trying to achieve.
How do I do this ? Also, what is the small triangle feature to the left known as (for future search tags) ?
I hope this is what you meant. The arrowButton is a JToggleButton which, when activated, displays a JWindow containing information about the selected value of the JList. This JWindow will remain visible until the JToggleButtons state is set back to unselected again. The ListPanel class should be reusable in your code.
Code:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.JToggleButton;
import javax.swing.JWindow;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
public class Example {
public Example() {
JFrame frame = new JFrame();
ArrayList<Object> elements = new ArrayList<Object>();
ArrayList<String> texts = new ArrayList<String>();
ListPanel listPanel = new ListPanel(elements, texts);
JButton addButton = new JButton("Add");
addButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
JTextField elementField = new JTextField(5);
JTextArea textArea = new JTextArea(5, 10);
JPanel panel = new JPanel();
panel.add(new JLabel("Element:"));
panel.add(elementField);
panel.add(Box.createHorizontalStrut(15));
panel.add(new JLabel("Text:"));
panel.add(new JScrollPane(textArea));
int result = JOptionPane.showConfirmDialog(frame, panel, "Element & Text",
JOptionPane.OK_CANCEL_OPTION);
if (result == JOptionPane.OK_OPTION) {
listPanel.addElementToList(elementField.getText(), textArea.getText());
}
}
});
JButton deleteButton = new JButton("Remove");
deleteButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (listPanel.getList().getSelectedValue() != null) {
listPanel.removeElementFromList(listPanel.getList().getSelectedValue());
}
}
});
JPanel buttonPanel = new JPanel();
buttonPanel.add(addButton);
buttonPanel.add(deleteButton);
frame.add(listPanel);
frame.add(buttonPanel, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
}
class ListPanel extends JPanel {
private JList<Object> list;
private JToggleButton arrowButton;
private ArrayList<String> texts;
private JWindow popup;
public ListPanel(ArrayList<Object> elements, ArrayList<String> texts) {
this.texts = texts;
popup = new JWindow();
arrowButton = new JToggleButton("\u25B6");
arrowButton.setMargin(new Insets(0, 0, 0, 0));
arrowButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (arrowButton.isSelected()) {
Object value = list.getSelectedValue();
if (value != null) {
JLabel titleLabel = new JLabel(value.toString());
titleLabel.setBackground(Color.WHITE);
titleLabel.setFont(new Font(Font.SANS_SERIF, Font.BOLD, 14));
titleLabel.setHorizontalAlignment(JLabel.LEFT);
JPanel titlePanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
titlePanel.setBackground(Color.WHITE);
titlePanel.add(titleLabel);
JTextPane textPane = new JTextPane();
textPane.setEditable(false);
textPane.setText(texts.get(list.getSelectedIndex()));
JPanel contentPanel = new JPanel(new BorderLayout());
contentPanel.setBorder(BorderFactory.createLineBorder(Color.BLACK));
contentPanel.add(titlePanel, BorderLayout.NORTH);
contentPanel.add(textPane);
popup.setLocation(arrowButton.getLocationOnScreen().x + arrowButton.getWidth(),
arrowButton.getLocationOnScreen().y);
popup.setContentPane(contentPanel);
popup.revalidate();
popup.pack();
popup.setVisible(true);
}
} else {
if (popup.isVisible()) {
popup.setVisible(false);
}
}
}
});
Timer timer = new Timer(100, null);
timer.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (((JFrame) SwingUtilities.getWindowAncestor(ListPanel.this)) != null) {
activateComponentListener();
timer.stop();
}
}
});
timer.start();
list = new JList<Object>(new DefaultListModel<Object>());
for (Object element : elements) {
((DefaultListModel<Object>) list.getModel()).addElement(element);
}
JPanel buttonPanel = new JPanel(new BorderLayout());
buttonPanel.setBackground(Color.WHITE);
buttonPanel.add(arrowButton, BorderLayout.NORTH);
JScrollPane scrollPane = new JScrollPane(list);
scrollPane.setBorder(null);
setLayout(new BorderLayout());
setBorder(BorderFactory.createLineBorder(Color.BLACK));
add(scrollPane);
add(buttonPanel, BorderLayout.WEST);
}
private void activateComponentListener() {
((JFrame) SwingUtilities.getWindowAncestor(this)).addComponentListener(new ComponentAdapter() {
#Override
public void componentMoved(ComponentEvent arg0) {
if (popup.isVisible()) {
popup.setLocation(arrowButton.getLocationOnScreen().x + arrowButton.getWidth(),
arrowButton.getLocationOnScreen().y);
}
}
});
}
public void removeElementFromList(Object element) {
int index = getElementIndex(element);
if (((DefaultListModel<Object>) getList().getModel()).getElementAt(getElementIndex(element)) != null) {
((DefaultListModel<Object>) getList().getModel()).removeElementAt(index);
getTexts().remove(index);
}
}
public void removeElementFromList(int index) {
if (((DefaultListModel<Object>) getList().getModel()).getElementAt(index) != null) {
((DefaultListModel<Object>) getList().getModel()).removeElementAt(index);
getTexts().remove(index);
}
}
private Integer getElementIndex(Object element) {
for (int i = 0; i < ((DefaultListModel<Object>) getList().getModel()).getSize(); i++) {
if (((DefaultListModel<Object>) getList().getModel()).getElementAt(i).equals(element)) {
return i;
}
}
return null;
}
public void addElementToList(Object element, String text) {
((DefaultListModel<Object>) list.getModel()).addElement(element);
getTexts().add(text);
}
public JList<Object> getList() {
return list;
}
public JToggleButton getArrowButton() {
return arrowButton;
}
public ArrayList<String> getTexts() {
return texts;
}
}

Add and remove button dynamically in Swing frame

I'm developing a swing application. In that I've a JFrame which add JTextfield and JButton dynamically on the button click.and remove the created components if the user clicks the same button.
In the below screen image , when user clicks ADD button new row was added, and text was changed to REMOVE like in 2nd image.
New Row added and previous button text changed to REMOVE.
Now, if I click the REMOVE button, then the newly added row has to dispose and then button has to change the text again to ADD.
I've tried till adding the components, but I stuck up with removing the newly added row.
Anyone please guide me to achieve this.
Below is my code.
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRootPane;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ButtonAddDynamic implements ActionListener {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new ButtonAddDynamic().createAndShowGUI();
}
});
}
private JFrame frame;
private JPanel panel = new JPanel(new GridBagLayout());
private GridBagConstraints constraints = new GridBagConstraints();
private List fields = new ArrayList();
private List fieldButton = new ArrayList();
private List fieldFile = new ArrayList();
private static int countReport = 0;
String files = null;
int y = 2;
protected void createAndShowGUI() {
try {
UIManager
.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
} catch (UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
} catch (InstantiationException ex) {
ex.printStackTrace();
} catch (ClassNotFoundException ex) {
ex.printStackTrace();
} catch (IllegalAccessException ex) {
ex.printStackTrace();
}
String[] labels = { "VALIDATION FORM" };
for (String label : labels)
addColumn(label);
frame = new JFrame("Add Button Dynamically");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(panel));
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
// Set the default button to button1, so that when return is hit, it
// will hit the button1
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
}
private void addColumn(String labelText) {
constraints.gridx = fields.size();
constraints.gridy = 1;
panel.add(new JLabel(labelText), constraints);
constraints.gridy = 2;
final JTextField field = new JTextField(40);
field.setEditable(false);
panel.add(field, constraints);
fields.add(field);
// constraints.gridy=3;
constraints.gridx = fields.size() + fieldButton.size();
final JButton button = new JButton("ADD");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (button.getText().equals("ADD")) {
button.setText("REMOVE");
addRowBelow();
frame.pack();
} else if (button.getText().equals("REMOVE")) {
button.setText("ADD");
frame.pack();
}
}
});
panel.add(button, constraints);
fieldButton.add(button);
panel.revalidate(); // redo layout for extra column
}
private void addRowBelow() {
y++;
constraints.gridy = y;
// System.out.println(fields.size());
for (int x = 0; x < fields.size(); x++) {
constraints.gridx = x;
final JTextField field = new JTextField(40);
field.setEditable(false);
panel.add(field, constraints);
constraints.gridx = x + 1;
final JButton button = new JButton("ADD");
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if (button.getText().equals("ADD")) {
button.setText("REMOVE");
addRowBelow();
frame.pack();
} else if (button.getText().equals("REMOVE")) {
button.setText("ADD");
frame.pack();
}
}
});
panel.add(button, constraints);
}
}
public void actionPerformed(ActionEvent ae) {
if ("Add Another TextField and Button".equals(ae.getActionCommand())) {
addRowBelow();
frame.pack();
frame.setLocationRelativeTo(null);
}
}
}
Trying to use GridBagLayout is making this very complicated for you. A nested layout scheme is much easier to work with when you are doing this type of thing.
See this MCVE:
I'm not sure I understood your intended functionality 100% correct but I don't think it's as important as the layouts.
My layout scheme is as follows:
This is nice because BoxLayout will handle the vertical listing without much hullabaloo. Instead of having to wrangle with GridBagConstraints, the text field and button are contained together by a panel.
import javax.swing.*;
import java.awt.event.*;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Insets;
public class FieldList implements Runnable, ActionListener {
public static void main(String... args) {
SwingUtilities.invokeLater(new FieldList());
}
final int maxFields = 2;
JFrame frame;
JPanel listing;
#Override
public void run() {
frame = new JFrame("Text Field Listing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel content = new JPanel(new BorderLayout());
content.add(new JLabel("Input Form", JLabel.CENTER), BorderLayout.NORTH);
listing = new JPanel();
listing.setLayout(new BoxLayout(listing, BoxLayout.Y_AXIS));
content.add(listing, BorderLayout.CENTER);
frame.setContentPane(content);
addNewField();
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
void addNewField() {
FieldButtonPair field = new FieldButtonPair();
field.button.addActionListener(this);
listing.add(field);
frame.pack();
}
void removeLastField() {
listing.remove(listing.getComponentCount() - 1);
frame.pack();
}
#Override
public void actionPerformed(ActionEvent ae) {
AddRemoveButton source = (AddRemoveButton)ae.getSource();
if(source.state == AddRemoveButton.State.ADD) {
if(listing.getComponentCount() < maxFields) {
addNewField();
source.setState(AddRemoveButton.State.REMOVE);
}
} else if(source.state == AddRemoveButton.State.REMOVE) {
removeLastField();
source.setState(AddRemoveButton.State.ADD);
}
}
}
class FieldButtonPair extends JPanel {
JTextField field;
AddRemoveButton button;
FieldButtonPair() {
super(new BorderLayout());
field = new JTextField();
add(field, BorderLayout.CENTER);
button = new AddRemoveButton();
add(button, BorderLayout.EAST);
}
#Override
public Dimension getPreferredSize() {
Dimension pref = super.getPreferredSize();
pref.width = Math.max(480, pref.width);
return pref;
}
}
class AddRemoveButton extends JButton {
enum State { ADD, REMOVE }
State state = State.ADD;
AddRemoveButton() {
setText(state.name());
}
void setState(State state) {
setText(state.name());
this.state = state;
}
#Override
public Dimension getPreferredSize() {
Dimension pref = super.getPreferredSize();
Font f = getFont();
FontMetrics fm = getFontMetrics(f);
int w = fm.stringWidth(State.REMOVE.name());
Insets ins = getInsets();
pref.width = (ins.left + w + ins.right);
return pref;
}
}

Putting JLabel on JScrollPane from another class in Java

I am making family tree and this is my problem. I have screens NewFamilyTree.java and NewPerson.java.
NewFamilyTree.java:
public class NewFamilyTree {
...
private void initialize() {
frame = new JFrame();
frame.setTitle("New family tree");
frame.setBounds(100, 100, 906, 569);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
...
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
JScrollPane scrollPane = new JScrollPane();
tabbedPane.addTab("Tree", null, scrollPane, null);
panel_1 = new JPanel();
scrollPane.setViewportView(panel_1);
panel_1.setLayout(new MigLayout("", "[][][][][][][][]", "[][][][][][]"));
NewPerson.java:
public class NewPerson{
...
buttonAdd = new JButton("Add");
buttonAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String names = textFieldNames.getText();
String dateBirth = textFieldDateOfBirth.getText();
String bio = textAreaBio.getText();
Data newData = new Data(names, dateBirth, bio, fileID);
//code that puts new label on scrollpane from NewFamilyTree.java
}
});
buttonAdd.setBackground(new Color(30, 144, 255));
frame.getContentPane().add(buttonAdd, "cell 2 6,grow");
}
I need to put new JLabel from class NewPerson, by pressing on button Add, on the JScrollPane of NewFamilytree.java. Hope someone can help, I searched a lot and couldn't help myself.
EDIT: After the answer from #mjr.
I added public JPanel panel_1; in NewFamilyTree. In Add action performed I added:
JLabel lblHomer = new JLabel("Homer");
lblHomer.setIcon(new ImageIcon("C:\\Users\\Tinmar\\Desktop\\HomerSimpson3.gif"));
panel_1.add(lblHomer, "cell 7 5");
No errors, but - nothing happens after I press the add button. I also added NewPerson EXTENDS NewFamilyTree, ofc.
NewPerson doesn't need extend from NewFamilyTree, it's not adding any functionality to the class
Instead of using a JFrame in NewPerson, consider using a modal JDialog instead. See How to Make Dialogs for more details
Limit the exposure of components between classes. There is no reason why NewFamilyTree should be able to access the "window" been used by NewPerson. There's no reason why NewPerson should be adding anything to NewFamilyTree
Don't mix heavy weight components (like java.awt.Button) with light weight components, this can cause no end of issues...
You need to change the way you think of things. Instead of trying to make the NewPerson update the UI of the NewFamilyTree, have NewPerson gather the details from the user and pass this information back to NewFamilyTree so it can use it...
For example...
JButton newPersonButton = new JButton("New Person");
newPersonButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Data data = NewPerson.createPerson(frame);
if (data != null) {
JLabel lblHomer = new JLabel(data.names);
panel_1.add(lblHomer, "cell 7 5");
panel_1.revalidate();
}
}
});
This basically uses a static method createPerson which passes back a instance of Data (or null if the user cancelled the operation), which NewFamilyTree can then use. It decouples the code, as NewPerson is not relient on anything from NewFamilyTree and NewFamilyTree maintains control. This clearly defines the areas of responsibility between the two classes, it also means that NewPerson could be called from anywhere...
The createPerson method looks, something like, this...
public static Data createPerson(Component comp) {
NewPerson newPerson = new NewPerson();
Window win = SwingUtilities.getWindowAncestor(comp);
JDialog dialog = null;
if (win instanceof Frame) {
dialog = new JDialog((Frame) win, "New person", true);
} else if (win instanceof Dialog) {
dialog = new JDialog((Dialog) win, "New person", true);
} else {
dialog = new JDialog((Frame) null, "New person", true);
}
newPerson.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof Component) {
Window win = SwingUtilities.getWindowAncestor((Component) source);
win.dispose();
}
}
});
dialog.add(newPerson);
dialog.setVisible(true);
return newPerson.getData();
}
It basically creates and instance of JDialog, shows it to the user and waits until the NewPerson class triggers an ActionEvent, which it uses to dispose of the dialog. It then asks the instance of NewPerson for the data...
And because there's a whole bunch of functionality I've not talked about, here's a fully runnable example...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
public class NewFamilyTree {
private JFrame frame;
private JPanel panel_1;
private JScrollPane scrollPane;
private JTabbedPane tabbedPane;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
NewFamilyTree window = new NewFamilyTree();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public NewFamilyTree() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setTitle("New family tree");
frame.getContentPane().setBackground(new Color(135, 206, 250));
frame.setBounds(100, 100, 906, 569);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(new Color(30, 144, 255));
frame.getContentPane().add(panel, BorderLayout.EAST);
panel.setLayout(new MigLayout("", "[]", "[][][][][][][][]"));
JButton newPersonButton = new JButton("New Person");
newPersonButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Data data = NewPerson.createPerson(frame);
if (data != null) {
JLabel lblHomer = new JLabel(data.names);
// lblHomer.setIcon(new ImageIcon("C:\\Users\\Tinmar\\Desktop\\HomerSimpson3.gif"));
panel_1.add(lblHomer, "cell 7 5");
panel_1.revalidate();
}
}
});
panel.add(newPersonButton, "cell 0 5");
JButton btnNewButton_1 = new JButton("New button");
panel.add(btnNewButton_1, "cell 0 6");
tabbedPane = new JTabbedPane(JTabbedPane.TOP);
frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
scrollPane = new JScrollPane();
tabbedPane.addTab("Tree", null, scrollPane, null);
panel_1 = new JPanel();
scrollPane.setViewportView(panel_1);
panel_1.setLayout(new MigLayout("", "[][][][][][][][]", "[][][][][][]"));
// JLabel lblHomer = new JLabel("Homer");
// lblHomer.setIcon(new ImageIcon("C:\\Users\\Tinmar\\Desktop\\HomerSimpson3.gif"));
// panel_1.add(lblHomer, "cell 7 5");
JScrollPane scrollPane_1 = new JScrollPane();
tabbedPane.addTab("Info", null, scrollPane_1, null);
frame.repaint();
}
//
// /**
// * Launch the application.
// */
// public static void main(String[] args) {
// EventQueue.invokeLater(new Runnable() {
// public void run() {
// try {
// NewPerson window = new NewPerson();
// window.frame.setVisible(true);
// } catch (Exception e) {
// e.printStackTrace();
// }
// }
// });
// }
public static class NewPerson extends JPanel {
private JTextField textFieldNames;
private JButton selectPictureButton;
private JLabel labelDateOfBirth;
private JTextField textFieldDateOfBirth;
private JLabel labelShortBio;
private JTextArea textAreaBio;
private JLabel labelSelectPicture;
private JButton buttonAdd;
private String fileID;
private Data data;
/**
* Create the application.
*/
private NewPerson() {
initialize();
}
public static Data createPerson(Component comp) {
NewPerson newPerson = new NewPerson();
Window win = SwingUtilities.getWindowAncestor(comp);
JDialog dialog = null;
if (win instanceof Frame) {
dialog = new JDialog((Frame) win, "New person", true);
} else if (win instanceof Dialog) {
dialog = new JDialog((Dialog) win, "New person", true);
} else {
dialog = new JDialog((Frame) null, "New person", true);
}
newPerson.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof Component) {
Window win = SwingUtilities.getWindowAncestor((Component) source);
win.dispose();
}
}
});
dialog.add(newPerson);
dialog.pack();
dialog.setLocationRelativeTo(comp);
dialog.setVisible(true);
return newPerson.getData();
}
public void addActionListener(ActionListener listener) {
listenerList.add(ActionListener.class, listener);
}
protected void fireActionPerformed() {
ActionListener[] listeners = listenerList.getListeners(ActionListener.class);
if (listeners != null && listeners.length > 0) {
ActionEvent evt = new ActionEvent(this, ActionEvent.ACTION_PERFORMED, "created");
for (ActionListener listener : listeners) {
listener.actionPerformed(evt);
}
}
}
public Data getData() {
return data;
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
setBackground(new Color(135, 206, 250));
setLayout(new MigLayout("", "[][][grow]", "[][][][grow][][][]"));
JLabel labelNames = new JLabel("Name and Surname:");
add(labelNames, "cell 1 1,alignx trailing");
textFieldNames = new JTextField();
add(textFieldNames, "cell 2 1,growx");
textFieldNames.setColumns(10);
labelDateOfBirth = new JLabel("Date of birth:");
add(labelDateOfBirth, "cell 1 2,alignx center,aligny center");
textFieldDateOfBirth = new JTextField();
add(textFieldDateOfBirth, "cell 2 2,growx");
textFieldDateOfBirth.setColumns(10);
labelShortBio = new JLabel("Bio:");
add(labelShortBio, "cell 1 3,alignx center,aligny center");
textAreaBio = new JTextArea();
add(textAreaBio, "cell 2 3,grow");
labelSelectPicture = new JLabel("Select picture:");
add(labelSelectPicture, "cell 1 4,alignx center,aligny center");
selectPictureButton = new JButton("...");
selectPictureButton.setBackground(new Color(30, 144, 255));
selectPictureButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
JFileChooser chooser = new JFileChooser(new File(System.getProperty("user.home") + "\\Desktop"));
chooser.setDialogTitle("Select Location");
chooser.setFileSelectionMode(JFileChooser.APPROVE_OPTION);
chooser.setAcceptAllFileFilterUsed(false);
if (chooser.showSaveDialog(null) == JFileChooser.APPROVE_OPTION) {
fileID = chooser.getSelectedFile().getPath();
// txtField.setText(fileID);
}
}
});
add(selectPictureButton, "cell 2 4");
buttonAdd = new JButton("Add");
buttonAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String names = textFieldNames.getText();
String dateBirth = textFieldDateOfBirth.getText();
String bio = textAreaBio.getText();
data = new Data(names, dateBirth, bio, fileID);
fireActionPerformed();
}
});
buttonAdd.setBackground(new Color(30, 144, 255));
add(buttonAdd, "cell 2 6,grow");
}
}
public static class Data {
private final String names;
private final String dateBirth;
private final String bio;
private final String fileID;
private Data(String names, String dateBirth, String bio, String fileID) {
this.names = names;
this.dateBirth = dateBirth;
this.bio = bio;
this.fileID = fileID;
}
}
}
Don't rely on static to provide functionality across classes. If you HAVE to have something from another class, pass it as a reference. static is not your friend and you should be careful and wary of it's use
Don't expose the fields of your class without very good reason, rely on interfaces to allow classes to provide or get information. This limits what other classes can do.
Separate and isolate responsibility
Take a look at How to Use Trees
The same way that NewFamilyTree's frame is accessible in NewPerson when you add the button to it, the scrollPane must also be accessible in NewPerson, if you want to add a label from that class. So just do the same thing with scrollPane as what you did with frame to be able to use it in NewPerson.
I assumed that the JScrollPane and addButton are in different frames... although it will work for sure if they are in the same frame.
Basically you need to provide getters for the JScrollPane and the JPanel, so that they can be accessed from the NewPerson class.
In the action listener of the buttonAdd, you need to increase the preferred size of the panel,, if the labels don't feet in the current size of the panel. The scrollbars will appear automatically when the preferred size of the panel are bigger that the view size of the JScrollPane.
Please see the code below:
NewFamilyTree.jva:
package dva.test001;
import java.awt.BorderLayout;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
public class NewFamilyTree {
private JFrame frame;
private JScrollPane scrollPane;
private JPanel panel;
public NewFamilyTree() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setTitle("New family tree");
frame.setBounds(100, 100, 906, 569);
frame.setLayout(new BorderLayout());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JTabbedPane tabbedPane = new JTabbedPane(JTabbedPane.TOP);
frame.getContentPane().add(tabbedPane, BorderLayout.CENTER);
panel = new JPanel();
panel.setPreferredSize(new Dimension(700, 300));
panel.setLayout(null);
scrollPane = new JScrollPane(panel);
tabbedPane.addTab("Tree", null, scrollPane, null);
frame.setVisible(true);
}
public static void main(String[] args) {
NewFamilyTree ft = new NewFamilyTree();
NewPerson np = new NewPerson(ft);
}
public JFrame getFrame() {
return frame;
}
public JScrollPane getScrollPane() {
return scrollPane;
}
public JPanel getPanel() {
return panel;
}
}
NewPerson.java:
package dva.test001;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class NewPerson {
private NewFamilyTree familyTree;
private static final int labelHeight = 30;
public NewPerson(NewFamilyTree familyTree) {
this.familyTree = familyTree;
init();
}
public void init() {
JFrame frame = new JFrame();
frame.setTitle("New Person");
frame.setBounds(100, 500, 906, 100);
JButton buttonAdd = new JButton("Add");
buttonAdd.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
String names = "names"; //textFieldNames.getText();
String dateBirth = "date"; //textFieldDateOfBirth.getText();
String bio = "bio"; //textAreaBio.getText();
//Data newData = new Data(names, dateBirth, bio, fileID);
//code that puts new label on scrollpane from NewFamilyTree.java
JLabel lbl = new JLabel(names);
int top = familyTree.getPanel().getComponentCount() * labelHeight;
if(top + labelHeight > familyTree.getPanel().getHeight()) {
familyTree.getPanel().setPreferredSize(new Dimension(familyTree.getPanel().getWidth(), top + labelHeight));
familyTree.getScrollPane().revalidate();
}
familyTree.getPanel().add(lbl);
lbl.setBounds(10, top, 100, labelHeight);
}
});
buttonAdd.setBackground(new Color(30, 144, 255));
frame.getContentPane().add(buttonAdd);
frame.setVisible(true);
}
}

Open new JFrame with JButton Click - Java Swing

I am trying to open a new JFrame window with a button click event. There is lots of info on this site but nothing that helps me because I think it is not so much the code I have, but the order it is executed (however I am uncertain).
This is the code for the frame holding the button that I want to initiate the event:
package messing with swing;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.util.*;
import javax.swing.border.EmptyBorder;
public class ReportGUI extends JFrame{
//Fields
private JButton viewAllReports = new JButton("View All Program Details");
private JButton viewPrograms = new JButton("View Programs and Majors Associated with this course");
private JButton viewTaughtCourses = new JButton("View Courses this Examiner Teaches");
private JLabel courseLabel = new JLabel("Select a Course: ");
private JLabel examinerLabel = new JLabel("Select an Examiner: ");
private JPanel panel = new JPanel(new GridLayout(6,2,4,4));
private ArrayList<String> list = new ArrayList<String>();
private ArrayList<String> courseList = new ArrayList<String>();
public ReportGUI(){
reportInterface();
allReportsBtn();
examinnerFileRead();
courseFileRead();
comboBoxes();
}
private void examinnerFileRead(){
try{
Scanner scan = new Scanner(new File("Examiner.txt"));
while(scan.hasNextLine()){
list.add(scan.nextLine());
}
scan.close();
}
catch (FileNotFoundException e){
e.printStackTrace();
}
}
private void courseFileRead(){
try{
Scanner scan = new Scanner(new File("Course.txt"));
while(scan.hasNextLine()){
courseList.add(scan.nextLine());
}
scan.close();
}
catch (FileNotFoundException e){
e.printStackTrace();
}
}
private void reportInterface(){
setTitle("Choose Report Specifications");
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(new FlowLayout());
add(panel, BorderLayout.CENTER);
setSize(650,200);
setVisible(true);
setResizable(false);
setLocationRelativeTo(null);
}
private void allReportsBtn(){
JPanel panel = new JPanel(new GridLayout(1,1));
panel.setBorder(new EmptyBorder(70, 50, 70, 25));
panel.add(viewAllReports);
viewAllReports.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e){
JFrame AllDataGUI = new JFrame();
new AllDataGUI();
}
});
add(panel, BorderLayout.LINE_END);
}
private void comboBoxes(){
panel.setBorder(new EmptyBorder(0, 5, 5, 10));
String[] comboBox1Array = list.toArray(new String[list.size()]);
JComboBox comboBox1 = new JComboBox(comboBox1Array);
panel.add(examinerLabel);
panel.add(comboBox1);
panel.add(viewTaughtCourses);
viewTaughtCourses.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFrame ViewCourseGUI = new JFrame();
new ViewCourseGUI();
}
});
String[] comboBox2Array = courseList.toArray(new String[courseList.size()]);
JComboBox comboBox2 = new JComboBox(comboBox2Array);
panel.add(courseLabel);
panel.add(comboBox2);
panel.add(viewPrograms);
add(panel, BorderLayout.LINE_START);
}
If you don't want to delve into the above code, the button ActionListener is here:
panel.add(viewTaughtCourses);
viewTaughtCourses.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFrame ViewCourseGUI = new JFrame();
new ViewCourseGUI();
}
});
This is the code in the class holding the JFrame I want to open:
package messing with swing;
import java.awt.BorderLayout;
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;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
public class ViewCourseGUI extends JFrame{
private JButton saveCloseBtn = new JButton("Save Changes and Close");
private JButton closeButton = new JButton("Exit Without Saving");
private JFrame frame=new JFrame("Courses taught by this examiner");
private JTextArea textArea = new JTextArea();
public void ViewCoursesGUI(){
panels();
}
private void panels(){
JPanel panel = new JPanel(new GridLayout(1,1));
panel.setBorder(new EmptyBorder(5, 5, 5, 5));
JPanel rightPanel = new JPanel(new GridLayout(15,0,10,10));
rightPanel.setBorder(new EmptyBorder(15, 5, 5, 10));
JScrollPane scrollBarForTextArea=new JScrollPane(textArea,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
panel.add(scrollBarForTextArea);
frame.add(panel);
frame.getContentPane().add(rightPanel,BorderLayout.EAST);
rightPanel.add(saveCloseBtn);
rightPanel.add(closeButton);
frame.setSize(1000, 700);
frame.setVisible(true);
frame.setLocationRelativeTo(null);
}
}
Could someone please point me in the right direction?
As pointed out by PM 77-3
I had:
public void ViewCoursesGUI(){
panels();
}
When I should have had:
public ViewCourseGUI(){
panels();
}
A Combination of syntax and spelling errors.
Set the visibility of the JFrame you want to open, to true in the actionListener:
ViewCourseGUI viewCourseGUI = new ViewCourseGUI();
viewCourseGUI.setVisible(true);
This will open the new JFrame window once you click the button.
Let ReportGUI implement ActionListener. Then you will implement actionPerformed for the button click. On button click, create the second frame (if it doesn't exist). Finally, set the second frame visible (if it is currently not visible):
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class ReportGUI extends JFrame implements ActionListener {
private static final long serialVersionUID = 8679886300517958494L;
private JButton button;
private ViewCourseGUI frame2 = null;
public ReportGUI() {
//frame1 stuff
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(300,200);
setLayout(new FlowLayout());
//create button
button = new JButton("Open other frame");
button.addActionListener(this);
add(button);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
ReportGUI frame = new ReportGUI();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == button) {
if (frame2 == null)
frame2 = new ViewCourseGUI();
if (!frame2.isVisible())
frame2.setVisible(true);
}
}
}
This is a simple example. You'll have to add the rest of your code here.

Categories

Resources