]> git.mxchange.org Git - addressbook-lib.git/blob - Addressbook/src/org/mxchange/addressbook/client/gui/AddressbookFrame.java
Introduced more methods + added first dialog call (yes, it is still visible by startu...
[addressbook-lib.git] / Addressbook / src / org / mxchange / addressbook / client / gui / AddressbookFrame.java
1 /*
2  * Copyright (C) 2015 Roland Haeder
3  *
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.
8  *
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.
13  *
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/>.
16  */
17 package org.mxchange.addressbook.client.gui;
18
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.text.MessageFormat;
28 import javax.swing.BorderFactory;
29 import javax.swing.BoxLayout;
30 import javax.swing.DefaultComboBoxModel;
31 import javax.swing.InputVerifier;
32 import javax.swing.JComboBox;
33 import javax.swing.JComponent;
34 import javax.swing.JDialog;
35 import javax.swing.JFrame;
36 import javax.swing.JLabel;
37 import javax.swing.JMenu;
38 import javax.swing.JMenuBar;
39 import javax.swing.JMenuItem;
40 import javax.swing.JPanel;
41 import javax.swing.JScrollPane;
42 import javax.swing.JTable;
43 import javax.swing.JTextField;
44 import javax.swing.border.TitledBorder;
45 import javax.swing.table.TableModel;
46 import org.mxchange.addressbook.BaseFrameworkSystem;
47 import org.mxchange.addressbook.application.AddressbookApplication;
48 import org.mxchange.addressbook.client.Client;
49 import org.mxchange.addressbook.contact.Contact;
50 import org.mxchange.addressbook.contact.Gender;
51 import org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException;
52 import org.mxchange.addressbook.model.contact.ContactTableModel;
53
54 /**
55  *
56  * @author Roland Haeder
57  */
58 public class AddressbookFrame extends BaseFrameworkSystem implements ClientFrame {
59
60         /**
61          * Own instance
62          */
63         private static ClientFrame self;
64
65         /**
66          * Singelton getter for this frame instance.
67          *
68          * @param client Client instance
69          * @return Returns a singelton instance of this frame
70          */
71         public static final ClientFrame getSelfInstance (final Client client) {
72                 // Is it set?
73                 if (!(self instanceof ClientFrame)) {
74                         // Create new instance
75                         self = new AddressbookFrame(client);
76                 }
77
78                 // Return instance
79                 return self;
80         }
81
82         /**
83          * Dialog box "add contact"
84          */
85         private JDialog addContact;
86
87         /**
88          * Frame instance for "add own data"
89          */
90         private JMenuItem addOwnItem;
91
92         /**
93          * Instance to table model
94          */
95         private TableModel dataModel;
96
97         /**
98          * Table instance
99          */
100         private JTable dataTable;
101
102         /**
103          * Frame instance for "edit own data"
104          */
105         private JMenuItem editOwnItem;
106
107         /**
108          * Frame instance
109          */
110         private final JFrame frame;
111
112         /**
113          * Whether this frame has been initialized
114          */
115         private boolean isInitialized;
116
117         /**
118          * Layout instance
119          */
120         private GridLayout layout;
121
122         /**
123          * Status label needs to be updated
124          */
125         private JLabel statusLabel;
126
127         /**
128          * Creates an instance of this frame with a client instance
129          *
130          * @param client
131          */
132         private AddressbookFrame (final Client client) {
133                 // Debug line
134                 this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
135
136                 // Set frame instance
137                 this.frame = new JFrame();
138                 this.frame.setTitle(this.generateFrameTitle("main")); //NOI18N
139
140                 // Set client here
141                 this.setClient(client);
142         }
143
144         @Override
145         public Contact doEnterOwnData () {
146                 // Is the "add contact" window visible?
147                 if (this.addContact.isVisible()) {
148                         // Something bad happened
149                         throw new IllegalStateException("Window addContact is already visible.");
150                 }
151
152                 // Disable main window
153                 this.frame.setEnabled(false);
154
155                 // Make other window visible
156                 this.addContact.setVisible(true);
157
158                 // Return value is not supported
159                 return null;
160         }
161
162         /**
163          * Shutdown this frame
164          */
165         @Override
166         public void doShutdown () {
167                 // First only show shutdown status
168                 this.updateStatus("shutdown"); //NOI18N
169         }
170
171
172         /**
173          * Enables main window (frame)
174          */
175         @Override
176         public void enableMainWindow () {
177                 // Enable it again
178                 this.frame.setEnabled(true);
179
180                 // Request focus for this window
181                 this.frame.requestFocus();
182         }
183
184         /**
185          * Setups the frame, do not set isInitialized here
186          *
187          * @param client Client instance
188          */
189         @Override
190         public void setupFrame (final Client client) {
191                 // Debug line
192                 this.getLogger().trace(MessageFormat.format("client={0}: CALLED!", client)); //NOI18N
193
194                 // Has the user entered own data?
195                 if (this.getClient().getContactManager().isOwnContactAdded()) {
196                         // Debug message
197                         this.getLogger().debug("Disabling menus: isOwnContactAdded()=false"); //NOI18N
198
199                         // Not entered yet, so disable "add" menu
200                         this.addOwnItem.setEnabled(false);
201                 } else {
202                         // Disable "edit"
203                         this.editOwnItem.setEnabled(false);
204                 }
205
206                 // Make the frame visible
207                 this.frame.setVisible(true);
208
209                 // All done here
210                 this.updateStatus("done"); //NOI18N
211         }
212
213         /**
214          * Initalizes this frame. Having initComponents() exposed (publicly
215          * accessible) means that any other object can initialize components which
216          * you may not want.
217          *
218          * @throws
219          * org.mxchange.addressbook.exceptions.FrameAlreadyInitializedException If
220          * this method has been called twice
221          */
222         @Override
223         public void init () throws FrameAlreadyInitializedException {
224                 // Debug line
225                 this.getLogger().trace("CALLED!"); //NOI18N
226
227                 // Has this frame been initialized?
228                 if (this.isInitialized()) {
229                         // Throw exception
230                         throw new FrameAlreadyInitializedException();
231                 }
232
233                 // Init components
234                 this.initComponents();
235
236                 // Set flag
237                 this.isInitialized = true;
238         }
239
240         /**
241          * Returns field isInitialized. This flag indicates whether this frame has
242          * been initialized or not.
243          *
244          * @return Field isInitialized
245          */
246         @Override
247         public final boolean isInitialized () {
248                 return this.isInitialized;
249         }
250
251         /**
252          * Shuts down the application.
253          */
254         @Override
255         public void shutdownApplication () {
256                 // To do this, the frame must be initialized
257                 if (!this.isInitialized()) {
258                         // Not initalized, so bad call
259                         this.getLogger().fatal("Bad call of shutdownApplication(). Please report this."); //NOI18N
260                         return;
261                 }
262                 this.getClient().getApplication().doShutdown();
263         }
264
265         /**
266          * Generates a title for borders
267          *
268          * @param key Key part to look for
269          * @return Human-readable title
270          */
271         private String generateBorderTitle (final String key) {
272                 // Call bundle instance
273                 return this.getBundle().getString(String.format("AddressbookFrame.border.%s.title.text", key)); //NOI18N
274         }
275
276         /**
277          * Generates a title for all frames based on given sub title key. If null is
278          * given, the sub title is not generated.
279          *
280          * @param subKey Key for sub title resource
281          * @return A full application title
282          */
283         private String generateFrameTitle (final String subKey) {
284                 // Base title
285                 String title = AddressbookApplication.printableTitle();
286
287                 // Is key given?
288                 if (subKey != null) {
289                         // Add sub title
290                         title = String.format("%s - %s", title, this.getBundle().getString(String.format("AddressbookFrame.%s.title.text", subKey))); //NOI18N
291                 }
292
293                 // Return it
294                 return title;
295         }
296
297         /**
298          * Initializes "add" and "cancel" buttons
299          */
300         private void initAddCancelButtons () {
301         }
302
303         /**
304          * Initializes "add contact" dialog
305          */
306         private void initAddContactDialog () {
307                 // Instance dialog and set title
308                 this.addContact = new JDialog();
309                 this.addContact.setTitle(this.generateFrameTitle("dialog.addContact")); //NOI18N
310
311                 // Set layout
312                 this.addContact.setLayout(new GridLayout(0, 1, 2, 2));
313
314                 // Only hide it on close and make it appear in middle of screen
315                 this.addContact.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
316                 this.addContact.setLocationRelativeTo(null);
317
318                 // Set always on top and auto-focus
319                 this.addContact.setAlwaysOnTop(true);
320                 this.addContact.setAutoRequestFocus(true);
321
322                 // Initial dimension
323                 this.addContact.setSize(500, 500);
324
325                 // And it is not resizeable
326                 this.addContact.setResizable(false);
327
328                 /*
329                  * Add listener which asks for confirmation, if data has been entered
330                  * but not saved yet. The user may appriciate this ... ;-)
331                  *
332                  * @TODO Unfinished
333                  */
334                 this.addContact.addWindowListener(new WindowAdapter() {
335                         /**
336                          * Invoked when a window has been closed.
337                          */
338                         @Override
339                         public void windowClosed (final WindowEvent e) {
340                                 // Enable main window again
341                                 AddressbookFrame.getSelfInstance(null).enableMainWindow();
342                         }
343
344                         /**
345                          * Invoked when a window is in the process of being closed. The
346                          * close operation can be overridden at this point.
347                          */
348                         @Override
349                         public void windowClosing (final WindowEvent e) {
350                                 e.getWindow().dispose();
351                         }
352                 });
353
354                 // Init 3 panels:
355                 // 1) "name" panel
356                 initNameDataPanel(this.addContact);
357
358                 // 2) "address" panel
359                 initAddressDataPanel(this.addContact);
360
361                 // 3) "other" panel
362                 initOtherDataPanel(this.addContact);
363
364                 // 4) "Add" and "Cancel" buttons
365                 initAddCancelButtons();
366
367                 // x)Only for developing:
368                 /* DEBUG: */ this.addContact.setVisible(true);
369         }
370
371         /**
372          * Initializes address panel
373          *
374          * @param dialog A JDialog instance to this components to
375          */
376         private void initAddressDataPanel (final JDialog dialog) {
377                 // Panel "address" input boxes
378                 JPanel addressPanel = new JPanel();
379                 addressPanel.setLayout(new BoxLayout(addressPanel, BoxLayout.Y_AXIS));
380
381                 // Set border to titled version
382                 addressPanel.setBorder(new TitledBorder(this.generateBorderTitle("address"))); //NOI18N
383
384                 // Init all elements:
385                 // 1) Street and number together
386                 JPanel streetNumberPanel = new JPanel();
387                 streetNumberPanel.setLayout(new GridLayout(1, 4, 5, 5));
388
389                 // Label for street
390                 JLabel streetLabel = new JLabel(this.getBundle().getString("AddressbookFrame.street.text"));
391
392                 // Init text field with label
393                 JTextField street = new JTextField(20);
394                 street.setToolTipText(this.getBundle().getString("AddressbookFrame.street.tooltipText"));
395
396                 // Add both to street panel
397                 streetNumberPanel.add(streetLabel);
398                 streetNumberPanel.add(street);
399
400                 // Number label
401                 JLabel numberLabel = new JLabel(this.getBundle().getString("AddressbookFrame.number.text"));
402
403                 // And text field, but only accept numbers
404                 JTextField number = new JTextField(4);
405                 number.setToolTipText(this.getBundle().getString("AddressbookFrame.number.tooltipText"));
406
407                 // Add number verifier
408                 number.setInputVerifier(new InputVerifier() {
409
410                         /**
411                          * Method to verify that the entered data is a number.
412                          *
413                          * @param input Input to verify
414                          * @return Whether the data is a number
415                          */
416                         @Override
417                         public boolean verify (final JComponent input) {
418                                 // Cast on text field
419                                 JTextField text = (JTextField) input;
420
421                                 // Default is passed
422                                 boolean isValid = true;
423
424                                 // Try to convert input text to a number
425                                 try {
426                                         int num = Integer.valueOf(text.getText());
427                                 } catch (final NumberFormatException ex) {
428                                         // Didn't work
429                                         isValid = false;
430                                 }
431
432                                 // Return status
433                                 return isValid;
434                         }
435                 });
436
437                 // Add both to street panel
438                 streetNumberPanel.add(numberLabel);
439                 streetNumberPanel.add(number);
440
441                 // Add panel to address panel
442                 addressPanel.add(streetNumberPanel);
443
444                 // 2) ZIP code and ccity name
445                 JPanel zipCityPanel = new JPanel();
446                 zipCityPanel.setLayout(new GridLayout(1, 4, 5, 5));
447
448                 // Label for ZIP code, again numbers only
449                 JLabel zipLabel = new JLabel(this.getBundle().getString("AddressbookFrame.zip.text"));
450
451                 // Init text field with label
452                 JTextField zip = new JTextField(20);
453                 zip.setToolTipText(this.getBundle().getString("AddressbookFrame.zip.tooltipText"));
454
455                 // Add number verifier
456                 zip.setInputVerifier(new InputVerifier() {
457
458                         /**
459                          * Method to verify that the entered data is a number.
460                          *
461                          * @param input Input to verify
462                          * @return Whether the data is a number
463                          */
464                         @Override
465                         public boolean verify (final JComponent input) {
466                                 // Cast on text field
467                                 JTextField text = (JTextField) input;
468
469                                 // Default is passed
470                                 boolean isValid = true;
471
472                                 // Try to convert input text to a number
473                                 try {
474                                         int num = Integer.valueOf(text.getText());
475                                 } catch (final NumberFormatException ex) {
476                                         // Didn't work
477                                         isValid = false;
478                                 }
479
480                                 // Return status
481                                 return isValid;
482                         }
483                 });
484
485                 // Add both to street panel
486                 zipCityPanel.add(zipLabel);
487                 zipCityPanel.add(zip);
488
489                 // Label for street
490                 JLabel cityLabel = new JLabel(this.getBundle().getString("AddressbookFrame.city.text"));
491
492                 // Init text field with label
493                 JTextField city = new JTextField(20);
494                 city.setToolTipText(this.getBundle().getString("AddressbookFrame.city.tooltipText"));
495
496                 // Add both to street panel
497                 zipCityPanel.add(cityLabel);
498                 zipCityPanel.add(city);
499
500                 // Add panel to address panel
501                 addressPanel.add(zipCityPanel);
502
503                 // Add panel to dialog
504                 dialog.add(addressPanel);
505         }
506
507         /**
508          * Initialize components
509          */
510         private void initComponents () {
511                 // Debug line
512                 this.getLogger().trace("CALLED!"); //NOI18N
513
514                 // Set default close operation
515                 this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
516
517                 // Register shutdown listener
518                 this.frame.addWindowListener(new WindowAdapter() {
519                         /**
520                          * Invoked when a window has been closed.
521                          */
522                         @Override
523                         public void windowClosed (final WindowEvent e) {
524                                 // Shutdown application cleanly
525                                 self.shutdownApplication();
526                         }
527
528                         /**
529                          * Invoked when a window is in the process of being closed. The
530                          * close operation can be overridden at this point.
531                          */
532                         @Override
533                         public void windowClosing (final WindowEvent e) {
534                                 // Also shutdown cleanly here
535                                 self.shutdownApplication();
536                         }
537                 });
538
539                 // Setup layout manager
540                 this.frame.setLayout(new BorderLayout(2, 2));
541
542                 // Set window size
543                 this.frame.setSize(700, 400);
544
545                 // Center window in middle of screen, instead of top-left corner
546                 this.frame.setLocationRelativeTo(null);
547
548                 // Init menu system
549                 initMenuSystem();
550
551                 // Init table
552                 initTable();
553
554                 // Init status panel
555                 initStatusPanel();
556
557                 // Init other windows
558                 initOtherDialogs();
559         }
560
561         /**
562          * Initializes the menu system
563          */
564         private void initMenuSystem () {
565                 // Init menu bar, menu and item instances
566                 JMenuBar menuBar = new JMenuBar();
567                 JMenu menu;
568                 JMenuItem item;
569
570                 // Init some menus:
571                 // 1) File menu
572                 menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.file.text"));
573
574                 // Add menu items:
575                 // 1.x) Exit program (should be last)
576                 item = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.text"));
577                 item.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.exitProgram.toolTipText"));
578
579                 // Add listener to exit menu
580                 item.addActionListener(new ActionListener() {
581                         /**
582                          * If the user has performed this action
583                          *
584                          * @param e An instance of an ActionEvent class
585                          */
586                         @Override
587                         public void actionPerformed (final ActionEvent e) {
588                                 self.shutdownApplication();
589                         }
590                 });
591
592                 // Add item -> menu
593                 menu.add(item);
594
595                 // Add menu -> menu bar
596                 menuBar.add(menu);
597
598                 // Init some menus:
599                 // 2) Addressbook menu
600                 menu = new JMenu(this.getBundle().getString("AddressbookFrame.menu.addressbook.text"));
601
602                 // 2.1) Add own data
603                 this.addOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.text"));
604                 this.addOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.addOwnData.toolTipText"));
605
606                 // Add listener to exit menu
607                 this.addOwnItem.addActionListener(new ActionListener() {
608                         /**
609                          * If the user has performed this action
610                          *
611                          * @param e An instance of an ActionEvent class
612                          */
613                         @Override
614                         public void actionPerformed (final ActionEvent e) {
615                                 self.getClient().getContactManager().doEnterOwnData();
616                         }
617                 });
618
619                 // Add item -> menu
620                 menu.add(this.addOwnItem);
621
622                 // 2.2) Edit own data
623                 this.editOwnItem = new JMenuItem(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.text"));
624                 this.editOwnItem.setToolTipText(this.getBundle().getString("AddressbookFrame.menuItem.editOwnData.toolTipText"));
625
626                 // Add listener to exit menu
627                 this.editOwnItem.addActionListener(new ActionListener() {
628                         /**
629                          * If the user has performed this action
630                          *
631                          * @param e An instance of an ActionEvent class
632                          */
633                         @Override
634                         public void actionPerformed (final ActionEvent e) {
635                                 self.getClient().getContactManager().doChangeOwnData();
636                         }
637                 });
638
639                 // Add item -> menu
640                 menu.add(this.editOwnItem);
641
642                 // Add menu -> menu bar
643                 menuBar.add(menu);
644
645                 // Add menu bar -> frame
646                 this.frame.add(menuBar, BorderLayout.NORTH);
647         }
648
649         /**
650          * Initializes name panel
651          *
652          * @param dialog A JDialog instance to this components to
653          */
654         private void initNameDataPanel (final JDialog dialog) {
655                 // Panel "name" input boxes
656                 JPanel namePanel = new JPanel();
657                 namePanel.setLayout(new BoxLayout(namePanel, BoxLayout.Y_AXIS));
658
659                 // Set border to titled version
660                 namePanel.setBorder(new TitledBorder(this.generateBorderTitle("name"))); //NOI18N
661
662                 // Panel for gender
663                 JPanel gPanel = new JPanel();
664                 gPanel.setLayout(new GridLayout(1, 2, 5, 5));
665
666                 // Gender text field
667                 JLabel gLabel = new JLabel(this.getBundle().getString("AddressbookFrame.gender.text"));
668
669                 // Get all genders
670                 Gender[] genders = Gender.values();
671
672                 // Init gender combo box with tool tip
673                 JComboBox<Gender> gender = new JComboBox<>(new DefaultComboBoxModel<>(genders));
674                 gender.setToolTipText(this.getBundle().getString("AddressbookFrame.gender.tooltipText"));
675
676                 // Add both to gender panel
677                 gPanel.add(gLabel);
678                 gPanel.add(gender);
679
680                 // Add gender panel to "name" panel
681                 namePanel.add(gPanel);
682
683                 // Panel for surname
684                 JPanel sPanel = new JPanel();
685                 sPanel.setLayout(new GridLayout(1, 2, 5, 5));
686
687                 // New label for surname is not needed
688                 JLabel sLabel = new JLabel(this.getBundle().getString("AddressbookFrame.surname.text"));
689
690                 // And input box wih tool tip
691                 JTextField surname = new JTextField(20);
692                 surname.setToolTipText(this.getBundle().getString("AddressbookFrame.surname.tooltipText"));
693
694                 // Add both to surname panel
695                 sPanel.add(sLabel);
696                 sPanel.add(surname);
697
698                 // Add surname panel to "name" panel
699                 namePanel.add(sPanel);
700
701                 // Panel for surname
702                 JPanel fPanel = new JPanel();
703                 fPanel.setLayout(new GridLayout(1, 2));
704
705                 // New label for surname is not needed
706                 JLabel fLabel = new JLabel(this.getBundle().getString("AddressbookFrame.familyName.text"));
707
708                 // And input box wih tool tip
709                 JTextField familyName = new JTextField(20);
710                 familyName.setToolTipText(this.getBundle().getString("AddressbookFrame.familyName.tooltipText"));
711
712                 // Add both to surname panel
713                 fPanel.add(fLabel);
714                 fPanel.add(familyName);
715
716                 // Add family namepanel to "name" panel
717                 namePanel.add(fPanel);
718
719                 // Finally add panel to dialog
720                 dialog.add(namePanel);
721         }
722
723         /**
724          * Initializes "other" data panel
725          *
726          * @param dialog A JDialog instance to this components to
727          * @todo Fill this with life
728          */
729         private void initOtherDataPanel (final JDialog dialog) {
730                 // Panel "other" input boxes
731                 JPanel otherPanel = new JPanel();
732                 otherPanel.setLayout(new BoxLayout(otherPanel, BoxLayout.Y_AXIS));
733
734                 // Set border to titled version
735                 otherPanel.setBorder(new TitledBorder(this.generateBorderTitle("other"))); //NOI18N
736
737                 // Finally add panel to dialog
738                 dialog.add(otherPanel);
739         }
740
741         /**
742          * Initialize other dialogs (e.g. "Add contact")
743          */
744         private void initOtherDialogs () {
745                 // Init other windows:
746                 // 1) Add contact
747                 initAddContactDialog();
748         }
749
750         /**
751          * Initializes status panel
752          */
753         private void initStatusPanel () {
754                 // Init status label (which needs to be updated
755                 this.statusLabel = new JLabel();
756                 this.updateStatus("initializing"); //NOI18N
757
758                 // Init status bar in south
759                 JPanel panel = new JPanel();
760                 panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
761                 panel.add(this.statusLabel);
762                 panel.setBorder(BorderFactory.createEtchedBorder());
763
764                 // Add panel to frame
765                 this.frame.add(panel, BorderLayout.SOUTH);
766         }
767
768         /**
769          * Initializes the table which will show all contacts
770          */
771         private void initTable () {
772                 // Instance table model
773                 this.dataModel = new ContactTableModel(this.getClient());
774
775                 // Instance table
776                 this.dataTable = new JTable(this.dataModel);
777
778                 // Add mouse listener
779                 this.dataTable.addMouseListener(new MouseAdapter() {
780                         /**
781                          * If the user peformed a click on a cell
782                          *
783                          * @param e Mouse event instance
784                          */
785                         @Override
786                         public void mouseClicked (final MouseEvent e) {
787                                 throw new UnsupportedOperationException("Unfinished."); //NOI18N
788                         }
789                 });
790
791                 // Instance scroll pane
792                 JScrollPane scroller = new JScrollPane();
793
794                 // Add table to scroll pane
795                 scroller.setViewportView(this.dataTable);
796                 scroller.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
797                 scroller.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
798
799                 // Add pane to frame
800                 this.frame.add(scroller, BorderLayout.CENTER);
801         }
802
803         /**
804          * Updates status to given type
805          *
806          * @param type Status type
807          */
808         private void updateStatus (final String type) {
809                 // Set status message
810                 this.statusLabel.setText(this.getBundle().getString(String.format("AddressbookFrame.statusLabel.%s.text", type))); //NOI18N
811         }
812 }