org.eclipsetrader.ui.charts.DateScaleCanvas.java Source code

Java tutorial

Introduction

Here is the source code for org.eclipsetrader.ui.charts.DateScaleCanvas.java

Source

/*
 * Copyright (c) 2004-2011 Marco Maccaferri 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:
 *     Marco Maccaferri - initial API and implementation
 */

package org.eclipsetrader.ui.charts;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Status;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.swt.SWT;
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.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.FontMetrics;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipsetrader.core.feed.TimeSpan;
import org.eclipsetrader.ui.internal.UIActivator;

public class DateScaleCanvas {

    private Canvas horizontalScaleCanvas;
    private Image horizontalScaleImage;
    private Label label;

    private TimeSpan resolutionTimeSpan;

    private SimpleDateFormat monthYearFormatter = new SimpleDateFormat("MMM, yyyy"); //$NON-NLS-1$
    private SimpleDateFormat monthFormatter = new SimpleDateFormat("MMM"); //$NON-NLS-1$
    private SimpleDateFormat dayFormatter = new SimpleDateFormat("MMM, d"); //$NON-NLS-1$
    private DateFormat dateFormat = DateFormat.getDateInstance();
    private DateFormat dateTimeFormat = DateFormat.getDateTimeInstance();

    Point location;
    DateValuesAxis datesAxis;
    Date[] visibleDates;

