MoleHillRocker's Blog :: Nerding around since 1985

To content | To menu | To search

Code-Schnippsel

Entries feed - Comments feed

Friday, April 9 2010

Gemeinsame Nutzung eines Models durch eine JTable und eine JComboBox

In den letzten Tagen stand ich vor dem Problem, Daten in einer JTable und einer JComboBox anzeigen zu lassen. Änderungen in der JTable sollten auf die JComboBox übertragen werden und umgekehrt. Da dies jedoch einigen Aufwand in Bezug auf die Synchronisierung der Daten bedeutet, habe ich mich schließlich entschieden ein Model zu entwickeln das von beiden genutzt werden kann.

Das Model
public class UserObjectsModel implements TableModel, ComboBoxModel, Constants {

    private List<UserObject> data;

    private List<EventListener> listenerList = new ArrayList<EventListener>();

    private int selectedIndex;

    private static UserObjectsModel model;

    private UserObjectsModel() {
        super();
        this.data = new ArrayList<UserObject>();
    }

    @Override
    public int getColumnCount() {
        return USER_TABLE_COLUMN_NAMES.length;
    }

    @Override
    public int getRowCount() {
        if(data == null)
            return 0;
        return data.size();
    }

    @Override
    public String getColumnName(int col) {
        return USER_TABLE_COLUMN_NAMES[col];
    }

    @Override
    public Object getValueAt(int row, int col) {
        UserObject userObject = null;
        try {
            userObject = data.get(row);
        }
        catch(NullPointerException npe) {
            return null;
        }
        catch(IndexOutOfBoundsException ioobe) {
            return null;
        }
        switch(col) {
            case USER_OBJECT_ID:
                return userObject.getUserId();
            case USER_OBJECT_FIRST_NAME:
                return userObject.getFirstName();
            case USER_OBJECT_SECOND_NAME:
                return userObject.getSecondName();
            case USER_OBJECT_STREET_NAME:
                return userObject.getStreetName();
            case USER_OBJECT_STREET_NUMBER:
                return userObject.getStreetNumber();
            case USER_OBJECT_ZIPCODE:
                return userObject.getZipcode();
            case USER_OBJECT_PLACE:
                return userObject.getPlace();
            default:
                return null;
        }
    }

    @Override
    public Class<? extends Object> getColumnClass(int c) {
        Object object = getValueAt(0, c);
        if(object == null)
            return Object.class;
        else
            return getValueAt(0, c).getClass();
    }

    @Override
    public boolean isCellEditable(int row, int col) {
        return false;
    }

    @Override
    public void setValueAt(Object value, int row, int col) {
        UserObject userObject = data.get(row);
        switch(col) {
            case USER_OBJECT_ID:
                userObject.setUserId(((Integer) value).intValue());
            case USER_OBJECT_FIRST_NAME:
                userObject.setFirstName(value.toString());
            case USER_OBJECT_SECOND_NAME:
                userObject.setSecondName(value.toString());
            case USER_OBJECT_STREET_NAME:
                userObject.setStreetName(value.toString());
            case USER_OBJECT_STREET_NUMBER:
                userObject.setStreetNumber(((Short) value).shortValue());
            case USER_OBJECT_ZIPCODE:
                userObject.setZipcode(value.toString());
            case USER_OBJECT_PLACE:
                userObject.setPlace(value.toString());
        }
        fireTableDataChanged();
    }

    public void addUserObject(UserObject userObject) {
        data.add(userObject);
        fireTableDataChanged();
    }

    public void removeUserObject(int row) {
        data.remove(row);
        fireTableDataChanged();
    }

    public void removeUserObject(UserObject userObject) {
        data.remove(userObject);
        fireTableDataChanged();
    }

    public void clearUsers() {
        data.clear();
        fireTableDataChanged();
    }

    public UserObject getUser(int index) {
        return data.get(index);
    }

    public Vector<UserObject> getUsers() {
        return new Vector<UserObject>(data);
    }

    @Override
    public void addTableModelListener(TableModelListener listener) {
        listenerList.add(listener);
    }

    @Override
    public void removeTableModelListener(TableModelListener listener) {
        listenerList.add(listener);
    }

    @Override
    public Object getSelectedItem() {
        if(data.size() > 0)
            return data.get(selectedIndex);
        else
            return null;
    }

    @Override
    public void setSelectedItem(Object item) {
        for(int i = 0; i < data.size(); i++) {
            if(data.get(i).equals(item))
                selectedIndex = i;
        }
        fireContentsChanged();
    }

