fuin.org

Small Open Source Java Tools and Libraries

Optimized View and Logic (Controller) Separation with Swing


Part 2: Single Thread Rule

All public panel (view) methods should run in the AWT Thread. For this, we will utilize some of the annotations of the Aspects4Swing library, which is still under construction and based on AspectJ External link:
package org.fuin.jaddr.part5;

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

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

import org.fuin.aspects4swing.InvokeAndWait;

public class AddressListPanel extends JPanel implements
        AddressController.LoadAddressesListener, AddressController.DeleteAddressListener {

    private static final long serialVersionUID = 1L;

    private AddressController addressController;

    private JButton buttonDelete;

    private JButton buttonLoad;

    public AddressListPanel(AddressController addressListController) {
        super();
        this.addressController = addressListController;
        // TODO Create controls...
        init();
    }

    private void init() {
        buttonDelete.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                final Address addressToDelete = getSelectedAddress();
                addressController.deleteAddress(addressToDelete, AddressListPanel.this);
            }
        });
        buttonLoad.addActionListener(new ActionListener() {
            public void actionPerformed(final ActionEvent e) {
                final Address selectedAddress = getSelectedAddress();
                addressController.loadAddresses(selectedAddress, AddressListPanel.this);
            }
        });
    }

    private Address getSelectedAddress() {
        Address address = null;
        // TODO Find selected address
        return address;
    }

    @InvokeAndWait
    public void selectAddress(Address address) {
        // TODO Reselect address in UI
    }

    @InvokeAndWait
    public void setAddresses(List<Address> list) {
        // TODO Set addresses in UI
    }

    @InvokeAndWait
    public void addressDeleted(Address address) {
        // TODO Remove address from UI
    }

}
The @InvokeAndWait Internal link outside layout annotation ensures that the request occurs in the proper thread. Matching annotations are also available for the controller implementation.
package org.fuin.jaddr.part5;

import java.util.ArrayList;
import java.util.List;

import org.fuin.aspects4swing.StartNewThread;

public class AddressControllerImpl implements AddressController {

    @StartNewThread
    public void deleteAddress(Address address, DeleteAddressListener listener) {
        // TODO Do the real work...
        listener.addressDeleted(address);
    }

    @StartNewThread
    public void loadAddresses(Address selectedAddress, LoadAddressesListener listener) {
        List<Address> list = new ArrayList<Address>();
        // TODO Do the real work...
        listener.setAddresses(list);
        // Do some more work here...
        listener.selectAddress(selectedAddress);
    }

}
The @StartNewThread Internal link outside layout annotation initiates a new thread every time the method marked accordingly is requested. Basically, we have completed an - admittedly relatively simple - MVC framework. However, the controller should not contain any entity variables or it should be allowed to access them only in a synchronized manner. Moreover, it is not particularly effective to start a new thread each time a method is requested. However, for smaller tasks such an approach could certainly be adequate.
 
Since we have not yet attained all of our objectives, let's move on to the next part.
 
Next Page: Part 3: Utilization of Existing Basic Java Technologies
 

 
Page: 1 / 2 / 3 / 4 / 5 / 6 / 7