net.bioclipse.cdk.ui.periodictable.PeriodicTableView.java Source code

Java tutorial

Introduction

Here is the source code for net.bioclipse.cdk.ui.periodictable.PeriodicTableView.java

Source

/*******************************************************************************
 * Copyright (c) 2008 The Bioclipse Project and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * <http://www.eclipse.org/legal/epl-v10.html>.
 *
 * Contributors:
 *     Arvid Berg <goglepox@users.sf.net>
 *
 ******************************************************************************/
package net.bioclipse.cdk.ui.periodictable;

import static org.openscience.cdk.tools.PeriodicTable.getChemicalSeries;
import static org.openscience.cdk.tools.PeriodicTable.getGroup;
import static org.openscience.cdk.tools.PeriodicTable.getPeriod;
import static org.openscience.cdk.tools.PeriodicTable.getPhase;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import net.bioclipse.cdk.domain.CDKChemObject;

import org.eclipse.core.runtime.ISafeRunnable;
import org.eclipse.core.runtime.ListenerList;
import org.eclipse.core.runtime.SafeRunner;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionChangedListener;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.SelectionChangedEvent;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.swt.SWT;
import org.eclipse.swt.SWTError;
import org.eclipse.swt.dnd.DND;
import org.eclipse.swt.dnd.DragSource;
import org.eclipse.swt.dnd.DragSourceEvent;
import org.eclipse.swt.dnd.DragSourceListener;
import org.eclipse.swt.dnd.TextTransfer;
import org.eclipse.swt.dnd.Transfer;
import org.eclipse.swt.events.ControlAdapter;
import org.eclipse.swt.events.ControlEvent;
import org.eclipse.swt.events.DisposeEvent;
import org.eclipse.swt.events.DisposeListener;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Device;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.FontData;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.ui.part.ViewPart;
import org.openscience.cdk.CDKConstants;
import org.openscience.cdk.PeriodicTableElement;
import org.openscience.cdk.config.ElementPTFactory;
import org.openscience.cdk.config.Symbols;
import org.openscience.cdk.exception.CDKException;
import org.openscience.cdk.tools.PeriodicTable;

/**
 * @author arvid
 *
 */
@SuppressWarnings("serial")
public class PeriodicTableView extends ViewPart implements ISelectionProvider {

    String[] elements;
    ColorAWTtoSWTConverter colorConverter;

    Canvas canvas;

    CDKChemObject<PeriodicTableElement> selection;
    ElementPTFactory eptf;

    ListenerList listeners = new ListenerList();
    ISelection theSelection = StructuredSelection.EMPTY;

    static final Map<String, java.awt.Color> colorMap = new HashMap<String, java.awt.Color>() {
        {
            put("Alkali Metals", new java.awt.Color(0xFF6666));
            put("Alkali Earth Metals", new java.awt.Color(0xFFDEAD));
            put("Lanthanides", new java.awt.Color(0xFFBFFF));
            put("Actinides", new java.awt.Color(0xFF99CC));
            put("Transition metals", new java.awt.Color(0xFFC0C0));
            put("Metals", new java.awt.Color(0xCCCCCC));
            put("Metalloids", new java.awt.Color(0xCCCC99));
            put("Nonmetals", new java.awt.Color(0xA0FFA0));
            put("Halogens", new java.awt.Color(0xFFFF99));
            put("Noble Gasses", new java.awt.Color(0xC0FFFF));
        }
    };

    static final Map<String, java.awt.Color> stateColorMap = new HashMap<String, java.awt.Color>() {
        {
            put("Gas", java.awt.Color.GREEN);
            put("Synthetic", java.awt.Color.RED);
            put("Liquid", java.awt.Color.BLUE);
            put("Solid", java.awt.Color.BLACK);

        }
    };