    public DateScaleCanvas(Composite parent) {
        GC gc = new GC(parent);
        FontMetrics fontMetrics = gc.getFontMetrics();
        gc.dispose();

        horizontalScaleCanvas = new Canvas(parent, SWT.DOUBLE_BUFFERED | SWT.NO_FOCUS | SWT.NO_BACKGROUND);
        horizontalScaleCanvas.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_LIST_BACKGROUND));
        horizontalScaleCanvas.setLayoutData(new GridData(SWT.FILL, SWT.BEGINNING, true, false));
        ((GridData) horizontalScaleCanvas.getLayoutData()).heightHint = Dialog
                .convertVerticalDLUsToPixels(fontMetrics, 14);
        horizontalScaleCanvas.addControlListener(new ControlAdapter() {

            @Override
            public void controlResized(ControlEvent e) {
                if (horizontalScaleImage != null) {
                    horizontalScaleImage.dispose();
                    horizontalScaleImage = null;
                }
                redraw();
            }
        });
        horizontalScaleCanvas.addDisposeListener(new DisposeListener() {

            @Override
            public void widgetDisposed(DisposeEvent e) {
                if (horizontalScaleImage != null) {
                    horizontalScaleImage.dispose();
                    horizontalScaleImage = null;
                }
            }
        });
        horizontalScaleCanvas.addPaintListener(new PaintListener() {

            @Override
            public void paintControl(PaintEvent e) {
                onPaint(e);
            }
        });

        label = new Label(horizontalScaleCanvas, SWT.NONE);
        label.setBackground(horizontalScaleCanvas.getDisplay().getSystemColor(SWT.COLOR_INFO_BACKGROUND));
        label.setBounds(-200, 0, 0, 0);
    }

    public void setLocation(Point location) {
        this.location = location;
    }

    public void setDatesAxis(DateValuesAxis datesAxis) {
        this.datesAxis = datesAxis;
    }

    public Control getControl() {
        return horizontalScaleCanvas;
    }

    public Canvas getCanvas() {
        return horizontalScaleCanvas;
    }

    public void setVisibleDates(Date[] visibleDates) {
        this.visibleDates = visibleDates;
    }

    public void redraw() {
        horizontalScaleCanvas.setData(BaseChartViewer.K_NEEDS_REDRAW, Boolean.TRUE);
        horizontalScaleCanvas.redraw();
    }

    private void onPaint(PaintEvent event) {
        Rectangle clientArea = horizontalScaleCanvas.getClientArea();
        boolean needsRedraw = Boolean.TRUE.equals(horizontalScaleCanvas.getData(BaseChartViewer.K_NEEDS_REDRAW));

        if (horizontalScaleImage != null && !horizontalScaleImage.isDisposed()) {
            if (horizontalScaleImage.getBounds().width != clientArea.width
                    || horizontalScaleImage.getBounds().height != clientArea.height) {
                horizontalScaleImage.dispose();
            }
        }
        if (horizontalScaleImage == null || horizontalScaleImage.isDisposed()) {
            horizontalScaleImage = new Image(horizontalScaleCanvas.getDisplay(), clientArea.width,
                    clientArea.height);
            needsRedraw = true;
        }

        if (needsRedraw) {
            Graphics graphics = new Graphics(horizontalScaleImage, location, datesAxis, new DoubleValuesAxis());
            try {
                graphics.fillRectangle(clientArea);

                Calendar oldDate = null;
                Calendar currentDate = Calendar.getInstance();

                for (int i = 0; i < visibleDates.length; i++) {
                    Date date = visibleDates[i];
                    boolean tick = false; // Draw a longer tick
                    boolean highlight = false; // Highlight the tick
                    String text = ""; //$NON-NLS-1$

                    currentDate.setTime(date);

                    if (oldDate != null) {
                        if (resolutionTimeSpan == null || resolutionTimeSpan.getUnits() == TimeSpan.Units.Days) {
                            if (currentDate.get(Calendar.YEAR) != oldDate.get(Calendar.YEAR)) {
                                tick = true;
                                highlight = true;
                                text = monthYearFormatter.format(currentDate.getTime());
                            } else if (currentDate.get(Calendar.MONTH) != oldDate.get(Calendar.MONTH)) {
                                tick = true;
                                highlight = false;
                                text = monthFormatter.format(currentDate.getTime());
                            }
                        } else {
                            if (currentDate.get(Calendar.MONTH) != oldDate.get(Calendar.MONTH)) {
                                tick = true;
                                highlight = true;
                                text = monthFormatter.format(currentDate.getTime());
                            } else if (currentDate.get(Calendar.DAY_OF_MONTH) != oldDate
                                    .get(Calendar.DAY_OF_MONTH)) {
                                tick = true;
                                highlight = false;
                                text = dayFormatter.format(currentDate.getTime());
                            }
                        }
                        oldDate.setTime(date);
                    } else {
                        oldDate = Calendar.getInstance();
                        oldDate.setTime(date);
                    }

                    int x = graphics.mapToHorizontalAxis(date);
                    graphics.setForegroundColor(highlight ? new RGB(255, 0, 0) : new RGB(0, 0, 0));
                    graphics.drawLine(x, 0, x, tick ? 6 : 3);
                    if (tick) {
                        graphics.drawString(text, x - 1, 7);
                    }
                }
            } catch (Error e) {
                Status status = new Status(IStatus.ERROR, UIActivator.PLUGIN_ID,
                        Messages.DateScaleCanvas_HorizontalScaleRenderingError);
                UIActivator.log(status);
            } finally {
                horizontalScaleCanvas.setData(BaseChartViewer.K_NEEDS_REDRAW, Boolean.FALSE);
                graphics.dispose();
            }
        }

        Util.paintImage(event, horizontalScaleImage);
    }

    public void hideToolTip() {
        label.setLocation(-200, 0);
    }

    public void showToolTip(int x, int y, Date value) {
        if (value != null) {
            if (resolutionTimeSpan == null || resolutionTimeSpan.getUnits() == TimeSpan.Units.Days) {
                label.setText(dateFormat.format(value));
            } else {
                label.setText(dateTimeFormat.format(value));
            }
            label.pack();
            label.setLocation(x - label.getSize().x / 2, 0);
        }
    }

    public TimeSpan getResolutionTimeSpan() {
        return resolutionTimeSpan;
    }

    public void setResolutionTimeSpan(TimeSpan resolutionTimeSpan) {
        this.resolutionTimeSpan = resolutionTimeSpan;
    }
}