org.mobicents.eclipslee.servicecreation.ui.table.EditableTableViewer.java Source code

Java tutorial

Introduction

Here is the source code for org.mobicents.eclipslee.servicecreation.ui.table.EditableTableViewer.java

Source

/**
 *   Copyright 2005 Open Cloud Ltd.
 *
 *   Licensed under the Apache License, Version 2.0 (the "License");
 *   you may not use this file except in compliance with the License.
 *   You may obtain a copy of the License at
 *
 *       http://www.apache.org/licenses/LICENSE-2.0
 *
 *   Unless required by applicable law or agreed to in writing, software
 *   distributed under the License is distributed on an "AS IS" BASIS,
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *   See the License for the specific language governing permissions and
 *   limitations under the License.
 */

package org.mobicents.eclipslee.servicecreation.ui.table;

import java.util.HashMap;

import org.eclipse.jface.viewers.CellEditor;
import org.eclipse.jface.viewers.CheckboxCellEditor;
import org.eclipse.jface.viewers.ComboBoxCellEditor;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.viewers.TextCellEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.TableEditor;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Table;
import org.eclipse.swt.widgets.TableColumn;
import org.eclipse.swt.widgets.TableItem;

/**
 * @author cath
 * @author Vladimir Ralev
 */
public class EditableTableViewer extends TableViewer implements SelectionListener {

    public static final int EDITOR_TEXT = 0;
    public static final int EDITOR_CHECKBOX = 1;
    public static final int EDITOR_CHOICE = 2;
    public static final int EDITOR_BUTTON = 3;
    public static final int EDITOR_NONE = 4; // Uneditable cell
    public static final int EDITOR_NUMERIC = 5;

    public static final int bigCellHeight = 22;
    public static final int bigCellButtonWidth = 100;

    Listener itemMeasureListener = new ItemMeasureListener();

    public EditableTableViewer(Composite parent, int style, String columnNames[], int columnEditors[],
            Object editorValues[][]) {
        super(parent, style | SWT.FULL_SELECTION);
        this.columnNames = columnNames;
        this.columnEditors = columnEditors;
        this.columnValues = editorValues;

        initialize(columnNames, columnEditors, editorValues);
    }

    public EditableTableViewer(Table table, String columnNames[], int columnEditors[], Object editorValues[][]) {
        super(table);

        this.columnNames = columnNames;
        this.columnEditors = columnEditors;
        this.columnValues = editorValues;

        initialize(columnNames, columnEditors, editorValues);
    }

    public void initialize(String[] columnNames, int columnEditors[], Object editorValues[][]) {

        if (columnNames.length != columnEditors.length && columnEditors.length != editorValues.length) {
            throw new IllegalArgumentException(
                    "The size of the columnNames, columnEditors and editorValues arrays must be the same.");
        }
        getTable().addListener(SWT.MeasureItem, itemMeasureListener);

        // Don't use a hash lookup as we're storing HashMaps in the store and the
        // hashCode of these changes when the data inside them changes.
        setUseHashlookup(false);
        Table table = getTable();

        CellEditor editors[] = new CellEditor[columnNames.length];
        TableColumn tableColumns[] = new TableColumn[columnNames.length];

        for (int i = 0; i < columnNames.length; i++) {
            tableColumns[i] = new TableColumn(table, SWT.NONE);
            tableColumns[i].setText(columnNames[i]);
            tableColumns[i].setWidth(150);
            tableColumns[i].setResizable(true);
            tableColumns[i].pack();
        }
        setColumnProperties(columnNames);

        for (int i = 0; i < columnEditors.length; i++) {
            switch (columnEditors[i]) {
            case EDITOR_TEXT:
                editors[i] = new TextCellEditor(table);
                break;

            case EDITOR_CHECKBOX:
                editors[i] = new CheckboxCellEditor(table);
                break;

            case EDITOR_CHOICE:
                String vals[] = new String[editorValues[i].length];
                for (int j = 0; j < editorValues[i].length; j++)
                    vals[j] = (String) editorValues[i][j];

                editors[i] = new ComboBoxCellEditor(table, vals, SWT.READ_ONLY);
                break;

            case EDITOR_BUTTON:
            case EDITOR_NUMERIC:
                editors[i] = null;
                break;

            case EDITOR_NONE:
                editors[i] = null;
                break; // May need to use a TextCellEditor and make uneditable.

            default:
                // Error message about unrecognised cell editor.
                System.err.println("Invalid cell editor value: " + columnEditors[i]);
            }
        }
        setCellEditors(editors);

        table.setHeaderVisible(true);

        table.addSelectionListener(this);

        store = new DataStore();
        setContentProvider(new GenericContentProvider(this, store));
        setInput(store);

        setCellModifier(new GenericCellModifier(this, columnNames, columnEditors));
        setLabelProvider(new GenericLabelProvider(columnNames, columnEditors, editorValues));
    }

