⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datefield.java

📁 Rapla是一个灵活的多用户资源管理系统。它提供的一些功能有:日历GUI
💻 JAVA
字号:
/*--------------------------------------------------------------------------*
 | Copyright (C) 2006 Christopher Kohlhaas                                  |
 |                                                                          |
 | 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. A copy of the license has been included with   |
 | these distribution in the COPYING file, if not go to www.fsf.org         |
 |                                                                          |
 | As a special exception, you are granted the permissions to link this     |
 | program with every library, which license fulfills the Open Source       |
 | Definition as published by the Open Source Initiative (OSI).             |
 *--------------------------------------------------------------------------*/
package org.rapla.components.calendar;

import java.awt.*;
import java.awt.event.*;
import java.text.*;
import java.util.Locale;
import java.util.Date;
import java.util.Calendar;
import java.util.TimeZone;
/** The DateField only accepts characters that are part of
 * DateFormat.getDateInstance(DateFormat.SHORT,locale).  The
 * inputblocks are [date,month,year]. The order of the input-blocks is
 * determined by the locale. You can use the keyboard to navigate
 * between the blocks or to increment/decrement the blocks.
 * @see AbstractBlockField
 */

final public class DateField extends AbstractBlockField {
    private static final long serialVersionUID = 1L;

    private DateFormat m_outputFormat;
    private DateFormat m_parsingFormat;
    private Calendar m_calendar;
    private int m_rank[] = null;
    private char[] m_separators;
    private SimpleDateFormat m_weekdayFormat;
    private boolean m_weekdaysVisible = true;
    private DateRenderer m_dateRenderer;
    /** stores the y-coordinate of the weekdays display field*/
    private int m_weekdaysX;


    public DateField() {
        this(Locale.getDefault());
    }

    public DateField(Locale locale) {
        this(locale,TimeZone.getDefault());
    }

    public DateField(Locale locale,TimeZone timeZone) {
        super();
        m_calendar = Calendar.getInstance(timeZone, locale);
        super.setLocale(locale);
        setFormat();
        setDate(new Date());
    }


    public void setLocale(Locale locale) {
        super.setLocale(locale);
        if (locale != null && getTimeZone() != null)
            update(getTimeZone(), locale);
    }

    public void setTimeZone(TimeZone timeZone) {
        if (timeZone != null)
            update(timeZone, getLocale());
    }

    private void update(TimeZone timeZone, Locale locale) {
        Date date = getDate();
        if (locale != null)
            m_calendar = Calendar.getInstance(timeZone, locale);
        else
            m_calendar = Calendar.getInstance(timeZone);
        setFormat();
        setText(m_outputFormat.format(date));
    }


    /** you can choose, if weekdays should be displayed in the right corner of the DateField.
        Default is true.
    */
    public void setWeekdaysVisible(boolean m_weekdaysVisible) {
        this.m_weekdaysVisible = m_weekdaysVisible;
    }

    /** sets the DateRenderer for the calendar */
    public void setDateRenderer(DateRenderer dateRenderer) {
        m_dateRenderer = dateRenderer;
    }

