[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Newsgroup Home]
[news.eclipse.platform.swt] popup-calendar

Hi,

I'm trying to write a calendar that popups when you click a button. It sort
of working. But now I want to hide my popup calendar when the user click on
other places. I put my calendar in a composite. I tried addFocusListener on
the top composite, but it's not working.
Can anyone help me?


import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.text.DateFormatSymbols;
import java.util.Date;
import java.util.GregorianCalendar;

import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;

/**
 * This composite displays either a "Button" or the "Calendar". To save
space it
 * display only the button. When the button is clicked, it hides the
 * compositeButton and show the compositeCalendar.
 *
 * @author mpermana@xxxxxxxxxxx
 */
public class DatePicker extends Composite {

    Composite compositeButton;

    Composite compositeCalendar;

    GregorianCalendar calendar = new GregorianCalendar();

    PropertyChangeListener listener;

    static Color black = new Color(null, 0, 0, 0);

    static Color gray = new Color(null, 127, 127, 127);

    static Color selectionBackground = new Color(null, 200, 200, 200);

    static Image buttonImage =
ImageDescriptor.createFromFile(DatePicker.class,
            "picker.ico").createImage();

    DateFormatSymbols dfs;

    Button buttonShow;

    Combo comboMonth;

    Combo comboYear;

    Label[][] labels = new Label[7][7];

    boolean showCalendar = false;

