I have to create a program with graphical user interfaces which buttons perform certain things including the login and registration. I wanted to use the MVC pattern to create this project in such a way that the code remains "ordered" and clean.
So I created 3 packages: Model, View and Controller.
In Model there are several classes that define the objects (for example: User, Message, etc.). In View there are classes with the code created by NetBeans for GUI. I know that using the NetBeans GUI Builder you can create listeners to associate the various buttons. But this code listener is created in the same file as the View while I would like to separate files in the view from that of the controller.
So I would have something like:
- Model: files that define the objects
- View: files that define the GUI
- Controller: file "manage" the GUI taking user input and process them
But now in the files of the view there are both the GUI and the Controllers (listener).
For example, this is the LoginView file:
public class Login extends javax.swing.JFrame {
/** Creates new form Login */
public Login() {
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();
usernameLabel = new javax.swing.JLabel();
passwordLabel = new javax.swing.JLabel();
usernameField = new javax.swing.JTextField();
regButton = new javax.swing.JButton();
logButton = new javax.swing.JButton();
titleLabel = new javax.swing.JLabel();
passwordField = new javax.swing.JPasswordField();
javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
jPanel1.setLayout(jPanel1Layout);
jPanel1Layout.setHorizontalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
jPanel1Layout.setVerticalGroup(
jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 0, Short.MAX_VALUE)
);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("Login");
setLocationByPlatform(true);
setName("login"); // NOI18N
setResizable(false);
usernameLabel.setText("Username:");
passwordLabel.setText("Password:");
passwordLabel.setOpaque(true);
usernameField.setToolTipText("");
regButton.setText("Registrati");
regButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
regButtonActionPerformed(evt);
}
});
logButton.setText("Accedi");
logButton.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
logButtonActionPerformed(evt);
}
});
titleLabel.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
titleLabel.setText("Inserisci i tuoi dati:");
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().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(26, 26, 26)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(usernameLabel)
.addComponent(passwordLabel, javax.swing.GroupLayout.Alignment.TRAILING))
.addGroup(layout.createSequentialGroup()
.addComponent(regButton)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 24, Short.MAX_VALUE)
.addComponent(logButton))
.addComponent(passwordField)
.addComponent(usernameField)))
.addGroup(layout.createSequentialGroup()
.addGap(54, 54, 54)
.addComponent(titleLabel)))
.addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addContainerGap()
.addComponent(titleLabel)
.addGap(18, 18, 18)
.addComponent(usernameLabel)
.addGap(3, 3, 3)
.addComponent(usernameField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
.addComponent(passwordLabel)
.addGap(3, 3, 3)
.addComponent(passwordField, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(18, 18, 18)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(logButton)
.addComponent(regButton))
.addContainerGap(22, Short.MAX_VALUE))
);
usernameLabel.getAccessibleContext().setAccessibleName("usernameLabel");
usernameLabel.getAccessibleContext().setAccessibleDescription("");
passwordLabel.getAccessibleContext().setAccessibleName("passwordLabel");
setSize(new java.awt.Dimension(218, 227));
setLocationRelativeTo(null);
}// </editor-fold>
private void regButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//**Code for signup (create a new record, insert in database, etc.)**
}
private void logButtonActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
//**Code for login (look in the database, etc.)**
}
/**
* @param args the command line arguments
*/
public static void start() {
/* 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(Login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(Login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(Login.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(Login.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 Login().setVisible(true);
}
});
}
// Variables declaration - do not modify
private javax.swing.JPanel jPanel1;
private javax.swing.JButton logButton;
private javax.swing.JPasswordField passwordField;
private javax.swing.JLabel passwordLabel;
private javax.swing.JButton regButton;
private javax.swing.JLabel titleLabel;
private javax.swing.JTextField usernameField;
private javax.swing.JLabel usernameLabel;
// End of variables declaration
}
How do I separate the View from the Controller? Could you show me an example? I searched a lot on the Internet but I could not find an example that is right for me.
My main problem is that the components that create the NetBeans GUI Builder (button, JLabel, JList, etc.) are private and included in the View class. I must be able to manage these objects from an external class (in the controller).
For example, the LoginView class has only the GUI code and the class LoginController manages buttons and JTextField of LoginView class...
How can I do? Thank you very much!