Java Source - Swing Date Time Editor Demo


Một ví dụ nhỏ demo về cách chỉnh sửa ngày tháng và thời gian.






DateTimeEditor.java
/*
Swing, Second Edition
by Matthew Robinson, Pavel Vorobiev

*/

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.text.DateFormat;
import java.text.FieldPosition;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.Iterator;
import java.util.NoSuchElementException;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.Caret;
import javax.swing.text.DefaultEditorKit;
import javax.swing.text.JTextComponent;
import javax.swing.text.Keymap;
import javax.swing.text.PlainDocument;
import javax.swing.text.TextAction;

public class DateTimeEditor extends JPanel {
  public static final long ONE_SECOND = 1000;

  public static final long ONE_MINUTE = 60 * ONE_SECOND;

  public static final long ONE_HOUR = 60 * ONE_MINUTE;

  public static final long ONE_DAY = 24 * ONE_HOUR;

  public static final long ONE_WEEK = 7 * ONE_DAY;

  public final static int TIME = 0;

  public final static int DATE = 1;

  public final static int DATETIME = 2;

  private int m_timeOrDateType;

  private int m_lengthStyle;

  private DateFormat m_format;

  private Calendar m_calendar = Calendar.getInstance();

  private ArrayList m_fieldPositions = new ArrayList();

  private Date m_lastDate = new Date();

  private Caret m_caret;

  private int m_curField = -1;

  private JTextField m_textField;

  private Spinner m_spinner;

  private AbstractAction m_upAction = new UpDownAction(1, "up");

  private AbstractAction m_downAction = new UpDownAction(-1, "down");

  private boolean m_settingDateText = false; // BUG FIX

  private int[] m_fieldTypes = { DateFormat.ERA_FIELD, DateFormat.YEAR_FIELD,
      DateFormat.MONTH_FIELD, DateFormat.DATE_FIELD,
      DateFormat.HOUR_OF_DAY1_FIELD, DateFormat.HOUR_OF_DAY0_FIELD,
      DateFormat.MINUTE_FIELD, DateFormat.SECOND_FIELD,
      DateFormat.MILLISECOND_FIELD, DateFormat.DAY_OF_WEEK_FIELD,
      DateFormat.DAY_OF_YEAR_FIELD,
      DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD,
      DateFormat.WEEK_OF_YEAR_FIELD, DateFormat.WEEK_OF_MONTH_FIELD,
      DateFormat.AM_PM_FIELD, DateFormat.HOUR1_FIELD,
      DateFormat.HOUR0_FIELD };

  public DateTimeEditor() {
    m_timeOrDateType = DATETIME;
    m_lengthStyle = DateFormat.SHORT;
    init();
  }

  public DateTimeEditor(int timeOrDateType) {
    m_timeOrDateType = timeOrDateType;
    m_lengthStyle = DateFormat.FULL;
    init();
  }

  public DateTimeEditor(int timeOrDateType, int lengthStyle) {
    m_timeOrDateType = timeOrDateType;
    m_lengthStyle = lengthStyle;
    init();
  }

  private void init() {
    setLayout(new BorderLayout());
    m_textField = new JTextField();

    m_textField.setDocument(new DateTimeDocument()); // BUG FIX

    m_spinner = new Spinner();
    m_spinner.getIncrementButton().addActionListener(m_upAction);
    m_spinner.getDecrementButton().addActionListener(m_downAction);
    add(m_textField, "Center");
    add(m_spinner, "East");
    m_caret = m_textField.getCaret();
    m_caret.addChangeListener(new ChangeListener() {
      public void stateChanged(ChangeEvent evt) {
        setCurField();
      }
    });
    setupKeymap();
    reinit();
  }

  protected class DateTimeDocument extends PlainDocument {
    public void insertString(int offset, String str, AttributeSet a)
        throws BadLocationException {
      if (m_settingDateText)
        super.insertString(offset, str, a);
    }
  } // BUG FIX

  public int getTimeOrDateType() {
    return m_timeOrDateType;
  }

