📄 raplatime.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.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Point;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.net.URL;
import java.text.DateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;
import javax.swing.BorderFactory;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.MenuElement;
import javax.swing.MenuSelectionManager;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
/** A ComboBox like time chooser.
* It is localizable and it uses swing-components.
* <p>The combobox editor is a {@link TimeField}. If the ComboBox-Button
* is pressed a TimeSelectionList will drop down.</p>
* @author Christopher Kohlhaas
*/
public final class RaplaTime extends RaplaComboBox {
private static final long serialVersionUID = 1L;
protected TimeField m_timeField;
protected TimeList m_timeList;
protected TimeModel m_timeModel;
protected Collection m_listenerList = new ArrayList();
private Date m_lastTime;
private int m_visibleRowCount = -1;
private int m_rowsPerHour = 4;
private TimeRenderer m_renderer;
private static Image clock;
boolean m_showClock;
/** Create a new TimeBox with the default locale. */
public RaplaTime() {
this(Locale.getDefault());
}
/** Create a new TimeBox with the specified locale. */
public RaplaTime(Locale locale) {
this(locale,TimeZone.getDefault(),true, true);
}
/** Create a new TimeBox with the specified locale and timeZone. */
public RaplaTime(Locale locale,TimeZone timeZone) {
this(locale,timeZone,true, true);
}
/** @deprecated replaced with #RaplaTime(Locale,TimeZone,boolean) */
public RaplaTime(Locale locale,boolean isDropDown) {
this(locale,TimeZone.getDefault(),true, true);
}
/** Create a new TimeBox with the specified locale and timeZone. The
isDropDown flag specifies if times could be selected
via a drop-down-box.
*/
public RaplaTime(Locale locale,TimeZone timeZone,boolean isDropDown, boolean showClock) {
super(isDropDown,new TimeField(locale,timeZone));
m_showClock = showClock;
m_timeModel = new TimeModel(locale, timeZone);
m_timeField = (TimeField) m_editorComponent;
Listener listener = new Listener();
m_timeField.addChangeListener(listener);
m_timeModel.addDateChangeListener(listener);
m_lastTime = m_timeModel.getTime();
if ( showClock )
{
if ( clock == null )
{
URL url = RaplaTime.class.getResource("clock.png");
if ( url != null )
{
clock =Toolkit.getDefaultToolkit().createImage(url );
MediaTracker m = new MediaTracker(this);
m.addImage(clock, 0);
try { m.waitForID(0); } catch (InterruptedException ex) {}
}
}
getLabel().setIcon( new ImageIcon( createClockImage()));
getLabel().setBorder( BorderFactory.createEmptyBorder(0,0,0,1));
}
}
static Color HOUR_POINTER = new Color( 40,40,100);
static Color MINUTE_POINTER = new Color( 100,100,180);
protected Image createClockImage() {
BufferedImage image = new BufferedImage( 17, 17, BufferedImage.TYPE_INT_ARGB);
Calendar calendar = Calendar.getInstance(getTimeZone(),m_timeModel.getLocale());
calendar.setTime( m_timeModel.getTime());
int hourOfDay = calendar.get( Calendar.HOUR_OF_DAY) % 12;
int minute = calendar.get( Calendar.MINUTE);
Graphics g = image.getGraphics();
double hourPos = (hourOfDay * 60 + minute - 180) / (60.0 * 12) * 2 * Math.PI ;
double minutePos = (minute -15) / 60.0 * 2 * Math.PI;
int xhour = (int) (Math.cos( hourPos) * 4.5);
int yhour = (int) (Math.sin( hourPos ) * 4.5 );
int xminute = (int) (Math.cos( minutePos ) * 6.5 );
int yminute = (int) (Math.sin( minutePos) * 6.5);
g.drawImage( clock,0,0,17,17, null);
g.setColor( HOUR_POINTER);
int centerx = 8;
int centery = 8;
g.drawLine( centerx, centery, centerx + xhour,centery + yhour);
g.setColor( MINUTE_POINTER);
g.drawLine( centerx, centery, centerx + xminute,centery +yminute);
return image;
}
/** The granularity of the selection rows:
* <ul>
* <li>1: 1 rows per hour = 1 Hour</li>
* <li>2: 2 rows per hour = 1/2 Hour</li>
* <li>2: 3 rows per hour = 20 Minutes</li>
* <li>4: 4 rows per hour = 15 Minutes</li>
* <li>6: 6 rows per hour = 10 Minutes</li>
* <li>12: 12 rows per hour = 5 Minutes</li>
* </ul>
*/
public void setRowsPerHour(int rowsPerHour) {
m_rowsPerHour = rowsPerHour;
if (m_timeList != null) {
throw new IllegalStateException("Property can only be set during initialization.");
}
}
/** @see #setRowsPerHour */
public int getRowsPerHour() {
return m_rowsPerHour;
}
class Listener implements ChangeListener,DateChangeListener {
// Implementation of ChangeListener
public void stateChanged(ChangeEvent evt) {
validateEditor();
}
public void dateChanged(DateChangeEvent evt) {
closePopup();
if (needSync())
m_timeField.setTime(evt.getDate());
if (m_lastTime == null || !m_lastTime.equals(evt.getDate()))
fireTimeChanged(evt.getDate());
m_lastTime = evt.getDate();
if ( clock != null && m_showClock)
{
getLabel().setIcon( new ImageIcon( createClockImage()));
}
}
}
/** test if we need to synchronize the dateModel and the m_timeField*/
private boolean needSync() {
return (m_timeField.getTime() != null && !m_timeModel.sameTime(m_timeField.getTime()));
}
protected void validateEditor() {
if (needSync())
m_timeModel.setTime(m_timeField.getTime());
}
/** the number of visble rows in the drop-down menu.*/
public void setVisibleRowCount(int count) {
m_visibleRowCount = count;
if (m_timeList != null)
m_timeList.getList().setVisibleRowCount(count);
}
public void setFont(Font font) {
super.setFont(font);
// Method called during constructor?
if (m_timeList == null || font == null)
return;
m_timeList.setFont(font);
}
public void setLocale(Locale locale) {
super.setLocale(locale);
if (m_timeField != null)
m_timeField.setLocale(locale);
}
public void setTimeZone(TimeZone zone) {
m_timeModel.setTimeZone(zone);
m_timeField.setTimeZone(zone);
}
public TimeZone getTimeZone() {
return m_timeField.getTimeZone();
}
/** Set the time relative to the given timezone.
* The date,month and year values will be ignored.
*/
public void setTime(Date time) {
m_timeModel.setTime(time);
}
/** Parse this date with a calendar-object set to the correct
time-zone to get the hour,minute and second. The
date,month and year values should be ignored.
*/
public Date getTime() {
return m_timeModel.getTime();
}
protected void showPopup() {
validateEditor();
super.showPopup();
m_timeList.selectTime(m_timeField.getTime());
}
/** registers new DateChangedListener for this component.
* An DateChangedEvent will be fired to every registered DateChangedListener
* when the a different time is selected.
* @see DateChangeListener
* @see DateChangeEvent
*/
public void addDateChangeListener(DateChangeListener listener) {
m_listenerList.add(listener);
}
/** removes a listener from this component.*/
public void removeDateChangeListener(DateChangeListener listener) {
m_listenerList.remove(listener);
}
public DateChangeListener[] getDateChangeListeners() {
return (DateChangeListener[])m_listenerList.toArray(new DateChangeListener[]{});
}
protected void fireTimeChanged(Date date) {
DateChangeListener[] listeners = getDateChangeListeners();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -