My project is to create a small temporary database with users and their passwords, so everything is saved in a second window, which would have a JTable and a button return to the main window. The problem would be precisely in JTable, when registering a new user, it ends up replacing the first user and so on, and a new row is not added with its respective registration.
Main:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.LinkedList;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
public class LoginGUI {
private static JPanel panel;
private static JFrame frame;
private static JLabel userLabel, passwordLabel;
private static JPasswordField passwordText;
private static JTextField userText;
private static JButton buttonRegister, buttonShow;
private static JLabel success;
//This is just for print in the console
private static final LinkedList<DataUser> array = new LinkedList();
private static String user, pass;
private static DataUser listUser;
private static Show show = new Show(); //Problem solved by instantiating this first
public static void main(String[] args) {
//Panel
panel = new JPanel();
frame = new JFrame();
frame.setSize(350, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(panel);
panel.setLayout(null);
//User
userLabel = new JLabel("User");
userLabel.setBounds(10, 20, 80, 25);
panel.add(userLabel);
//Password
passwordLabel = new JLabel("Password");
passwordLabel.setBounds(10, 50, 80, 25);
panel.add(passwordLabel);
//Password TextField
passwordText = new JPasswordField();
passwordText.setBounds(100, 50, 165, 25);
panel.add(passwordText);
//User TextField
userText = new JTextField(20);
userText.setBounds(100, 20, 165, 25);
panel.add(userText);
//Register Button
buttonRegister = new JButton("Login");
buttonRegister.setBounds(10, 90, 80, 25);
panel.add(buttonRegister);
RegisterButtonListener registerButtonListener = new RegisterButtonListener();
buttonRegister.addActionListener(registerButtonListener);
//Show list Button
buttonShow = new JButton("Show list");
buttonShow.setBounds(100, 90, 100, 25);
panel.add(buttonShow);
ShowButtonListener showButtonListener = new ShowButtonListener();
buttonShow.addActionListener(showButtonListener);
//Login successful
success = new JLabel("");
success.setBounds(100, 110, 300, 25);
panel.add(success);
//Panel visible
frame.setVisible(true);
}
//ActionListener for register
public static class RegisterButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
user = userText.getText();
pass = passwordText.getText();
listUser = new DataUser(user, pass);
array.add(listUser);
System.out.println(array);
success.setText("Registration added!");
}
}
//ActionListener for show list
public static class ShowButtonListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
//show = new Show();(This was the problem)
show.setUser(user);
show.setPass(pass);
show.saveData();
show.setVisible(true);
}
}
}
DataUser:
public class DataUser {
private final String user;
private final String pass;
private final String breakLine = "";
public DataUser(String user, String pass) {
this.user = user;
this.pass = pass;
}
#Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append(breakLine).append(System.getProperty("line.separator"));
return "User: " + user + " | Pass: " + pass
+ sb.toString();
}
}
And the new JFrame where is the JTable: JTable
Code (Problem is probably in the saveData() method):
import javax.swing.table.DefaultTableModel;
public final class Show extends javax.swing.JFrame {
DefaultTableModel table;
private final String[][] matrix = {};
String head[] = {"User", "Pass"};
private String user, pass;
public Show() {
initComponents();
table = new DefaultTableModel(matrix, head);
jTable.setModel(table);
}
public String getUser() {
return user;
}
public void setUser(String user) {
this.user = user;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
public void saveData() { //Problem is probably here
String data[] = {getUser(), getPass()};
table.addRow(data);
}
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
jButton1 = new javax.swing.JButton();
jScrollPane2 = new javax.swing.JScrollPane();
jTable = new javax.swing.JTable();
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
{null, null}
},
new String [] {
"User", "Pass"
}
));
jScrollPane1.setViewportView(jTable1);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jButton1.setText("<- Return");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jTable.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Title1", "Title2"
}
) {
boolean[] canEdit = new boolean [] {
false, false
};
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
jScrollPane2.setViewportView(jTable);
if (jTable.getColumnModel().getColumnCount() > 0) {
jTable.getColumnModel().getColumn(0).setResizable(false);
jTable.getColumnModel().getColumn(1).setResizable(false);
}
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(jButton1)
.addGap(0, 0, Short.MAX_VALUE))
.addComponent(jScrollPane2, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.DEFAULT_SIZE, 376, Short.MAX_VALUE))
.addContainerGap())
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap()
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.DEFAULT_SIZE, 275, Short.MAX_VALUE)
.addContainerGap())
);
pack();
}// </editor-fold>
//Return Button
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
dispose();
}
public static void main(String args[]) {
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Show.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Show.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Show.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Show.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(() -> {
new Show().setVisible(true);
});
}
// Variables declaration - do not modify
private javax.swing.JButton jButton1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTable jTable;
private javax.swing.JTable jTable1;
// End of variables declaration
}
Related
(Edited)
I'm creating a small project with dynamically changing panels.
I've been able to write code that can call a JPanel using an action event from a button within the the JFrame (ManagerScreen). For example:
package route66.JFrames;
import route66.pannels.BuyReserve;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import route66.pannels.Buy;
import route66.pannels.BuyReport;
import route66.pannels.CustomerDetails;
import route66.pannels.NewUser;
import route66.pannels.QuotPanel;
import route66.pannels.ReportPanel;
import route66.pannels.Salaries_Com;
import route66.pannels.SaleSucces;
/**
*
* #author Vavu
*/
public class ManagerScreen extends javax.swing.JFrame {
GridBagLayout layout = new GridBagLayout();
Buy BuyPanel = new Buy();
Buy b = new Buy();
BuyReserve buyR = new BuyReserve();
BuyReport brep = new BuyReport();
CustomerDetails cusD = new CustomerDetails();
QuotPanel QP = new QuotPanel();
ReportPanel RP = new ReportPanel();
NewUser NW = new NewUser();
Salaries_Com SalCom = new Salaries_Com();
SaleSucces SalS = new SaleSucces();
boolean visible;
/**
* Creates new form ManagerScreen
* #param pabel
*/
public ManagerScreen() {
initComponents();
DynamicPanel.setLayout(layout);
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 0;
DynamicPanel.add(b,c);
DynamicPanel.add(buyR,c);
DynamicPanel.add(brep,c);
DynamicPanel.add(cusD,c);
DynamicPanel.add(QP,c);
DynamicPanel.add(RP,c);
DynamicPanel.add(NW,c);
DynamicPanel.add(SalCom,c);
DynamicPanel.add(SalS,c);
b.setVisible(false);
buyR.setVisible(false);
brep.setVisible(false);
cusD.setVisible(false);
QP.setVisible(false);
RP.setVisible(false);
NW.setVisible(false);
SalCom.setVisible(false);
SalS.setVisible(false);
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
DynamicPanel = new javax.swing.JPanel();
MSbuy = new javax.swing.JButton();
MSQuotation = new javax.swing.JButton();
MSReserve = new javax.swing.JButton();
MSSalCom = new javax.swing.JButton();
MSReport = new javax.swing.JButton();
MSCreateNew = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setMinimumSize(new java.awt.Dimension(980, 740));
getContentPane().setLayout(null);
DynamicPanel.setBackground(new java.awt.Color(255, 0, 0));
DynamicPanel.setMaximumSize(new java.awt.Dimension(500, 500));
DynamicPanel.setMinimumSize(new java.awt.Dimension(500, 500));
DynamicPanel.setPreferredSize(new java.awt.Dimension(700, 500));
javax.swing.GroupLayout DynamicPanelLayout = new javax.swing.GroupLayout(DynamicPanel);
DynamicPanel.setLayout(DynamicPanelLayout);
DynamicPanelLayout.setHorizontalGroup(
DynamicPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 700, Short.MAX_VALUE)
);
DynamicPanelLayout.setVerticalGroup(
DynamicPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 500, Short.MAX_VALUE)
);
getContentPane().add(DynamicPanel);
DynamicPanel.setBounds(330, 260, 700, 500);
MSbuy.setText("Buy");
MSbuy.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MSbuyActionPerformed(evt);
}
});
getContentPane().add(MSbuy);
MSbuy.setBounds(70, 480, 188, 29);
MSQuotation.setText("Quotation");
MSQuotation.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MSQuotationActionPerformed(evt);
}
});
getContentPane().add(MSQuotation);
MSQuotation.setBounds(70, 520, 188, 29);
MSReserve.setText("Reserve");
MSReserve.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MSReserveActionPerformed(evt);
}
});
getContentPane().add(MSReserve);
MSReserve.setBounds(70, 440, 188, 29);
MSSalCom.setText("Salaries & Commission");
MSSalCom.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MSSalComActionPerformed(evt);
}
});
getContentPane().add(MSSalCom);
MSSalCom.setBounds(70, 400, 188, 29);
MSReport.setText("Report");
MSReport.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MSReportActionPerformed(evt);
}
});
getContentPane().add(MSReport);
MSReport.setBounds(70, 560, 187, 29);
MSCreateNew.setText("Create New User");
MSCreateNew.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
MSCreateNewActionPerformed(evt);
}
});
getContentPane().add(MSCreateNew);
MSCreateNew.setBounds(70, 600, 187, 29);
jLabel1.setFont(new java.awt.Font("Lucida Grande", 0, 48)); // NOI18N
jLabel1.setForeground(new java.awt.Color(0, 0, 204));
jLabel1.setText("ROUTE66 CAR DEALERSHIP");
getContentPane().add(jLabel1);
jLabel1.setBounds(330, 0, 650, 130);
jLabel3.setText(".");
getContentPane().add(jLabel3);
jLabel3.setBounds(0, 0, 330, 260);
jLabel2.setText(".");
getContentPane().add(jLabel2);
jLabel2.setBounds(330, 90, 650, 210);
pack();
}// </editor-fold>
private void MSbuyActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
b.setVisible(false);
buyR.setVisible(true);
brep.setVisible(false);
cusD.setVisible(false);
QP.setVisible(false);
RP.setVisible(false);
NW.setVisible(false);
SalCom.setVisible(false);
SalS.setVisible(false);
}
private void MSSalComActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
b.setVisible(false);
buyR.setVisible(false);
brep.setVisible(false);
cusD.setVisible(false);
QP.setVisible(false);
RP.setVisible(false);
NW.setVisible(false);
SalCom.setVisible(true);
SalS.setVisible(false);
}
private void MSReserveActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
b.setVisible(false);
buyR.setVisible(false);
brep.setVisible(false);
cusD.setVisible(false);
QP.setVisible(false);
RP.setVisible(true);
NW.setVisible(false);
SalCom.setVisible(false);
SalS.setVisible(false);
}
private void MSQuotationActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
private void MSReportActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
private void MSCreateNewActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(ManagerScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(ManagerScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(ManagerScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(ManagerScreen.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new ManagerScreen().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JPanel DynamicPanel;
private javax.swing.JButton MSCreateNew;
private javax.swing.JButton MSQuotation;
private javax.swing.JButton MSReport;
private javax.swing.JButton MSReserve;
private javax.swing.JButton MSSalCom;
private javax.swing.JButton MSbuy;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
// End of variables declaration
}
My problem is that the BR panel (buyReserve()), containing two buttons - within the JFrame, is supposed to be able to call either the buy panel or brep panel (BuyReport()) from the within the DynamicPanel() or at least thats what I think, if that makes sense.
so basically I've tried somethings including the following:
package route66.pannels;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import route66.pannels.BuyReport;
import route66.pannels.CustomerDetails;
/**
*
* #author Vavu
*/
public class BuyReserve extends javax.swing.JPanel {
GridBagLayout layout = new GridBagLayout();
Buy BuyPanel = new Buy();
Buy b = new Buy();
BuyReserve buyR = new BuyReserve();
BuyReport brep = new BuyReport();
CustomerDetails cusD = new CustomerDetails();
QuotPanel QP = new QuotPanel();
ReportPanel RP = new ReportPanel();
NewUser NW = new NewUser();
Salaries_Com SalCom = new Salaries_Com();
SaleSucces SalS = new SaleSucces();
/**
* Creates new form BuyReserve
*/
public BuyReserve() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
btnBuy = new javax.swing.JButton();
btnReserve = new javax.swing.JButton();
jLabel1 = new javax.swing.JLabel();
btnBuy.setText("New Client");
btnBuy.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
btnBuyActionPerformed(evt);
}
});
btnReserve.setText("Reserve Client");
jLabel1.setText("Select Option");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(144, 144, 144)
.addComponent(btnBuy)
.addGap(35, 35, 35)
.addComponent(btnReserve))
.addGroup(layout.createSequentialGroup()
.addGap(230, 230, 230)
.addComponent(jLabel1)))
.addContainerGap(162, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(62, 62, 62)
.addComponent(jLabel1)
.addGap(72, 72, 72)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(btnBuy)
.addComponent(btnReserve))
.addContainerGap(201, Short.MAX_VALUE))
);
}// </editor-fold>
private void btnBuyActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
b.setVisible(true);
}
// Variables declaration - do not modify
private javax.swing.JButton btnBuy;
private javax.swing.JButton btnReserve;
private javax.swing.JLabel jLabel1;
// End of variables declaration
}
If I run the ManagerScreen with the inclusion of the second code snippet I get an error. I've also tried other types of code that end up saying things like the jpanel doesn't have a main class n so on.
So, hopefully by this stage I've been able to get my point across to be to able ask (again); how do I call a panel, within a panel that is inside a JFrame?
You state that you want to "call" JPanels, but this doesn't really have any meaning. If your goal is to swap JPanel views, then the simplest and easiest way is to use a CardLayout. For more on this useful tool, please see the CardLayout Tutorial.
For example:
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import javax.swing.*;
public class ManagerPanel extends JPanel {
private CardLayout cardLayout = new CardLayout();
private JPanel cardLayoutPanel = new JPanel(cardLayout);
private BuyPanel buyPanel = new BuyPanel(this);
private BuyReportPanel buyReportPanel = new BuyReportPanel(this);
private DefaultComboBoxModel<String> comboModel = new DefaultComboBoxModel<>();
private JComboBox<String> panelComboBox = new JComboBox<>(comboModel);
public ManagerPanel() {
comboModel.addElement(BuyPanel.BUY);
comboModel.addElement(BuyReportPanel.BUY_REPORT);
panelComboBox.addActionListener(evt -> {
String key = panelComboBox.getSelectedItem().toString();
cardLayout.show(cardLayoutPanel, key);
});
JPanel comboPanel = new JPanel();
comboPanel.add(panelComboBox);
cardLayoutPanel.add(buyPanel, BuyPanel.BUY);
cardLayoutPanel.add(buyReportPanel, BuyReportPanel.BUY_REPORT);
setLayout(new BorderLayout());
add(cardLayoutPanel, BorderLayout.CENTER);
add(comboPanel, BorderLayout.PAGE_END);
}
private static void createAndShowGui() {
ManagerPanel mainPanel = new ManagerPanel();
JFrame frame = new JFrame("ManagerPanel");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
public void nextPanel() {
cardLayout.next(cardLayoutPanel);
}
}
class BuyReportPanel extends JPanel {
public final static String BUY_REPORT = "Buy Report";
private ManagerPanel managerPanel;
public BuyReportPanel(ManagerPanel managerPanel) {
this.managerPanel = managerPanel;
add(new JLabel(BUY_REPORT), SwingConstants.CENTER);
add(new JButton(new NextPanelAction(managerPanel)));
}
}
class BuyPanel extends JPanel {
public final static String BUY = "Buy";
private ManagerPanel managerPanel;
public BuyPanel(ManagerPanel managerPanel) {
setPreferredSize(new Dimension(400, 300));
this.managerPanel = managerPanel;
add(new JLabel(BUY), SwingConstants.CENTER);
add(new JButton(new NextPanelAction(managerPanel)));
}
}
class NextPanelAction extends AbstractAction {
private ManagerPanel managerPanel;
public NextPanelAction(ManagerPanel managerPanel) {
super("Next Panel");
this.managerPanel = managerPanel;
}
#Override
public void actionPerformed(ActionEvent e) {
managerPanel.nextPanel();
}
}
Note that I've passed my main class, here ManagerPanel, into other classes, and so they can call any of its public methods including nextPanel(), as needed.
How do I wire output to paneWithList?
PaneWithList has a listener on its JList so that the selected row is output to the console. How can I direct that output to the JTextPane on output?
Could PaneWithList fire an event which Main picks up? Would PropertyChangeSupport suffice?
Main.java:
package dur.bounceme.net;
import javax.swing.JTabbedPane;
public class Main {
private static JTabbedPane tabs;
private static PaneWithList paneWithList;
private static PaneWithTable paneWithTable;
private static Output output;
public static void main(String[] args) {
tabs = new javax.swing.JTabbedPane();
paneWithList = new PaneWithList();
paneWithTable = new PaneWithTable();
tabs.addTab("list", paneWithList);
tabs.addTab("table", paneWithTable);
tabs.addTab("output", output);
}
}
Here's an example using the observer pattern, also seen here, here and here. Note that it would also be possible to listen to the combo's model.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
/**
* #see http://en.wikipedia.org/wiki/Observer_pattern
* #see https://stackoverflow.com/a/10523401/230513
*/
public class PropertyChangeDemo {
public PropertyChangeDemo() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.add(new ObserverPanel());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PropertyChangeDemo example = new PropertyChangeDemo();
}
});
}
}
class ObserverPanel extends JPanel {
private JLabel title = new JLabel("Value received: ");
private JLabel label = new JLabel("null", JLabel.CENTER);
public ObserverPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObserverPanel"));
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(title);
panel.add(label);
this.add(panel);
ObservedPanel observed = new ObservedPanel();
observed.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals(ObservedPanel.PHYSICIST)) {
String value = e.getNewValue().toString();
label.setText(value);
}
}
});
this.add(observed);
}
}
class ObservedPanel extends JPanel {
public static final String PHYSICIST = "Physicist";
private static final String[] items = new String[]{
"Alpher", "Bethe", "Gamow", "Dirac", "Einstein"
};
private JComboBox combo = new JComboBox(items);
private String oldValue;
public ObservedPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObservedPanel"));
combo.addActionListener(new ComboBoxListener());
this.add(combo);
}
private class ComboBoxListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent ae) {
String newValue = (String) combo.getSelectedItem();
firePropertyChange(PHYSICIST, oldValue, newValue);
oldValue = newValue;
}
}
}
I'd be use JMenu with JMenuItems with contents layed by using CardLayout rather than very complicated JTabbedPane(s)
For my own reference, and for anyone using the Netbeans GUI builder, this works so far as it goes:
The PanelWithList class:
package dur.bounceme.net;
public class PanelWithList extends javax.swing.JPanel {
public PanelWithList() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList();
jScrollPane2 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jList1.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
jList1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jList1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jList1MouseClicked(evt);
}
});
jList1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
jList1KeyReleased(evt);
}
});
jScrollPane1.setViewportView(jList1);
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane2.setViewportView(jTextArea1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(54, 54, 54)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 308, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(167, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(35, 35, 35)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane2)
.addComponent(jScrollPane1))
.addContainerGap(166, Short.MAX_VALUE))
);
}// </editor-fold>
private void jList1MouseClicked(java.awt.event.MouseEvent evt) {
row();
}
private void jList1KeyReleased(java.awt.event.KeyEvent evt) {
row();
}
// Variables declaration - do not modify
private javax.swing.JList jList1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
private void row() {
Object o = jList1.getSelectedValue();
String s = (String)o;
jTextArea1.setText(s);
this.firePropertyChange("list", -1, 1);
}
}
and Frame.java as a driver:
package dur.bounceme.net;
public class Frame extends javax.swing.JFrame {
public Frame() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jTabbedPane1 = new javax.swing.JTabbedPane();
panelWithList1 = new dur.bounceme.net.PanelWithList();
panelWithTable1 = new dur.bounceme.net.PanelWithTable();
newJPanel1 = new dur.bounceme.net.PanelWithCombo();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
panelWithList1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
panelWithList1PropertyChange(evt);
}
});
jTabbedPane1.addTab("tab1", panelWithList1);
jTabbedPane1.addTab("tab2", panelWithTable1);
jTabbedPane1.addTab("tab3", newJPanel1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 937, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 913, Short.MAX_VALUE)
.addContainerGap()))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 555, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 521, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(22, Short.MAX_VALUE)))
);
pack();
}// </editor-fold>
private void panelWithList1PropertyChange(java.beans.PropertyChangeEvent evt) {
System.out.println("panelWithList1PropertyChange ");
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/*
* Set the Nimbus look and feel
*/
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/*
* If Nimbus (introduced in Java SE 6) is not available, stay with the
* default look and feel. For details see
* http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Frame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JTabbedPane jTabbedPane1;
private dur.bounceme.net.PanelWithCombo newJPanel1;
private dur.bounceme.net.PanelWithList panelWithList1;
private dur.bounceme.net.PanelWithTable panelWithTable1;
// End of variables declaration
}
The key being that panelWithList1PropertyChange is the listener on 'panelWithList' itself.
Because PanelWithList.firePropertyChange("list", -1, 1); cannot send Object nor String that I see, I'm not exactly sure how to get the value selected all the way from the JList up to the JFrame.
Hmm, well the API says yes it can send Objects. Have to check that out.
I think it's necessary to get some info about the model which the JList is using up to the JFrame. However, doesn't that break MVC? Or maybe that's the wrong approach.
How do I wire output to paneWithList?
PaneWithList has a listener on its JList so that the selected row is output to the console. How can I direct that output to the JTextPane on output?
Could PaneWithList fire an event which Main picks up? Would PropertyChangeSupport suffice?
Main.java:
package dur.bounceme.net;
import javax.swing.JTabbedPane;
public class Main {
private static JTabbedPane tabs;
private static PaneWithList paneWithList;
private static PaneWithTable paneWithTable;
private static Output output;
public static void main(String[] args) {
tabs = new javax.swing.JTabbedPane();
paneWithList = new PaneWithList();
paneWithTable = new PaneWithTable();
tabs.addTab("list", paneWithList);
tabs.addTab("table", paneWithTable);
tabs.addTab("output", output);
}
}
Here's an example using the observer pattern, also seen here, here and here. Note that it would also be possible to listen to the combo's model.
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
/**
* #see http://en.wikipedia.org/wiki/Observer_pattern
* #see https://stackoverflow.com/a/10523401/230513
*/
public class PropertyChangeDemo {
public PropertyChangeDemo() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setResizable(false);
f.add(new ObserverPanel());
f.pack();
f.setLocationByPlatform(true);
f.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
PropertyChangeDemo example = new PropertyChangeDemo();
}
});
}
}
class ObserverPanel extends JPanel {
private JLabel title = new JLabel("Value received: ");
private JLabel label = new JLabel("null", JLabel.CENTER);
public ObserverPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObserverPanel"));
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.add(title);
panel.add(label);
this.add(panel);
ObservedPanel observed = new ObservedPanel();
observed.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent e) {
if (e.getPropertyName().equals(ObservedPanel.PHYSICIST)) {
String value = e.getNewValue().toString();
label.setText(value);
}
}
});
this.add(observed);
}
}
class ObservedPanel extends JPanel {
public static final String PHYSICIST = "Physicist";
private static final String[] items = new String[]{
"Alpher", "Bethe", "Gamow", "Dirac", "Einstein"
};
private JComboBox combo = new JComboBox(items);
private String oldValue;
public ObservedPanel() {
this.setBorder(BorderFactory.createTitledBorder("ObservedPanel"));
combo.addActionListener(new ComboBoxListener());
this.add(combo);
}
private class ComboBoxListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent ae) {
String newValue = (String) combo.getSelectedItem();
firePropertyChange(PHYSICIST, oldValue, newValue);
oldValue = newValue;
}
}
}
I'd be use JMenu with JMenuItems with contents layed by using CardLayout rather than very complicated JTabbedPane(s)
For my own reference, and for anyone using the Netbeans GUI builder, this works so far as it goes:
The PanelWithList class:
package dur.bounceme.net;
public class PanelWithList extends javax.swing.JPanel {
public PanelWithList() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList();
jScrollPane2 = new javax.swing.JScrollPane();
jTextArea1 = new javax.swing.JTextArea();
jList1.setModel(new javax.swing.AbstractListModel() {
String[] strings = { "Item 1", "Item 2", "Item 3", "Item 4", "Item 5" };
public int getSize() { return strings.length; }
public Object getElementAt(int i) { return strings[i]; }
});
jList1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jList1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
jList1MouseClicked(evt);
}
});
jList1.addKeyListener(new java.awt.event.KeyAdapter() {
public void keyReleased(java.awt.event.KeyEvent evt) {
jList1KeyReleased(evt);
}
});
jScrollPane1.setViewportView(jList1);
jTextArea1.setColumns(20);
jTextArea1.setRows(5);
jScrollPane2.setViewportView(jTextArea1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(54, 54, 54)
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 247, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 308, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(167, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(35, 35, 35)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addComponent(jScrollPane2)
.addComponent(jScrollPane1))
.addContainerGap(166, Short.MAX_VALUE))
);
}// </editor-fold>
private void jList1MouseClicked(java.awt.event.MouseEvent evt) {
row();
}
private void jList1KeyReleased(java.awt.event.KeyEvent evt) {
row();
}
// Variables declaration - do not modify
private javax.swing.JList jList1;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JScrollPane jScrollPane2;
private javax.swing.JTextArea jTextArea1;
// End of variables declaration
private void row() {
Object o = jList1.getSelectedValue();
String s = (String)o;
jTextArea1.setText(s);
this.firePropertyChange("list", -1, 1);
}
}
and Frame.java as a driver:
package dur.bounceme.net;
public class Frame extends javax.swing.JFrame {
public Frame() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jTabbedPane1 = new javax.swing.JTabbedPane();
panelWithList1 = new dur.bounceme.net.PanelWithList();
panelWithTable1 = new dur.bounceme.net.PanelWithTable();
newJPanel1 = new dur.bounceme.net.PanelWithCombo();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
panelWithList1.addPropertyChangeListener(new java.beans.PropertyChangeListener() {
public void propertyChange(java.beans.PropertyChangeEvent evt) {
panelWithList1PropertyChange(evt);
}
});
jTabbedPane1.addTab("tab1", panelWithList1);
jTabbedPane1.addTab("tab2", panelWithTable1);
jTabbedPane1.addTab("tab3", newJPanel1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 937, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 913, Short.MAX_VALUE)
.addContainerGap()))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 555, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jTabbedPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 521, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(22, Short.MAX_VALUE)))
);
pack();
}// </editor-fold>
private void panelWithList1PropertyChange(java.beans.PropertyChangeEvent evt) {
System.out.println("panelWithList1PropertyChange ");
}
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/*
* Set the Nimbus look and feel
*/
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/*
* If Nimbus (introduced in Java SE 6) is not available, stay with the
* default look and feel. For details see
* http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Frame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/*
* Create and display the form
*/
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new Frame().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JTabbedPane jTabbedPane1;
private dur.bounceme.net.PanelWithCombo newJPanel1;
private dur.bounceme.net.PanelWithList panelWithList1;
private dur.bounceme.net.PanelWithTable panelWithTable1;
// End of variables declaration
}
The key being that panelWithList1PropertyChange is the listener on 'panelWithList' itself.
Because PanelWithList.firePropertyChange("list", -1, 1); cannot send Object nor String that I see, I'm not exactly sure how to get the value selected all the way from the JList up to the JFrame.
Hmm, well the API says yes it can send Objects. Have to check that out.
I think it's necessary to get some info about the model which the JList is using up to the JFrame. However, doesn't that break MVC? Or maybe that's the wrong approach.
I am trying to implement Observer pattern with multiple JFrame instances. However, when notifyObservers() is called, only the last instantiated JFrame instance is updated.
This is my code:
Mall.java
import java.util.ArrayList;
import java.util.Observable;
public class Mall extends Observable{
private ArrayList<String> stores;
public Mall(){
stores = new ArrayList<String>();
}
public void addNewStore(String store){
stores.add(store);
System.out.println(store);
setChanged();
notifyObservers(store);
}
public ArrayList<String> getStores(){
return stores;
}
}
CustomerFrame.java
public class CustomerFrame extends javax.swing.JFrame {
public CustomerFrame() {
initComponents();
}
public CustomerFrame(Mall theMall) {
initComponents();
MallObserver mallObs = new MallObserver();
theMall.addObserver(mallObs);
}
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new javax.swing.JList();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jList1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(jList1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 249, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(141, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 165, javax.swing.GroupLayout.PREFERRED_SIZE)
.addContainerGap(124, Short.MAX_VALUE))
);
pack();
}
public static javax.swing.JList jList1;
private javax.swing.JScrollPane jScrollPane1;
}
MallObserver.java
import java.util.Observable;
import java.util.Observer;
import javax.swing.DefaultListModel;
public class MallObserver implements Observer{
private Mall mallUpdate;
#Override
public void update(Observable o, Object arg) {
mallUpdate = (Mall) o;
DefaultListModel listModel = new DefaultListModel();
for(int i = 0; i < mallUpdate.getStores().size(); i++)
listModel.addElement(mallUpdate.getStores().get(i));
CustomerFrame.jList1.setModel(listModel);
}
}
AdminFrame.java
public class AdminFrame extends javax.swing.JFrame {
Mall theMall;
public AdminFrame() {
initComponents();
theMall = new Mall();
}
#SuppressWarnings("unchecked")
private void initComponents() {
jTextField1 = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
jButton1 = new javax.swing.JButton();
jButton2 = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTextField1.setText("jTextField1");
jLabel1.setText("jLabel1");
jButton1.setText("Add Store");
jButton1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton1ActionPerformed(evt);
}
});
jButton2.setText("New Customer");
jButton2.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jButton2ActionPerformed(evt);
}
});
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addContainerGap(143, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(jButton2)
.addComponent(jButton1)
.addGroup(layout.createSequentialGroup()
.addComponent(jLabel1)
.addGap(26, 26, 26)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGap(138, 138, 138))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(129, 129, 129)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
.addComponent(jTextField1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addComponent(jLabel1))
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(jButton1)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
.addComponent(jButton2)
.addContainerGap(88, Short.MAX_VALUE))
);
pack();
}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
CustomerFrame newCust = new CustomerFrame();
newCust.setVisible(true);
}
private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
theMall.addNewStore(jTextField1.getText());
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(AdminFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(AdminFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(AdminFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(AdminFrame.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AdminFrame().setVisible(true);
}
});
}
private javax.swing.JButton jButton1;
private javax.swing.JButton jButton2;
private javax.swing.JLabel jLabel1;
private javax.swing.JTextField jTextField1;
}
The idea is, when a customer enters the store, the store will open up a new JFrame for the customer. When admin adds a store, all the JFrame CustomerFrame.java will have their list item updated. However, in my case, only the CustomerFrame.java that is last instantiated will get the update while the others remains the same.
The problem above can be reproduced by Opening 2 New Customer and try to Add Store at AdminFrame.java
What is the problem here?
You don't call any methods on thisFrame from within the MallCustomer's update(...) method. Rather than setting the model on storeList (where the heck does that come from?), give CustomerFrame a public method, say called setStoreListModel(ListModel listModel) that you call in update, passing in the storeModel.
i.e.,
public class CustomerFrame extends javax.swing.JFrame {
privarte Mall theMall;
private JList storesList = new JList();
public CustomerFrame(Customer customer, Mall theMall){
MallCustomer mallObserver = new MallCustomer(this);
theMall.addObserver(mallObserver);
}
public setStoresListModel(ListModel listModel) {
storesList.setModel(listModel);
}
}
and
#Override
public void update(Observable o, Object arg) {
mallUpdate = (Mall) o;
DefaultListModel storeModel = new DefaultListModel();
//Stores update
for(int i = 0; i < mallUpdate.getStores().size();i++) {
storeModel.addElement(mallUpdate.getStores().get(i));
}
// storesList.setModel(storeModel);//a JList variable
thisFrame.setStoresListModel(storeModel);
}
Note: code not compiled nor tested
Edit
You've got several issues that I can see:
Your JList should not be public nor static. Make it a private instance field.
Again (as I suggested all along), give the Customer window a public setListModel type of method.
An application should only have one main JFrame, and so the CustomerFrame JFrame should not be a JFrame but rather should be a non-modal JDialog, or maybe better a JPanel that can be placed anywhere -- in its own JDialog, in the main JFrame.
Pass the main JFrame into your JDialogs so that the dialog can register the parent JFrame in its super's constructor.
Pass the CustomerDialog instance into your MallObserver instance, and then use it to set a field inside of MallObserver.
In the update method, create or update the model and call `setListModel on the customer dialog instance that MallObserver holds.
Create Mall instance before calling initComponents(). This way you can use the same Mall instance inside of your action listener methods.
A nit-pick: when creating and posting MCVE's, get rid of the messy and distracting NetBeans generated code. Instead only post simple code and simple GUI's that you've created yourself, similar to the changes that I've made below.
And you MCVE should all fit in a single file. The file can have several classes, but it should be easy for us to cut and paste into our IDE's and then run.
For example:
import java.util.ArrayList;
import java.util.Observable;
import java.util.Observer;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class AdminFrame extends javax.swing.JFrame {
private Mall theMall = new Mall(); //!!
public AdminFrame() {
initComponents();
//!! theMall = new Mall();
}
private void initComponents() {
jTextField1 = new javax.swing.JTextField();
jLabel1 = new javax.swing.JLabel();
addStoreBtn = new javax.swing.JButton();
newCustBtn = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jTextField1.setText("jTextField1");
jLabel1.setText("jLabel1");
addStoreBtn.setText("Add Store");
addStoreBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
theMall.addNewStore(jTextField1.getText());
}
});
addStoreBtn.setMnemonic(KeyEvent.VK_S);
newCustBtn.setText("New Customer");
newCustBtn.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
// !! CustomerFrame newCust = new CustomerFrame();
CustomerDialog newCust = new CustomerDialog(AdminFrame.this, theMall);
newCust.pack();
newCust.setLocationByPlatform(true);
newCust.setVisible(true);
}
});
newCustBtn.setMnemonic(KeyEvent.VK_C);
JPanel mainPanel = new JPanel();
mainPanel.add(jLabel1);
mainPanel.add(jTextField1);
mainPanel.add(addStoreBtn);
mainPanel.add(newCustBtn);
add(mainPanel);
pack();
setLocationRelativeTo(null);
}
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new AdminFrame().setVisible(true);
}
});
}
private javax.swing.JButton addStoreBtn;
private javax.swing.JButton newCustBtn;
private javax.swing.JLabel jLabel1;
private javax.swing.JTextField jTextField1;
}
class MallObserver implements Observer {
private Mall mallUpdate;
private CustomerDialog customerDialog; // !!
// !!
public MallObserver(CustomerDialog customerFrame) {
this.customerDialog = customerFrame; // !!
}
#Override
public void update(Observable o, Object arg) {
mallUpdate = (Mall) o;
DefaultListModel<String> listModel = new DefaultListModel<>();
for (int i = 0; i < mallUpdate.getStores().size(); i++) {
listModel.addElement(mallUpdate.getStores().get(i));
}
customerDialog.setListModel(listModel);
}
}
#SuppressWarnings("serial")
class CustomerDialog extends JDialog { //!!
// !!!!!!! public CustomerFrame() {
// initComponents();
// }
public void setListModel(ListModel<String> listModel) {
jList1.setModel(listModel);
}
public CustomerDialog(AdminFrame adminFrame, Mall theMall) {
super(adminFrame, "Customer Dialog", ModalityType.MODELESS);
initComponents();
// !! MallObserver mallObs = new MallObserver();
MallObserver mallObs = new MallObserver(this); // !!
theMall.addObserver(mallObs);
}
private void initComponents() {
jScrollPane1 = new javax.swing.JScrollPane();
jList1 = new JList<>();
jList1.setPrototypeCellValue(" ");
jList1.setVisibleRowCount(15);
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
jList1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(jList1);
add(jScrollPane1);
pack();
}
// public static javax.swing.JList jList1;
private JList<String> jList1;
private JScrollPane jScrollPane1;
}
class Mall extends Observable {
private ArrayList<String> stores;
public Mall() {
stores = new ArrayList<String>();
}
public void addNewStore(String store) {
stores.add(store);
setChanged();
notifyObservers(store);
}
public ArrayList<String> getStores() {
return stores;
}
}
I have created the following JTable and some buttons.
One of the buttons (jbtClear) is trying to empty the table using the setRowCount() function.
Any ideas , why it is not working and produces this error?
Here is the code :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package nysemarketpick;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
/**
*
* #author Administrator
*/
public class PortfolioForm extends javax.swing.JFrame {
/**
* Creates new form PortfolioForm
*/
public PortfolioForm() {
initComponents();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jbtAddRow = new javax.swing.JButton();
jbtDeleteRow = new javax.swing.JButton();
jScrollPane1 = new javax.swing.JScrollPane();
jTable1 = new javax.swing.JTable();
jPanel2 = new javax.swing.JPanel();
jbtSave = new javax.swing.JButton();
jbtClear = new javax.swing.JButton();
jbtRestore = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jPanel1.setBorder(javax.swing.BorderFactory.createTitledBorder("Row functions"));
jbtAddRow.setText("Add New Row");
jbtDeleteRow.setText("Delete Selected Row");
org.jdesktop.layout.GroupLayout jPanel1Layout = new org.jdesktop.layout.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.add(jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.add(34, 34, 34)
.add(jbtAddRow))
.add(jPanel1Layout.createSequentialGroup()
.add(16, 16, 16)
.add(jbtDeleteRow)))
.addContainerGap(40, Short.MAX_VALUE))
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel1Layout.createSequentialGroup()
.addContainerGap()
.add(jbtAddRow)
.add(18, 18, 18)
.add(jbtDeleteRow)
.addContainerGap(26, Short.MAX_VALUE))
);
jTable1.setAutoCreateRowSorter(true);
jTable1.setModel(new javax.swing.table.DefaultTableModel(
new Object [][] {
},
new String [] {
"Stock Symbol", "Stock Name", "Shares", "Value (in Dollars)", "Total Value"
}
) {
Class[] types = new Class [] {
java.lang.String.class, java.lang.String.class, java.lang.Integer.class, java.lang.Double.class, java.lang.Double.class
};
boolean[] canEdit = new boolean [] {
true, false, true, true, false
};
public Class getColumnClass(int columnIndex) {
return types [columnIndex];
}
public boolean isCellEditable(int rowIndex, int columnIndex) {
return canEdit [columnIndex];
}
});
tableModel = (DefaultTableModel)jTable1.getModel();
jTable1.setColumnSelectionAllowed(true);
jTable1.setRowSelectionAllowed(true);
jTable1.setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
jScrollPane1.setViewportView(jTable1);
jTable1.getColumnModel().getSelectionModel().setSelectionMode(javax.swing.ListSelectionModel.SINGLE_SELECTION);
//add action listeners
jbtAddRow.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if (jTable1.getSelectedRow() >= 0)
tableModel.insertRow(jTable1.getSelectedRow(), new Vector());
else
tableModel.addRow(new Vector());
}
});
jbtDeleteRow.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
if (jTable1.getSelectedRow() >= 0)
tableModel.removeRow(jTable1.getSelectedRow());
}
});
jbtSave.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("portfolio.dat"));
out.writeObject(tableModel.getDataVector());
out.writeObject(getColumnNames());
out.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
});
jbtClear.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
tableModel.setRowCount(0);
}
});
jbtRestore.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e)
{
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("portfolio.dat"));
Vector rowData = (Vector)in.readObject();
Vector columnNames = (Vector)in.readObject();
tableModel.setDataVector(rowData, columnNames);
in.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
});
//add other listeners
tableModel.addTableModelListener(new TableModelListener(){
public void tableChanged(TableModelEvent e)
{
DefaultTableModel model = (DefaultTableModel)e.getSource();
//Object data = model.getValueAt(e.getFirstRow(), e.getColumn());
if (e.getColumn() == 0)
{
Object data = model.getValueAt(e.getFirstRow(), e.getColumn());
String stockSymbol = (String)data;
XMLService2 myService = new XMLService2(stockSymbol);
String stockName = XMLService2.getStockName();
model.setValueAt(stockName, e.getFirstRow(), e.getColumn() + 1);
}
if (e.getColumn() != 4 && model.getValueAt(e.getFirstRow(), 2) != null && model.getValueAt(e.getFirstRow(), 3) != null)
{
Double myDouble =(Integer)model.getValueAt(e.getFirstRow(), 2)*(Double)model.getValueAt(e.getFirstRow(), 3);
model.setValueAt(myDouble, e.getFirstRow(), 4);
}
}
});
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Table functions"));
jbtSave.setText("Save");
jbtClear.setText("Clear");
jbtRestore.setText("Restore");
org.jdesktop.layout.GroupLayout jPanel2Layout = new org.jdesktop.layout.GroupLayout(jPanel2);
jPanel2.setLayout(jPanel2Layout);
jPanel2Layout.setHorizontalGroup(
jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel2Layout.createSequentialGroup()
.add(34, 34, 34)
.add(jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jbtRestore)
.add(jbtClear)
.add(jbtSave))
.addContainerGap(41, Short.MAX_VALUE))
);
jPanel2Layout.linkSize(new java.awt.Component[] {jbtClear, jbtRestore, jbtSave}, org.jdesktop.layout.GroupLayout.HORIZONTAL);
jPanel2Layout.setVerticalGroup(
jPanel2Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel2Layout.createSequentialGroup()
.addContainerGap()
.add(jbtSave)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED)
.add(jbtClear)
.addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(jbtRestore))
);
org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.add(21, 21, 21)
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 645, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE))
.add(layout.createSequentialGroup()
.add(31, 31, 31)
.add(jPanel1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(78, 78, 78)
.add(jPanel2, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)))
.addContainerGap(50, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(layout.createSequentialGroup()
.addContainerGap()
.add(jScrollPane1, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, 399, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)
.add(27, 27, 27)
.add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING, false)
.add(jPanel1, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
.add(jPanel2, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
.addContainerGap(org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
pack();
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new PortfolioForm().setVisible(true);
}
});
}
//---other methods
private Vector getColumnNames()
{
Vector<String> columnNames = new Vector<String>();
for (int i = 0; i < jTable1.getColumnCount(); i++)
columnNames.add(jTable1.getColumnName(i));
return columnNames;
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JScrollPane jScrollPane1;
private javax.swing.JTable jTable1;
private DefaultTableModel tableModel;
private javax.swing.JButton jbtAddRow;
private javax.swing.JButton jbtClear;
private javax.swing.JButton jbtDeleteRow;
private javax.swing.JButton jbtRestore;
private javax.swing.JButton jbtSave;
// End of variables declaration
}
Post edit : Here is working code from a book with the same function :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package projecttable5;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.UIManager;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;
/**
*
* #author Administrator
*/
public class ModifyTable extends JFrame{
//Create table column names
private String[] columnNames = {"Country", "Capital", "Population in Millions", "Democracy"};
//Create table data
private Object[][] rowData = {
{"USA", "Washington DC", 280, true},
{"Canada", "Ottawa", 32, true},
{"United Kingdom", "London", 60, true},
{"Germany", "Berlin", 83, true},
{"France", "Paris", 60, true},
{"Norway", "Oslo", 4.5, true},
{"India", "New Delhi", 1046, true}
};
//Create a table model
private DefaultTableModel tableModel = new DefaultTableModel(rowData, columnNames);
//Create a table
private JTable jTable1 = new JTable(tableModel);
//Create buttons
private JButton jbtAddRow = new JButton("Add New Row");
private JButton jbtAddColumn = new JButton("Add New Column");
private JButton jbtDeleteRow = new JButton("Delete Selected Row");
private JButton jbtDeleteColumn = new JButton("Delete Selected Column");
private JButton jbtSave = new JButton("Save");
private JButton jbtClear = new JButton("Clear");
private JButton jbtRestore = new JButton("Restore");
//Create a combo box for selection modes
private JComboBox jcboSelectionMode = new JComboBox(new String[] {"SINGLE_SELECTION", "SINGLE_INTERVAL_SELECTION", "MULTIPLE_INTERVAL_SELECTION"});
//Create check boxes
private JCheckBox jchkRowSelectionAllowed = new JCheckBox("RowSelectionAllowed", true);
private JCheckBox jchkColumnSelectionAllowed = new JCheckBox("ColumnSelectionAllowed", false);
//---Default constructor
public ModifyTable()
{
JPanel panel1 = new JPanel();
panel1.setLayout(new GridLayout(2, 2));
panel1.add(jbtAddRow);
panel1.add(jbtAddColumn);
panel1.add(jbtDeleteRow);
panel1.add(jbtDeleteColumn);
JPanel panel2 = new JPanel();
panel2.add(jbtSave);
panel2.add(jbtClear);
panel2.add(jbtRestore);
JPanel panel3 = new JPanel();
panel3.setLayout(new BorderLayout(5, 0));
panel3.add(new JLabel("Selection Mode"), BorderLayout.WEST);
panel3.add(jcboSelectionMode, BorderLayout.CENTER);
JPanel panel4 = new JPanel();
panel4.setLayout(new FlowLayout(FlowLayout.LEFT));
panel4.add(jchkRowSelectionAllowed);
panel4.add(jchkColumnSelectionAllowed);
//Gather panel3 and panel4
JPanel panel5 = new JPanel();
panel5.setLayout(new GridLayout(2, 1));
panel5.add(panel3);
panel5.add(panel4);
//Gather panel1 and panel2
JPanel panel6 = new JPanel();
panel6.setLayout(new BorderLayout());
panel6.add(panel1, BorderLayout.SOUTH);
panel6.add(panel2, BorderLayout.CENTER);
add(panel5, BorderLayout.NORTH);
add(new JScrollPane(jTable1), BorderLayout.CENTER);
add(panel6, BorderLayout.SOUTH);
//Initialize table selection mode
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//Add listeners
jbtAddRow.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if (jTable1.getSelectedRow() >= 0)
tableModel.insertRow(jTable1.getSelectedRow(), new Vector());
else
tableModel.addRow(new Vector());
}
});
jbtAddColumn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
String name = JOptionPane.showInputDialog("New Column Name");
tableModel.addColumn(name, new Vector());
}
});
jbtDeleteRow.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if (jTable1.getSelectedRow() >= 0)
tableModel.removeRow(jTable1.getSelectedRow());
}
});
jbtDeleteColumn.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if (jTable1.getSelectedColumn() >= 0)
{
TableColumnModel columnModel = jTable1.getColumnModel();
TableColumn tableColumn = columnModel.getColumn(jTable1.getSelectedColumn());
columnModel.removeColumn(tableColumn);
}
}
});
jbtSave.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("tablemodel.dat"));
out.writeObject(tableModel.getDataVector());
out.writeObject(getColumnNames());
out.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
});
jbtClear.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
tableModel.setRowCount(0);
}
});
jbtRestore.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("tablemodel.dat"));
Vector rowData = (Vector)in.readObject();
Vector columnNames = (Vector)in.readObject();
tableModel.setDataVector(rowData, columnNames);
in.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
});
jchkRowSelectionAllowed.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
jTable1.setRowSelectionAllowed(jchkRowSelectionAllowed.isSelected());
}
});
jchkColumnSelectionAllowed.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
jTable1.setColumnSelectionAllowed(jchkColumnSelectionAllowed.isSelected());
}
});
jcboSelectionMode.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
String selectedItem = (String)jcboSelectionMode.getSelectedItem();
if (selectedItem.equals("SINGLE_SELECTION"))
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
else if (selectedItem.equals("SINGLE_INTERVAL_SELECTION"))
jTable1.setSelectionMode(ListSelectionModel.SINGLE_INTERVAL_SELECTION);
else if (selectedItem.equals("MULTIPLE_INTERVAL_SELECTION"))
jTable1.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
}
});
}//end of default constructor
private Vector getColumnNames()
{
Vector<String> theColumnNames = new Vector<>();
for (int i = 0; i < jTable1.getColumnCount(); i++)
theColumnNames.add(jTable1.getColumnName(i));
return theColumnNames;
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
try
{
UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName());
}
catch(Exception e)
{
}
ModifyTable frame = new ModifyTable();
frame.setLocationRelativeTo(null); //Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("TableSortFilter");
frame.pack();
//frame.setSize(new Dimension(300, 300));
frame.setVisible(true);
}
}
If you wish to alter table content, it's better to work with table model directly. Create your own model and do what you want.
See http://docs.oracle.com/javase/tutorial/uiswing/components/table.html#data
Here is the final solution.
The last answer of this question (http://stackoverflow.com/questions/2668547/stackoverflowerror-being-caused-by-a-tablemodellistener) helped me alot :
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package nysemarketpick;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.Vector;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
/**
*
* #author Administrator
*/
public class PortfolioForm extends javax.swing.JFrame {
//Create table column names
private String[] columnNames = {"Stock Symbol", "Stock Name", "Shares", "Price (in dollars)", "Total"};
//Create table data
private Object[][] rowData = {
{null, null, null, null, null}
};
//Create a table model
private MyTableModel myTableModel = new MyTableModel(rowData, columnNames);
//Create a table
private JTable jTable1 = new JTable(myTableModel);
/**
* Creates new form PortfolioForm
*/
public PortfolioForm() {
initComponents();
add(new JScrollPane(jTable1), BorderLayout.CENTER);
//Initialize table selection mode
jTable1.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
//Allow row selection
jTable1.setRowSelectionAllowed(true);
//Load data
loadData();
//add listeners
jbtAddRow.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if (jTable1.getSelectedRow() >= 0)
myTableModel.insertRow(jTable1.getSelectedRow(), new Vector());
else
myTableModel.addRow(new Vector());
}
});
jbtDeleteRow.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
if ((jTable1.getSelectedRow() >= 0) && (myTableModel.getValueAt(jTable1.getSelectedRow(), 1) != null))
{
System.out.println(myTableModel.getValueAt(jTable1.getSelectedRow(), 1));
myTableModel.removeRow(jTable1.getSelectedRow());
}
}
});
jbtSave.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
try
{
ObjectOutputStream out = new ObjectOutputStream(new FileOutputStream("portfolio.dat"));
out.writeObject(myTableModel.getDataVector());
out.writeObject(getColumnNames());
out.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
disposeForm();
}
});
jbtClear.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
myTableModel.setRowCount(0);
}
});
jbtTotal.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
double sum = 0;
int numberOfRows = myTableModel.getRowCount();
for (int i = 0; i < numberOfRows; i++)
{
sum = sum + (Double)myTableModel.getValueAt(i, 4);
}
jLabelTotal.setText(String.valueOf(sum));
}
});
jbtTotals.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent e) {
Double myDouble;
for (int i = 0; i < myTableModel.getRowCount(); i++)
{
myDouble = (Integer)myTableModel.getValueAt(i, 2) * (Double)myTableModel.getValueAt(i, 3);
myTableModel.setValueAt(myDouble, i, 4);
}
}
});
myTableModel.addTableModelListener(new TableModelListener(){
#Override
public void tableChanged(TableModelEvent e) {
myTableModel.removeTableModelListener(this);
if (myTableModel.getRowCount() > 0)
{
if (e.getColumn() == 0)
{
Object data = myTableModel.getValueAt(e.getFirstRow(), e.getColumn());
String stockSymbol = (String)data;
XMLService2 myService = new XMLService2(stockSymbol);
String stockName = XMLService2.getStockName();
myTableModel.setValueAt(stockName, e.getFirstRow(), e.getColumn() + 1);
}
}
myTableModel.addTableModelListener(this);
}
});
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
#SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
jPanel1 = new javax.swing.JPanel();
jPanel2 = new javax.swing.JPanel();
jbtAddRow = new javax.swing.JButton();
jbtDeleteRow = new javax.swing.JButton();
jPanel3 = new javax.swing.JPanel();
jbtSave = new javax.swing.JButton();
jbtClear = new javax.swing.JButton();
jPanel4 = new javax.swing.JPanel();
jLabelTotal = new javax.swing.JLabel();
jbtTotal = new javax.swing.JButton();
jPanel5 = new javax.swing.JPanel();
jbtTotals = new javax.swing.JButton();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setSize(new java.awt.Dimension(600, 400));
jPanel2.setBorder(javax.swing.BorderFactory.createTitledBorder("Row functions"));
jPanel2.setLayout(new java.awt.GridLayout(2, 1));
jbtAddRow.setText("Add New Row");
jPanel2.add(jbtAddRow);
jbtDeleteRow.setText("Delete Selected Row");
jPanel2.add(jbtDeleteRow);
jPanel1.add(jPanel2);
jPanel3.setBorder(javax.swing.BorderFactory.createTitledBorder("Table functions"));
jPanel3.setMinimumSize(new java.awt.Dimension(200, 111));
jPanel3.setPreferredSize(new java.awt.Dimension(150, 100));
jPanel3.setLayout(new java.awt.GridLayout(3, 1));
jbtSave.setText("Save & Close");
jPanel3.add(jbtSave);
jbtClear.setText("Clear");
jPanel3.add(jbtClear);
jPanel1.add(jPanel3);
jPanel4.setBorder(javax.swing.BorderFactory.createTitledBorder("Total Position"));
jPanel4.setLayout(new java.awt.GridLayout(2, 1));
jLabelTotal.setHorizontalAlignment(javax.swing.SwingConstants.CENTER);
jLabelTotal.setBorder(javax.swing.BorderFactory.createEtchedBorder());
jPanel4.add(jLabelTotal);
jbtTotal.setText("Calculate");
jPanel4.add(jbtTotal);
jPanel1.add(jPanel4);
getContentPane().add(jPanel1, java.awt.BorderLayout.SOUTH);
jbtTotals.setText("Calculate Totals");
org.jdesktop.layout.GroupLayout jPanel5Layout = new org.jdesktop.layout.GroupLayout(jPanel5);
jPanel5.setLayout(jPanel5Layout);
jPanel5Layout.setHorizontalGroup(
jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 145, Short.MAX_VALUE)
.add(jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel5Layout.createSequentialGroup()
.add(0, 0, Short.MAX_VALUE)
.add(jbtTotals)
.add(0, 0, Short.MAX_VALUE)))
);
jPanel5Layout.setVerticalGroup(
jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(0, 336, Short.MAX_VALUE)
.add(jPanel5Layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING)
.add(jPanel5Layout.createSequentialGroup()
.add(0, 153, Short.MAX_VALUE)
.add(jbtTotals)
.add(0, 154, Short.MAX_VALUE)))
);
getContentPane().add(jPanel5, java.awt.BorderLayout.EAST);
}// </editor-fold>
/**
* #param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(PortfolioForm.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new PortfolioForm().setVisible(true);
}
});
}
//---Other methods
private Vector getColumnNames()
{
Vector<String> columnNames = new Vector<String>();
for (int i = 0; i < jTable1.getColumnCount(); i++)
columnNames.add(jTable1.getColumnName(i));
return columnNames;
}
private void disposeForm()
{
this.dispose();
}
private void loadData()
{
try
{
ObjectInputStream in = new ObjectInputStream(new FileInputStream("portfolio.dat"));
Vector rows = (Vector)in.readObject();
Vector columns = (Vector)in.readObject();
myTableModel.setDataVector(rows, columns);
in.close();
}
catch(Exception ex)
{
ex.printStackTrace();
}
}
// Variables declaration - do not modify
private javax.swing.JLabel jLabelTotal;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JPanel jPanel4;
private javax.swing.JPanel jPanel5;
private javax.swing.JButton jbtAddRow;
private javax.swing.JButton jbtClear;
private javax.swing.JButton jbtDeleteRow;
private javax.swing.JButton jbtSave;
private javax.swing.JButton jbtTotal;
private javax.swing.JButton jbtTotals;
// End of variables declaration
}