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

FocusListener doesn't work as intended because I added the listener on my
top composite.
Mr. Simons' solution worked for me, it displays my composite in a Shell.
Using Shell is generic enough, that it can be used to "popup" anyting.
So here's my final code, thanks everyone, it works nicely.

public class PopupCalendar {

    public PopupCalendar(Shell parent,Point location,GregorianCalendar
calendar,PropertyChangeListener listener) {
        final Shell shell = new Shell(parent,SWT.NO_TRIM);
        shell.setLayout(new GridLayout());
        CalendarPicker picker = new CalendarPicker(shell, SWT.BORDER);
        picker.setCalendar(calendar);
        picker.addPropertyChangeListener(new PropertyChangeListener() {
            public void propertyChange(PropertyChangeEvent evt) {
                shell.close();
            }
        });
        picker.addPropertyChangeListener(listener);
        shell.pack();
        shell.setLocation(location);
        shell.addShellListener(new ShellAdapter() {
            public void shellDeactivated(ShellEvent e) {
                shell.close();
            }
        });
        shell.open();
    }

}

public class CalendarPicker extends Composite {

    PropertyChangeSupport propertyChangeSupport = new
PropertyChangeSupport(this);

    GregorianCalendar calendar = new GregorianCalendar();

    DateFormatSymbols dfs;

    Combo comboMonth;

    Combo comboYear;

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

    Color foreground;

    Color grayForeground;

    Color sundayForeground;

    Color selectionBackground;

    Color selectionForeground;

    DateFormat df = DateFormat.getDateInstance(DateFormat.LONG);

    SelectionListener selectionListener;

    /**
     * @param parent
     * @param style
     */
    public CalendarPicker(Composite parent, int style) {

        super(parent, style);
        selectionBackground = parent.getShell().getDisplay().getSystemColor(
                SWT.COLOR_LIST_SELECTION);
        selectionForeground = parent.getShell().getDisplay().getSystemColor(
                SWT.COLOR_LIST_SELECTION_TEXT);
        grayForeground = parent.getShell().getDisplay().getSystemColor(
                SWT.COLOR_GRAY);
        sundayForeground = parent.getShell().getDisplay().getSystemColor(
                SWT.COLOR_RED);

        setBackground(parent.getShell().getDisplay().getSystemColor(
                SWT.COLOR_LIST_BACKGROUND));
        setForeground(parent.getShell().getDisplay().getSystemColor(
                SWT.COLOR_LIST_FOREGROUND));

        GridLayout gridLayout = new GridLayout();
        gridLayout.marginHeight = 0;
        gridLayout.marginWidth = 0;
        gridLayout.numColumns = 7;
        setLayout(gridLayout);

        dfs = new DateFormatSymbols();

        selectionListener = new SelectionAdapter() {
            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();
            }
        };

        Button buttonPrevious = new Button(this, SWT.ARROW | SWT.LEFT);
        buttonPrevious.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                comboMonth.select((comboMonth.getSelectionIndex()+11)%12);
                if (11 == comboMonth.getSelectionIndex() && 0 <
comboYear.getSelectionIndex()) {
                    comboYear.select(comboYear.getSelectionIndex()-1);
                }
                selectionListener.widgetSelected(e);
            }
        });

        comboMonth = new Combo(this, SWT.READ_ONLY);
        comboMonth.setItems(dfs.getMonths());
        comboMonth.remove(12);
        comboMonth.addSelectionListener(selectionListener);
        GridData gridData = new GridData(GridData.FILL_BOTH);
        gridData.horizontalSpan = 3;
        comboMonth.setLayoutData(gridData);

        comboYear = new Combo(this, 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.FILL_BOTH);
        gridData.horizontalSpan = 2;
        comboYear.setLayoutData(gridData);

        Button buttonNext = new Button(this, SWT.ARROW | SWT.RIGHT);
        buttonNext.addSelectionListener(new SelectionAdapter() {
            public void widgetSelected(SelectionEvent e) {
                comboMonth.select((comboMonth.getSelectionIndex()+1)%12);
                if (0 == comboMonth.getSelectionIndex()) {

comboYear.setText(String.valueOf(1+Integer.parseInt(comboYear.getText())));
                }
                selectionListener.widgetSelected(e);
            }
        });

        for (int week = 0; week < 7; week++) {
            for (int i = 0; i < 7; i++) {
                final Label fLabel = new Label(CalendarPicker.this,
SWT.NONE);
                fLabel.setBackground(getBackground());
                gridData = new GridData(GridData.FILL_BOTH);
                fLabel.setLayoutData(gridData);
                labels[week][i] = fLabel;
                if (week > 0) {
                    labels[week][i].addMouseListener(new MouseAdapter() {
                        public void mouseDown(MouseEvent e) {
                            setSelection(fLabel);
                        }
                    });
                }
            }
        }

        // create week day label Sunday Monday Tuesday ...
        for (int i = 0; i < 7; i++) {
            labels[0][i].setText(dfs.getShortWeekdays()[1 + i]);
        }

        updateDates();
    }

    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);

                // set colors
                if (calendarDay.equals(calendar)) {
                    this.selection = labels[week][i];
                    labels[week][i].setBackground(selectionBackground);
                    labels[week][i].setForeground(selectionForeground);
                } else {
                    Color dayForeground = (iterateMonth == month) ?
foreground
                            : grayForeground;
                    if (calendarDay.get(GregorianCalendar.DAY_OF_WEEK) ==
GregorianCalendar.SUNDAY)
                        dayForeground = sundayForeground;
                    labels[week][i].setForeground(dayForeground);
                    labels[week][i].setBackground(getBackground());
                }
                // set tool tip
                labels[week][i]
                        .setToolTipText(df.format(calendarDay.getTime()));
                // set day number 1..31
                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.setForeground(foreground);
        this.selection = selection;
        selection.setBackground(selectionBackground);
        selection.setForeground(selectionForeground);
        calendar.setTime((Date) selection.getData());
        propertyChangeSupport.firePropertyChange("calendar",null,calendar);
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        propertyChangeSupport.addPropertyChangeListener(listener);
    }

    public GregorianCalendar getCalendar() {
        return calendar;
    }

    public void setCalendar(GregorianCalendar calendar) {
        this.calendar = calendar;
        updateDates();
    }

}


"Max Rotvel" <rotvel@xxxxxxxxxxxxxxxxxx> wrote in message
news:op.spwflzy094ko3h@xxxxxxxxxxxxxxxx
> On Tue, 26 Apr 2005 23:07:10 +0200, Michael Permana <mpermana@xxxxxxxxxxx>
> wrote:
>
> > 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.
>
> What happens? I think you should be able to use a mechanism similar to
> this:
>
> shell.addFocusListener(new FocusAdapter()
> {
> public void focusLost(FocusEvent e)
> {
> display.asyncExec(new Runnable()
> {
> public void run()
> {
> shell.dispose();
> }
> });
> }
> });
>
> Regards
> -- 
>   Max  - rotvel AT bolignet-aarhus DOT dk