/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.apache.jmeter.gui.util; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.text.DateFormat; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; import javax.swing.JTextField; import javax.swing.SwingUtilities; /** * This is Date mask control. Using this control we can pop up our date in the * text field. And this control is developed basically for JDK1.3 and lower * version support. This control is similar to JSpinner control this is * available in JDK1.4 and above only. * <p> * This will set the date "yyyy/MM/dd HH:mm:ss" in this format only. * </p> */ public class JDateField extends JTextField { private static final long serialVersionUID = 240L; // Datefields are not thread-safe private final DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); // $NON-NLS-1$ /* * The following array must agree with dateFormat * * It is used to translate the positions in the buffer to the values used by * the Calendar class for the field id. * * Current format: MM/DD/YYYY HH:MM:SS 01234567890123456789 ^buffer * positions */ private static final int[] FIELD_POSITIONS = { Calendar.YEAR, // Y Calendar.YEAR, // Y Calendar.YEAR, // Y Calendar.YEAR, // Y Calendar.YEAR, // sp Calendar.MONTH, // M Calendar.MONTH, // M Calendar.MONTH, // / Calendar.DAY_OF_MONTH, // D Calendar.DAY_OF_MONTH, // D Calendar.DAY_OF_MONTH, // / Calendar.HOUR_OF_DAY, // H Calendar.HOUR_OF_DAY, // H Calendar.HOUR_OF_DAY, // : Calendar.MINUTE, // M Calendar.MINUTE, // M Calendar.MINUTE, // : Calendar.SECOND, // S Calendar.SECOND, // S Calendar.SECOND // end }; /** * Create a DateField with the specified date. * * @param date * The {@link Date} to be used */ public JDateField(Date date) { super(20); this.addKeyListener(new KeyFocus()); this.addFocusListener(new FocusClass()); String myString = dateFormat.format(date); setText(myString); } // Dummy constructor to allo JUnit tests to work public JDateField() { this(new Date()); } /** * Set the date to the Date mask control. * * @param date * The {@link Date} to be set */ public void setDate(Date date) { setText(dateFormat.format(date)); } /** * Get the date from the Date mask control. * * @return The currently set date */ public Date getDate() { try { return dateFormat.parse(getText()); } catch (ParseException e) { return new Date(); } } /* * Convert position in buffer to Calendar type Assumes that pos >=0 (which * is true for getCaretPosition()) */ private static int posToField(int pos) { if (pos >= FIELD_POSITIONS.length) { // if beyond the end pos = FIELD_POSITIONS.length - 1; // then set to the end } return FIELD_POSITIONS[pos]; } /** * Converts a date/time to a calendar using the defined format */ private Calendar parseDate(String datetime) { Calendar c = Calendar.getInstance(); try { Date dat = dateFormat.parse(datetime); c.setTime(dat); } catch (ParseException e) { // Do nothing; the current time will be returned } return c; } /* * Update the current field. The addend is only expected to be +1/-1, but * other values will work. N.B. the roll() method only supports changes by a * single unit - up or down */ private void update(int addend, boolean shifted) { Calendar c = parseDate(getText()); int pos = getCaretPosition(); int field = posToField(pos); if (shifted) { c.roll(field, true); } else { c.add(field, addend); } String newDate = dateFormat.format(c.getTime()); setText(newDate); if (pos > newDate.length()) { pos = newDate.length(); } final int newPosition = pos; SwingUtilities.invokeLater(() -> setCaretPosition(newPosition)); } class KeyFocus extends KeyAdapter { KeyFocus() {} @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_UP) { update(1, e.isShiftDown()); } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { update(-1, e.isShiftDown()); } } } class FocusClass implements FocusListener { FocusClass() {} @Override public void focusGained(FocusEvent e) {} @Override public void focusLost(FocusEvent e) { if(getText() == null || getText().isEmpty()) { return; } try { dateFormat.parse(getText()); } catch (ParseException e1) { requestFocusInWindow(); } } } }