Eliminate use of jcalendar. Replaced DateEditor with non-editable

display for Options use.
This commit is contained in:
ghidra1 2019-06-13 15:36:26 -04:00
parent 3b999fd86e
commit 8377f8394b
7 changed files with 11 additions and 718 deletions

View file

@ -1,302 +0,0 @@
/* ###
* IP: GHIDRA
*
* Licensed 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 docking.options.editor;
import java.awt.Color;
import java.awt.Toolkit;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.*;
import com.toedter.calendar.JCalendar;
import docking.widgets.label.GDLabel;
import docking.widgets.label.GLabel;
import ghidra.util.layout.HorizontalLayout;
/**
* A simple set of label and text fields to show the current time and allow for editing
*/
class Clock extends JPanel implements CaretListener {
private JLabel dateLabel = new GDLabel("Apr 18, 2006");
private JTextField hoursField;
private JTextField minutesField;
private JTextField secondsField;
private SimpleDateFormat formatter;
private DocumentListener docListener;
private boolean isEditing;
private JTextField currentEditField;
private int min;
private int max;
private int value;
private Color defaultBackgroundColor;
private static Color CURRENT_BACKGROUND_COLOR = new Color(204, 204, 255);
private JCalendar jCalendar;
/**
* Construct a new Clock.
* @param calendar JCalendar component that has the Calendar object being edited.
*/
Clock(JCalendar calendar) {
super(new HorizontalLayout(1));
this.jCalendar = calendar;
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
create();
}
@Override
public void caretUpdate(CaretEvent e) {
JTextField tf = (JTextField) e.getSource();
Document doc = tf.getDocument();
max = 59;
if (hoursField.getDocument() == doc) {
max = 23;
currentEditField = hoursField;
updateColors(minutesField);
updateColors(secondsField);
}
else if (minutesField.getDocument() == doc) {
currentEditField = minutesField;
updateColors(hoursField);
updateColors(secondsField);
}
else {
currentEditField = secondsField;
updateColors(hoursField);
updateColors(minutesField);
}
currentEditField.setBackground(CURRENT_BACKGROUND_COLOR);
}
/*
* Update the text fields that show the time.
*/
void update(Date date) {
if (isEditing) {
return;
}
removeDocumentListeners();
try {
String dateStr = formatter.format(date);
dateLabel.setText(getDate(dateStr) + " ");
hoursField.setText(getHours(dateStr));
minutesField.setText(getMinutes(dateStr));
secondsField.setText(getSeconds(dateStr));
}
finally {
addDocumentListeners();
}
if (currentEditField != null) {
setValue(Integer.parseInt(currentEditField.getText()), false);
}
}
private void create() {
hoursField = new JTextField(2);
minutesField = new JTextField(2);
secondsField = new JTextField(2);
hoursField.addCaretListener(this);
minutesField.addCaretListener(this);
secondsField.addCaretListener(this);
// junit access
hoursField.setName("Hours");
minutesField.setName("Minutes");
secondsField.setName("Seconds");
dateLabel.setName("DateString");
min = 0;
max = 60;
value = 0;
add(dateLabel);
add(hoursField);
add(new GLabel(":"));
add(minutesField);
add(new GLabel(":"));
add(secondsField);
formatter = new SimpleDateFormat("HH:mm:ss MMM dd, yyyy");
hoursField.setDocument(new TimeDocument(true));
minutesField.setDocument(new TimeDocument(false));
secondsField.setDocument(new TimeDocument(false));
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
update(date);
docListener = new DocumentListener() {
@Override
public void removeUpdate(DocumentEvent e) {
checkInput(e);
}
@Override
public void insertUpdate(DocumentEvent e) {
checkInput(e);
}
@Override
public void changedUpdate(DocumentEvent e) {
checkInput(e);
}
};
addDocumentListeners();
defaultBackgroundColor = hoursField.getBackground();
}
private void addDocumentListeners() {
hoursField.getDocument().addDocumentListener(docListener);
minutesField.getDocument().addDocumentListener(docListener);
secondsField.getDocument().addDocumentListener(docListener);
}
private void removeDocumentListeners() {
hoursField.getDocument().removeDocumentListener(docListener);
minutesField.getDocument().removeDocumentListener(docListener);
secondsField.getDocument().removeDocumentListener(docListener);
}
private void checkInput(DocumentEvent e) {
isEditing = true;
Calendar cal = jCalendar.getCalendar();
try {
int hourValue = Integer.parseInt(hoursField.getText());
int minutesValue = Integer.parseInt(minutesField.getText());
int secondsValue = Integer.parseInt(secondsField.getText());
if (hourValue >= 0 && hourValue <= 23 && minutesValue >= 0 && minutesValue <= 59 &&
secondsValue >= 0 && secondsValue <= 59) {
cal.set(Calendar.HOUR_OF_DAY, hourValue);
cal.set(Calendar.MINUTE, minutesValue);
cal.set(Calendar.SECOND, secondsValue);
}
}
catch (NumberFormatException exc) {
// this can happen for the empty string
}
finally {
isEditing = false;
}
}
private void updateColors(JTextField field) {
field.setBackground(defaultBackgroundColor);
}
private void setValue(int newValue, boolean updateTextField) {
if (newValue < min) {
value = min;
}
else if (newValue > max) {
value = max;
}
else {
value = newValue;
}
if (updateTextField) {
String str = Integer.toString(value);
if (str.length() < 2) {
str = "0" + str;
}
currentEditField.setText(str);
}
}
private String getHours(String dateStr) {
int pos = dateStr.indexOf(":");
return dateStr.substring(0, pos);
}
private String getMinutes(String dateStr) {
return dateStr.substring(3, 5);
}
private String getSeconds(String dateStr) {
return dateStr.substring(6, 8);
}
private String getDate(String dateStr) {
int pos = dateStr.indexOf(" ");
return dateStr.substring(pos + 1);
}
private class TimeDocument extends PlainDocument {
private boolean isHours;
TimeDocument(boolean isHours) {
super();
this.isHours = isHours;
}
@Override
public void insertString(int offs, String str, AttributeSet a) throws BadLocationException {
char[] source = str.toCharArray();
char[] result = new char[source.length];
int j = 0;
for (int i = 0; i < result.length; i++) {
if (Character.isDigit(source[i]) && isValidDigit(source[i])) {
result[j++] = source[i];
}
else {
Toolkit.getDefaultToolkit().beep();
}
String s = this.getText(0, getLength());
try {
if (s.length() > 0) {
if (offs == 0) {
s = str + s;
}
else {
s = s + str;
}
int numericValue = Integer.parseInt(s);
if (s.length() > 2 ||
(isHours && (numericValue < 0 || numericValue > 23)) ||
(!isHours && (numericValue < 0 || numericValue >= 60))) {
Toolkit.getDefaultToolkit().beep();
return;
}
}
}
catch (NumberFormatException e) {
Toolkit.getDefaultToolkit().beep();
return;
}
}
super.insertString(offs, new String(result, 0, j), a);
}
private boolean isValidDigit(char c) {
return c >= 0x30 && c <= 0x39;
}
}
}

