001: /*
002: * Copyright (c) 1998-2002 Carnegie Mellon University. All rights
003: * reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * 1. Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * 2. Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in
014: * the documentation and/or other materials provided with the
015: * distribution.
016: *
017: * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND
018: * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
019: * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
020: * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
021: * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022: * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023: * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027: * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028: *
029: */
030:
031: package rcm.awt;
032:
033: import java.awt.*;
034: import java.awt.event.*;
035: import java.util.Vector;
036: import rcm.util.Win;
037:
038: // Note: after creating a PopupDialog (like any other top-level window, it
039: // seems), the JDK 1.1 runtime won't exit by itself, even if the PopupDialog
040: // is properly disposed. Need to force it to exit using System.exit().
041:
042: public class PopupDialog extends Dialog {
043:
044: public static final int YES = 0;
045: public static final int OK = 0;
046: public static final int NO = 1;
047: public static final int CANCEL = 2;
048:
049: Component parent;
050: int answer = -1;
051: String text;
052:
053: TextField textfield;
054: Button okButton, noButton, cancelButton;
055:
056: public static String ask(Component comp, String topic,
057: String question, String defaultAnswer) {
058: PopupDialog d = new PopupDialog(comp, topic, true, question,
059: defaultAnswer, "OK", null, "Cancel");
060: d.show();
061: switch (d.getAnswer()) {
062: case OK:
063: return d.getText();
064: default:
065: return null;
066: }
067: }
068:
069: public static String ask(Component comp, String topic,
070: String question) {
071: return ask(comp, topic, question, "");
072: }
073:
074: public static boolean okcancel(Component comp, String topic,
075: String question) {
076: PopupDialog d = new PopupDialog(comp, topic, true, question,
077: null, "OK", null, "Cancel");
078: d.show();
079: return (d.getAnswer() == OK);
080: }
081:
082: public static boolean yesno(Component comp, String topic,
083: String question) {
084: PopupDialog d = new PopupDialog(comp, topic, true, question,
085: null, "Yes", "No", null);
086: d.show();
087: return (d.getAnswer() == YES);
088: }
089:
090: public static int yesnocancel(Component comp, String topic,
091: String question) {
092: PopupDialog d = new PopupDialog(comp, topic, true, question,
093: null, "Yes", "No", "Cancel");
094: d.show();
095: return d.getAnswer();
096: }
097:
098: public static void warn(Component comp, String topic, String message) {
099: PopupDialog d = new PopupDialog(comp, topic, true, message,
100: null, "OK", null, null);
101: d.show();
102: }
103:
104: public static String currentDirectory = "";
105:
106: public static String askFilename(Component comp, String topic,
107: String defaultFilename, boolean loading) {
108: try {
109: FileDialog fd = new FileDialog(Win.findFrame(comp), topic,
110: loading ? FileDialog.LOAD : FileDialog.SAVE);
111:
112: if (currentDirectory != null)
113: fd.setDirectory(currentDirectory);
114: if (defaultFilename != null)
115: fd.setFile(defaultFilename);
116:
117: fd.show();
118:
119: String dir = fd.getDirectory();
120: String file = fd.getFile();
121:
122: if (dir == null || file == null)
123: return null;
124:
125: currentDirectory = dir;
126: return dir + file;
127: } catch (AWTError e) {
128: return ask(comp, topic, "Filename:", defaultFilename);
129: }
130: }
131:
132: public static String askDirectory(Component comp, String topic,
133: String defaultFilename, boolean loading) {
134: try {
135: FileDialog fd = new FileDialog(Win.findFrame(comp), topic,
136: loading ? FileDialog.LOAD : FileDialog.SAVE);
137:
138: if (currentDirectory != null)
139: fd.setDirectory(currentDirectory);
140: if (defaultFilename != null)
141: fd.setFile(defaultFilename);
142:
143: fd.show();
144:
145: String dir = fd.getDirectory();
146:
147: if (dir != null)
148: currentDirectory = dir;
149:
150: return dir;
151: } catch (AWTError e) {
152: return ask(comp, topic, "Directory:", defaultFilename);
153: }
154: }
155:
156: public PopupDialog(Component parent, String title, boolean modal) {
157: super (Win.findFrameOrMakeFrame(parent), title, modal);
158: this .parent = parent;
159: }
160:
161: public PopupDialog(Component parent, String title, boolean modal,
162: String question, String initialEntry, String okOrYes,
163: String no, String cancel) {
164: this (parent, title, modal);
165:
166: if (parent != null)
167: setFont(parent.getFont());
168:
169: Panel middle = new Panel();
170: add("Center", BorderPanel.wrap(middle, 10, 10, 10, 5));
171: middle.setLayout(new BorderLayout());
172: MultiLineLabel questionLabel = new MultiLineLabel(question,
173: Label.LEFT);
174: middle.add("Center", questionLabel);
175: if (initialEntry != null) {
176: textfield = new TextField(Math.max(40, initialEntry
177: .length() + 1));
178: middle.add("South", textfield);
179: textfield.setText(initialEntry);
180: textfield.selectAll();
181: textfield.addActionListener(new ActionListener() {
182: public void actionPerformed(ActionEvent event) {
183: answer = OK;
184: close();
185: }
186: });
187: }
188:
189: Panel bottom = new Panel();
190: add("South", bottom);
191:
192: if (okOrYes != null) {
193: okButton = new Button(okOrYes);
194: okButton.addActionListener(new ActionListener() {
195: public void actionPerformed(ActionEvent event) {
196: answer = OK;
197: close();
198: }
199: });
200: bottom.add(okButton);
201: }
202:
203: if (no != null) {
204: noButton = new Button(no);
205: noButton.addActionListener(new ActionListener() {
206: public void actionPerformed(ActionEvent event) {
207: answer = NO;
208: close();
209: }
210: });
211: bottom.add(noButton);
212: }
213:
214: if (cancel != null) {
215: cancelButton = new Button(cancel);
216: cancelButton.addActionListener(new ActionListener() {
217: public void actionPerformed(ActionEvent event) {
218: answer = CANCEL;
219: close();
220: }
221: });
222: bottom.add(cancelButton);
223: }
224:
225: addWindowListener(new WindowAdapter() {
226: public void windowClosing(WindowEvent event) {
227: if (cancelButton != null) {
228: answer = CANCEL;
229: close();
230: } else if (noButton == null && cancelButton == null) {
231: answer = OK;
232: close();
233: }
234: }
235: });
236:
237: // if (System.getProperty ("java.vendor").startsWith ("Netscape")) {
238: // // pack() doesn't work under Netscape!
239: // Dimension d = questionLabel.preferredSize();
240: // resize (Math.max (100, d.width), 100 + d.height);
241: // }
242: // else
243: pack();
244: }
245:
246: public static void centerWindow(Window window, Component ref) {
247: Dimension size = window.getSize();
248: Dimension refSize = (ref != null) ? ref.getSize() : Toolkit
249: .getDefaultToolkit().getScreenSize();
250: Point origin = (ref != null) ? ref.getLocationOnScreen()
251: : new Point(0, 0);
252:
253: if (refSize != null) {
254: int x = Math.max(0, origin.x + (refSize.width - size.width)
255: / 2);
256: int y = Math.max(0, origin.y
257: + (refSize.height - size.height) / 2);
258: window.setLocation(x, y);
259: }
260: }
261:
262: public void show() {
263: centerWindow(this , parent);
264: super .show();
265: if (textfield != null)
266: textfield.requestFocus();
267: }
268:
269: public int getAnswer() {
270: return answer;
271: }
272:
273: public void setAnswer(int answer) {
274: this .answer = answer;
275: }
276:
277: public String getText() {
278: return text;
279: }
280:
281: Vector listeners = new Vector();
282:
283: public synchronized void addPopupListener(PopupListener listener) {
284: listeners.addElement(listener);
285: }
286:
287: public synchronized void removePopupListener(PopupListener listener) {
288: listeners.removeElement(listener);
289: }
290:
291: public synchronized void close() {
292: text = (answer == OK && textfield != null) ? textfield
293: .getText() : null;
294:
295: dispose();
296: if (parent == null)
297: ((Frame) getParent()).dispose();
298: else
299: parent.requestFocus();
300:
301: if (answer != -1) {
302: PopupEvent e = new PopupEvent(answer, text);
303: for (int i = 0; i < listeners.size(); ++i) {
304: PopupListener p = (PopupListener) (listeners
305: .elementAt(i));
306: switch (e.getID()) {
307: case YES:
308: p.yes(e);
309: break;
310: case NO:
311: p.no(e);
312: break;
313: case CANCEL:
314: p.cancel(e);
315: break;
316: }
317: }
318: }
319:
320: try {
321: finalize();
322: } catch (Throwable t) {
323: throw new RuntimeException(t.toString());
324: }
325: }
326:
327: /*
328: * Testing
329: *
330: */
331: public static void main(String[] args) {
332: String name = ask(null, "Enter Name", "Enter your full name:");
333:
334: if (name != null) {
335: switch (yesnocancel(null, "Confirm", "Hello, " + name
336: + ".\nIs this your name?")) {
337: case PopupDialog.YES:
338: if (okcancel(null, "Thanks",
339: "Great!\nDo you want to play a game?")) {
340: warn(null, "Sorry",
341: "Too bad, my mommy won't let me out of the house.");
342: }
343: break;
344:
345: case PopupDialog.NO:
346: warn(null, "D'oh", "Oops. My bad.");
347: break;
348: }
349: }
350:
351: System.exit(0);
352: }
353:
354: }
|