  public void setTimeOrDateType(int timeOrDateType) {
    m_timeOrDateType = timeOrDateType;
    reinit();
  }

  public int getLengthStyle() {
    return m_lengthStyle;
  }

  public void setLengthStyle(int lengthStyle) {
    m_lengthStyle = lengthStyle;
    reinit();
  }

  public Date getDate() {
    return (m_lastDate);
  }

  // public void setDate(Date date)
  // {
  //    m_lastDate = date;
  //    m_calendar.setTime(m_lastDate);
  //    m_textField.setText(m_format.format(m_lastDate));
  //    getFieldPositions();
  // }

  public void setDate(Date date) {
    m_lastDate = date;
    m_calendar.setTime(m_lastDate);
    m_settingDateText = true;
    m_textField.setText(m_format.format(m_lastDate));
    m_settingDateText = false;
    getFieldPositions();
  } // BUG FIX

  private int getFieldBeginIndex(int fieldNum) {
    int beginIndex = -1;
    for (Iterator iter = m_fieldPositions.iterator(); iter.hasNext();) {
      FieldPosition fieldPos = (FieldPosition) iter.next();
      if (fieldPos.getField() == fieldNum) {
        beginIndex = fieldPos.getBeginIndex();
        break;
      }
    }
    return (beginIndex);
  }

  private FieldPosition getFieldPosition(int fieldNum) {
    FieldPosition result = null;
    for (Iterator iter = m_fieldPositions.iterator(); iter.hasNext();) {
      FieldPosition fieldPosition = (FieldPosition) iter.next();
      if (fieldPosition.getField() == fieldNum) {
        result = fieldPosition;
        break;
      }
    }
    return (result);
  }

  private void reinit() {
    setupFormat();
    setDate(m_lastDate);
    m_caret.setDot(0);
    setCurField();
    repaint();
  }

  protected void setupFormat() {
    switch (m_timeOrDateType) {
    case TIME:
      m_format = DateFormat.getTimeInstance(m_lengthStyle);
      break;
    case DATE:
      m_format = DateFormat.getDateInstance(m_lengthStyle);
      break;
    case DATETIME:
      m_format = DateFormat.getDateTimeInstance(m_lengthStyle,
          m_lengthStyle);
      break;
    }
  }

  protected class UpDownAction extends AbstractAction {
    int m_direction; // +1 = up; -1 = down

    public UpDownAction(int direction, String name) {
      super(name);
      m_direction = direction;
    }

    public void actionPerformed(ActionEvent evt) {
      if (!this.isEnabled())
        return;
      boolean dateSet = true;
      switch (m_curField) {
      case DateFormat.AM_PM_FIELD:
        m_lastDate.setTime(m_lastDate.getTime()
            + (m_direction * 12 * ONE_HOUR));
        break;
      case DateFormat.DATE_FIELD:
      case DateFormat.DAY_OF_WEEK_FIELD:
      case DateFormat.DAY_OF_WEEK_IN_MONTH_FIELD:
      case DateFormat.DAY_OF_YEAR_FIELD:
        m_lastDate.setTime(m_lastDate.getTime()
            + (m_direction * ONE_DAY));
        break;
      case DateFormat.ERA_FIELD:
        dateSet = false;
        break;
      case DateFormat.HOUR0_FIELD:
      case DateFormat.HOUR1_FIELD:
      case DateFormat.HOUR_OF_DAY0_FIELD:
      case DateFormat.HOUR_OF_DAY1_FIELD:
        m_lastDate.setTime(m_lastDate.getTime()
            + (m_direction * ONE_HOUR));
        break;
      case DateFormat.MILLISECOND_FIELD:
        m_lastDate.setTime(m_lastDate.getTime() + (m_direction * 1));
        break;
      case DateFormat.MINUTE_FIELD:
        m_lastDate.setTime(m_lastDate.getTime()
            + (m_direction * ONE_MINUTE));
        break;
      case DateFormat.MONTH_FIELD:
        m_calendar.set(Calendar.MONTH, m_calendar.get(Calendar.MONTH)
            + m_direction);
        m_lastDate = m_calendar.getTime();
        break;
      case DateFormat.SECOND_FIELD:
        m_lastDate.setTime(m_lastDate.getTime()
            + (m_direction * ONE_SECOND));
        break;
      case DateFormat.WEEK_OF_MONTH_FIELD:
        m_calendar.set(Calendar.WEEK_OF_MONTH, m_calendar
            .get(Calendar.WEEK_OF_MONTH)
            + m_direction);
        m_lastDate = m_calendar.getTime();
        break;
      case DateFormat.WEEK_OF_YEAR_FIELD:
        m_calendar.set(Calendar.WEEK_OF_MONTH, m_calendar
            .get(Calendar.WEEK_OF_MONTH)
            + m_direction);
        m_lastDate = m_calendar.getTime();
        break;
      case DateFormat.YEAR_FIELD:
        m_calendar.set(Calendar.YEAR, m_calendar.get(Calendar.YEAR)
            + m_direction);
        m_lastDate = m_calendar.getTime();
        break;
      default:
        dateSet = false;
      }

      if (dateSet) {
        int fieldId = m_curField;
        setDate(m_lastDate);
        FieldPosition fieldPosition = getFieldPosition(fieldId);
        m_caret.setDot(fieldPosition.getBeginIndex());

        m_textField.requestFocus();
        repaint();
      }
    }
  }

