datepickercombo.java

来自「一个SWT日期时间选择控件类」· Java 代码 · 共 1,120 行 · 第 1/3 页

JAVA
1,120
字号
package com.tiff.common.ui.datepicker;

import org.eclipse.swt.SWT;
import org.eclipse.swt.accessibility.ACC;
import org.eclipse.swt.accessibility.AccessibleAdapter;
import org.eclipse.swt.accessibility.AccessibleControlAdapter;
import org.eclipse.swt.accessibility.AccessibleControlEvent;
import org.eclipse.swt.accessibility.AccessibleEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Font;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.swt.widgets.TypedListener;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;

import java.util.Date;


/**
 * The combo widget with drop-down date-picker panel.
 *
 * changes by andyglow
 *  + added method setEnabled to properly manage state of control
 * changes by sebthom
 *  ~ declared package accessible methods as private
 *  ~ declared getEditable() as public
 *  + added useSingleMouseClickToCommit behaviour
 *  + manually modifying the date in the text field is reflected in the date picker
 *  + setDate(null) clears the date.
 *  + added getText & setText()
 *
 * @author <a href="mailto:andy@tiff.ru">Andrey Onistchuk</a>
 *
 */
public final class DatePickerCombo extends Composite {
    //~ Instance fields --------------------------------------------------------

    private Button arrow;
    private DatePicker dp;
    private boolean hasFocus;

    /**
     * @author sebthom
     */
    private boolean isClosePopupWithSingleMouseClick = false;
    private Shell popup;
    private Text text;
    
    /**
     * @author andyglow
     */
    private DateFormat format = null;

    //~ Constructors -----------------------------------------------------------

    /**
     * Creates a new DatePickerCombo object.
     *
     * @param parent parent Composite
     * @param style SWT style
     */
    public DatePickerCombo(Composite parent, int style) {
        super(parent, checkStyle(style));

        style = getStyle();

        int textStyle = SWT.SINGLE;

        if ((style & SWT.READ_ONLY) != 0) {
            textStyle |= SWT.READ_ONLY;
        }

        if ((style & SWT.FLAT) != 0) {
            textStyle |= SWT.FLAT;
        }

        text = new Text(this, textStyle);

        popup = new Shell(getShell(), SWT.NO_TRIM);

        int pickerStyle = SWT.SINGLE;

        if ((style & SWT.FLAT) != 0) {
            pickerStyle |= SWT.FLAT;
        }

        dp = new DatePicker(popup, pickerStyle);

        int arrowStyle = SWT.ARROW | SWT.DOWN;

        if ((style & SWT.FLAT) != 0) {
            arrowStyle |= SWT.FLAT;
        }

        arrow = new Button(this, arrowStyle);

        Listener listener = new Listener() {
                public void handleEvent(Event event) {
                    if (popup == event.widget) {
                        popupEvent(event);

                        return;
                    }

                    if (text == event.widget) {
                        textEvent(event);

                        return;
                    }

                    if (dp == event.widget) {
                        dpEvent(event);

                        return;
                    }

                    if (arrow == event.widget) {
                        arrowEvent(event);

                        return;
                    }

                    if (DatePickerCombo.this == event.widget) {
                        comboEvent(event);

                        return;
                    }
                }
            };

        int[] comboEvents = { SWT.Dispose, SWT.Move, SWT.Resize };

        for (int i = 0; i < comboEvents.length; i++)
            this.addListener(comboEvents[i], listener);

        int[] popupEvents = { SWT.Close, SWT.Paint, SWT.Deactivate };

        for (int i = 0; i < popupEvents.length; i++)
            popup.addListener(popupEvents[i], listener);

        int[] textEvents = {
            SWT.KeyDown, SWT.KeyUp, SWT.Modify, SWT.MouseDown, SWT.MouseUp,
            SWT.Traverse, SWT.FocusIn, SWT.FocusOut
        };

        for (int i = 0; i < textEvents.length; i++)
            text.addListener(textEvents[i], listener);

        int[] dpEvents = {
            SWT.MouseUp, SWT.MouseDoubleClick, SWT.Selection, SWT.Traverse,
            SWT.KeyDown, SWT.KeyUp, SWT.FocusIn, SWT.FocusOut
        };

        for (int i = 0; i < dpEvents.length; i++)
            dp.addListener(dpEvents[i], listener);

        int[] arrowEvents = { SWT.Selection, SWT.FocusIn, SWT.FocusOut };

        for (int i = 0; i < arrowEvents.length; i++)
            arrow.addListener(arrowEvents[i], listener);

        initAccessible();
    }