    public void repack() {
        TableColumn[] cols = getTable().getColumns();
        for (int q = 0; q < cols.length; q++)
            cols[q].pack();

        // Try to force a redraw of the table - this may not redraw the buttons though.
        getTable().layout(true);

        // Try to force a redraw of the editors and buttons      
        Object data[] = store.getElements();
        for (int i = 0; i < data.length; i++) {
            HashMap map = (HashMap) data[i];

            for (int column = 0; column < columnEditors.length; column++) {
                if (columnEditors[column] == EDITOR_BUTTON) {

                    Button button = (Button) map.get("Button_" + column);
                    if (button != null) {
                        button.redraw();
                        button.getParent().layout(true);
                    }
                    TableEditor editor = (TableEditor) map.get("Editor_" + column);
                    if (editor != null) {
                        editor.layout();
                    }
                }

                if (columnEditors[column] == EDITOR_NUMERIC) {
                    Scale scale = (Scale) map.get("Scale_" + column);
                    if (scale != null) {
                        scale.redraw();
                        scale.getParent().layout(false);
                    }
                    TableEditor editor = (TableEditor) map.get("Editor_" + column);
                    if (editor != null) {
                        editor.layout();
                    }
                }
            }
        }

    }

    public HashMap addRow(HashMap map) {
        // Make the table lines visible
        getTable().setLinesVisible(true);
        store.add(map);
        return map;
    }

    public HashMap addRow() {
        // Make the table lines visible
        getTable().setLinesVisible(true);
        HashMap map = new HashMap();

        // Initialize the HashMap with sensible values.
        for (int i = 0; i < columnNames.length; i++) {
            switch (columnEditors[i]) {
            case EDITOR_CHECKBOX:
                map.put(columnNames[i], Boolean.FALSE);
                break;

            case EDITOR_CHOICE:
                map.put(columnNames[i], new Integer(0));
                break;

            case EDITOR_NUMERIC:
                map.put(columnNames[i], new Integer(0));
                break;

            default:
                map.put(columnNames[i], "?");
                break;
            }
        }

        store.add(map);
        return map;
    }

    public void removeRow(HashMap map) {
        store.remove(map);
    }

    public void remove(Object o) {
        HashMap map = (HashMap) o;

        for (int column = 0; column < columnEditors.length; column++) {
            if (columnEditors[column] == EDITOR_BUTTON) {
                if (map.get("Editor_" + column) != null) {
                    TableEditor editor = (TableEditor) map.get("Editor_" + column);
                    Button button = (Button) map.get("Button_" + column);

                    button.setVisible(false);
                    button.dispose();
                    editor.dispose();

                    map.remove("Editor_" + column);
                    map.remove("Button_" + column);
                }
            }
            if (columnEditors[column] == EDITOR_NUMERIC) {
                if (map.get("Editor_" + column) != null) {
                    TableEditor editor = (TableEditor) map.get("Editor_" + column);
                    Scale scale = (Scale) map.get("Scale_" + column);
                    scale.setVisible(false);
                    scale.dispose();
                    editor.dispose();

                    map.remove("Editor_" + column);
                    map.remove("Scale_" + column);
                }
            }
        }

        /* 
         * Ugly hack! Not needed for Eclipse 3.3, but Eclipse 3.2 has
         * a bug http://dev.eclipse.org/newslists/news.eclipse.platform.swt/msg29738.html
         * Reinstall the listener each time you remove seems to work.
         */
        this.getTable().removeListener(SWT.MeasureItem, itemMeasureListener);
        super.remove(o);
        this.getTable().addListener(SWT.MeasureItem, itemMeasureListener);
    }

