bogdan.rechi.swt.commons.controls.TimeCombo.java Source code

Java tutorial

Introduction

Here is the source code for bogdan.rechi.swt.commons.controls.TimeCombo.java

Source

/*
The MIT License (MIT)
    
Copyright (c) 2015 Bogdan Rechi
    
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
    
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.
    
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

package bogdan.rechi.swt.commons.controls;

import java.util.Calendar;
import java.util.regex.Pattern;

import org.apache.commons.lang3.StringUtils;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.KeyEvent;
import org.eclipse.swt.events.KeyListener;
import org.eclipse.swt.events.MenuDetectEvent;
import org.eclipse.swt.events.MenuDetectListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.widgets.Combo;

import bogdan.rechi.swt.commons.SwtColors;

/**
 * Time options combo.
 *
 * @author Bogdan Rechi
 */
public class TimeCombo {
    protected static Pattern _pattern = Pattern
            .compile("^\\s*([0-9]|((0|1)[0-9]|2[0-3]))\\s*:?\\s*([0-9]|([0-5][0-9]))\\s*$");

    private Color _invalidTimeBackground;

    private Combo _combo;
    private Color _initialBackground;

    /**
     * Public constructor.
     *
     * @param combo
     *          Combo to modify.
     * @param invalidTimeBackground
     *          Combo background in case of invalid time.
     */
    public TimeCombo(Combo combo, Color invalidTimeBackground) {
        _combo = combo;

        _initialBackground = _combo.getBackground();
        _invalidTimeBackground = invalidTimeBackground;

        initialize();
    }

    /**
     * Public constructor.
     *
     * @param combo
     *          Combo to modify.
     */
    public TimeCombo(Combo combo) {
        this(combo, SwtColors.colorNameToColor("palered"));
    }

    /**
     * Initialize combo values.
     */
    private void initialize() {
        _combo.addVerifyListener(new VerifyListener() {
            @Override
            public void verifyText(VerifyEvent e) {
                String text = _combo.getText();
                text = String.format("%s%s%s", text.substring(0, e.start), e.text, text.substring(e.end));

                _combo.setBackground(_pattern.matcher(text).find() ? _initialBackground : _invalidTimeBackground);

                e.doit = true;
            }
        });

        _combo.addKeyListener(new KeyListener() {
            @Override
            public void keyReleased(KeyEvent e) {
            }

            @Override
            public void keyPressed(KeyEvent e) {
                if (e.keyCode == SWT.ARROW_UP || e.keyCode == SWT.ARROW_DOWN) {
                    if (!isValid())
                        _combo.select(0);
                    else {
                        String[] items = _combo.getText().split(":");
                        if (items.length == 1)
                            items = StringUtils.split(_combo.getText());

                        items[0] = items[0].trim();
                        items[1] = items[1].trim();

                        Calendar moment = Calendar.getInstance();
                        moment.set(Calendar.HOUR_OF_DAY, Integer.parseInt(items[0]));
                        moment.set(Calendar.MINUTE, Integer.parseInt(items[1]));
                        moment.add(Calendar.MINUTE, e.keyCode == SWT.ARROW_UP ? 1 : -1);

                        String newTime = String.format("%02d:%02d", moment.get(Calendar.HOUR_OF_DAY),
                                moment.get(Calendar.MINUTE));
                        _combo.setText(newTime);
                        _combo.setSelection(new Point(0, newTime.length()));
                    }

                    e.doit = false;
                }
            }
        });

        _combo.addMenuDetectListener(new MenuDetectListener() {
            @Override
            public void menuDetected(MenuDetectEvent arg0) {
                arg0.doit = false;
            }
        });

        for (int i = 0; i < 24; i++) {
            _combo.add(String.format("%02d:00", i));
            _combo.add(String.format("%02d:30", i));
        }

        _combo.setBackground(
                _pattern.matcher(_combo.getText()).find() ? _initialBackground : _invalidTimeBackground);
    }

    /**
     * Gets valid state of time in combo.
     *
     * @return true if time is valid, otherwise false.
     */
    public Boolean isValid() {
        return (_pattern.matcher(_combo.getText()).find());
    }

    /**
     * Get beautified time (without changing the combo text).
     *
     * @return Beautified time text if valid, otherwise null.
     */
    public String getBeautifiedTime() {
        return getBeautifiedTime(false);
    }

    /**
     * Get beautified time.
     *
     * @param withComboUpdate
     *          True to update the combo text, otherwise false.
     *
     * @return Beautified time text if valid, otherwise null.
     */
    public String getBeautifiedTime(Boolean withComboUpdate) {
        String text = _combo.getText();

        if (!_pattern.matcher(text).find())
            return null;

        String[] items = _combo.getText().split(":");
        if (items.length == 1)
            items = StringUtils.split(_combo.getText());

        items[0] = items[0].trim();
        items[1] = items[1].trim();

        String beautifiedText = String.format("%s%s:%s%s", items[0].length() == 1 ? "0" : "", items[0],
                items[1].length() == 1 ? "0" : "", items[1]);

        if (withComboUpdate)
            _combo.setText(beautifiedText);

        return beautifiedText;
    }

    /**
     * Get hour and minute.
     *
     * @return Pair of hour and minute.
     */
    public int[] getHourAndMinute() {
        return getHourAndMinute(false);
    }

    /**
     * Get hour and minute.
     *
     * @param withComboBeautify
     *          True to beautify the combo text, otherwise false.
     *
     * @return Pair of hour and minute.
     */
    public int[] getHourAndMinute(Boolean withComboBeautify) {
        String text = _combo.getText();

        if (!_pattern.matcher(text).find())
            return null;

        String[] items = _combo.getText().split(":");
        if (items.length == 1)
            items = StringUtils.split(_combo.getText());

        items[0] = items[0].trim();
        items[1] = items[1].trim();

        if (withComboBeautify) {
            String beautifiedText = String.format("%s%s:%s%s", items[0].length() == 1 ? "0" : "", items[0],
                    items[1].length() == 1 ? "0" : "", items[1]);
            _combo.setText(beautifiedText);
        }

        return new int[] { Integer.parseInt(items[0]), Integer.parseInt(items[1]) };
    }

    /**
     * Set time for combo.
     *
     * @param time
     *          Time to set the combo with.
     */
    public void setTime(Calendar time) {
        String text = String.format("%02d:%02d", time.get(Calendar.HOUR_OF_DAY), time.get(Calendar.MINUTE));
        _combo.setText(text);
    }
}