Model View Controller mit Java 7

Model View Controller Tutorial mit Java 7 (Swing, Awt) und Netbeans

 

Im Folgenden wird gezeigt, wie man eine MVC-Anwendung mit Java (Java 7) Swing/Awt und NetBeans (NetBeans 7.1) erstellen kann.

 

Rechnungen Suche Frame:

1. Projekt erstellen:

Meinestadt Aktuell

2. Projekt Struktur:

Meinestadt Aktuell

3. Quellcode komplett:

3.1 Package com.sambi.mvc:

MainFrame.java:

package com.sambi.mvc;
import com.sambi.mvc.controller.InvoicesSearchController;
import com.sambi.mvc.model.InvoicesSearchModel;
import com.sambi.mvc.view.InvoicesSearchFrame;
/**
 * @author SAM BI
 */
public class MainFrame {
    public MainFrame() {
        InvoicesSearchModel invoicesSearchModel = new InvoicesSearchModel();
        InvoicesSearchController controller = new InvoicesSearchController();
        InvoicesSearchFrame propertiesViewPanel = new InvoicesSearchFrame(controller);
        
        controller.addView(propertiesViewPanel);
        controller.addModel(invoicesSearchModel);
        invoicesSearchModel.initDefault();
    }
    public static void main(String[] args) {
        new MainFrame();
    }
}

3.2 Package com.sambi.mvc.controller:

AbstractController.java

package com.sambi.mvc.controller;
import com.sambi.mvc.model.AbstractModel;
import com.sambi.mvc.view.AbstractFrame;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
 * @author SAM BI
 */
public abstract class AbstractController implements PropertyChangeListener {
    private ArrayList registeredViews;
    private ArrayList registeredModels;
    public AbstractController() {
        registeredViews = new ArrayList<>();
        registeredModels = new ArrayList<>();
    }
    public void addModel(AbstractModel model) {
        registeredModels.add(model);
        model.addPropertyChangeListener(this);
    }
    public void removeModel(AbstractModel model) {
        registeredModels.remove(model);
        model.removePropertyChangeListener(this);
    }
    public void addView(AbstractFrame view) {
        registeredViews.add(view);
    }
    public void removeView(AbstractFrame view) {
        registeredViews.remove(view);
    }
    @Override
    public void propertyChange(PropertyChangeEvent event) {
        for (AbstractFrame view: registeredViews) {
            view.modelPropertyChange(event);
        }
    }
    protected void setModelProperty(String propertyName, Object newValue) {
        for (AbstractModel model: registeredModels) {
            try {
                Method method = model.getClass().getMethod("set" + propertyName, new Class[] { newValue.getClass() });
                method.invoke(model, newValue);
            } catch (NoSuchMethodException | SecurityException | IllegalAccessException | IllegalArgumentException | InvocationTargetException ex) {
                System.err.println(ex.getMessage());
            }
        }
    }
}

InvoicesSearchController.java

package com.sambi.mvc.controller;
import java.util.regex.Pattern;
/**
 * @author SAM BI
 */
public class InvoicesSearchController extends AbstractController {
    /**
     * properties constants called by the GUI event listeners of the view.
     */
    public static final String CUSTOMERID_PROPERTY   = "CustomerId";
    public static final String CUSTOMERNAME_PROPERTY = "CustomerName";
    public static final String NBINVOICES_PROPERTY   = "NbInvoices";
    /**
     * methods called by the GUI event listeners of the view.
     */
    public void changeCustomerId(String newCustomerId) {
        setModelProperty(CUSTOMERID_PROPERTY, newCustomerId);
    }
    public void changeCustomerName(String newCustomerName) {
        setModelProperty(CUSTOMERNAME_PROPERTY, newCustomerName);
    }
        public void changeNbInvoices(int newNbInvoices) {
        setModelProperty(NBINVOICES_PROPERTY, newNbInvoices);
    }
    public boolean validateParameters(String customerId, String nbInvoices){
        return this.validateCustomerId(customerId) && this.validateNbInvoices(nbInvoices);
    }
    public boolean validateCustomerId(String customerId){
        //customerId: alphanumeric
        return Pattern.matches("[a-zA-Z0-9]+", customerId) && (customerId.length() <= 11);
    }
    public boolean validateNbInvoices(String nbInvoices){
        // 0 <= nbInvoices <= 99 999
        return Pattern.matches("\\d+", nbInvoices) && (nbInvoices.length() <= 5);
    }
}

3.3 Package com.sambi.mvc.model:

AbstractModel.java

package com.sambi.mvc.model;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
/**
 * @author SAM BI
 */
public abstract class AbstractModel {
    /**
     * The PropertyChangeSupport class is used to register, deregister,
     * and notify interested listeners of changes to the model.
     */
    protected PropertyChangeSupport propertyChangeSupport;
    public AbstractModel() {
        propertyChangeSupport = new PropertyChangeSupport(this);
    }
    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.removePropertyChangeListener(listener);
    }
    protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
        propertyChangeSupport.firePropertyChange(propertyName, oldValue, newValue);
    }
}

