blob: ae8bbd4f62adc172a2a6c11df8b7097dceb32497 [file] [log] [blame]
/*
* Copyright 2001-2005 Stephen Colebourne
*
* 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 org.joda.example.time;
import java.awt.Component;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.Timer;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.text.Document;
import org.joda.time.Chronology;
import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.DurationField;
import org.joda.time.chrono.ISOChronology;
/**
* AgeCalculator is a small Swing application that computes age from a specific
* birthdate and time zone. Age is broken down into multiple fields, which can
* be independently disabled.
*
* @author Brian S O'Neill
*/
public class AgeCalculator extends JFrame {
static final int
YEARS = 1,
MONTHS = 2,
DAYS = 3,
WEEKYEARS = 4,
WEEKS = 5,
HOURS = 101,
MINUTES = 102,
SECONDS = 103;
public static void main(String[] args) throws Exception {
new AgeCalculator().show();
}
static JComponent fixedSize(JComponent component) {
component.setMaximumSize(component.getPreferredSize());
return component;
}
static JComponent fixedHeight(JComponent component) {
Dimension dim = component.getMaximumSize();
dim.height = component.getPreferredSize().height;
component.setMaximumSize(dim);
return component;
}
Chronology iChronology;
private String iBirthdateStr;
private FieldSet[] iFieldSets;
private Timer iTimer;
public AgeCalculator() {
super();
iChronology = ISOChronology.getInstance();
iBirthdateStr = "1970-01-01T00:00:00";
setTitle("Age Calculator");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addMainArea(getContentPane());
addNotify();
Dimension size = getPreferredSize();
setSize(size);
Dimension screenSize = getToolkit().getScreenSize();
setLocation(screenSize.width / 2 - size.width / 2,
screenSize.height / 2 - size.height / 2);
iTimer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent e) {
updateResults();
}
});
iTimer.setInitialDelay(0);
iTimer.start();
}
private void addMainArea(Container container) {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
addTopArea(panel);
panel.add(Box.createVerticalStrut(10));
addBottomArea(panel);
panel.add(Box.createVerticalGlue());
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
container.add(panel);
}
private void addTopArea(Container container) {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
panel.add(fixedHeight(new JLabel("Birthdate")));
panel.add(Box.createHorizontalStrut(10));
final JTextField birthdateField = new JTextField(iBirthdateStr + ' ');
Document doc = birthdateField.getDocument();
doc.addDocumentListener(new DocumentListener() {
public void insertUpdate(DocumentEvent e) {
update(e);
}
public void removeUpdate(DocumentEvent e) {
update(e);
}
public void changedUpdate(DocumentEvent e) {
update(e);
}
private void update(DocumentEvent e) {
iBirthdateStr = birthdateField.getText();
updateResults();
}
});
panel.add(fixedHeight(birthdateField));
panel.add(Box.createHorizontalStrut(10));
Object[] ids = DateTimeZone.getAvailableIDs().toArray();
final JComboBox zoneSelector = new JComboBox(ids);
zoneSelector.setSelectedItem(DateTimeZone.getDefault().getID());
panel.add(fixedSize(zoneSelector));
zoneSelector.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
String id = (String)zoneSelector.getSelectedItem();
iChronology = ISOChronology.getInstance(DateTimeZone.forID(id));
updateResults();
}
});
container.add(fixedHeight(panel));
}
private void addBottomArea(Container container) {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
ItemListener listener = new ItemListener() {
public void itemStateChanged(ItemEvent e) {
updateResults();
}
};
iFieldSets = new FieldSet[] {
new FieldSet("Month Based", new FieldGroup[] {
new FieldGroup(listener, "Years", YEARS),
new FieldGroup(listener, "Months", MONTHS),
new FieldGroup(listener, "Days", DAYS),
new FieldGroup(listener, "Hours", HOURS),
new FieldGroup(listener, "Minutes", MINUTES),
new FieldGroup(listener, "Seconds", SECONDS)
})
,
new FieldSet("Week Based", new FieldGroup[] {
new FieldGroup(listener, "Weekyears", WEEKYEARS),
new FieldGroup(listener, "Weeks", WEEKS),
new FieldGroup(listener, "Days", DAYS),
new FieldGroup(listener, "Hours", HOURS),
new FieldGroup(listener, "Minutes", MINUTES),
new FieldGroup(listener, "Seconds", SECONDS)
})
};
for (int i=0; i<iFieldSets.length; i++) {
if (i > 0) {
panel.add(Box.createHorizontalStrut(10));
}
iFieldSets[i].addTo(panel);
}
panel.add(Box.createVerticalGlue());
container.add(fixedHeight(panel));
}
private void updateResults() {
try {
DateTime dt = new DateTime(iBirthdateStr.trim(), iChronology);
long minuend = System.currentTimeMillis();
long subtrahend = dt.getMillis();
for (int i=0; i<iFieldSets.length; i++) {
iFieldSets[i].updateResults(minuend, subtrahend);
}
}
catch (IllegalArgumentException e) {
for (int i=0; i<iFieldSets.length; i++) {
iFieldSets[i].setResultsText("");
}
}
}
private class FieldGroup {
public final JCheckBox iCheckbox;
public final JTextField iResult;
public final int iFieldType;
FieldGroup(ItemListener listener, String checkboxText, int fieldType) {
iCheckbox = new JCheckBox(checkboxText, true);
iCheckbox.addItemListener(listener);
iResult = new JTextField();
iResult.setEditable(false);
iFieldType = fieldType;
}
public long updateResult(long minuend, long subtrahend) {
// Because time zone can be dynamically changed, field must be
// dynamically acquired.
DurationField field;
switch (iFieldType) {
case YEARS:
field = iChronology.years();
break;
case MONTHS:
field = iChronology.months();
break;
case DAYS:
field = iChronology.days();
break;
case WEEKYEARS:
field = iChronology.weekyears();
break;
case WEEKS:
field = iChronology.weeks();
break;
case HOURS:
field = iChronology.hours();
break;
case MINUTES:
field = iChronology.minutes();
break;
case SECONDS: default:
field = iChronology.seconds();
break;
}
String textToSet = "";
if (iCheckbox.isSelected()) {
long difference = field.getDifferenceAsLong(minuend, subtrahend);
textToSet = Long.toString(difference);
subtrahend = field.add(subtrahend, difference);
}
if (!iResult.getText().equals(textToSet)) {
iResult.setText(textToSet);
}
return subtrahend;
}
public void setResultText(String text) {
iResult.setText(text);
}
}
private static class FieldSet {
private final String iTitle;
private final FieldGroup[] iGroups;
FieldSet(String title, FieldGroup[] groups) {
iTitle = title;
iGroups = groups;
}
private long updateResults(long minuend, long subtrahend) {
for (int i=0; i<iGroups.length; i++) {
subtrahend = iGroups[i].updateResult(minuend, subtrahend);
}
return subtrahend;
}
public void setResultsText(String text) {
for (int i=0; i<iGroups.length; i++) {
iGroups[i].setResultText(text);
}
}
private void addTo(Container container) {
JPanel panel = new JPanel();
GridBagLayout layout = new GridBagLayout();
panel.setLayout(layout);
panel.setBorder(BorderFactory.createTitledBorder(iTitle));
for (int i=0; i<iGroups.length; i++) {
FieldGroup fg = iGroups[i];
panel.add(fg.iCheckbox);
setCheckboxConstraints(layout, fg.iCheckbox, 0, i);
panel.add(fg.iResult);
setResultConstraints(layout, fg.iResult, 1, i);
}
container.add(fixedHeight(panel));
}
private void setCheckboxConstraints(GridBagLayout layout, Component c,
int x, int y)
{
GridBagConstraints cons = new GridBagConstraints();
cons.gridx = x;
cons.gridy = y;
cons.weightx = 0.1;
cons.anchor = GridBagConstraints.WEST;
layout.setConstraints(c, cons);
}
private void setResultConstraints(GridBagLayout layout, Component c,
int x, int y)
{
GridBagConstraints cons = new GridBagConstraints();
cons.gridx = x;
cons.gridy = y;
cons.weightx = 1.0;
cons.anchor = GridBagConstraints.WEST;
cons.fill = GridBagConstraints.HORIZONTAL;
layout.setConstraints(c, cons);
}
}
}