View file

@ -15,23 +15,15 @@
*/
package docking.options.editor;
import java.awt.*;
import java.beans.*;
import java.awt.Component;
import java.beans.PropertyEditorSupport;
import java.text.*;
import java.util.Calendar;
import java.util.Date;
import javax.swing.*;
import com.toedter.calendar.JCalendar;
import docking.DialogComponentProvider;
import docking.DockingWindowManager;
/**
* Editor for date and time; creates a text field for the string version of the date, and
* a browse button to pop up the editor panel that contains a JCalendar to edit the date,
* and a separate component to edit the time.
* Non-editable Editor for date and time; creates a text field for the string version of the date.
*/
public class DateEditor extends PropertyEditorSupport {
@ -40,9 +32,7 @@ public class DateEditor extends PropertyEditorSupport {
private final static int NUMBER_OF_COLUMNS = 20;
private Date date;
private CalendarPanel calendarPanel;
private JTextField textField;
private EditDateDialog dialog;
private DateFormat dateFormat = DEFAULT_DATE_FORMAT;
public void setDateFormat(DateFormat format) {
@ -81,10 +71,6 @@ public class DateEditor extends PropertyEditorSupport {
this.date = (Date) value;
if (calendarPanel != null) {
calendarPanel.setDate(date);
}
if (textField != null) {
textField.setText(format(date));
}
@ -101,19 +87,6 @@ public class DateEditor extends PropertyEditorSupport {
}
}
private void displayCalendarEditor(Component parent) {
if (calendarPanel == null) {
calendarPanel = new CalendarPanel();
}
if (date != null) {
calendarPanel.setDate(date);
}
if (dialog == null) {
dialog = new EditDateDialog(parent);
}
DockingWindowManager.showDialog(parent, dialog);
}
private class DatePanel extends JPanel {
private JButton browseButton;
@ -123,101 +96,9 @@ public class DateEditor extends PropertyEditorSupport {
textField = new JTextField(NUMBER_OF_COLUMNS);
textField.setText(date != null ? format(date) : "");
textField.setEditable(false);
browseButton = ButtonPanelFactory.createButton(ButtonPanelFactory.BROWSE_TYPE);
Font f = browseButton.getFont();
f = new Font(f.getName(), Font.BOLD, f.getSize());
browseButton.setFont(f);
add(textField);
add(Box.createHorizontalStrut(5));
add(browseButton);
setBorder(BorderFactory.createEmptyBorder());
browseButton.addActionListener(e -> displayCalendarEditor(browseButton));
}
}
private class CalendarPanel extends JPanel implements PropertyChangeListener {
private JCalendar jcal;
private Clock clock;
// this formatter is just used for parsing dates for input into JCalendar
private SimpleDateFormat formatter;
CalendarPanel() {
super(new BorderLayout(0, 5));
setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5));
jcal = new JCalendar();
jcal.addPropertyChangeListener(this);
clock = new Clock(jcal);
add(jcal, BorderLayout.CENTER);
add(clock, BorderLayout.SOUTH);
formatter = new SimpleDateFormat("MM dd yyyy");
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
String propertyName = evt.getPropertyName();
if (propertyName == null || propertyName.equals("calendar")) {
Calendar newCal = (Calendar) evt.getNewValue();
Date newDate = newCal.getTime();
clock.update(newDate);
}
}
@Override
public Dimension getPreferredSize() {
return super.getPreferredSize();
}
void setDate(Date date) {
Calendar calendar = jcal.getCalendar();
Calendar c = (Calendar) calendar.clone();
//need the month,day, year from the date
String dateString = formatter.format(date);
int month = Integer.parseInt(dateString.substring(0, 2));
int day = Integer.parseInt(dateString.substring(3, 5));
int year = Integer.parseInt(dateString.substring(6));
c.set(Calendar.MONTH, month);
c.set(Calendar.DAY_OF_WEEK, day);
c.set(Calendar.YEAR, year);
c.setTime(date);
jcal.setCalendar(c);
clock.update(date);
}
}
private class EditDateDialog extends DialogComponentProvider {
EditDateDialog(Component parent) {
super("Edit Date", true);
JPanel dialogPanel = new JPanel();
dialogPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
dialogPanel.setLayout(new BorderLayout());
dialogPanel.add(calendarPanel, BorderLayout.CENTER);
addWorkPanel(dialogPanel);
addOKButton();
addCancelButton();
}
/**
* Gets called when the user clicks on the OK Action for the dialog.
*/
@Override
protected void okCallback() {
Date newDate = calendarPanel.jcal.getCalendar().getTime();
DateEditor.this.setValue(newDate);
DateEditor.this.firePropertyChange();
close();
}
@Override
protected void cancelCallback() {
close();
}
}
}