    Point extent = new Point(0, 0);
    private Font font;

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#createPartControl(org.eclipse.swt.widgets.Composite)
     */
    @Override
    public void createPartControl(Composite parent) {

        try {
            eptf = ElementPTFactory.getInstance();
        } catch (IOException e1) {

        }

        elements = Symbols.byAtomicNumber;

        canvas = new Canvas(parent, SWT.NONE);
        canvas.setBackground(canvas.getDisplay().getSystemColor(SWT.COLOR_WHITE));
        colorConverter = new ColorAWTtoSWTConverter(canvas.getDisplay());
        canvas.addDisposeListener(new DisposeListener() {

            public void widgetDisposed(DisposeEvent e) {

                colorConverter.dispose();
                if (font != null)
                    font.dispose();
            }

        });

        canvas.addControlListener(new ControlAdapter() {
            @Override
            public void controlResized(ControlEvent e) {
                resizeControl(e);
            }
        });

        canvas.addPaintListener(new PaintListener() {

            public void paintControl(PaintEvent e) {
                PeriodicTableView.this.paintControl(e);
            }

        });

        initSelection();
        getSite().setSelectionProvider(this);

        int ops = DND.DROP_COPY;
        Transfer[] transfers = new Transfer[] { TextTransfer.getInstance() };
        this.addDragSupport(ops, transfers, new DragSourceListener() {

            public void dragFinished(DragSourceEvent event) {
            }

            public void dragSetData(DragSourceEvent event) {

                // Provide the data of the requested type.
                if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
                    event.data = selection.getChemobj().getSymbol();
                }
            }

            public void dragStart(DragSourceEvent event) {
                if (selection == null)
                    event.doit = false;
            }

        });

    }

    private String checkHit(Point p) {
        Rectangle rect = new Rectangle(0, 0, extent.x, extent.y);

        for (String s : elements) {
            Point gP = getGroupPeriodFor(s);
            if (gP == null)
                continue;

            rect.x = gP.x;
            rect.y = gP.y;

            if (rect.contains(p))
                return s;
        }
        return null;
    }

    private void initSelection() {

        canvas.addMouseListener(new MouseAdapter() {
            @Override
            public void mouseDown(MouseEvent e) {

                String s = checkHit(new Point(e.x, e.y));
                if (s != null) {

                    PeriodicTableElement element = new PeriodicTableElement(s);
                    element.setProperty(CDKConstants.TITLE, PeriodicTable.getName(s));
                    if (eptf != null) {
                        try {
                            eptf.configure(element);
                        } catch (CDKException e1) {
                            // if we cant configer ignore it
                        }
                    }
                    selection = new CDKChemObject<PeriodicTableElement>(element);
                    setSelection(new StructuredSelection(selection));
                } else {
                    selection = null;
                    setSelection(StructuredSelection.EMPTY);
                }
                canvas.redraw();
            }
        });

    }

    protected void resizeControl(ControlEvent event) {
        Rectangle clientArea = canvas.getClientArea();
        int rowHeight = (int) Math.round(clientArea.height / 9.5);
        int columnWidth = (int) Math.round(clientArea.width / 18d);
        extent = new Point(columnWidth, rowHeight);
        if (font != null && !font.isDisposed()) {
            Font newFont = font;
            font.dispose();
            FontData fd = newFont.getFontData()[0];
            fd.setHeight((int) (.50 * canvas.getClientArea().width / 18d));
            font = new Font(canvas.getDisplay(), fd);
        }

    }

    private Point getGroupPeriodFor(String symbol) {
        Integer gTmp = getGroup(symbol);
        Integer pTmp = getPeriod(symbol);
        double group, period;

        if (gTmp != null && pTmp != null) {
            group = gTmp;
            period = pTmp;
            //        Out-commented pending bug 1013
            //        }
            //        else if(pTmp != null){
            //            int atomNumber = getAtomicNumber( symbol );
            //            if(atomNumber<90) {
            //                group = 4+atomNumber-58;
            //            }else
            //                group = 4+atomNumber-90;
            //            period = pTmp + 2.5;
        } else {
            return null;
        }
        int x = (int) ((group - 1) * extent.x);
        int y = (int) ((period - 1) * extent.y);

        return new Point(x, y);
    }

    protected void paintControl(PaintEvent e) {

        GC gc = e.gc;

        if (font != null)
            gc.setFont(font);

        for (String symbol : elements) {

            Point gP = getGroupPeriodFor(symbol);
            if (gP == null)
                continue;

            String ser = getChemicalSeries(symbol);
            String state = getPhase(symbol);

            int x = gP.x;
            int y = gP.y;

            java.awt.Color color = colorMap.get(ser);
            if (color != null) {
                gc.setBackground(colorConverter.toSWTColor(color));
                gc.fillRectangle(x, y, extent.x, extent.y);
            }
            gc.setForeground(colorConverter.toSWTColor(stateColorMap.get(state)));
            Point ext2 = gc.textExtent(symbol);
            int width = extent.x - ext2.x;
            int height = extent.y - ext2.y;
            gc.drawText(symbol, x + width / 2, y + height / 2, true);
            gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_BLACK));

            gc.drawRectangle(x, y, extent.x, extent.y);
        }
        if (selection != null) {
            int oldWidth = gc.getLineWidth();
            Color oldColor = gc.getForeground();
            gc.setForeground(gc.getDevice().getSystemColor(SWT.COLOR_LIST_SELECTION));
            Point gP = getGroupPeriodFor(selection.getChemobj().getSymbol());
            gc.setLineWidth(3);
            gc.drawRectangle(gP.x, gP.y, extent.x, extent.y);
            gc.setLineWidth(oldWidth);
            gc.setForeground(oldColor);
        }
    }

    /* (non-Javadoc)
     * @see org.eclipse.ui.part.WorkbenchPart#setFocus()
     */
    @Override
    public void setFocus() {

        // TODO Auto-generated method stub

    }

    static class ColorAWTtoSWTConverter {

        Device device;
        Color DEFAULT_COLOR;
        HashMap<java.awt.Color, org.eclipse.swt.graphics.Color> lookup;
        boolean isDisposing = false;

        public ColorAWTtoSWTConverter(Device device) {
            this.device = device;
            lookup = new HashMap<java.awt.Color, org.eclipse.swt.graphics.Color>();
            DEFAULT_COLOR = this.device.getSystemColor(SWT.COLOR_MAGENTA);
        }

        public Color toSWTColor(java.awt.Color color) {
            if (isDisposing) {
                throw new SWTError(SWT.ERROR_WIDGET_DISPOSED);
            }
            if (color == null) {
                return DEFAULT_COLOR;
            }

            assert (color != null);

            Color otherColor = lookup.get(color);
            if (otherColor == null) {
                otherColor = new Color(device, color.getRed(), color.getGreen(), color.getBlue());
                lookup.put(color, otherColor);
            }
            return otherColor;
        }

        public void dispose() {
            isDisposing = true;
            for (Color c : lookup.values()) {
                c.dispose();
            }
        }
    }

    public void addSelectionChangedListener(ISelectionChangedListener listener) {

        if (listeners == null)
            listeners = new ListenerList();

        listeners.add(listener);
    }

    public ISelection getSelection() {

        return theSelection;
    }

    public void removeSelectionChangedListener(ISelectionChangedListener listener) {

        listeners.remove(listener);
    }

    public void setSelection(ISelection selection) {
        theSelection = selection;
        final SelectionChangedEvent e = new SelectionChangedEvent(this, selection);

        Object[] listenersArray = listeners.getListeners();

        for (Object listener : listenersArray) {
            final ISelectionChangedListener l = (ISelectionChangedListener) listener;
            SafeRunner.run(new ISafeRunnable() {

                public void handleException(Throwable exception) {

                }

                public void run() throws Exception {
                    l.selectionChanged(e);
                }
            });
        }
    }

    public void addDragSupport(int operations, Transfer[] transferTypes, DragSourceListener listener) {

        Control myControl = canvas;
        final DragSource dragSource = new DragSource(myControl, operations);
        dragSource.setTransfer(transferTypes);
        dragSource.addDragListener(listener);
    }
}