    //~ Methods ----------------------------------------------------------------

    /**
     * Style cheking
     *
     * @param style STT style
     *
     * @return style
     */
    public static int checkStyle(int style) {
        int mask = SWT.BORDER | SWT.READ_ONLY | SWT.FLAT;

        return style & mask;
    }

    /**
     * Adds the listener to receive events.
     *
     * @param listener
     *                the listener
     *
     * @exception SWTError(ERROR_THREAD_INVALID_ACCESS)
     *                when called from the wrong thread
     * @exception SWTError(ERROR_WIDGET_DISPOSED)
     *                when the widget has been disposed
     * @exception SWTError(ERROR_NULL_ARGUMENT)
     *                when listener is null
     */
    public void addModifyListener(ModifyListener listener) {
        checkWidget();

        if (listener == null) {
            SWT.error(SWT.ERROR_NULL_ARGUMENT);
        }

        TypedListener typedListener = new TypedListener(listener);
        addListener(SWT.Modify, typedListener);
    }

    /**
     * Adds the listener to receive events.
     *
     * @param listener
     *            the listener
     *
     * @exception SWTError(ERROR_THREAD_INVALID_ACCESS)
     *                when called from the wrong thread
     * @exception SWTError(ERROR_WIDGET_DISPOSED)
     *                when the widget has been disposed
     * @exception SWTError(ERROR_NULL_ARGUMENT)
     *                when listener is null
     */
    public void addSelectionListener(SelectionListener listener) {
        checkWidget();

        if (listener == null) {
            SWT.error(SWT.ERROR_NULL_ARGUMENT);
        }

        TypedListener typedListener = new TypedListener(listener);
        addListener(SWT.Selection, typedListener);
        addListener(SWT.DefaultSelection, typedListener);
    }

    private void arrowEvent(Event event) {
        switch (event.type) {
        case SWT.FocusIn: {
            if (hasFocus) {
                return;
            }

            hasFocus = true;

            if (getEditable()) {
                text.selectAll();
            }

            Event e = new Event();
            e.time = event.time;
            notifyListeners(SWT.FocusIn, e);

            break;
        }

        case SWT.FocusOut: {
            Control focusControl = getDisplay().getFocusControl();

            if ((focusControl == dp) || (focusControl == text)) {
                return;
            }

            hasFocus = false;

            Event e = new Event();
            e.time = event.time;
            notifyListeners(SWT.FocusOut, e);

            break;
        }

        case SWT.Selection: {
            dropDown(!isDropped());

            break;
        }
        }
    }

    /**
     * Clears the current selection.
     *
     * @exception SWTError(ERROR_THREAD_INVALID_ACCESS)
     *                when called from the wrong thread
     * @exception SWTError(ERROR_WIDGET_DISPOSED)
     *                when the widget has been disposed
     */
    public void clearSelection() {
        checkWidget();
        text.clearSelection();
        dp.reset();
    }

    private void comboEvent(Event event) {
        switch (event.type) {
        case SWT.Dispose:

            if ((popup != null) && !popup.isDisposed()) {
                popup.dispose();
            }

            popup = null;
            text = null;
            dp = null;
            arrow = null;

            break;

        case SWT.Move:
            dropDown(false);

            break;

        case SWT.Resize:
            internalLayout();

            break;
        }
    }

    public Point computeSize(int wHint, int hHint, boolean changed) {
        checkWidget();

        int width = 0;
        int height = 0;
        Point textSize = text.computeSize(wHint, SWT.DEFAULT, changed);
        Point arrowSize = arrow.computeSize(SWT.DEFAULT, SWT.DEFAULT, changed);
        Point listSize = dp.computeSize(wHint, SWT.DEFAULT, changed);
        int borderWidth = getBorderWidth();

        height = Math.max(hHint,
                Math.max(textSize.y, arrowSize.y) + (2 * borderWidth));
        width = Math.max(wHint,
                Math.max(textSize.x + arrowSize.x + (2 * borderWidth),
                    listSize.x + 2));

        return new Point(width, height);
    }

    private void dpEvent(Event event) {
        switch (event.type) {
        case SWT.FocusIn: {
            if (hasFocus) {
                return;
            }

            hasFocus = true;

            if (getEditable()) {
                text.selectAll();
            }

            Event e = new Event();
            e.time = event.time;
            notifyListeners(SWT.FocusIn, e);

            break;
        }

        case SWT.FocusOut: {
            Control focusControl = getDisplay().getFocusControl();

            if ((focusControl == text) || (focusControl == arrow)) {
                return;
            }

            hasFocus = false;

            Event e = new Event();

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?