// (c) 2003 Allen I Holub. All rights reserved. package com.holub.ui.HTML; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.URL; import java.util.Properties; import java.io.IOException; /** * A modal dialog that holds an {@link HTMLPane}. The dialog shuts * down when the user hits a button created by either an * <input type=submit> or (HTMLPane-specific) * <inputAction > tag. * Display the dialog by calling <code>show()</code>. * For example: * <PRE> * HTMLDialog d = new HTMLDialog( owner, * "com/holub/ui/HTML/test/okay.html", * "Test HTMLDialog" ); * if( d.popup() ) // Dialog not cancelled * d.data().list( System.out ); * </PRE> * The <a href="HTMLPane.html#customTags">default custom tags</a> * are all preinstalled in the underlying * {@link HTMLPane}. * * <!-- ====================== distribution terms ===================== --> * <p><blockquote * style="border-style: solid; border-width:thin; padding: 1em 1em 1em 1em;"> * <center> * Copyright © 2003, Allen I. Holub. All rights reserved. * </center> * <br> * <br> * This code is distributed under the terms of the * <a href="http://www.gnu.org/licenses/gpl.html" * >GNU Public License</a> (GPL) * with the following ammendment to section 2.c: * <p> * As a requirement for distributing this code, your splash screen, * about box, or equivalent must include an my name, copyright, * <em>and URL</em>. An acceptable message would be: * <center> * This program contains Allen Holub's <em>XXX</em> utility.<br> * (c) 2003 Allen I. Holub. All Rights Reserved.<br> * http://www.holub.com<br> * </center> * If your progam does not run interactively, then the foregoing * notice must appear in your documentation. * </blockquote> * <!-- =============================================================== --> * @author Allen I. Holub */ public class HTMLDialog extends JDialog { private Properties data = null; private final HTMLPane pane = new HTMLPane(true); /** Create and initialize a modal HTMLPane. * @param owner The Frame that "owns" this dialog (the parent). * @param htmlPath The CLASSPATH-relative path to the .html file * that holds the contents. For example, if CLASSPATH * contains the directory /usr/src, then get the * file in /usr/src/html/test.html by specifying * <code>"html/test.html"</code> (no leading slash). * @param title Dialog-box title-bar contents. * @throws IOException if it can't open the file on the htmlPath; */ public HTMLDialog( Frame owner, String htmlPath, String title ) throws IOException { super( owner, title, true /*it's modal*/ ); // Set up an action listener that handles the form // submission. [actionPerformed() is called when the // user hits Submit or Cancel. pane.addActionListener //{=HTMLDialog.listener} ( new ActionListener() { public void actionPerformed(ActionEvent event ) { HTMLDialog.this.setVisible(false); HTMLDialog.this.dispose(); data = ((HTMLPane.FormActionEvent)event).data(); } } ); // Load the input file from a CLASSPATH-relative directory // specified in the htmlPath argument, then import it into // the HTMLDialog for display. URL loadFrom = getClass().getClassLoader().getResource(htmlPath); if( loadFrom == null ) { throw new IOException("Can't find $CLASSPATH/" + htmlPath ); } pane.setPage( loadFrom ); // {=HTMLDialog.load} getContentPane().add( pane ); pack(); } /** Get a {@link java.util.Properties} object that holds the * data provided by the <input> elements on the form * (or equivalent). The key is the element "name," the value * is either the value specified in the attribute or the * data the user typed. * * @return the form data * @throws java.lang.IllegalStateException if you try to call this * method before the user submits the form. This can only * happen if <code>data()</code> is called from a thread * other than the one that issued the <code>popup()</code> * request (which blocks). */ public Properties data() { if( data == null ) throw new java.lang.IllegalStateException( "Tried to access data before form was submitted"); return data; } /** Add custom-tag processing to this dialog. Passes arguments through * to a contained HTMLPane's {@link HTMLPane#addTag addTag(...)} method. * A few out-of-the-box custom tags are already implemented for you * (see {#link HTMLPane}). * * @param tag * @param handler */ public void addTag( String tag, TagHandler handler ) { pane.addTag(tag,handler); } /** Works just like {@link JFrame#show}, but returns true if the * dialog was closed with a normal close button. Returns false if * the user submitted the dialog by pressing a button specified with * the tag * <PRE> * <inputAction name=cancel ... > * </PRE> * (<a href=HTMLPane.java#inputAction>See</a>) * or just closed the dialog by clicking the "close" icon. */ public boolean popup() { show(); if( data == null ) // dialog aborted with "close" icon return false; // treat it like a cancel. String cancel = data.getProperty("cancel"); if( cancel == null ) // no cancel button return true; return !cancel.equals("true"); // true ==> cancel button pressed, // so return false } static private class Test { public static void main( String[] args ) throws Exception { JFrame owner = new JFrame(); owner.getContentPane().add( new JLabel("Parent Frame") ); owner.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); owner.pack(); owner.show(); HTMLDialog d = new HTMLDialog(owner, "com/holub/ui/HTML/test/okay.html", "Test HTMLDialog"); if( d.popup() ) System.out.println("OK Pressed"); else System.out.println("Cancel Pressed"); d.data().list( System.out ); } } }