| Day Planner Applicarion |
TABLE OF CONTENTS
<!-- Fig. 6.14: planner.dtd -->
<!-- DTD for day planner -->
<!ELEMENT planner ( year* )>
<!ELEMENT year ( date+ )>
<!ATTLIST year value CDATA #REQUIRED>
<!ELEMENT date ( note+ )>
<!ATTLIST date month CDATA #REQUIRED>
<!ATTLIST date day CDATA #REQUIRED>
<!ELEMENT note ( #PCDATA )>
<!ATTLIST note time CDATA #IMPLIED>
<?xml version = "1.0"?>
<!-- Travel Planner XML document -->
<!DOCTYPE planner SYSTEM "planner.dtd">
<planner>
<year value = "2001">
<date month = "12" day = "22">
<note time = "0630">Go to airport </note>
<note time = "0930">Catch flight to Vancouver </note>
</date>
</year>
<year value = "2002">
<date month = "1" day = "3">
<note time = "1430">Catch flight to Washington DC </note>
</date>
<date month = "1" day = "8">
<note time = "0830">Leave Washington DC for New Zealand </note>
</date>
<date month = "1" day = "10">
<note time = "0800">Arrive in Auckland, New Zealand </note>
<note time = "1130">Arrive in Queenstown, New Zealand </note>
</date>
<date month = "1" day = "22">
<note time = "1700">Leave Queenstown for Washington DC </note>
<note time = "1200">Meet Jim at LAX for a drink </note>
<note time = "2000">Arrive back in Washington DC </note>
</date>
<date month = "3" day = "22">
<note time = "2030"> Leave Washington DC for Sweden </note>
</date>
<date month = "3" day = "30">
<note time = "0800"> Leave Copenhagen for Washington DC </note>
</date>
</year>
</planner>
/*
* ===========================================================================
* DayPlanner.java: Program for GUI interface for the day planner application.
*
* Code developed by Deitel and Deitel, 2000.
* Code slightly modified for JAXP: By Mark Austin March, 2002
* ===========================================================================
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
public class DayPlanner extends JFrame implements ActionListener {
// GUI components
private JTextArea display;
private JComboBox year, month, day, time;
private JButton query;
private JPanel panel1, panel2;
private DOMPlanner handler;
public DayPlanner() {
super( "DOM-Based Travel Planner" );
// Set the output font
Font font = new Font( "Monospaced", java.awt.Font.BOLD, 16 );
display = new JTextArea();
display.setFont( font );
display.setEditable( false );
handler = new DOMPlanner( display );
// Initialize the user interface components
year = new JComboBox( handler.getYears() );
String months[] = new String[ 13 ];
months[ 0 ] = "ANY";
for ( int i = 1; i < 13; i++ )
months[ i ] = Integer.toString( i );
month = new JComboBox( months );
String days[] = new String[ 32 ];
days[ 0 ] = "ANY";
for ( int i = 1; i < 32; i++ )
days[ i ] = Integer.toString( i );
day = new JComboBox( days );
String times[] = { "ANY",
"Morning",
"Afternoon",
"Evening",
"Night" };
time = new JComboBox( times );
// Create "Get Schedules" button and attach listener.
query = new JButton( "Get Schedules" );
query.addActionListener( this );
// Panel containing components for querying
panel1 = new JPanel();
panel1.setLayout( new GridLayout( 4, 2 ) );
panel1.add( new JLabel( "Year" ) );
panel1.add( year );
panel1.add( new JLabel( "Month" ) );
panel1.add( month );
panel1.add( new JLabel( "Day" ) );
panel1.add( day );
panel1.add( new JLabel("Time") );
panel1.add( time );
// Panel containing text area for output
// and panel2 containing other GUI components.
panel2 = new JPanel();
panel2.setLayout( new GridLayout( 1, 2 ) );
panel2.add( panel1 );
panel2.add( query );
// Arrange panels on content pane using border layout.....
Container c = getContentPane();
c.setLayout( new BorderLayout() );
c.add( new JScrollPane( display ), BorderLayout.CENTER );
c.add( panel2, BorderLayout.SOUTH );
// Size and display frame....
setSize( 700, 450 );
show();
}
// Method executed when query button is pressed
public void actionPerformed( ActionEvent e ) {
if ( e.getSource() == query ) {
int yearIndex, monthIndex, dayIndex, timeIndex;
// Get the integer values of all the query parameters
yearIndex = getIntegerValue( ( String ) year.getSelectedItem() );
monthIndex = getIntegerValue( ( String ) month.getSelectedItem() );
dayIndex = getIntegerValue( ( String ) day.getSelectedItem() );
timeIndex = time.getSelectedIndex() - 1;
// Get the result of query
handler.getQueryResult( yearIndex, monthIndex,
dayIndex, timeIndex );
}
}
// Method to convert the string value to integer
public int getIntegerValue( String str ) {
// If the value 'ANY' is selected, return -1
if ( str.equals( "ANY" ) )
return -1;
else
return Integer.parseInt( str );
}
// Main method for Day Planner application.....
public static void main( String s[] ) {
// Create instance of DayPlanner().....
DayPlanner d = new DayPlanner();
// Setup (inner class) listener to close window.....
d.addWindowListener(
new WindowAdapter() {
public void windowClosing( WindowEvent e ) {
System.exit( 0 );
}
}
);
}
}
/*
* ===========================================================================
* DOMPlanner.java: A day planner application using DOM.
*
* Code developed by Deitel and Deitel, 2000.
* Code slightly modified for JAXP: By Mark Austin March, 2002
* ===========================================================================
*/
import java.io.*;
import java.awt.*;
import java.util.*;
import javax.swing.*;
import org.w3c.dom.*;
import org.xml.sax.*;
import javax.xml.parsers.*;
public class DOMPlanner {
private JTextArea display; // for displaying output
private InputSource input; // for reading the XML document
private Document document; // document node object
// Variables to store the query parameters and the result
private int year, month, day, timePeriod;
private String resultYear, resultDay;
public DOMPlanner( JTextArea output ) {
year = month = day = timePeriod = -1;
display = output;
try {
// Obtain the default parser
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setValidating( true );
DocumentBuilder builder = factory.newDocumentBuilder();
// Set error handler for validation errors
builder.setErrorHandler( new MyErrorHandler() );
// Obtain Document Object from XML Document
document = builder.parse( new File( "planner.xml" ) );
}
// Catch errors .....
catch ( SAXParseException spe ) {
System.err.println( "Parse error: " +
spe.getMessage() );
System.exit( 1 );
}
catch ( SAXException se ) {
se.printStackTrace();
}
catch ( FileNotFoundException fne ) {
System.err.println( "File \"planner.xml\" not found." );
System.exit( 1 );
}
catch ( Exception e ) {
e.printStackTrace();
}
}
// Method to get the available years from the XML file
public String[] getYears() {
String availableYears[];
StringTokenizer tokens;
String str = " ";
int i = 0;
Element root = document.getDocumentElement();
NodeList yearNodes = root.getElementsByTagName( "year" );
// Get value of attribute 'value' for each 'year' node
for ( i = 0; i < yearNodes.getLength(); i++ ) {
NamedNodeMap yearAttributes = yearNodes.item(i).getAttributes();
str += " " + yearAttributes.item( 0 ).getNodeValue();
}
tokens = new StringTokenizer( str );
availableYears = new String[ tokens.countTokens() + 1 ];
availableYears[ 0 ] = "ANY";
i = 1;
// Form an array of strings containing available years
while ( tokens.hasMoreTokens() )
availableYears[ i++ ] = tokens.nextToken();
return availableYears;
}
// method to initialize the query
public void getQueryResult( int y, int m, int d, int t ) {
year = y;
month = m;
day = d;
resultYear = "";
resultDay = "";
timePeriod = t;
display.setText( "*** Mark Austin's Travel Planner ***" );
getResult( document );
}
// Method to output the result of query
public void getResult( Node node ) {
// Recursively process each type of node...
switch ( node.getNodeType() ) {
// If it is a Document node process its children
case Node.DOCUMENT_NODE:
Document doc = ( Document ) node;
getResult( doc.getDocumentElement() );
break;
// Process element node according to its tag name
case Node.ELEMENT_NODE:
if ( node.getNodeName().equals( "planner" ) )
processChildNodes( node.getChildNodes() );
else if ( node.getNodeName().equals( "year" ) ) {
// find the attribute value for year and
// check if it matches the query
NamedNodeMap yearAttributes = node.getAttributes();
Node value = yearAttributes.item( 0 );
if ( Integer.parseInt( value.getNodeValue() ) == year || year == -1 ) {
resultYear = " Y " + Integer.parseInt( value.getNodeValue() );
processChildNodes( node.getChildNodes() );
} else
return;
} else if ( node.getNodeName().equals( "date" ) ) {
Element dateElement = ( Element ) node;
int m = Integer.parseInt( dateElement.getAttribute( "month" ) );
int d = Integer.parseInt( dateElement.getAttribute( "day" ) );
// Check if the current 'date' node satisfies query
if ( ( m == month && d == day ) || ( month == -1 && d == day ) ||
( m == month && day == -1 ) || ( month == -1 && day == -1 ) ) {
resultDay = "DATE: D " + d + " M " + m ;
processChildNodes( dateElement.getChildNodes() );
} else
return;
} else if ( node.getNodeName().equals( "note" ) ) {
// Fetch attributes for the note node and
// verify its attribute values with the query
NamedNodeMap noteAttributes = node.getAttributes();
int scheduleTime;
if ( noteAttributes.getLength() != 0 ) {
Node nodeTime = noteAttributes.item( 0 );
scheduleTime = Integer.parseInt( nodeTime.getNodeValue() );
} else
scheduleTime = -1;
// If the time lies between the periods of the
// day display the value of node 'note'
if ( isBetween( scheduleTime ) ) {
Node child = ( node.getChildNodes() ).item( 0 );
String s = child.getNodeValue().trim();
display.append( "\n" + resultDay + resultYear );
if ( scheduleTime != -1 )
display.append( "\nTIME: " + scheduleTime +" > " + s );
else
display.append( "\nALL DAY > " + s );
display.append( "\n* * * * * * * * * *" );
} else
return;
}
break;
}
}
// Method to process child nodes
public void processChildNodes( NodeList children ) {
if ( children.getLength() != 0 )
for ( int i = 0; i < children.getLength(); i++ )
getResult( children.item( i ) );
return;
}
// Method to compare the time with various periods of the day
public boolean isBetween( int time ) {
switch ( timePeriod ) {
case -1: // add day
return true;
case 0: // morning
if ( time >= 500 && time < 1200 )
return true;
break;
case 1: // afternoon
if ( time >= 1200 && time < 1800 )
return true;
break;
case 2: // evening
if ( time >= 1800 && time < 2100 )
return true;
break;
case 3: // night
if ( time >= 2100 || time < 500 )
return true;
break;
default:
System.out.println( "Illegal time in XML file" );
}
return false;
}
}
/*
* ===========================================================================
* MyErrorHandler.java: Error Handler for validation errors.
*
* Code developed by Deitel and Deitel. 2000.
* ===========================================================================
*/
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
public class MyErrorHandler implements ErrorHandler {
// Throw SAX Exception for fatal errors
public void fatalError( SAXParseException exception ) throws SAXException {
throw exception;
}
public void error( SAXParseException e ) throws SAXParseException {
throw e;
}
// Print any warnings
public void warning( SAXParseException err ) throws SAXParseException {
System.err.println( "Warning: " + err.getMessage() );
}
}
Developed in April 2002 by Mark Austin
Copyright © 2002, Mark Austin, University of Maryland