    private void setFormat() {
        m_parsingFormat = DateFormat.getDateInstance(DateFormat.SHORT, getLocale());
        m_weekdayFormat = new SimpleDateFormat("EE", getLocale());
        m_parsingFormat.setTimeZone(getTimeZone());
        m_weekdayFormat.setTimeZone(getTimeZone());

        String formatStr = m_parsingFormat.format(m_calendar.getTime());
        FieldPosition datePos = new FieldPosition(DateFormat.DATE_FIELD);
        FieldPosition monthPos = new FieldPosition(DateFormat.MONTH_FIELD);
        FieldPosition yearPos = new FieldPosition(DateFormat.YEAR_FIELD);
        m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),datePos);
        m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),monthPos);
        m_parsingFormat.format(m_calendar.getTime(), new StringBuffer(),yearPos);

        int mp = monthPos.getBeginIndex();
        int dp = datePos.getBeginIndex();
        int yp = yearPos.getBeginIndex();
        int pos[] = null;
        //      System.out.println(formatStr + " day:"+dp+" month:"+mp+" year:"+yp);
        if (mp<0 || dp<0 || yp<0) {
            throw new IllegalArgumentException("Can't parse the date-format for this locale");
        }
        // quick and diry sorting
        if (dp<mp && mp<yp) {
            pos = new int[] {dp,mp,yp};
            m_rank = new int[] {Calendar.DATE, Calendar.MONTH, Calendar.YEAR};
        } else if (dp<yp && yp<mp) {
            pos = new int[] {dp,yp,mp};
            m_rank = new int[] {Calendar.DATE, Calendar.YEAR, Calendar.MONTH};
        } else if (mp<dp && dp<yp) {
            pos = new int[] {mp,dp,yp};
            m_rank = new int[] {Calendar.MONTH, Calendar.DATE, Calendar.YEAR};
        } else if (mp<yp && yp<dp) {
            pos = new int[] {mp,yp,dp};
            m_rank = new int[] {Calendar.MONTH, Calendar.YEAR, Calendar.DATE};
        } else if (yp<dp && dp<mp) {
            pos = new int[] {yp,dp,mp};
            m_rank = new int[] {Calendar.YEAR, Calendar.DATE, Calendar.MONTH};
        } else if (yp<mp && mp<dp) {
            pos = new int[] {yp,mp,dp};
            m_rank = new int[] {Calendar.YEAR, Calendar.MONTH, Calendar.DATE};
        }
        char firstSeparator = formatStr.charAt(pos[1]-1);
        char secondSeparator = formatStr.charAt(pos[2]-1);
        //      System.out.println("first-sep:"+firstSeparator+" sec-sep:"+secondSeparator);
        if (Character.isDigit(firstSeparator)
            || Character.isDigit(secondSeparator))
            throw new IllegalArgumentException("Can't parse the date-format for this locale");
        m_separators = new char[] {firstSeparator,secondSeparator};
        StringBuffer buf = new StringBuffer();
        for (int i=0;i<m_rank.length;i++) {
            if (m_rank[i] == Calendar.YEAR) {
                buf.append("yyyy");
            } else if (m_rank[i] == Calendar.MONTH) {
                buf.append("MM");
            } else if (m_rank[i] == Calendar.DATE) {
                buf.append("dd");
            }

            if (i==0) {
                buf.append(firstSeparator);
            } else if (i==1) {
                buf.append(secondSeparator);
            }
        }
        setColumns(buf.length() -1 + (m_weekdaysVisible ? 1:0 ));
        m_outputFormat= new SimpleDateFormat(buf.toString(),getLocale());
        m_outputFormat.setTimeZone(getTimeZone());
    }

    public TimeZone getTimeZone() {
        if (m_calendar != null)
            return m_calendar.getTimeZone();
        return
            null;
    }

    public Date getDate() {
        return m_calendar.getTime();
    }

    public void setDate(Date value) {
        m_calendar.setTime(value);
        if (m_dateRenderer != null) {
            String text =
               m_dateRenderer.getToolTipText(
                                            m_calendar.get(Calendar.DAY_OF_WEEK)
                                            ,m_calendar.get(Calendar.DATE)
                                            ,m_calendar.get(Calendar.MONTH)
                                            ,m_calendar.get(Calendar.YEAR)
                                            );
            setToolTipText(text);
        }
        setText(m_outputFormat.format(value));
    }

    protected char[] getSeparators() {
        return m_separators;
    }

    protected boolean isSeparator(char c) {
        for (int i=0;i<m_separators.length;i++)
            if (m_separators[i] == c)
                return true;
        return false;
    }

    /** returns the parsingFormat of the selected locale.
        This is same as the default date-format of the selected locale.*/
    public DateFormat getParsingFormat() {
        return m_parsingFormat;
    }

    /** returns the output format of the date-field.
        The OutputFormat always uses the full block size:
        01.01.2000 instead of 1.1.2000  */
    public DateFormat getOutputFormat() {
        return m_outputFormat;
    }

    protected void changeSelectedBlock(int[] blocks,int block,String selected,int count) {
        int type = m_rank[block];
        if (m_rank.length<block)
            return;

        if (type == Calendar.MONTH)
            if (Math.abs(count) == 10)
                m_calendar.add(type,count/Math.abs(count) * 3);
            else
                m_calendar.add(type,count/Math.abs(count));
        else if (type == Calendar.DATE)
            if (Math.abs(count) == 10)
                m_calendar.add(type,count/Math.abs(count) * 7);
            else
                m_calendar.add(type,count/Math.abs(count));
        else
            m_calendar.add(type,count);

        setDate(m_calendar.getTime());
        calcBlocks(blocks);
        markBlock(blocks,block);
    }

    public String getToolTipText(MouseEvent event) {
        if (m_weekdaysVisible && event.getX() >= m_weekdaysX)
            return super.getToolTipText(event);
        return null;
    }

    public boolean blocksValid() {
        try {
            m_calendar.setTime(m_parsingFormat.parse(getText()));
            return true;
        } catch (ParseException e) {
            return false;
        }
    }

    static int[] BLOCKLENGTH = new int[] {2,2,5};

    protected int blockCount() {
        return BLOCKLENGTH.length;
    }

    protected void mark(int dot,int mark) {
        super.mark(dot,mark);
        if (!m_weekdaysVisible)
            repaint();
    }

    protected int maxBlockLength(int block) {
        return BLOCKLENGTH[block];
    }

    protected boolean isValidChar(char c) {
        return (Character.isDigit(c) || isSeparator(c) );
    }

    /** This method is necessary to shorten the names down to 2 characters.
        Some date-formats ignore the setting.
    */
    private String small(String string) {
        return string.substring(0,Math.min(string.length(),2));
    }

    public void paint(Graphics g) {
        super.paint(g);
        if (!m_weekdaysVisible)
            return;
        Insets insets = getInsets();
        String s = small(m_weekdayFormat.format(m_calendar.getTime()));
        FontMetrics fm = g.getFontMetrics();
        int width = fm.stringWidth(s);
        int x = getWidth()-width-insets.right-3;
        m_weekdaysX = x;
        int y = insets.top + (getHeight() - (insets.bottom + insets.top))/2 + fm.getAscent()/3;
        if (m_dateRenderer != null) {
            Color color =m_dateRenderer.getBackgroundColor(
                                             m_calendar.get(Calendar.DAY_OF_WEEK)
                                             ,m_calendar.get(Calendar.DATE)
                                             ,m_calendar.get(Calendar.MONTH)
                                             ,m_calendar.get(Calendar.YEAR)
                                             );
            if (color != null) {
                g.setColor(color);
                g.fillRect(x-1, insets.top, width + 3 , getHeight() - insets.bottom - insets.top - 1);
            }
        }
        g.setColor(Color.gray);
        g.drawString(s,x,y);
    }
}

⌨️ 快捷键说明

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