InvoicesSearchModel.java

package com.sambi.mvc.model;
import com.sambi.mvc.controller.InvoicesSearchController;
/**
 * @author SAM BI
 */
public class InvoicesSearchModel extends AbstractModel {
    private String customerId;
    private String customerName;
    private int nbInvoices;
    public void initDefault() {
        this.setCustomerId("");
        this.setCustomerName("");
        this.setNbInvoices(100);
    }
    public String getCustomerId() {
        return customerId;
    }
    public void setCustomerId(String customerId) {
        String oldCustomerId = this.customerId;
        this.customerId = customerId;
        firePropertyChange(InvoicesSearchController.CUSTOMERID_PROPERTY, oldCustomerId, customerId);
    }
    public String getCustomerName() {
        return this.customerName;
    }
    public void setCustomerName(String customerName) {
        String oldCustomerName = this.customerName;
        this.customerName = customerName;
        firePropertyChange(InvoicesSearchController.CUSTOMERNAME_PROPERTY, oldCustomerName, customerName);
    }
 public int getNbInvoices() {
        return nbInvoices;
    }
    public void setNbInvoices(int nbInvoices) {
        int oldNbInvoices = this.nbInvoices;
        this.nbInvoices = nbInvoices;
        firePropertyChange(InvoicesSearchController.NBINVOICES_PROPERTY, oldNbInvoices, nbInvoices);
    }
}

3.4 Package com.sambi.mvc.view:

AbstractFrame.java

package com.sambi.mvc.view;
import java.beans.PropertyChangeEvent;
import javax.swing.JFrame;
/**
 * @author SAM BI
 */
public abstract class AbstractFrame extends JFrame {
    public abstract void modelPropertyChange(PropertyChangeEvent event);
}

InvoicesSearchFrame.java

package com.sambi.mvc.view;
import com.sambi.mvc.controller.InvoicesSearchController;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.beans.PropertyChangeEvent;
import javax.swing.*;
/**
 * @author SAM BI
 */