  protected class BackwardAction extends TextAction {
    BackwardAction(String name) {
      super(name);
    }

    public void actionPerformed(ActionEvent e) {
      JTextComponent target = getTextComponent(e);
      if (target != null) {
        int dot = target.getCaretPosition();
        if (dot > 0) {
          FieldPosition position = getPrevField(dot);
          if (position != null)
            target.setCaretPosition(position.getBeginIndex());
          else {
            position = getFirstField();
            if (position != null)
              target.setCaretPosition(position.getBeginIndex());
          }
        } else
          target.getToolkit().beep();
        target.getCaret().setMagicCaretPosition(null);
      }
    }
  }

  protected class ForwardAction extends TextAction {
    ForwardAction(String name) {
      super(name);
    }

    public void actionPerformed(ActionEvent e) {
      JTextComponent target = getTextComponent(e);
      if (target != null) {
        FieldPosition position = getNextField(target.getCaretPosition());
        if (position != null)
          target.setCaretPosition(position.getBeginIndex());
        else {
          position = getLastField();
          if (position != null)
            target.setCaretPosition(position.getBeginIndex());
        }
        target.getCaret().setMagicCaretPosition(null);
      }
    }
  }

  protected class BeginAction extends TextAction {
    BeginAction(String name) {
      super(name);
    }

    public void actionPerformed(ActionEvent e) {
      JTextComponent target = getTextComponent(e);
      if (target != null) {
        FieldPosition position = getFirstField();
        if (position != null)
          target.setCaretPosition(position.getBeginIndex());
      }
    }
  }

  protected class EndAction extends TextAction {
    EndAction(String name) {
      super(name);
    }

    public void actionPerformed(ActionEvent e) {
      JTextComponent target = getTextComponent(e);
      if (target != null) {
        FieldPosition position = getLastField();
        if (position != null)
          target.setCaretPosition(position.getBeginIndex());
      }
    }
  }