    /**
     *
     */
    public DatePicker(Composite parent) {
        super(parent, SWT.NONE);
        FormLayout formLayout = new FormLayout();
        setLayout(formLayout);
        /*
        addFocusListener(new FocusListener() {

            public void focusGained(FocusEvent e) {
            }

            public void focusLost(FocusEvent e) {
                setShown(false);
                System.out.println("focusLost");

            }});
            */
        compositeButton = new Composite(this, SWT.NONE);
        GridLayout gridLayout = new GridLayout();
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
        compositeButton.setLayout(gridLayout);
        compositeButton.setVisible(true);

        compositeCalendar = new Composite(this, SWT.BORDER);
        gridLayout = new GridLayout();
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
        gridLayout.numColumns = 7;
        compositeCalendar.setLayout(gridLayout);
        compositeCalendar.setVisible(false);

        dfs = new DateFormatSymbols();

        buttonShow = new Button(compositeButton, SWT.ARROW);
        buttonShow.setToolTipText("tooltip.calendar");
        buttonShow.setImage(buttonImage);
        buttonShow.addSelectionListener(new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                setShown(!showCalendar);
            }

            public void widgetDefaultSelected(SelectionEvent e) {
            }
        });

        GridData gridData = new GridData();
        gridData.horizontalSpan = 7;
        buttonShow.setLayoutData(gridData);

        SelectionListener selectionListener = new SelectionListener() {

            public void widgetSelected(SelectionEvent e) {
                int month = comboMonth.getSelectionIndex();
                calendar.set(GregorianCalendar.MONTH, month);
                while (calendar.get(GregorianCalendar.MONTH) != month)
                    calendar.add(GregorianCalendar.DATE, -1);
                int year = calendar.get(GregorianCalendar.YEAR);
                try {
                    year = Integer.parseInt(comboYear.getText());
                } catch (Exception e2) {
                }
                calendar.set(GregorianCalendar.YEAR, year);
                while (calendar.get(GregorianCalendar.MONTH) != month)
                    calendar.add(GregorianCalendar.DATE, -1);
                updateDates();
            }

            public void widgetDefaultSelected(SelectionEvent e) {

            }
        };

        comboMonth = new Combo(compositeCalendar, SWT.READ_ONLY);
        comboMonth.setItems(dfs.getMonths());
        comboMonth.remove(12);
        comboMonth.addSelectionListener(selectionListener);

        gridData = new GridData();
        gridData.horizontalSpan = 5;
        comboMonth.setLayoutData(gridData);

        comboYear = new Combo(compositeCalendar, SWT.READ_ONLY);
        String[] years = new String[25];
        int year = calendar.get(GregorianCalendar.YEAR);
        for (int i = 0; i < years.length; i++)
            years[i] = String.valueOf(year + i);
        comboYear.setItems(years);
        comboYear.addSelectionListener(selectionListener);

        gridData = new GridData();
        gridData.horizontalSpan = 2;
        comboYear.setLayoutData(gridData);

        for (int week = 0; week < 7; week++) {
            for (int i = 0; i < 7; i++) {
                final Label fLabel = new Label(compositeCalendar, SWT.NONE);
                gridData = new GridData();
                gridData.widthHint = 23;
                fLabel.setLayoutData(gridData);
                labels[week][i] = fLabel;
                if (week > 0) {

                    labels[week][i].addMouseListener(new MouseListener() {

                        public void mouseDoubleClick(MouseEvent e) {
                        }

                        public void mouseDown(MouseEvent e) {
                            setSelection(fLabel);
                            setShown(false);
                        }

                        public void mouseUp(MouseEvent e) {
                        }
                    });
                }
            }
        }

        // create week day label
        for (int i = 0; i < 7; i++) {
            labels[0][i]
                    .setText(dfs.getShortWeekdays()[1 + (new
GregorianCalendar()
                            .getFirstDayOfWeek()
                            + i - 1) % 7]);
        }

        updateDates();
    }

    /**
     * @param b
     */
    protected void setShown(boolean shown) {
        this.showCalendar = shown;
        compositeButton.setVisible(!shown);
        compositeCalendar.setVisible(shown);
        setSize(computeSize(-1, -1));
    }

    public void updateDates() {
        GregorianCalendar firstDay = (GregorianCalendar) calendar.clone();
        firstDay.set(GregorianCalendar.DATE, 1);

        int month = calendar.get(GregorianCalendar.MONTH);
        int year = calendar.get(GregorianCalendar.YEAR);

        GregorianCalendar calendarDay = (GregorianCalendar)
firstDay.clone();
        calendarDay.add(GregorianCalendar.DAY_OF_MONTH, -firstDay
                .get(GregorianCalendar.DAY_OF_WEEK) + 1);
        comboMonth.select(month);
        comboYear.setText(String.valueOf(year));
        int week = 1;
        int endMonth = (month + 1) % 12;
        while (true) {
            for (int i = 0; i < 7; i++) {
                int iterateDay = calendarDay
                        .get(GregorianCalendar.DAY_OF_MONTH);
                int iterateMonth = calendarDay.get(GregorianCalendar.MONTH);
                labels[week][i].setForeground((month == iterateMonth) ?
black
                        : gray);
                labels[week][i]
                        .setBackground(calendarDay.equals(calendar) ?
selectionBackground
                                : getBackground());
                if (calendarDay.equals(calendar))
                    this.selection = labels[week][i];
                labels[week][i].setText(String.valueOf(iterateDay));
                labels[week][i].setData(calendarDay.getTime());
                calendarDay.add(GregorianCalendar.DAY_OF_MONTH, 1);
            }
            if (endMonth == calendarDay.get(GregorianCalendar.MONTH))
                break;
            week++;
        }
        for (int i = 0; i < 7; i++) {
            labels[6][i].setVisible(5 < week);
        }
    }

    Label selection;

    public void setSelection(Label selection) {
        this.selection.setBackground(getBackground());
        this.selection = selection;
        selection.setBackground(selectionBackground);
        calendar.setTime((Date) selection.getData());
        if (null != listener) {
            PropertyChangeEvent event = new PropertyChangeEvent(this,
"calendar",
                    null, calendar);
            listener.propertyChange(event);
        }
    }

    /**
     *
     */
    public Point computeSize(int wHint, int hHint, boolean changed) {
        if (showCalendar)
            return compositeCalendar.computeSize(wHint, hHint, changed);
        else
            return compositeButton.computeSize(wHint, hHint, changed);
    }

    /**
     * @param listener
     *            The listener to set.
     */
    public void setListener(PropertyChangeListener listener) {
        this.listener = listener;
    }

    /**
     * @return Returns the calendar.
     */
    public GregorianCalendar getCalendar() {
        return calendar;
    }

  /**
     * unit test code
     */
    public static void main(String[] args) {
        Locale locale = Locale.US;
        locale = Locale.CHINESE;
        //locale = Locale.FRENCH; // lundi=monday,
        Locale.setDefault(locale);

        final Display display = new Display();
        final Shell shell = new Shell(display);
        GridLayout gridLayout = new GridLayout();
        gridLayout.numColumns = 3;

        shell.setLayout(gridLayout);

        new Label(shell, SWT.BORDER).setText("date");
        new Label(shell, SWT.BORDER).setText("date");
        new Label(shell, SWT.BORDER).setText("date");

        new Label(shell, SWT.BORDER).setText("date");
        new DatePicker(shell);
        new Label(shell, SWT.BORDER).setText("date");

        new Label(shell, SWT.BORDER).setText("date");
        new Label(shell, SWT.BORDER).setText("date");
        new Label(shell, SWT.BORDER).setText("date");

        new Label(shell, SWT.BORDER).setText("date");
        new DatePicker(shell);
        new Label(shell, SWT.BORDER).setText("date");

        shell.setSize(640, 480);
        shell.open();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();

    }

}