// This example is from the book "Java in a Nutshell, Second Edition". // Written by David Flanagan. Copyright (c) 1997 O'Reilly & Associates. // You may distribute this source code for non-commercial purposes only. // You may study, modify, and use this example for any purpose, as long as // this notice is retained. Note that this example is provided "as is", // WITHOUT WARRANTY of any kind either expressed or implied. package oreilly.beans.yesno; // Put this bean in its own private package. import java.awt.*; import java.awt.event.*; import java.util.*; public class YesNoDialog { // Properties of the bean. protected String message, title; protected String yesLabel, noLabel, cancelLabel; protected int alignment; protected Font font = new Font("Serif", Font.PLAIN, 12); protected Color background = SystemColor.control; protected Color foreground = SystemColor.controlText; // Constants for the alignment property. public static final int LEFT = MultiLineLabel.LEFT; public static final int RIGHT = MultiLineLabel.RIGHT; public static final int CENTER = MultiLineLabel.CENTER; // Methods to query all of the bean properties. public String getMessage() { return message; } public String getTitle() { return title; } public String getYesLabel() { return yesLabel; } public String getNoLabel() { return noLabel; } public String getCancelLabel() { return cancelLabel; } public int getAlignment() { return alignment; } public Font getFont() { return font; } public Color getBackground() { return background; } public Color getForeground() { return foreground; } // Methods to set all of the bean properties. public void setMessage(String m) { message = m; } public void setTitle(String t) { title=t; } public void setYesLabel(String l) { yesLabel = l; } public void setNoLabel(String l) { noLabel = l; } public void setCancelLabel(String l) { cancelLabel = l; } public void setAlignment(int a) { alignment = a; } public void setFont(Font f) { font = f; } public void setBackground(Color bg) { background = bg; } public void setForeground(Color fg) { foreground = fg; } /** This field holds a list of registered ActionListeners. * Vector is internally synchronized to prevent race conditions */ protected Vector listeners = new Vector(); /** Register an action listener to be notified when a button is pressed */ public void addAnswerListener(AnswerListener l) { listeners.addElement(l); } /** Remove an Answer listener from our list of interested listeners */ public void removeAnswerListener(AnswerListener l) { listeners.removeElement(l); } /** Send an event to all registered listeners */ public void fireEvent(AnswerEvent e) { // Make a copy of the list and fire the events using that copy. // This means that listeners can be added or removed from the original // list in response to this event. We ought to be able to just use an // enumeration for the vector, but that doesn't copy the list internally. Vector list = (Vector) listeners.clone(); for(int i = 0; i < list.size(); i++) { AnswerListener listener = (AnswerListener)list.elementAt(i); switch(e.getID()) { case AnswerEvent.YES: listener.yes(e); break; case AnswerEvent.NO: listener.no(e); break; case AnswerEvent.CANCEL: listener.cancel(e); break; } } } /** The no-argument bean constructor, with default property values */ public YesNoDialog() { this("Question", "Your\nMessage\nHere", "Yes", "No", "Cancel", LEFT); } /** A constructor for programmers using this class "by hand" */ public YesNoDialog(String title, String message, String yesLabel, String noLabel, String cancelLabel, int alignment) { this.title = title; this.message = message; this.yesLabel = yesLabel; this.noLabel = noLabel; this.cancelLabel = cancelLabel; this.alignment = alignment; } /** This method makes the bean display the dialog box */ public void display() { // Create a frame with the specified title. It would be nice to // use a Dialog, but that needs to be passed a Frame argument, and // the BDK beanbox tool only seems to work with no-argument methods. final Frame frame = new Frame(title); // Specify a LayoutManager for it. frame.setLayout(new BorderLayout(15, 15)); // Specify font and colors, if any are specified. if (font != null) frame.setFont(font); if (background != null) frame.setBackground(background); if (foreground != null) frame.setForeground(foreground); // Put the message label in the middle of the window. frame.add("Center", new MultiLineLabel(message, 20, 20, alignment)); // Create an action listener for use by the buttons of the dialog. // When a button is pressed, this listener first closes the dialog box. // Then, it creates an AnswerEvent object that corresponds to the // button that was pressed, and send that new event to all registered // listeners, using the fireEvent() method defined above. ActionListener listener = new ActionListener() { public void actionPerformed(ActionEvent e) { frame.dispose(); // pop down window if (listeners != null) { // notify any registered listeners String cmd = e.getActionCommand(); int type; if (cmd.equals("yes")) type = AnswerEvent.YES; else if (cmd.equals("no")) type = AnswerEvent.NO; else type = AnswerEvent.CANCEL; fireEvent(new AnswerEvent(YesNoDialog.this, type)); } } }; // Create a panel for the dialog buttons and put it at the bottom // of the dialog. Specify a FlowLayout layout manager for it. Panel buttonbox = new Panel(); buttonbox.setLayout(new FlowLayout(FlowLayout.CENTER, 25, 15)); frame.add("South", buttonbox); // Create each specified button, specifying the action listener // and action command for each, and adding them to the buttonbox if ((yesLabel != null) && (yesLabel.length() > 0)) { Button yes = new Button(yesLabel); // Create button. yes.setActionCommand("yes"); // Set action command. yes.addActionListener(listener); // Set listener. buttonbox.add(yes); // Add button to the panel. } if ((noLabel != null) && (noLabel.length() > 0)) { Button no = new Button(noLabel); no.setActionCommand("no"); no.addActionListener(listener); buttonbox.add(no); } if ((cancelLabel != null) && (cancelLabel.length() > 0)) { Button cancel = new Button(cancelLabel); cancel.setActionCommand("cancel"); cancel.addActionListener(listener); buttonbox.add(cancel); } // Finally, set the dialog to its preferred size and display it. frame.pack(); frame.show(); } /** * A main method that demonstrates how to use this class, and allows testing */ public static void main(String[] args) { // Create an instance of InfoDialog, with title and message specified: YesNoDialog d = new YesNoDialog("YesNoDialog Test", "There are unsaved files.\n" + "Do you want to save them before quitting?", "Yes, save and quit", "No, quit without saving", "Cancel; don't quit", YesNoDialog.CENTER); // Register an action listener for the dialog. This one just prints // the results out to the console. d.addAnswerListener(new AnswerListener() { public void yes(AnswerEvent e) { System.out.println("Yes"); } public void no(AnswerEvent e) { System.out.println("No"); } public void cancel(AnswerEvent e) { System.out.println("Cancel"); } }); // Now pop the dialog up. It will pop itself down automatically. d.display(); } }