  protected void setupKeymap() {
    Keymap keymap = m_textField.addKeymap("DateTimeKeymap", null);
    keymap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0),
        m_upAction);
    keymap.addActionForKeyStroke(KeyStroke
        .getKeyStroke(KeyEvent.VK_DOWN, 0), m_downAction);
    keymap.addActionForKeyStroke(KeyStroke
        .getKeyStroke(KeyEvent.VK_LEFT, 0), new BackwardAction(
        DefaultEditorKit.backwardAction));
    keymap.addActionForKeyStroke(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,
        0), new ForwardAction(DefaultEditorKit.forwardAction));
    keymap.addActionForKeyStroke(KeyStroke
        .getKeyStroke(KeyEvent.VK_HOME, 0), new BeginAction(
        DefaultEditorKit.beginAction));
    keymap.addActionForKeyStroke(
        KeyStroke.getKeyStroke(KeyEvent.VK_END, 0), new EndAction(
            DefaultEditorKit.endAction));
    m_textField.setKeymap(keymap);
  }

  private void getFieldPositions() {
    m_fieldPositions.clear();
    for (int ctr = 0; ctr < m_fieldTypes.length; ++ctr) {
      int fieldId = m_fieldTypes[ctr];
      FieldPosition fieldPosition = new FieldPosition(fieldId);
      StringBuffer formattedField = new StringBuffer();
      m_format.format(m_lastDate, formattedField, fieldPosition);
      if (fieldPosition.getEndIndex() > 0)
        m_fieldPositions.add(fieldPosition);
    }
    m_fieldPositions.trimToSize();
    Collections.sort(m_fieldPositions, new Comparator() {
      public int compare(Object o1, Object o2) {
        return (((FieldPosition) o1).getBeginIndex() - ((FieldPosition) o2)
            .getBeginIndex());
      }
    });
  }

  private FieldPosition getField(int caretLoc) {
    FieldPosition fieldPosition = null;
    for (Iterator iter = m_fieldPositions.iterator(); iter.hasNext();) {
      FieldPosition chkFieldPosition = (FieldPosition) iter.next();
      if ((chkFieldPosition.getBeginIndex() <= caretLoc)
          && (chkFieldPosition.getEndIndex() > caretLoc)) {
        fieldPosition = chkFieldPosition;
        break;
      }
    }
    return (fieldPosition);
  }

  private FieldPosition getPrevField(int caretLoc) {
    FieldPosition fieldPosition = null;
    for (int ctr = m_fieldPositions.size() - 1; ctr > -1; --ctr) {
      FieldPosition chkFieldPosition = (FieldPosition) m_fieldPositions
          .get(ctr);
      if (chkFieldPosition.getEndIndex() <= caretLoc) {
        fieldPosition = chkFieldPosition;
        break;
      }
    }
    return (fieldPosition);
  }

  private FieldPosition getNextField(int caretLoc) {
    FieldPosition fieldPosition = null;
    for (Iterator iter = m_fieldPositions.iterator(); iter.hasNext();) {
      FieldPosition chkFieldPosition = (FieldPosition) iter.next();
      if (chkFieldPosition.getBeginIndex() > caretLoc) {
        fieldPosition = chkFieldPosition;
        break;
      }
    }
    return (fieldPosition);
  }

  private FieldPosition getFirstField() {
    FieldPosition result = null;
    try {
      result = ((FieldPosition) m_fieldPositions.get(0));
    } catch (NoSuchElementException ex) {
    }
    return (result);
  }

  private FieldPosition getLastField() {
    FieldPosition result = null;
    try {
      result = ((FieldPosition) m_fieldPositions.get(m_fieldPositions
          .size() - 1));
    } catch (NoSuchElementException ex) {
    }
    return (result);
  }

  private void setCurField() {
    FieldPosition fieldPosition = getField(m_caret.getDot());
    if (fieldPosition != null) {
      if (m_caret.getDot() != fieldPosition.getBeginIndex())
        m_caret.setDot(fieldPosition.getBeginIndex());
    } else {
      fieldPosition = getPrevField(m_caret.getDot());
      if (fieldPosition != null)
        m_caret.setDot(fieldPosition.getBeginIndex());
      else {
        fieldPosition = getFirstField();
        if (fieldPosition != null)
          m_caret.setDot(fieldPosition.getBeginIndex());
      }
    }

    if (fieldPosition != null)
      m_curField = fieldPosition.getField();
    else
      m_curField = -1;
  }

  public void setEnabled(boolean enable) {
    m_textField.setEnabled(enable);
    m_spinner.setEnabled(enable);
  }

  public boolean isEnabled() {
    return (m_textField.isEnabled() && m_spinner.isEnabled());
  }

  public static void main(String[] args) {
    JFrame frame = new JFrame();
    frame.addWindowListener(new WindowAdapter() {
      public void windowClosing(WindowEvent evt) {
        System.exit(0);
      }
    });

    JPanel panel = new JPanel(new BorderLayout());
    panel.setBorder(new EmptyBorder(5, 5, 5, 5));
    frame.setContentPane(panel);
    final DateTimeEditor field = new DateTimeEditor(
        DateTimeEditor.DATETIME, DateFormat.FULL);
    panel.add(field, "North");

    JPanel buttonBox = new JPanel(new GridLayout(2, 2));
    JButton showDateButton = new JButton("Show Date");
    buttonBox.add(showDateButton);

    final JComboBox timeDateChoice = new JComboBox();
    timeDateChoice.addItem("Time");
    timeDateChoice.addItem("Date");
    timeDateChoice.addItem("Date/Time");
    timeDateChoice.setSelectedIndex(2);
    timeDateChoice.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        field.setTimeOrDateType(timeDateChoice.getSelectedIndex());
      }
    });
    buttonBox.add(timeDateChoice);

    JButton toggleButton = new JButton("Toggle Enable");
    buttonBox.add(toggleButton);
    showDateButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        System.out.println(field.getDate());
      }
    });
    toggleButton.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        field.setEnabled(!field.isEnabled());
      }
    });
    panel.add(buttonBox, "South");

    final JComboBox lengthStyleChoice = new JComboBox();
    lengthStyleChoice.addItem("Full");
    lengthStyleChoice.addItem("Long");
    lengthStyleChoice.addItem("Medium");
    lengthStyleChoice.addItem("Short");
    lengthStyleChoice.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent evt) {
        field.setLengthStyle(lengthStyleChoice.getSelectedIndex());
      }
    });
    buttonBox.add(lengthStyleChoice);

    frame.pack();
    Dimension dim = frame.getToolkit().getScreenSize();
    frame.setLocation(dim.width / 2 - frame.getWidth() / 2, dim.height / 2
        - frame.getHeight() / 2);
    frame.show();
  }
}

