Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: jpl2/common/gui/JPLToolkit.java


1   /***********************************************************************
2    *   JavaPsionLink 2.0, a java implementation of the psion link protocol
3    *   Copyright (C) 2002, 2003  John S Montgomery (john.montgomery@lineone.net)
4    *
5    *   This program is free software; you can redistribute it and/or modify
6    *   it under the terms of the GNU Lesser General Public License as published by
7    *   the Free Software Foundation; either version 2.1 of the License, or
8    *   (at your option) any later version.
9    *
10   *   This program is distributed in the hope that it will be useful,
11   *   but WITHOUT ANY WARRANTY; without even the implied warranty of
12   *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   *   GNU Lesser General Public License for more details.
14   *
15   *   You should have received a copy of the GNU General Public License
16   *   along with this program; if not, write to the Free Software
17   *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18   ************************************************************************/
19  package jpl2.common.gui;
20  
21  import jpl2.PsionLink;
22  import jpl2.link.gui.DragAndDrop;
23  import jpl2.link.gui.Images;
24  import jpl2.link.gui.PsionBrowserPane;
25  import jpl2.common.Preference;
26  
27  import java.awt.*;
28  import java.awt.event.*;
29  import java.io.File;
30  import java.util.ResourceBundle;
31  import java.util.MissingResourceException;
32  import java.text.MessageFormat;
33  import java.lang.reflect.*;
34  
35  
36  /** A class for allowig the use of AWT or Swing, without needing to now 
37   *  the difference.  This is so that under MacOS 9 we shall use AWT and have 
38   *  a native look and feel and under Linux we shall use swing and have the
39   *  native look and feel too.  Bizarre tho it sounds!
40   **/
41  
42  public abstract class JPLToolkit {
43    private static JPLToolkit tk = null;
44    private static ResourceBundle resources = null;
45    private static Preference prefs = new Preference( ".jpl", "Java Psion Link 2.0 preference file" );
46    private boolean queryResult = false;
47    private String  multipleQueryResult = null;
48    private Dialog  dialog = null;
49    
50    public static Preference getPreferences() {
51      return prefs;
52    }
53    
54    public static ResourceBundle getResourceBundle() {
55      if ( resources == null ) {
56        try {
57          resources = ResourceBundle.getBundle( "jplres" );
58        }
59        catch( Exception e ) {
60          e.printStackTrace();
61        }
62      }
63      return resources;
64    }
65    
66    public static String getResourceString( String key ) {
67      if ( key.startsWith( "@res:" ) ) {
68        key = key.substring( "@res:".length() );  
69        try {
70          return getResourceBundle().getString( key );
71        }
72        catch( MissingResourceException mre ) {
73          //if ( PsionLink.DEBUG )
74          System.err.println( "no resource/translation for: " + key );
75        }
76      }
77      
78      return key;
79    }
80    
81    public static String getResourceString( String key, Object[] params ) {
82      String str = getResourceString( key );
83      return MessageFormat.format( str, params );
84    }
85    
86    public static JPLToolkit getToolkit() {
87      if ( tk == null ) {
88        try {
89          if ( prefs.getPreference( "use_swing", true ) ) {
90            Class clazz = Class.forName( "jpl2.common.gui.SwingToolkit" );
91            tk = (JPLToolkit)clazz.newInstance();
92          }
93        }
94        catch( Throwable t ) {
95        }
96        if ( tk == null )
97          tk = new AWTToolkit();
98      }
99      return tk;
100   }
101   
102   public static boolean isSwingToolkitAvailable() {
103     try {
104       Class clazz = Class.forName( "jpl2.common.gui.SwingToolkit" );
105       return true;
106     }
107     catch( Throwable t ) {
108     }
109     return false;
110   }
111   
112   private boolean installDragAndDrop( String className, PsionLink link, PsionBrowserPane browserPane ) {
113     try {
114       Class clazz = Class.forName( className );
115       DragAndDrop dnd = (DragAndDrop)clazz.newInstance();
116       dnd.install( link, browserPane );
117       //System.out.println( "Installed: " + className );
118       return true;
119     }
120     catch( Throwable t ) {
121       //t.printStackTrace();
122       
123     }
124     return false;
125   }
126   
127   public void installDragAndDrop( PsionLink link, PsionBrowserPane browserPane ) {
128     if ( !installDragAndDrop( "jpl2.link.gui.JavaDragAndDrop", link, browserPane ) ) {
129       installDragAndDrop( "jpl2.link.gui.MacDragAndDrop", link, browserPane );
130     }
131   }
132   
133   /** Get a list of installed fonts.
134    **/
135   public String[] getFonts() {
136     // see if we have access to the GraphicsEnvironment class
137     // to find out about fonts, or use the old way of doing things
138     try {
139       Class geClass = Class.forName( "java.awt.GraphicsEnvironment" );
140       // get the class and find the method getLocalGraphicsEnvironment()
141       Method getLGE = geClass.getDeclaredMethod( "getLocalGraphicsEnvironment", new Class[ 0 ] );
142       // static method, so no object needed
143       Object lge    = getLGE.invoke( null, new Object[ 0 ] );
144       if ( PsionLink.DEBUG )
145         System.out.println( lge );
146         
147       // get the method getAvailableFontFamilyNames()
148       Method getFontNames = geClass.getDeclaredMethod( "getAvailableFontFamilyNames", new Class[ 0 ] );
149       Object fontNames = getFontNames.invoke( lge, new Object[ 0 ] );
150       
151       if ( PsionLink.DEBUG )
152         System.out.println( "using getAvailableFontFamilyNames()" );
153       return (String[])fontNames;
154     }
155     catch( Throwable t ) {
156       if ( PsionLink.DEBUG )
157         t.printStackTrace();
158     }
159     try {
160       // this seems to sometimes throw an exception
161       // on some systems (probably because it has been
162       // deprecated)
163       return Toolkit.getDefaultToolkit().getFontList();
164     }
165     catch( Throwable t ) {
166       if ( PsionLink.DEBUG )
167         t.printStackTrace();
168     }
169     return new String[] {
170       "Serif", "SansSerif", "Monospaced"
171     };
172   }
173   
174   /** Attempt to set the modification date on a file.
175    *  Returns true if date was changed.
176    **/
177   public static boolean setFileLastModified( File file, long modified ) {
178     // try 1.2+ way
179     try {
180       Class clazz = File.class;
181       Method method = clazz.getDeclaredMethod( "setLastModified", new Class[] { Long.TYPE } );
182       Object res    = method.invoke( file, new Object[] { new Long( modified ) } );
183       return res.equals( Boolean.TRUE );
184     }
185     catch( Throwable t ) {
186     }
187     
188     // try using MRJ
189     try {
190       Class clazz = Class.forName( "com.apple.mrj.MRJFileUtils" );
191       Method method = clazz.getDeclaredMethod( "setFileLastModified", new Class[] { java.io.File.class, Long.TYPE } );
192       Object res    = method.invoke( null, new Object[] { file, new Long( modified ) } );
193       return res.equals( Boolean.TRUE );
194     }
195     catch( Throwable t ) {
196     }
197     return false;
198   }
199   
200   /** Attempt to make a temporary file (which will hopefully be deleted at exit).
201    *  Returns null if this system does not support the creation of temporary files.
202    **/
203   public static File createTemporaryFile( String prefix, String suffix ) {
204     // try 1.2+ way
205     try {
206       Class clazz = File.class;
207       Method method = clazz.getDeclaredMethod( "createTempFile", new Class[] { String.class, String.class } );
208       Object file   = method.invoke( null, new Object[] { prefix, "." + suffix } );
209       method        = clazz.getDeclaredMethod( "deleteOnExit", new Class[ 0 ] );
210       method.invoke( file, new Object[ 0 ] );
211       return (File)file;
212     }
213     catch( Throwable t ) {
214     }
215     
216     // else do it the MRJ way
217     File parentDir = null;
218     
219     try {
220       Class clazz = Class.forName( "com.apple.mrj.MRJFileUtils" );
221       Field field = clazz.getDeclaredField( "kTemporaryFolderType" );
222       // static field
223       Object mrjOsType = field.get( null );
224       Method method = clazz.getDeclaredMethod( "findFolder", new Class[] { Class.forName( "com.apple.mrj.MRJOSType" ) } );
225       parentDir = (File)method.invoke( null, new Object[] { mrjOsType } );
226       //"findFolder( MRJOSType )"
227       
228     }
229     catch( Throwable t ) {
230     }
231     
232     if ( parentDir != null ) {
233       // attempt file name as is
234       int num = -1;
235       File file = null;
236       // overwrite file
237       //do {
238         String name = prefix + ((num != -1)? Integer.toHexString( num ):"") + ((suffix != null)? "."+suffix:"");
239         file = new File( parentDir, name );
240         num++;
241       //}
242       //while( file.exists() );
243       return file;
244     }
245     return null;
246   }
247   
248   /**
249    * Try to see if the file is hidden or not.
250    * @param file
251    * @return
252    */
253   public static boolean isHiddenFile( File file ) {
254     //    try 1.2+ way
255     try {
256       Class clazz = File.class;
257       Method method = clazz.getDeclaredMethod( "isHidden", new Class[] {} );
258       Object result   = method.invoke( file, new Object[ 0 ] );
259       return result.equals( Boolean.TRUE );
260     }
261     catch( Throwable t ) {
262     }
263     // otherwise assume it's not hidden
264     return false;
265   }
266   
267   /** Returns either a java.awt.Frame or a javax.swing.JFrame
268    **/
269   public Frame makeFrame( String title ) {
270     Frame frame = makeFrameImp();
271     frame.setIconImage( Images.getImage( "icon.gif" ) );
272     frame.setTitle( getResourceString( title ) );
273     return frame;
274   }
275   
276   protected abstract Frame makeFrameImp();
277   
278   /** Returns either a java.awt.Dialog or a javax.swing.JDialog
279    **/
280   public Dialog makeDialog( Frame parent, String title, boolean modal ) {
281     Dialog dialog = makeDialogImp( parent, modal );
282     dialog.setTitle( getResourceString( title ) );
283     return dialog;
284   }
285   
286   protected abstract Dialog makeDialogImp( Frame parent, boolean modal );
287   
288   /** Adds a component to a window.  In the case of swing getContentPane() must be used.
289    **/
290   public abstract void add( Window w, Component c );
291   
292   /** Adds a component to a window.  In the case of swing getContentPane() must be used.
293    **/
294   public abstract void add( Window w, Component c, Object constraints );
295   
296   /** Sets a layout for a window.  In the case of swing getContentPane() must be used.
297    **/
298   public abstract void setLayout( Window w, LayoutManager l );
299   
300   /** Returns either a java.awt.Panel or a javax.swing.JPanel.
301    **/
302   public abstract Container makePanel();
303   
304   /** Returns either a java.awt.Panel or a javax.swing.JPanel.
305    **/
306   public Container makeGroupPanel( String title ) {
307     return makeGroupPanelImp( getResourceString( title ) );
308   }
309   
310   protected abstract Container makeGroupPanelImp( String title );
311   
312   /** Returns either a java.awt.Button or a javax.swing.JButton.
313    **/
314   public Component makeButton( String text, String action, ActionListener listener ) {
315     return makeButtonImp( getResourceString( text ), action, listener );
316   }
317 
318   protected abstract Component makeButtonImp( String text, String action, ActionListener listener );
319   
320   /** Make the button the default on a dialog.
321    **/
322   public abstract void setDefaultButton( Dialog dialog, Component button );
323   
324   /** Make the button the "cancel" button on a dialog. ie the button
325    *  which dismisses the dialog without takign any action.
326    **/
327   public abstract void setCancelButton( Dialog dialog, Component button );
328   
329   /** Associate a key press with the button.  ie so a key can be pressed instead of
330    *  using the mouse to press the button.
331    **/
332   public abstract void setButtonKey( Dialog dialog, Component button, int keyCode );
333 
334   /** Make the button the default on a frame.
335    **/
336   public abstract void setDefaultButton( Frame frame, Component button );
337   
338   /** Make the button the "cancel" button on a frame. ie the button
339    *  which dismisses the frame without taking any action.
340    **/
341   public abstract void setCancelButton( Frame frame, Component button );
342   
343   /** Associate a key press with the button.  ie so a key can be pressed instead of
344    *  using the mouse to press the button.
345    **/
346   public abstract void setButtonKey( Frame frame, Component button, int keyCode );
347   
348   /** Returns either a java.awt.Label or a javax.swing.JLabel.
349    **/
350   public Component makeLabel( String text, int horizontalAlignment ) {
351     return makeLabelImp( getResourceString( text ), horizontalAlignment );
352   }
353   
354   /** Returns either a java.awt.Label or a javax.swing.JLabel.
355    **/
356   public Component makeLabel( String text, Object[] params, int horizontalAlignment ) {
357     return makeLabelImp( getResourceString( text, params ), horizontalAlignment );
358   }
359 
360   protected abstract Component makeLabelImp( String text, int horizontalAlignment );
361   
362   /** Returns either a java.awt.Label or a javax.swing.JLabel.
363    **/
364   public Component makeLabel( String text ) {
365     return makeLabel( text, Label.LEFT );
366   }
367   
368   /** Returns either a java.awt.Label or a javax.swing.JLabel.
369    **/
370   public Component makeLabel( String text, Object[] params ) {
371     return makeLabel( text, params, Label.LEFT );
372   }
373   
374   /** Sets the text on what may be a button, label or a text field.
375    **/
376   public void setText( Component c, String text ) {
377     setTextImp( c, getResourceString( text ) );
378   }
379   
380   /** Sets the text on what may be a button, label or a text field.
381    **/
382   public void setText( Component c, String text, Object[] params ) {
383     setTextImp( c, getResourceString( text, params ) );
384   }
385   
386   protected abstract void setTextImp( Component c, String text );
387   
388   /** Returns either a java.awt.MenuBar or a javax.swing.JMenuBar.
389    **/
390   public abstract Object makeMenuBar();
391   
392   /** Sets a frames menu bar.
393    **/
394   public abstract void setMenuBar( Frame frame, Object menuBar );
395   
396   /** Returns either a java.awt.Menu or a javax.swing.JMenu.
397    **/
398   public Object makeMenu( String label ) {
399     return makeMenuImp( getResourceString( label ) );
400   }
401   
402   protected abstract Object makeMenuImp( String label );
403   
404   /** Insert a seperator/divider into the menu.
405    **/
406   public abstract void addSeparator( Object menu );
407   
408   /** Remove all items from a menu.
409    **/
410   public abstract void removeAll( Object menu );
411   
412   /** Add a menu to a menu bar.
413    **/
414   public abstract void addMenu( Object menuBar, Object menu );
415   
416   /** Set the help menu on a menu bar.
417    **/
418   public abstract void setHelpMenu( Object menuBar, Object menu );
419   
420   /** Returns either a java.awt.MenuItem or a javax.swing.JMenuItem.
421    **/
422   public Object makeMenuItem( String label, MenuShortcut s, String action, ActionListener listener ) {
423     return makeMenuItemImp( getResourceString( label ), s, action, listener );
424   }
425 
426   protected abstract Object makeMenuItemImp( String label, MenuShortcut s, String action, ActionListener listener );
427   
428   /** Add a menu item to a menu.
429    **/
430   public abstract void addMenuItem( Object menu, Object menuItem );
431   
432   /** Enable disable a menu/menuitem.
433    **/
434   public abstract void setEnabled( Object menuItem, boolean enabled );
435   
436   /** Returns either a java.awt.ScrollPane of a javax.swing.JScrollPane.
437    **/
438   public abstract Container makeScrollPane( Component contents );
439   
440   /** Returns the viewport size of a scrollpane.
441    **/
442   public abstract Dimension getViewportSize( Container scrollpane );
443   
444   /** Returns the scroll position of a scrollpane.
445    **/
446   public abstract Point getScrollPosition( Container scrollpane );
447   
448   /** Sets the scroll position of a scrollpane.
449    **/
450   public abstract void setScrollPosition( Container scrollpane, int x, int y );
451   
452   /** Returns either a java.awt.Choice or a javax.swing.JComboBox.
453    **/
454   public abstract Component makeChoice( String[] items, ItemListener itemListener );
455 
456   /** Set the items on a choice.
457    **/
458   public abstract void setChoiceItems( Component choice, String[] items );
459   
460   /** Returns either a java.awt.List or a javax.swing.JList.
461    **/
462   public abstract Component makeList( String[] items, ItemListener itemListener );
463 
464   /** Set the items on a list.
465    **/
466   public abstract void setListItems( Component list, String[] items );
467   
468   /** Set the currently selected item on a choice.
469    **/
470   public abstract void setSelected( Component choice, String item );
471   
472   /** Get the currently selected item on a choice.
473    **/
474   public abstract String getSelected( Component choice );
475   
476   /** Get the currently selected item on a choice.
477    **/
478   public abstract int getSelectedIndex( Component choice );
479   
480   /** Returns either a ProgressBar or a javax.swing.JProgressBar.
481    **/
482   public abstract Component makeProgressBar();
483   
484   /** Set the max value on a progress bar.
485    **/
486   public abstract void setProgressBarMax( Component progressBar, int max );  
487   
488   /** Set the current value of a progress bar.
489    **/
490   public abstract void setProgressBarValue( Component progressBar, int value );
491   
492   /** Returns either a java.awt.TextField or a javax.swing.JTextField.
493    **/
494   public abstract Component makeTextField( String text, int columns, TextListener listener );
495   
496   public abstract void setEditable( Component textField, boolean editable );
497   
498   /** Get the text from a text field.
499    **/
500   public abstract String getText( Component textField );
501   
502   /** Returns either a java.awt.Checkbox or a javax.swing.JCheckBox
503    **/
504   public Component makeCheckBox( String label, ItemListener listener ) {
505     return makeCheckBoxImpl( getResourceString( label ), listener );
506   }
507   
508   protected abstract Component makeCheckBoxImpl( String label, ItemListener listener );
509   
510   /** Get the current state of a CheckBox
511    **/
512   public abstract boolean getCheckBoxState( Component checkBox );
513   
514   /** Set the state of a CheckBox.
515    **/
516   public abstract void setCheckBoxState( Component checkBox, boolean state );
517   
518   /** Under this setup can we create a folder/directory
519    *  chooser?
520    **/
521   public abstract boolean canChooseFolders();
522   
523   /** Display a dialog to allow the user to choose a folder (eg for 
524    *  where to download files to.
525    **/
526   public File chooseFolder( Frame parent, String title ) {
527     return chooseFolderImp( parent, getResourceString( title ) );
528   }
529                                  
530   protected abstract File chooseFolderImp( Frame parent, String title );
531   
532   /** Display a dialog to allow the user to save a file.
533    **/
534   public File chooseSaveFile( Frame parent, String title ) {
535     return chooseSaveFileImp( parent, getResourceString( title ) );
536   }
537   
538   protected abstract File chooseSaveFileImp( Frame parent, String title );
539                                  
540   /** Display a dialog to allow the user to open a file.
541    **/
542   public File chooseOpenFile( Frame parent, String title ) {
543     return chooseOpenFileImp( parent, getResourceString( title ) );
544   }
545   
546   protected abstract File chooseOpenFileImp( Frame parent, String title );
547                                  
548   /** Centre child relative to parent.
549    **/
550   public void centreWindow( Window parent, Window child ) {
551     Point p         = parent.getLocation();
552     Dimension size  = parent.getSize();
553     Dimension childSize = child.getSize();
554     int x = p.x + (size.width-childSize.width)/2;
555     int y = p.y + (size.height-childSize.height)/2;
556     child.setLocation( x, y );
557   }
558   
559   /** Make a panel, containing multiple lines of text (as labels).
560    *  divided by new lines (\n)
561    **/
562   public Container makeMultiLineLabel( String text ) {
563     text = getResourceString( text );
564     Container panel = makePanel();
565     java.util.StringTokenizer st = new java.util.StringTokenizer( text, "\n" );
566     java.util.Vector lines = new java.util.Vector();
567     while( st.hasMoreTokens() ) {
568       String token = st.nextToken();
569       Component label = makeLabel( token.trim() );
570       lines.addElement( label );
571     }
572     panel.setLayout( new GridLayout( lines.size(), 1, 5, 0 ) );
573     for ( int i = 0; i < lines.size(); i++ ) {
574       panel.add( (Component)lines.elementAt( i ) );
575     }
576     return panel;
577   }
578                                  
579   /** Display a simple, yes/no dialog.
580    **/
581   //  TODO make SwingToolkit override this to use JOptionPane
582   public synchronized boolean doQueryDialog( Frame frame, String title, String query ) {
583     queryResult = false;
584     dialog = makeDialog( frame, title, true );
585     
586     
587     ActionListener listener = new ActionListener() {
588       public void actionPerformed( ActionEvent ae ) {
589         if ( ae.getActionCommand().equals( "yes" ) )
590           queryResult = true;
591         dialog.setVisible( false );
592       }
593     };
594     
595     Component label = makeMultiLineLabel( query );
596     Component yesButton = makeButton( "@res:yesButton", "yes", listener );
597     Component noButton  = makeButton( "@res:noButton",  "no",  listener );
598     
599     add( dialog, label, BorderLayout.CENTER );
600     Container c = makePanel();
601     c.add( noButton );
602     c.add( yesButton );
603     add( dialog, c, BorderLayout.SOUTH );
604     
605     setButtonKey( dialog, yesButton, KeyEvent.VK_Y );
606     setButtonKey( dialog, noButton,  KeyEvent.VK_N );                             
607                                  
608     dialog.pack();
609     centreWindow( frame, dialog );
610     dialog.requestFocus();
611     dialog.show();
612     
613     return queryResult;
614   }
615                                  
616   /** A query dialog that may be one of many, hence it has a "yes to all" button, as well as a yes button.
617    *   Returns either "yes", "no" or "yes all" depending on button pressed.
618    **/
619   //  TODO make SwingToolkit override this to use JOptionPane
620   public synchronized String doMultipleQueryDialog( Frame frame, String title, String query ) {
621     multipleQueryResult = null;
622     dialog = makeDialog( frame, title, true );
623     
624     
625     ActionListener listener = new ActionListener() {
626       public void actionPerformed( ActionEvent ae ) {
627         multipleQueryResult = ae.getActionCommand();
628         dialog.setVisible( false );
629       }
630     };
631     
632     Component label = makeMultiLineLabel( query );
633     Component yesButton = makeButton( "@res:yesButton", "yes", listener );
634     Component noButton  = makeButton( "@res:noButton",  "no",  listener );
635     Component yesAllButton = makeButton( "@res:yesAllButton", "yes all", listener );
636 
637     add( dialog, label, BorderLayout.CENTER );
638     Container c = makePanel();
639     c.add( noButton );
640     c.add( yesButton );
641     c.add( yesAllButton );
642     add( dialog, c, BorderLayout.SOUTH );
643     
644     setButtonKey( dialog, yesButton,    KeyEvent.VK_Y );
645     setButtonKey( dialog, yesAllButton, KeyEvent.VK_A );
646     setButtonKey( dialog, noButton,     KeyEvent.VK_N );                             
647                                  
648     dialog.pack();
649     centreWindow( frame, dialog );
650     dialog.requestFocus();
651     dialog.show();
652     
653     return multipleQueryResult;
654   }
655                                  
656   /** Display a simple dialog with a message and an ok/done button.
657    **/
658   // TODO make SwingToolkit override this to use JOptionPane
659   public synchronized void showMessageDialog( Frame frame, String title, String msg ) {
660     dialog = makeDialog( frame, title, true );
661         
662     ActionListener listener = new ActionListener() {
663       public void actionPerformed( ActionEvent ae ) {
664         dialog.setVisible( false );
665       }
666     };
667     
668     Component label = makeMultiLineLabel( msg );
669     Component doneButton = makeButton( "@res:doneButton", "done", listener );
670     
671     add( dialog, label, BorderLayout.CENTER );
672     Container c = makePanel();
673     c.add( doneButton );
674     add( dialog, c, BorderLayout.SOUTH );
675     
676     setDefaultButton( dialog, doneButton );                               
677                                  
678     dialog.pack();
679     centreWindow( frame, dialog );
680     dialog.requestFocus();
681     dialog.show();
682   }
683   
684   public synchronized String doTextInputDialog( Frame frame, String title, String msg, String text ) {
685     
686     queryResult = false;
687     dialog = makeDialog( frame, title, true );
688     
689     
690     ActionListener listener = new ActionListener() {
691       public void actionPerformed( ActionEvent ae ) {
692         queryResult = ae.getActionCommand().equals( "done" );
693         dialog.setVisible( false );
694       }
695     };
696     
697     Component label = makeMultiLineLabel( msg );
698     Component textField  = makeTextField( text, Math.max( 20, text.length() ), null );
699     Component doneButton = makeButton( "@res:doneButton", "done", listener );
700     Component cancelButton  = makeButton( "@res:cancelButton",  "cancel",  listener );
701     
702     Container c = makePanel();
703     c.setLayout( new GridLayout( 2,1 ) );
704     c.add( label );
705     c.add( textField );
706     add( dialog, c, BorderLayout.CENTER );
707     
708     c = makePanel();
709     c.add( cancelButton );
710     c.add( doneButton );
711     add( dialog, c, BorderLayout.SOUTH );
712 
713     setDefaultButton( dialog, doneButton );
714     setButtonKey( dialog, cancelButton, KeyEvent.VK_ESCAPE );
715                              
716     dialog.pack();
717     centreWindow( frame, dialog );
718     dialog.requestFocus();
719     dialog.show();
720 
721     return queryResult? getText( textField ) : null;
722   }
723 
724 }