    @Override
    public void addListDataListener(ListDataListener listener) {
        listenerList.add(listener);
    }

    @Override
    public Object getElementAt(int idx) {
        if(idx >= 0 && idx < data.size())
            return data.get(idx);
        else
            return null;
    }

    @Override
    public int getSize() {
        return data.size();
    }

    @Override
    public void removeListDataListener(ListDataListener listener) {
        listenerList.remove(listener);
    }

    public void fireTableDataChanged() {
        fireTableChanged(new TableModelEvent(this));
    }

    public void fireTableChanged(TableModelEvent event) {
        for(EventListener listener : listenerList) {
            if(listener instanceof TableModelListener)
                ((TableModelListener) listener).tableChanged(event);
        }
    }

    public void fireContentsChanged() {
        fireContentsChanged(new ListDataEvent(this, ListDataEvent.CONTENTS_CHANGED,
                selectedIndex, selectedIndex));
    }

    public void fireContentsChanged(ListDataEvent event) {
        for(EventListener listener : listenerList) {
            if(listener instanceof ListDataListener)
                ((ListDataListener) listener).contentsChanged(event);
        }
    }

    public static UserObjectsModel getInstance() {
        if(model == null)
            model = new UserObjectsModel();
        return model;
    }

}


Klasse UserObject
public class UserObject {

    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private int userId;

    @Basic
    private String firstName;

    @Basic
    private String secondName;

    @Basic
    private String streetName;

    @Basic
    private short streetNumber;

    @Basic
    private String zipcode;

    @Basic
    private String place;

    public UserObject() {
        super();
    }

    public UserObject(String firstName, String secondName, String streetName,
            short streetNumber, String zipcode, String place) {
        super();
        this.firstName = firstName;
        this.secondName = secondName;
        this.streetName = streetName;
        this.streetNumber = streetNumber;
        this.zipcode = zipcode;
        this.place = place;
    }

    public int getUserId() {
        return userId;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getSecondName() {
        return secondName;
    }

    public void setSecondName(String secondName) {
        this.secondName = secondName;
    }

    public String getStreetName() {
        return streetName;
    }

    public void setStreetName(String streetName) {
        this.streetName = streetName;
    }

    public short getStreetNumber() {
        return streetNumber;
    }

    public void setStreetNumber(short streetNumber) {
        this.streetNumber = streetNumber;
    }

    public String getZipcode() {
        return zipcode;
    }

    public void setZipcode(String zipcode) {
        this.zipcode = zipcode;
    }

    public String getPlace() {
        return place;
    }

    public void setPlace(String place) {
        this.place = place;
    }

    public String toString() {
        return "UserObject [ " + userId + "   " + firstName + "   " + secondName + " ]";
    }

}

Interface Constants

public interface Constants {

    public static final String[] USER_TABLE_COLUMN_NAMES = { "User-ID", "First name",
            "Last name", "Street name", "Street number", "Zip code", "Place" };

    public static final int USER_OBJECT_ID = 0;

    public static final int USER_OBJECT_FIRST_NAME = 1;

    public static final int USER_OBJECT_SECOND_NAME = 2;

    public static final int USER_OBJECT_STREET_NAME = 3;

    public static final int USER_OBJECT_STREET_NUMBER = 4;

    public static final int USER_OBJECT_ZIPCODE = 5;

    public static final int USER_OBJECT_PLACE = 6;

}

Das Model kann nun durch Aufruf der Methode #setModel(UserObjectsModel.getInstance())an die JTable/JComboBox gebunden werden.

Monday, July 27 2009

Eclipse RCP :: VerifyListener

Ein VerifyListener kann bei der Applikationsentwicklung mit Eclipse RCP dazu verwendet werden, den User-Input in ein Text-Feld zu "validieren". Die nachfolgende Listener-Implementierung erlaubt z.B. nur numerische Werte und die Verwendung der Pfeiltasten, der Backspace sowie der Entfernen-Taste.

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.widgets.Text;

public class IntegerInputVerifyListener implements VerifyListener {

    private Text text;

    public IntegerInputVerifyListener(Text text) {
        super();
        this.text = text;
    }

    @Override
    public void verifyText(VerifyEvent e) {
        if(e.doit == false) {
            return;
        }
        e.doit = (Character.isDigit(e.character) || e.character == SWT.DEL || e.character == SWT.BS);
        if(e.doit) {
            // Valid input, do something
        }
        else {
            // Invalid input, a user may now
            // - Delete the text by pressing backspace
            // - Delete text by using the arrow-keys and the delete-button
            // - Enter a numeric value
        }
    }

}