    public void add(Object o) {

        super.add(o);

        // Get all existing rows and find row(s) without a defined button.
        // Create buttons for it.

        Table table = getTable();
        TableItem items[] = getTable().getItems();
        for (int column = 0; column < columnEditors.length; column++) {
            if (columnEditors[column] == EDITOR_BUTTON) {

                for (int row = 0; row < items.length; row++) {
                    TableItem item = items[row];
                    HashMap map = (HashMap) item.getData();
                    if (map.get("Editor_" + column) == null) {
                        TableEditor editor = new TableEditor(table);
                        Button button = new Button(table, SWT.NONE);
                        String buttonText = (String) map.get("ButtonText_" + column);
                        if (buttonText == null)
                            button.setText((String) columnValues[column][0]);
                        else
                            button.setText(buttonText);
                        button.addSelectionListener((SelectionListener) columnValues[column][1]);
                        button.pack();
                        editor.grabHorizontal = true;
                        editor.minimumWidth = button.getSize().x;
                        editor.horizontalAlignment = SWT.LEFT;
                        editor.setEditor(button, item, column); // TableItem.getItems(row), column
                        map.put("Editor_" + column, editor);
                        map.put("Button_" + column, button);
                    }
                }
            }

            if (columnEditors[column] == EDITOR_NUMERIC) {

                for (int row = 0; row < items.length; row++) {
                    TableItem item = items[row];
                    HashMap map = (HashMap) item.getData();
                    if (map.get("Editor_" + column) == null) {
                        TableEditor editor = new TableEditor(table);
                        Scale scale = new Scale(table, SWT.NONE);
                        int min = ((Integer) columnValues[column][0]).intValue();
                        int max = ((Integer) columnValues[column][1]).intValue();
                        int increment = ((Integer) columnValues[column][2]).intValue();

                        scale.setMinimum(min);
                        scale.setMaximum(max);
                        scale.setIncrement(increment);
                        scale.pack();

                        editor.grabHorizontal = true;
                        editor.minimumWidth = scale.getSize().x;
                        editor.horizontalAlignment = SWT.LEFT;
                        editor.setEditor(scale, item, column);
                        map.put("Editor_" + column, editor);
                        map.put("Scale_" + column, scale);
                    }
                }
            }
        }
    }

    public void widgetDefaultSelected(SelectionEvent event) {
    }

    public void widgetSelected(SelectionEvent event) {

        // SWT.CHECK in object detail field means a check button changed value      
        if ((event.detail & SWT.CHECK) == SWT.CHECK) {
            System.err.println("A checkbox changed value.");
        }
    }

    public DataStore getStore() {
        return store;
    }

    private class ItemMeasureListener implements Listener {
        public void handleEvent(Event event) {
            if (bigCellHeight == SWT.DEFAULT)
                return;
            event.height = bigCellHeight;
            TableColumn column = getTable().getColumn(event.index);
            TableItem ti = (TableItem) event.item;
            HashMap map = (HashMap) ti.getData();
            if (map.get("Button_" + event.index) != null)
                event.width = bigCellButtonWidth;
        }
    }

    protected DataStore store;
    private String columnNames[];
    private int columnEditors[];
    private Object columnValues[][];
}