Spinner.java
上传用户:haobig99
上传日期:2022-06-15
资源大小:369k
文件大小:19k
- /*
- * Copyright 2008 Sun Microsystems, Inc. All Rights Reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation. Sun designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Sun in the LICENSE file that accompanied this code.
- *
- * This code 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
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
- * CA 95054 USA or visit www.sun.com if you need additional information or
- * have any questions.
- */
- package com.sun.lwuit.spinner;
- import com.sun.lwuit.Component;
- import com.sun.lwuit.Display;
- import com.sun.lwuit.Graphics;
- import com.sun.lwuit.Image;
- import com.sun.lwuit.List;
- import com.sun.lwuit.TextArea;
- import com.sun.lwuit.TextField;
- import com.sun.lwuit.geom.Dimension;
- import com.sun.lwuit.list.DefaultListCellRenderer;
- import com.sun.lwuit.list.ListCellRenderer;
- import com.sun.lwuit.list.ListModel;
- import com.sun.lwuit.plaf.Style;
- import java.util.Calendar;
- import java.util.Date;
- /**
- * A spinner allows us to select a numeric, date or time value using the arrow keys
- * in a similar way to a list or a combo box.
- *
- * @author Shai Almog
- */
- public class Spinner extends List {
- /**
- * Value for create date renderer represnting Day-Month-4 Digit Year
- */
- public static final int DATE_FORMAT_DD_MM_YYYY = 1;
- /**
- * Value for create date renderer represnting Month-Day-4 Digit Year
- */
- public static final int DATE_FORMAT_MM_DD_YYYY = 2;
- /**
- * Value for create date renderer represnting Day-Month-2 Digit Year
- */
- public static final int DATE_FORMAT_DD_MM_YY = 11;
- /**
- * Value for create date renderer represnting Month-Day-2 Digit Year
- */
- public static final int DATE_FORMAT_MM_DD_YY = 12;
- /**
- * The image appearing on the side of the spinner widget to indicate its "spinnability"
- */
- private static Image spinnerHandle;
- private long lastKeyInteraction;
- private TextField quickType = new TextField();
- private boolean monthFirst;
- private int currentInputAlign = LEFT;
- private static int inputSkipDelay = 2000;
- /**
- * Creates a new time spinner instance, time is an integer represented in seconds
- * since mindnight
- *
- * @param min lowest value allowed in seconds since midnight
- * @param max maximum value allowed in seconds since midnight
- * @param currentValue the starting value in seconds since midnight
- * @param step increments in the spinner (in seconds)
- * @param twentyFourHours show the value as 24 hour values or AM/PM
- * @param showSeconds show the value of the seconds as well or hide it
- * @return new spinner instance
- */
- public static Spinner createTime(int min, int max, int currentValue, int step, boolean twentyFourHours, boolean showSeconds) {
- Spinner s = new Spinner(new SpinnerNumberModel(min, max, currentValue, step),
- DateTimeRenderer.createTimeRenderer(twentyFourHours, showSeconds));
- return s;
- }
- /**
- * Creates a new date spinner instance
- *
- * @param min lowest value allowed
- * @param max maximum value allowed
- * @param currentValue the starting value for the mode
- * @param separatorChar character to separate the entries during rendering
- * @param format formatting type for the field
- * @return new spinner instance
- */
- public static Spinner createDate(long min, long max, long currentValue, char separatorChar, int format) {
- Spinner s = new Spinner(new SpinnerDateModel(min, max, currentValue), DateTimeRenderer.createDateRenderer(separatorChar, format));
- s.monthFirst = format == DATE_FORMAT_MM_DD_YY || format == DATE_FORMAT_MM_DD_YYYY;
- return s;
- }
- /**
- * Creates a new numeric spinner instance
- *
- * @param min lowest value allowed
- * @param max maximum value allowed
- * @param currentValue the starting value for the mode
- * @param step the value by which we increment the entries in the model
- * @return new spinner instance
- */
- public static Spinner create(int min, int max, int currentValue, int step) {
- return new Spinner(new SpinnerNumberModel(min, max, currentValue, step), new DefaultListCellRenderer(false));
- }
- /**
- * Creates a new numeric spinner instance
- *
- * @param min lowest value allowed
- * @param max maximum value allowed
- * @param currentValue the starting value for the mode
- * @param step the value by which we increment the entries in the model
- * @return new spinner instance
- */
- public static Spinner create(double min, double max, double currentValue, double step) {
- return new Spinner(new SpinnerNumberModel(min, max, currentValue, step), new DefaultListCellRenderer(false));
- }
- /**
- * Creates a new spinner instance with the given spinner model
- *
- * @param spinner model such as SpinnerDateModel or SpinnerNumberModel
- */
- private Spinner(ListModel model, ListCellRenderer rendererInstance) {
- super(model);
- setListCellRenderer(rendererInstance);
- setUIID("Spinner");
- setFixedSelection(FIXED_CENTER);
- setOrientation(2);
- setInputOnFocus(false);
- setIsScrollVisible(false);
- DefaultListCellRenderer render = ((DefaultListCellRenderer) super.getRenderer());
- render.setRTL(false);
- render.setShowNumbers(false);
- render.setUIID("SpinnerRenderer");
- Component bgFocus = render.getListFocusComponent(this);
- bgFocus.getSelectedStyle().setBgTransparency(0);
- bgFocus.getUnselectedStyle().setBgTransparency(0);
- quickType.setReplaceMenu(false);
- quickType.setInputModeOrder(new String[]{"123"});
- quickType.setFocus(true);
- quickType.setRTL(false);
- quickType.setAlignment(LEFT);
- setIgnoreFocusComponentWhenUnfocused(true);
- setRenderingPrototype(model.getItemAt(model.getSize() - 1));
- if (getRenderer() instanceof DateTimeRenderer) {
- quickType.setColumns(2);
- }
- }
- /**
- * @inheritDoc
- */
- protected void initComponent() {
- getComponentForm().registerAnimated(this);
- }
- /**
- * @inheritDoc
- */
- protected Dimension calcScrollSize() {
- return super.calcPreferredSize();
- }
- /**
- * @inheritDoc
- */
- protected Dimension calcPreferredSize() {
- int boxWidth = 0;
- int verticalPadding = getStyle().getPadding(false, Component.TOP) + getStyle().getPadding(false, Component.BOTTOM);
- int horizontalPadding = getStyle().getPadding(isRTL(), Component.RIGHT) + getStyle().getPadding(isRTL(), Component.LEFT);
- Object prototype = getRenderingPrototype();
- int selectedHeight;
- ListCellRenderer renderer = getRenderer();
- Component cmp;
- if (prototype != null) {
- cmp = renderer.getListCellRendererComponent(this, prototype, 0, true);
- } else {
- if (getModel().getSize() > 0) {
- cmp = renderer.getListCellRendererComponent(this, getModel().getItemAt(0), 0, true);
- } else {
- cmp = renderer.getListCellRendererComponent(this, null, 0, true);
- }
- }
- selectedHeight = cmp.getPreferredH();
- if(spinnerHandle != null) {
- if(spinnerHandle.getHeight() > selectedHeight) {
- selectedHeight = spinnerHandle.getHeight();
- }
- boxWidth += spinnerHandle.getWidth();
- }
- return new Dimension(cmp.getPreferredW() + boxWidth + horizontalPadding, (selectedHeight + verticalPadding));
- }
- /**
- * @inheritDoc
- */
- public void keyPressed(int code) {
- int game = Display.getInstance().getGameAction(code);
- if (game > 0) {
- super.keyPressed(code);
- } else {
- quickType.keyPressed(code);
- lastKeyInteraction = System.currentTimeMillis();
- }
- }
- /**
- * Set the value of the spinner to a number or a date based on the spinner type
- *
- * @param o a number or a date
- */
- public void setValue(Object o) {
- ListModel m = getModel();
- if (m instanceof SpinnerDateModel) {
- ((SpinnerDateModel) m).setValue((Date) o);
- } else {
- ((SpinnerNumberModel) m).setValue(o);
- }
- }
- /**
- * Returns the value of the spinner to a number or a date based on the spinner type
- *
- * @return a number or a date
- */
- public Object getValue() {
- ListModel m = getModel();
- if (m instanceof SpinnerDateModel) {
- return ((SpinnerDateModel) m).getValue();
- }
- return ((SpinnerNumberModel) m).getValue();
- }
- /**
- * @inheritDoc
- */
- public void keyReleased(int code) {
- int game = Display.getInstance().getGameAction(code);
- if (game > 0) {
- super.keyReleased(code);
- } else {
- try {
- quickType.keyReleased(code);
- lastKeyInteraction = System.currentTimeMillis();
- String t = quickType.getText();
- if (getRenderer() instanceof DateTimeRenderer) {
- // is this is a time input or a date input?
- if(getModel() instanceof SpinnerNumberModel) {
- int time = ((Integer)getValue()).intValue();
- int seconds = time % 60;
- int minutes = time / 60;
- int hours = minutes / 60;
- minutes %= 60;
- switch (currentInputAlign) {
- case LEFT:
- hours = Integer.parseInt(t);
- if(((DateTimeRenderer)getRenderer()).isTwentyFourHours()) {
- if(hours > 24) {
- return;
- }
- } else {
- if(hours > 12) {
- return;
- }
- }
- break;
- case CENTER:
- minutes = Integer.parseInt(t);
- if(minutes > 59) {
- return;
- }
- break;
- case RIGHT:
- seconds = Integer.parseInt(t);
- if(seconds > 59) {
- return;
- }
- break;
- }
- int actual = seconds + minutes * 60 + hours * 60 * 60;
- setValue(new Integer(actual));
- // update the spinner positioning if we have two characters
- if (quickType.getText().length() > 1) {
- quickType.setText("");
- switch (currentInputAlign) {
- case LEFT:
- currentInputAlign = CENTER;
- break;
- case CENTER:
- if(((DateTimeRenderer)getRenderer()).isShowSeconds()) {
- currentInputAlign = RIGHT;
- } else {
- currentInputAlign = LEFT;
- lastKeyInteraction = -1;
- }
- break;
- case RIGHT:
- currentInputAlign = LEFT;
- lastKeyInteraction = -1;
- break;
- }
- }
- } else {
- Calendar c = Calendar.getInstance();
- c.setTime((Date) getValue());
- switch (currentInputAlign) {
- case LEFT:
- if (monthFirst) {
- c.set(Calendar.MONTH, Integer.parseInt(t) - 1);
- } else {
- c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(t));
- }
- break;
- case CENTER:
- if (monthFirst) {
- c.set(Calendar.DAY_OF_MONTH, Integer.parseInt(t));
- } else {
- c.set(Calendar.MONTH, Integer.parseInt(t) - 1);
- }
- break;
- case RIGHT:
- int y = c.get(Calendar.YEAR);
- c.set(Calendar.YEAR, y - (y % 100) + Integer.parseInt(t));
- break;
- }
- setValue(c.getTime());
- // update the spinner positioning if we have two characters
- if (quickType.getText().length() > 1) {
- quickType.setText("");
- switch (currentInputAlign) {
- case LEFT:
- currentInputAlign = CENTER;
- break;
- case CENTER:
- currentInputAlign = RIGHT;
- break;
- case RIGHT:
- currentInputAlign = LEFT;
- lastKeyInteraction = -1;
- break;
- }
- }
- }
- return;
- } else {
- SpinnerNumberModel n = (SpinnerNumberModel) getModel();
- if (n.realValues) {
- double val = Double.parseDouble(t);
- if(val > ((SpinnerNumberModel)getModel()).getMax() ||
- val < ((SpinnerNumberModel)getModel()).getMin()) {
- return;
- }
- setValue(new Double(val));
- } else {
- int val = Integer.parseInt(t);
- if(val > ((SpinnerNumberModel)getModel()).getMax() ||
- val < ((SpinnerNumberModel)getModel()).getMin()) {
- return;
- }
- setValue(new Integer(val));
- }
- }
- int modelSize = getModel().getSize();
- for (int iter = 0; iter < modelSize; iter++) {
- String v = getModel().getItemAt(iter).toString();
- if (v.startsWith(t)) {
- setSelectedIndex(iter);
- return;
- }
- }
- // easier to ignore exceptions than build "proper" error handling
- } catch(IllegalArgumentException ignore) {
- ignore.printStackTrace();
- }
- }
- }
- /**
- * @inheritDoc
- */
- public boolean isRTL() {
- // Since spinner is numeric it shouldn't be affected by RTL and should naturally be right aligned
- return false;
- }
- /**
- * @inheritDoc
- */
- public void setRTL(boolean rtl) {
- // Since spinner is numeric it shouldn't be affected by RTL and should naturally be right aligned
- }
- /**
- * @inheritDoc
- */
- public void paint(Graphics g) {
- super.paint(g);
- if(spinnerHandle != null) {
- Style s = getStyle();
- g.drawImage(spinnerHandle, getX() + getWidth() - spinnerHandle.getWidth() - s.getPadding(isRTL(), LEFT) - s.getPadding(isRTL(), RIGHT),
- getY() + s.getPadding(false, TOP));
- }
- if (System.currentTimeMillis() - inputSkipDelay < lastKeyInteraction || quickType.isPendingCommit()) {
- quickType.setWidth(Math.min(getWidth(), quickType.getPreferredW()));
- quickType.setHeight(Math.min(getHeight(), quickType.getPreferredH()));
- Style s = quickType.getStyle();
- quickType.setY(getScrollY() + getY());
- // positioning based on date/time
- if (getRenderer() instanceof DateTimeRenderer) {
- switch (currentInputAlign) {
- case LEFT:
- quickType.setX(getX());
- break;
- case RIGHT:
- quickType.setX(getX() + quickType.getStyle().getFont().charWidth(TextArea.getWidestChar()) * 4 + s.getMargin(false, RIGHT));
- break;
- default:
- quickType.setX(getX() + quickType.getStyle().getFont().charWidth(TextArea.getWidestChar()) * 2 + s.getMargin(false, RIGHT));
- break;
- }
- } else {
- quickType.setX(getX());
- }
- quickType.paintComponent(g, true);
- }
- }
- /**
- * @inheritDoc
- */
- public boolean animate() {
- boolean val = super.animate();
- if (lastKeyInteraction != -1) {
- quickType.animate();
- if (System.currentTimeMillis() - inputSkipDelay > lastKeyInteraction && !quickType.isPendingCommit()) {
- lastKeyInteraction = -1;
- quickType.clear();
- currentInputAlign = LEFT;
- }
- return true;
- }
- return val;
- }
- /**
- * The image appearing on the side of the spinner widget to indicate its "spinnability"
- *
- * @return the spinnerHandle
- */
- public static Image getSpinnerHandle() {
- return spinnerHandle;
- }
- /**
- * The image appearing on the side of the spinner widget to indicate its "spinnability"
- *
- * @param aSpinnerHandle the spinnerHandle to set
- */
- public static void setSpinnerHandle(Image aSpinnerHandle) {
- spinnerHandle = aSpinnerHandle;
- }
- /**
- * Indicates the time after which the skip input area for entering spinner values manually will disappear
- *
- * @return the inputSkipDelay
- */
- public static int getInputSkipDelay() {
- return inputSkipDelay;
- }
- /**
- * Indicates the time after which the skip input area for entering spinner values manually will disappear
- *
- * @param aInputSkipDelay the time for disappearing
- */
- public static void setInputSkipDelay(int aInputSkipDelay) {
- inputSkipDelay = aInputSkipDelay;
- }
- }