2 * Copyright (C) 2015 Roland Haeder
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 package org.mxchange.addressbook.client.gui;
19 import java.awt.BorderLayout;
20 import java.awt.GridLayout;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.awt.event.MouseAdapter;
24 import java.awt.event.MouseEvent;
25 import java.awt.event.WindowAdapter;
26 import java.awt.event.WindowEvent;
27 import java.io.IOException;
28 import java.lang.reflect.InvocationTargetException;
29 import java.sql.SQLException;
30 import java.text.MessageFormat;
31 import javax.swing.BorderFactory;
32 import javax.swing.BoxLayout;
33 import javax.swing.DefaultComboBoxModel;
34 import javax.swing.JButton;
35 import javax.swing.JComboBox;
36 import javax.swing.JDialog;
37 import javax.swing.JFormattedTextField;
38 import javax.swing.JFrame;
39 import javax.swing.JLabel;
40 import javax.swing.JMenu;
41 import javax.swing.JMenuBar;
42 import javax.swing.JMenuItem;
43 import javax.swing.JPanel;
44 import javax.swing.JScrollPane;
45 import javax.swing.JTable;
46 import javax.swing.JTextArea;
47 import javax.swing.JTextField;
48 import javax.swing.border.TitledBorder;
49 import javax.swing.table.TableModel;
50 import org.mxchange.addressbook.BaseAddressbookSystem;
51 import org.mxchange.addressbook.application.AddressbookApplication;
52 import org.mxchange.addressbook.exceptions.ContactAlreadyAddedException;
53 import org.mxchange.addressbook.manager.contact.ManageableAddressbookContact;
54 import org.mxchange.jcore.client.Client;
55 import org.mxchange.jcore.client.gui.ClientFrame;
56 import org.mxchange.jcore.contact.Contact;
57 import org.mxchange.jcore.contact.Gender;
58 import org.mxchange.jcore.exceptions.BadTokenException;
59 import org.mxchange.jcore.exceptions.CorruptedDatabaseFileException;
60 import org.mxchange.jcore.exceptions.FrameAlreadyInitializedException;
61 import org.mxchange.jcore.model.swing.contact.ContactTableModel;
65 * @author Roland Haeder
67 public class AddressbookFrame extends BaseAddressbookSystem implements ClientFrame {
72 private static ClientFrame self;
75 * Singelton getter for this frame instance.
77 * @param client Client instance
78 * @return Returns a singelton instance of this frame
80 public static final ClientFrame getSelfInstance (final Client client) {
82 if (!(self instanceof ClientFrame)) {
83 // Create new instance
84 self = new AddressbookFrame(client);
92 * Dialog box "add contact"
94 private JDialog addContact;
97 * Frame instance for "add own data"
99 private JMenuItem addOwnItem;
102 * Instance to table model
104 private TableModel dataModel;
109 private JTable dataTable;
112 * Frame instance for "edit own data"
114 private JMenuItem editOwnItem;
119 private final JFrame frame;
122 * Whether this frame has been initialized
124 private boolean initialized;
127 * Status label needs to be updated
129 private JLabel statusLabel;
132 * Creates an instance of this frame with a client instance
136 private AddressbookFrame (final Client client) {
138 this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
140 // Set frame instance
141 this.frame = new JFrame();
142 this.frame.setTitle(this.generateFrameTitle("main")); //NOI18N
145 this.setClient(client);
148 this.getLogger().trace("EXIT!"); //NOI18N
152 public Contact doEnterOwnData () {
154 this.getLogger().trace("CALLED!"); //NOI18N
156 // Is the "add contact" window visible?
157 if (this.addContact.isVisible()) {
158 // Something bad happened
159 throw new IllegalStateException("Window addContact is already visible."); //NOI18N
162 // Disable main window
163 this.frame.setEnabled(false);
165 // Make other window visible
166 this.addContact.setVisible(true);
169 this.getLogger().trace("Returning null : EXIT!"); //NOI18N
171 // Return value is not supported
176 * Shutdown this frame
179 public void doShutdown () {
181 this.getLogger().trace("CALLED!"); //NOI18N
183 // First only show shutdown status
184 this.updateStatus("shutdown"); //NOI18N
187 this.getLogger().trace("EXIT!"); //NOI18N
192 * Enables main window (frame)
195 public void enableMainWindow () {
197 this.getLogger().trace("CALLED!"); //NOI18N
200 this.frame.setEnabled(true);
202 // Request focus for this window
203 this.frame.requestFocus();
206 this.getLogger().trace("EXIT!"); //NOI18N
210 * Setups the frame, do not set isInitialized here
212 * @param client Client instance
215 public void setupFrame (final Client client) throws IOException, BadTokenException {
217 this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
219 // Get and cast manager instance
220 ManageableAddressbookContact manager = (ManageableAddressbookContact) this.getClient().getManager();
222 // Has the user entered own data?
223 if (manager.isOwnContactAdded()) {
225 this.getLogger().debug("Disabling menus: isOwnContactAdded()=false"); //NOI18N
227 // Not entered yet, so disable "add" menu
228 this.addOwnItem.setEnabled(false);
231 this.editOwnItem.setEnabled(false);
234 // Make the frame visible
235 this.frame.setVisible(true);
238 this.updateStatus("done"); //NOI18N
241 this.getLogger().trace("EXIT!"); //NOI18N
245 * Initalizes this frame. Having initComponents() exposed (publicly
246 * accessible) means that any other object can initialize components which
250 * org.mxchange.jcore.exceptions.FrameAlreadyInitializedException If
251 * this method has been called twice
254 public void init () throws FrameAlreadyInitializedException {
256 this.getLogger().trace("CALLED!"); //NOI18N
258 // Has this frame been initialized?
259 if (this.isInitialized()) {
261 throw new FrameAlreadyInitializedException();
265 this.initComponents();
268 this.initialized = true;
271 this.getLogger().trace("EXIT!"); //NOI18N
275 * Returns field isInitialized. This flag indicates whether this frame has
276 * been initialized or not.
278 * @return Field isInitialized
281 public final boolean isInitialized () {
282 return this.initialized;
286 * Shuts down the application.
289 public void shutdownApplication () {
291 this.getLogger().trace("CALLED!"); //NOI18N
293 // To do this, the frame must be initialized
294 if (!this.isInitialized()) {
295 // Not initalized, so bad call
296 this.getLogger().fatal("Bad call of shutdownApplication(). Please report this."); //NOI18N
300 // Call shutdown method
302 this.getClient().getApplication().doShutdown();
303 } catch (final SQLException | IOException ex) {
305 this.abortProgramWithException(ex);
309 this.getLogger().trace("EXIT!"); //NOI18N
313 * Adds a new menu item with given key to menu instance
315 * @param menu Menu instance to add item to
316 * @param key Message key part
317 * @param listener Listener instance
319 private void addMenuItem (final JMenu menu, final String key, final ActionListener listener) {
321 this.getLogger().trace(MessageFormat.format("menu={0},key={1},listener={2} - CALLED!", menu, key, listener)); //NOI18N
324 JMenuItem item = this.initMenuItemWithTooltip(key);
327 item.addActionListener(listener);
333 this.getLogger().trace("EXIT!"); //NOI18N
337 * Adds a JTextField with label and tool tip to given panel
339 * @param panel Panel instance to add text field
340 * @param key Part of message key from resource bundle
341 * @param fieldLength Length of text field
343 private void addTextFieldWithLabelToPanel (final JPanel panel, final String key, final int fieldLength) {
345 this.getLogger().trace(MessageFormat.format("panel={0},key={1},fieldLength={2} - CALLED!", panel, key, fieldLength)); //NOI18N
347 // Init label for given key
348 JLabel label = new JLabel(this.getBundle().getString(String.format("AddressbookFrame.%s.text", key))); //NOI18N
350 // And input box wih tool tip
351 JTextField field = new JTextField(fieldLength);
352 field.setToolTipText(this.getBundle().getString(String.format("AddressbookFrame.%s.toolTipText", key))); //NOI18N
359 this.getLogger().trace("EXIT!"); //NOI18N
363 * Generates a title for borders
365 * @param key Key part to look for
366 * @return Human-readable title
368 private String generateBorderTitle (final String key) {
369 // Call bundle instance
370 return this.getBundle().getString(String.format("AddressbookFrame.border.%s.title.text", key)); //NOI18N
374 * Generates a title for all frames based on given sub title key. If null is
375 * given, the sub title is not generated.
377 * @param subKey Key for sub title resource
378 * @return A full application title
380 private String generateFrameTitle (final String subKey) {
382 String title = AddressbookApplication.printableTitle();
385 if (subKey != null) {
387 title = String.format("%s - %s", title, this.getBundle().getString(String.format("AddressbookFrame.%s.title.text", subKey))); //NOI18N
395 * Initializes "add" and "cancel" buttons
397 private void initAddCancelButtons () {
399 this.getLogger().trace("CALLED!"); //NOI18N
402 JPanel panel = new JPanel();
403 panel.setLayout(new GridLayout(1, 2, 10, 10));
405 // Generate "add" button
406 JButton addButton = new JButton(this.getBundle().getString("AddressbookFrame.button.addAddress.text"));
409 addButton.addActionListener(new AddActionListener(this.addContact, this));
411 // Add button to panel
412 panel.add(addButton);
414 // Generate "cancel" button
415 JButton cancelButton = new JButton(this.getBundle().getString("AddressbookFrame.button.cancel.text"));
418 cancelButton.addActionListener(new CancelActionListener(this.addContact, this));
420 // Add button to panel
421 panel.add(cancelButton);
423 // Add panel to main panel
424 this.addContact.add(panel);
427 this.getLogger().trace("EXIT!"); //NOI18N
431 * Initializes "add contact" dialog
433 private void initAddContactDialog () {
435 this.getLogger().trace("CALLED!"); //NOI18N
437 // Instance dialog and set title
438 this.addContact = new JDialog();
439 this.addContact.setTitle(this.generateFrameTitle("dialog.addContact")); //NOI18N
442 this.addContact.setLayout(new GridLayout(0, 1, 2, 2));
444 // Only hide it on close and make it appear in middle of screen
445 this.addContact.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
446 this.addContact.setLocationRelativeTo(this.frame);
448 // Set always on top and auto-focus
449 this.addContact.setAlwaysOnTop(true);
450 this.addContact.setAutoRequestFocus(true);
453 this.addContact.setSize(500, 500);
455 // And it is not resizeable
456 this.addContact.setResizable(false);
459 * Add listener which asks for confirmation, if data has been entered
460 * but not saved yet. The user may appriciate this ... ;-)
464 this.addContact.addWindowListener(new WindowAdapter() {
466 * Invoked when a window has been closed.
469 public void windowClosed (final WindowEvent e) {
470 // Enable main window again
471 AddressbookFrame.getSelfInstance(null).enableMainWindow();
475 * Invoked when a window is in the process of being closed. The
476 * close operation can be overridden at this point.
479 public void windowClosing (final WindowEvent e) {
480 e.getWindow().dispose();
486 initNameDataPanel(this.addContact);
488 // 2) "address" panel
489 initAddressDataPanel(this.addContact);
492 initOtherDataPanel(this.addContact);
494 // 4) "Add" and "Cancel" buttons, combined they are unique for this dialog
495 initAddCancelButtons();
497 // x)Only for developing:
498 /* DEBUG: */ this.addContact.setVisible(true);
501 this.getLogger().trace("EXIT!"); //NOI18N
505 * Initializes address panel
507 * @param dialog A JDialog instance to this components to
509 private void initAddressDataPanel (final JDialog dialog) {
511 this.getLogger().trace("CALLED!"); //NOI18N
513 // Panel "address" input boxes
514 JPanel addressPanel = new JPanel();
515 addressPanel.setLayout(new GridLayout(0, 4, 3, 3));
517 // Set border to titled version
518 addressPanel.setBorder(new TitledBorder(this.generateBorderTitle("address"))); //NOI18N
520 // Add text field for street
521 this.addTextFieldWithLabelToPanel(addressPanel, "street", 20); //NOI18N
524 JLabel numberLabel = new JLabel(this.getBundle().getString("AddressbookFrame.number.text"));
526 // And text field, but only accept numbers
527 JFormattedTextField number = new JFormattedTextField();
528 number.setToolTipText(this.getBundle().getString("AddressbookFrame.number.toolTipText"));
530 // Add both to street panel
531 addressPanel.add(numberLabel);
532 addressPanel.add(number);
534 // Label for ZIP code, again numbers only
535 JLabel zipLabel = new JLabel(this.getBundle().getString("AddressbookFrame.zip.text"));
537 // Init text field with label
538 JFormattedTextField zip = new JFormattedTextField();
539 zip.setToolTipText(this.getBundle().getString("AddressbookFrame.zip.toolTipText"));
541 // Add both to street panel
542 addressPanel.add(zipLabel);
543 addressPanel.add(zip);
545 // Add text field for city name
546 this.addTextFieldWithLabelToPanel(addressPanel, "city", 20); //NOI18N
548 // Add panel to dialog
549 dialog.add(addressPanel);
552 this.getLogger().trace("EXIT!"); //NOI18N
556 * Initialize components
558 private void initComponents () {
560 this.getLogger().trace("CALLED!"); //NOI18N
562 // Set default close operation
563 this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
565 // Register shutdown listener
566 this.frame.addWindowListener(new WindowAdapter() {
568 * Invoked when a window has been closed.
571 public void windowClosed (final WindowEvent e) {
572 // Shutdown application cleanly
573 self.shutdownApplication();
577 * Invoked when a window is in the process of being closed. The
578 * close operation can be overridden at this point.
581 public void windowClosing (final WindowEvent e) {
582 // Also shutdown cleanly here
583 self.shutdownApplication();
587 // Setup layout manager
588 this.frame.setLayout(new BorderLayout(2, 2));
591 this.frame.setSize(700, 400);
593 // Center window in middle of screen, instead of top-left corner
594 this.frame.setLocationRelativeTo(null);
605 // Init other windows
609 this.getLogger().trace("EXIT!"); //NOI18N
613 * Initializes a menu item instance with tool tip
615 * @param key Message key part
616 * @return A finished JMenuItem instance
618 private JMenuItem initMenuItemWithTooltip (final String key) {
620 this.getLogger().trace(MessageFormat.format("key={0} - CALLED!", key)); //NOI18N
622 JMenuItem item = new JMenuItem(this.getBundle().getString(String.format("AddressbookFrame.menuItem.%s.text", key))); //NOI18N
623 item.setToolTipText(this.getBundle().getString(String.format("AddressbookFrame.menuItem.%s.toolTipText", key))); //NOI18N
626 this.getLogger().trace(MessageFormat.format("item={0} - EXIT!", item)); //NOI18N
633 * Initializes the menu system
635 private void initMenuSystem () {
637 this.getLogger().trace("CALLED!"); //NOI18N
639 // Init menu bar, menu and item instances
640 JMenuBar menuBar = new JMenuBar();
646 menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
649 // 1.x) Exit program (should be last)
650 this.addMenuItem(menu, "exitProgram", new ActionListener() { //NOI18N
652 * If the user has performed this action
654 * @param e An instance of an ActionEvent class
657 public void actionPerformed (final ActionEvent e) {
658 self.shutdownApplication();
662 // Add menu -> menu bar
666 // 2) Addressbook menu
667 menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
670 this.addOwnItem = this.initMenuItemWithTooltip("addOwnData"); //NOI18N
672 // Add listener to exit menu
673 this.addOwnItem.addActionListener(new ActionListener() {
675 * If the user has performed this action
677 * @param e An instance of an ActionEvent class
680 public void actionPerformed (final ActionEvent e) {
682 ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
683 manager.doEnterOwnData();
684 } catch (final ContactAlreadyAddedException ex) {
685 // Already added, log away
686 // @TODO maybe output message here?
687 self.logException(ex);
688 } catch (final IOException | BadTokenException ex) {
689 // Somethind bad happened here
690 // @TODO Output error message here?
696 menu.add(this.addOwnItem);
698 // 2.2) Edit own data
699 this.editOwnItem = this.initMenuItemWithTooltip("editOwnData"); //NOI18N
701 // Add listener to exit menu
702 this.editOwnItem.addActionListener(new ActionListener() {
704 * If the user has performed this action
706 * @param e An instance of an ActionEvent class
709 public void actionPerformed (final ActionEvent e) {
710 ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
712 manager.doChangeOwnData();
713 } catch (final IOException | BadTokenException | CorruptedDatabaseFileException | SQLException | NoSuchMethodException | IllegalAccessException | InvocationTargetException ex) {
714 self.logException(ex);
720 menu.add(this.editOwnItem);
723 // 1) Add new contact
724 this.addMenuItem(menu, "addNewContact", new ActionListener() { //NOI18N
726 * If the user has performed this action
728 * @param e An instance of an ActionEvent class
731 public void actionPerformed (final ActionEvent e) {
732 ManageableAddressbookContact manager = (ManageableAddressbookContact) self.getClient().getManager();
733 manager.doAddOtherAddress();
737 // Add menu -> menu bar
740 // Add menu bar -> frame
741 this.frame.add(menuBar, BorderLayout.NORTH);
744 this.getLogger().trace("EXIT!"); //NOI18N
748 * Initializes name panel
750 * @param dialog A JDialog instance to this components to
752 private void initNameDataPanel (final JDialog dialog) {
754 this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N
756 // Panel "name" input boxes
757 JPanel namePanel = new JPanel();
758 namePanel.setLayout(new GridLayout(0, 2, 3, 3));
760 // Set border to titled version
761 namePanel.setBorder(new TitledBorder(this.generateBorderTitle("name"))); //NOI18N
764 JLabel gLabel = new JLabel(this.getBundle().getString("AddressbookFrame.gender.text"));
767 Gender[] genders = Gender.values();
769 // Init gender combo box with tool tip
770 JComboBox<Gender> gender = new JComboBox<>(new DefaultComboBoxModel<>(genders));
771 gender.setToolTipText(this.getBundle().getString("AddressbookFrame.gender.toolTipText"));
773 // Add both to gender panel
774 namePanel.add(gLabel);
775 namePanel.add(gender);
777 // Add text field for surname
778 this.addTextFieldWithLabelToPanel(namePanel, "surname", 20); //NOI18N
780 // Add text field for family name
781 this.addTextFieldWithLabelToPanel(namePanel, "familyName", 20); //NOI18N
783 // Finally add panel to dialog
784 dialog.add(namePanel);
787 this.getLogger().trace("EXIT!"); //NOI18N
791 * Initializes "other" data panel
793 * @param dialog A JDialog instance to this components to
794 * @todo Fill this with life
796 private void initOtherDataPanel (final JDialog dialog) {
798 this.getLogger().trace(MessageFormat.format("dialog={0} - CALLED!", dialog)); //NOI18N
800 // Panel "other" input boxes
801 JPanel otherPanel = new JPanel();
802 otherPanel.setLayout(new GridLayout(0, 2, 3, 3));
803 otherPanel.setBorder(new TitledBorder(this.generateBorderTitle("other"))); //NOI18N
805 // Add text field for email address
806 this.addTextFieldWithLabelToPanel(otherPanel, "emailAddress", 20); //NOI18N
808 // Add text field for phone number
809 this.addTextFieldWithLabelToPanel(otherPanel, "phoneNumber", 20); //NOI18N
811 // Add text field for cellphone number
812 this.addTextFieldWithLabelToPanel(otherPanel, "cellphoneNumber", 20); //NOI18N
814 // Add text field for fax number
815 this.addTextFieldWithLabelToPanel(otherPanel, "faxNumber", 20); //NOI18N
818 JLabel commentLabel = new JLabel(this.getBundle().getString("AddressbookFrame.comment.text"));
820 // Init text area with tool tip
821 JTextArea comment = new JTextArea(5, 20);
822 comment.setToolTipText(this.getBundle().getString("AddressbookFrame.comment.toolTipText"));
825 otherPanel.add(commentLabel);
826 otherPanel.add(comment);
828 // Finally add panel to dialog
829 dialog.add(otherPanel);
832 this.getLogger().trace("EXIT!"); //NOI18N
836 * Initialize other dialogs (e.g. "Add contact")
838 private void initOtherDialogs () {
840 this.getLogger().trace("CALLED!"); //NOI18N
842 // Init other windows:
844 initAddContactDialog();
847 this.getLogger().trace("EXIT!"); //NOI18N
851 * Initializes status panel
853 private void initStatusPanel () {
855 this.getLogger().trace("CALLED!"); //NOI18N
857 // Init status label (which needs to be updated
858 this.statusLabel = new JLabel();
859 this.updateStatus("initializing"); //NOI18N
861 // Init status bar in south
862 JPanel panel = new JPanel();
863 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
864 panel.add(this.statusLabel);
865 panel.setBorder(BorderFactory.createEtchedBorder());
867 // Add panel to frame
868 this.frame.add(panel, BorderLayout.SOUTH);
871 this.getLogger().trace("EXIT!"); //NOI18N
875 * Initializes the table which will show all contacts
877 private void initTable () {
879 this.getLogger().trace("CALLED!"); //NOI18N
881 // Instance table model
882 this.dataModel = new ContactTableModel(this.getClient());
885 this.dataTable = new JTable(this.dataModel);
887 // Add mouse listener
888 this.dataTable.addMouseListener(new MouseAdapter() {
890 * If the user peformed a click on a cell
892 * @param e Mouse event instance
895 public void mouseClicked (final MouseEvent e) {
896 throw new UnsupportedOperationException("Unfinished."); //NOI18N
900 // Instance scroll pane
901 JScrollPane scroller = new JScrollPane();
903 // Add table to scroll pane
904 scroller.setViewportView(this.dataTable);
905 scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
906 scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
909 this.frame.add(scroller, BorderLayout.CENTER);
912 this.getLogger().trace("EXIT!"); //NOI18N
916 * Updates status to given type
918 * @param type Status type
920 private void updateStatus (final String type) {
922 this.getLogger().trace(MessageFormat.format("type={0} - CALLED!", type)); //NOI18N
924 // Set status message
925 this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type))); //NOI18N
928 this.getLogger().trace("EXIT!"); //NOI18N
932 * Class for "add address" button
934 private static class AddActionListener extends BaseAddressbookSystem implements ActionListener {
938 private final JDialog dialog;
941 * Frame (not JFrame) instance
943 private final ClientFrame frame;
946 * Constructor for action listener
948 * @param dialog Dialog instance to call back
949 * @param frame Frame instance (not JFrame)
951 protected AddActionListener (final JDialog dialog, final ClientFrame frame) {
952 // Set dialog and frame here
953 this.dialog = dialog;
958 * If the action has been performed
960 * @param e The performed action event
963 public void actionPerformed (final ActionEvent e) {
964 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
969 * Class for "cancel address" button
971 private static class CancelActionListener extends BaseAddressbookSystem implements ActionListener {
975 private final JDialog dialog;
978 * Frame (not JFrame) instance
980 private final ClientFrame frame;
983 * Constructor for action listener
985 * @param dialog Dialog instance to call back
986 * @param frame Frame instance (not JFrame)
988 protected CancelActionListener (final JDialog dialog, final ClientFrame frame) {
989 // Set dialog and frame here
990 this.dialog = dialog;
995 * If the action has been performed
997 * @param e The performed action event
1000 public void actionPerformed (final ActionEvent e) {
1001 throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.