class Spinner extends JPanel
{
   private int m_orientation = SwingConstants.VERTICAL;
   private BasicArrowButton m_incrementButton;
   private BasicArrowButton m_decrementButton;

   public Spinner() { createComponents(); }

   public Spinner(int orientation)
   {
      m_orientation = orientation;
      createComponents();
   }

   public void setEnabled(boolean enable)
   {
      m_incrementButton.setEnabled(enable);
      m_decrementButton.setEnabled(enable);
   }

   public boolean isEnabled()
   {
      return (m_incrementButton.isEnabled() &&
         m_decrementButton.isEnabled());
   }
  
   protected void createComponents()
   {
      if (m_orientation == SwingConstants.VERTICAL)
      {
         setLayout(new GridLayout(2, 1));
         m_incrementButton = new BasicArrowButton(
            SwingConstants.NORTH);
         m_decrementButton = new BasicArrowButton(
            SwingConstants.SOUTH);
         add(m_incrementButton);
         add(m_decrementButton);
      }
      else if (m_orientation == SwingConstants.HORIZONTAL)
      {
         setLayout(new GridLayout(1, 2));
         m_incrementButton = new BasicArrowButton(
            SwingConstants.EAST);
         m_decrementButton = new BasicArrowButton(
            SwingConstants.WEST);
         add(m_decrementButton);
         add(m_incrementButton);
      }
   }

   public JButton getIncrementButton() {
      return (m_incrementButton); }
   public JButton getDecrementButton() {
      return (m_decrementButton); }

   public static void main(String[] args)
   {
      JFrame frame = new JFrame();
      JPanel panel = (JPanel) frame.getContentPane();
      panel.setLayout(new BorderLayout());
      JTextField  field = new JTextField(20);
      Spinner spinner = new Spinner();

      panel.add(field, "Center");
      panel.add(spinner, "East");

      Dimension dim = frame.getToolkit().getScreenSize();
      frame.setLocation(dim.width/2 - frame.getWidth()/2,
         dim.height/2 - frame.getHeight()/2);
      frame.pack();
      frame.show();
   }
}


Kết quả - Result









No comments:

Post a Comment