public class InvoicesSearchFrame extends AbstractFrame {
    private InvoicesSearchController controller;
    private JPanel jPanel;
    private JLabel jLCustomerId;
    private JTextField jTCustomerId;
    private JLabel jLCustomerName;
    private JTextField jTCustomerName;
    private JLabel jLNbInvoices;
    private JTextField jTNbInvoices;
    private JButton jBSearch;
    private JButton jBCancel;
    /**
     * Creates new form PropertiesViewPanel
     * @param controller the controller used by this view to process GUI actions
     */
    public InvoicesSearchFrame(InvoicesSearchController controller) {
        this.controller = controller;
        initComponents();
    }
    /**
     * @param event The property change event
     */
    @Override
    public void modelPropertyChange(final PropertyChangeEvent event) {
        switch (event.getPropertyName()) {
            case InvoicesSearchController.CUSTOMERID_PROPERTY: {
                String newStringValue = event.getNewValue().toString();
                if (!jTCustomerId.getText().equals(newStringValue)) {
                    jTCustomerId.setText(newStringValue);
                }
                break;
            }
            case InvoicesSearchController.CUSTOMERNAME_PROPERTY: {
                String newStringValue = event.getNewValue().toString();
                if (!jTCustomerName.getText().equals(newStringValue)) {
                    jTCustomerName.setText(newStringValue);
                }
                break;
            }
            case InvoicesSearchController.NBINVOICES_PROPERTY: {
                int newIntegerValue = (Integer) event.getNewValue();
                if (Integer.parseInt(jTNbInvoices.getText()) != newIntegerValue) {
                    jTNbInvoices.setText(newIntegerValue + "");
                }
                break;
            }
            default:
                break;
        }
    }   
    private void initComponents() {
        jPanel         = new JPanel();
        jLCustomerId   = new JLabel("Kundennummer:");
        jTCustomerId   = new JTextField("");
        jLCustomerName = new JLabel("Kundenname: ");
        jTCustomerName = new JTextField("");
        jLNbInvoices   = new JLabel("Anzahl der Rechnungen:");
        jTNbInvoices   = new JTextField("100");
        jBSearch       = new JButton("Suchen");
        jBCancel       = new JButton("Abbrechen");
        jTCustomerId.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                jTCustomerIdActionPerformed(event);
            }
        });
        jTCustomerId.addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusLost(FocusEvent event) {
                jTCustomerIdFocusLost(event);
            }
            @Override
            public void focusGained(FocusEvent event) {
                jTCustomerIdFocusGained(event);
            }
        });
        jTCustomerName.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                jTCustomerNameActionPerformed(event);
            }
        });
        jTCustomerName.addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusLost(FocusEvent event) {
                jTCustomerNameFocusLost(event);
            }
        });
        jTNbInvoices.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                jTNbInvoicesActionPerformed(event);
            }
        });
        jTNbInvoices.addFocusListener(new java.awt.event.FocusAdapter() {
            @Override
            public void focusLost(FocusEvent event) {
                jTNbInvoicesFocusLost(event);
            }
            @Override
            public void focusGained(FocusEvent event) {
                jTNbInvoicesFocusGained(event);
            }
        });
        jBSearch.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                jBSearchActionPerformed(event);
            }
        });
        jBCancel.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                jBCancelActionPerformed(event);
            }
        });
        jPanel.setLayout(null);
        Insets insets = jPanel.getInsets();
        // Label Customer Id
        Dimension size = jLCustomerId.getPreferredSize();
        jLCustomerId.setBounds(25 + insets.left, 55 + insets.top, size.width, size.height);
        jPanel.add(jLCustomerId);
        //--TextField Customer Id
        size = jTCustomerId.getPreferredSize();
        jTCustomerId.setBounds(170, 55 + insets.top, 100, size.height);
        jPanel.add(jTCustomerId);
        //--Label Customer Name
        size = jLCustomerName.getPreferredSize();
        jLCustomerName.setBounds(25 + insets.left, 90 + insets.top, size.width, size.height);
        jPanel.add(jLCustomerName);
        //--Textfield Customer Name
        size = jTCustomerName.getPreferredSize();
        jTCustomerName.setBounds(170, 90 + insets.top, 200, size.height);
        jPanel.add(jTCustomerName);
        //--Label Nb Invoices
        size = jLNbInvoices.getPreferredSize();
        jLNbInvoices.setBounds(25 + insets.left, 125 + insets.top, size.width, size.height);
        jPanel.add(jLNbInvoices);
        //--Textfield Nb Invoices
        size = jTNbInvoices.getPreferredSize();
        jTNbInvoices.setBounds(170, 125 + insets.top, 100, size.height);
        jPanel.add(jTNbInvoices);
        //--Button "Search"
        size = jBSearch.getPreferredSize();
        jBSearch.setBounds(100 + insets.left, 200 + insets.top, size.width, size.height);
        jPanel.add(jBSearch);
        //--Button "Cancel"
        size = jBCancel.getPreferredSize();
        jBCancel.setBounds(200 + insets.left, 200 + insets.top, size.width, size.height);
        jPanel.add(jBCancel);
        this.setTitle("Rechnungen Suche");
        this.getContentPane().add(jPanel);
        this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        this.pack();
        this.setSize(400, 300);
        this.setLocation(200, 200);
        this.setVisible(true);
    }
    //----Customer ID
    private void jTCustomerIdFocusLost(FocusEvent event) {
        System.out.println("Kundennummer: " + jTCustomerId.getText());
        this.repaint(); // refresh the frame
        controller.changeCustomerId(jTCustomerId.getText());
    }
    private void jTCustomerIdFocusGained(FocusEvent event) {
        if(controller.validateCustomerId(jTCustomerId.getText())){
            jTCustomerId.setForeground(new Color(0, 0, 0));
        }
    }
    private void jTCustomerIdActionPerformed(ActionEvent event) {
        controller.changeCustomerId(jTCustomerId.getText());
    }
    //----Customer Name
    private void jTCustomerNameFocusLost(FocusEvent event) {
        System.out.println("Kunden Name: " + jTCustomerName.getText());
        this.repaint(); // refresh the frame
        controller.changeCustomerName(jTCustomerName.getText());
    }
    private void jTCustomerNameActionPerformed(ActionEvent event) {
        controller.changeCustomerName(jTCustomerName.getText());
    }
    //----NbInvoices
    private void jTNbInvoicesFocusLost(FocusEvent event) {
        controller.changeNbInvoices(Integer.parseInt(jTNbInvoices.getText()));
    }
    private void jTNbInvoicesFocusGained(FocusEvent event) {
        if(controller.validateNbInvoices(jTNbInvoices.getText())){
            jTNbInvoices.setForeground(new Color(0, 0, 0));
        }
    }
    private void jTNbInvoicesActionPerformed(ActionEvent event) {
        controller.changeNbInvoices(Integer.parseInt(jTNbInvoices.getText()));
    }
    private void jBSearchActionPerformed(ActionEvent event) {
        boolean valid = controller.validateParameters(jTCustomerId.getText(), jTNbInvoices.getText());
        System.out.println("valid: " + valid);
        if (valid) {
            this.setVisible(false);
            dispose(); // destroy the JFrame object
            System.exit(0);
        } else {
            if (!controller.validateCustomerId(jTCustomerId.getText())) {
                jTCustomerId.setForeground(new Color(255, 0, 0));
                System.out.println("Kundennummer ist falsch");
            }
            if (!controller.validateNbInvoices(jTNbInvoices.getText())) {
                jTNbInvoices.setForeground(new Color(255, 0, 0));
                System.out.println("Anzahl der Rechnungen ist falsch");
            }
        }
    }
    private void jBCancelActionPerformed(ActionEvent event) {
        this.setVisible(false);
        dispose(); // destroy the JFrame object
        System.exit(0);
    }
}
Java MVC Tutorial - SAM Business Informatics