9.3 Toolbars and Multiple Container Classes


Toolbars and Menus

Toolbars and Menus are containers for components, such as general actions related to an application. In most applications you will have a File menu that allows you to exit, or load a file or print your document etc.

The JToolBar Class

Figure 9.14, “The JToolBar Example Application. Toolbar (a) at top (b) at bottom.” shows two views of the same application, where the toolbar is shown on top in (a) and at the bottom in (b). The toolbar has several components added to it. The first is a JLabel component with an ImageIcon, the second is a JButton component, the third is a JComboBox component with 5 items and finally a JToggleButton. The JToolBar object was created and the items added using the following code:



                theToolbar = new JToolBar("My Toolbar");
                theToolbar.setFloatable(true);

                theTextArea = new JTextArea(20,20);
                JScrollPane p = new JScrollPane(this.theTextArea,
                        JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                        JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

                URL iconLocation = this.getClass().getResource("image.gif");
                ImageIcon icon = new ImageIcon(iconLocation, "A running dog icon");
                JLabel theLabel = new JLabel(icon);
                theToolbar.add(theLabel);

                testButton = new JButton("Test");
                testButton.addActionListener(this);
                theToolbar.add(testButton);
                
                String[] items = {"Item 1", "Item 2", "Item 3", "Item 4", "Item 5"};
                 comboBox = new JComboBox<String>(items);
                 comboBox.addActionListener(this);
                 theToolbar.add(comboBox);

                theToolbar.addSeparator();
                
                toggleButton = new JToggleButton("Test Toggle");
                toggleButton.addActionListener(this);
                theToolbar.add(toggleButton);

To allow the JToolBar object to be dragged from the top to the sides and to the bottom, the window container should have a BorderLayout and should not have other components added to the North, South, East or West.

In the code segment an ActionListener is added to the JButton object, to the JComboBox object and to the JToggleButton object. This class implements the ActionListener and so has an actionPerformed() method implemented. We will use the getSource() on the ActionEvent to identify the source object of the event. A space is added on the toolbar using the addSeperator() method. This method also allows you to specify the size of gap you require. To add the toolbar to the window container simply use the add() method, in this case applied to the Container returned from the JFrame getContentPane() method.

Figure 9.14. The JToolBar Example Application. Toolbar (a) at top (b) at bottom.


If you allow the JToolbar to be floatable (using the JToolBar setFloatable(true) method then the menu bar can be dragged off the top of the application and can exist as its own window. See Figure 9.15, “The JToolBar Example with Floating Toolbar” to see this.

Figure 9.15. The JToolBar Example with Floating Toolbar


The full code for this example is in JToolbarExample.java

The JMenuBar Class

The same application as shown above in the section called “The JToolBar Class” (and source code in JToolBarExample.java) also demonstrates the use of the JMenuBar class.

Figure 9.16, “The JMenuBar Example” shows the menu in action. There are four menu items and a sub-menu with two sub menu items. Notice that the first three items have short-cut keys (or accelerator keys). The constructors for JMenuItem are:

Constructors 
Constructor and Description
JMenuItem()
Creates a JMenuItem with no set text or icon.
JMenuItem(Action a)
Creates a menu item whose properties are taken from the specified Action.
JMenuItem(Icon icon)
Creates a JMenuItem with the specified icon.
JMenuItem(String text)
Creates a JMenuItem with the specified text.
JMenuItem(String text, Icon icon)
Creates a JMenuItem with the specified text and icon.
JMenuItem(String text, int mnemonic)
Creates a JMenuItem with the specified text and keyboard mnemonic.

Each of the JMenuItem objects has had an ActionListener applied, so when it is selected an ActionEvent object is generated and so our actionPerformed() method is called and in this case simply displays the menu item that was selected.

Figure 9.16. The JMenuBar Example

To add the MenuBar to a JFrame, use the JFrame class setJMenuBar() method (remember to put in the J as otherwise you would be using the AWT MenuBar and Frame methods). So you add the JMenuItem objects to the JMenu object and then you add the JMenu object to the JMenuBar object which is in turn added to the JFrame object. To create a sub-menu, as in Figure 9.16, “The JMenuBar Example” simply create a new JMenu object and add it to a JMenu object (i.e. there is no special sub menu 

                JMenuBar menuBar = new JMenuBar();
                JMenu firstMenu = new JMenu("First Menu");
                JMenuItem item1 = new JMenuItem("First Item", KeyEvent.VK_F);
                JMenuItem item2 = new JMenuItem("Second Item", KeyEvent.VK_S);
                JMenuItem item3 = new JMenuItem("Third Item", KeyEvent.VK_T);
                JMenuItem item4 = new JMenuItem("Some Item", icon);
                JMenuItem sub1 = new JMenuItem("Sub Menu Item 1");
                JMenuItem sub2 = new JMenuItem("Sub Menu Item 2");
                JMenu aSubMenu = new JMenu("Sub Menu");
                aSubMenu.add(sub1);
                aSubMenu.add(sub2);                

                item1.addActionListener(this);
                item2.addActionListener(this);
                item3.addActionListener(this);
                item4.addActionListener(this);
                sub1.addActionListener(this);
                sub2.addActionListener(this);

                menuBar.add(firstMenu);
                firstMenu.add(item1);
                firstMenu.add(item2);
                firstMenu.add(item3);
                firstMenu.add(item4);
                firstMenu.add(aSubMenu);         
        
                this.setJMenuBar(menuBar);

Multi-Panel Containers

The JTabbedPane Class.

The JTabbedPane class allows the creation of a container that allows several panels to be added to the one space. Figure 9.17, “The JTabbedPane Example (a) first tab (b) second tab.” shows an example of a JTabbedPane with two tabs. You can select which container to view by pressing the tab at the top. To create a JTabbedPane simply use a default constructor:

  JTabbedPane tabbedPane = new JTabbedPane();

and then to add tabs to the JTabbedPane use:

  tabbedPane.addTab(String Title, ImageIcon icon, JPanel thePanel, String ToolTip);
  

For this example two JPanel objects are added to each tab. The first JPanel object contains a TextArea object in a JScrollPane container. The second JPanel container has a JLabel object and a JButton object.

Figure 9.17. The JTabbedPane Example (a) first tab (b) second tab.

The full code for this example is here - JTabbedPaneExample.java

The JInternalFrame Class.

The JInternalFrame class allows you to create an application where you have windows within the main application. You may have seen this in applications like Adobe PhotoShop. To use JInternalFrame objects are added to a JDesktopPane, which is like a blank panel that contains the internal windows. Internal Frames are not windows, so they do not generate window events. They can be minimised to an icon within the desktop pane. The constructors for JInternalFrame are:

Constructors 
Constructor and Description
JInternalFrame()
Creates a non-resizable, non-closable, non-maximizable, non-iconifiable JInternalFrame with no title.
JInternalFrame(String title)
Creates a non-resizable, non-closable, non-maximizable, non-iconifiable JInternalFrame with the specified title.
JInternalFrame(String title, boolean resizable)
Creates a non-closable, non-maximizable, non-iconifiable JInternalFrame with the specified title and resizability.
JInternalFrame(String title, boolean resizable, boolean closable)
Creates a non-maximizable, non-iconifiable JInternalFrame with the specified title, resizability, and closability.
JInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable)
Creates a non-iconifiable JInternalFrame with the specified title, resizability, closability, and maximizability.
JInternalFrame(String title, boolean resizable, boolean closable, boolean maximizable, boolean iconifiable)
Creates a JInternalFrame with the specified title, resizability, closability, maximizability, and iconifiability.

Figure 9.18, “The JInternalFrame Example” shows an example of the JInternalFrame in action. The full code for this example is below and in JInternalFrameExample.java.

Figure 9.18. The JInternalFrame Example


12345678910111213141516171819202122232425262728293031323334353637
/** Java Swing Examples - Written by Derek Molloy, Dublin City University, Ireland
* see: http://ee402.eeng.dcu.ie/
*/
package ee402;

import javax.swing.*;
import java.awt.*;
import java.net.URL;

@SuppressWarnings("serial")
public class JInternalFrameExample extends JFrame
{        
        public JInternalFrameExample() {
                super("JInternalFrame Example");
                JDesktopPane desktop = new JDesktopPane();                

                this.getContentPane().add("North", new JLabel("A Regular JLabel"));
                this.getContentPane().add("Center", desktop);

                JInternalFrame internal1 = new JInternalFrame("Frame 1", true, true, true, true);
                internal1.setSize(300,300);
                internal1.show();
                
                URL imageURL = this.getClass().getResource("test.jpg");
                Image testImage = this.getToolkit().getImage(imageURL);
                internal1.getContentPane().add(new JScrollPane(new JLabel(new ImageIcon(testImage))));
                internal1.setLocation(50,50);
                desktop.add(internal1);

                this.setSize(400,400);
                this.setVisible(true);
        }
        
        public static void main(String[] args) {
                new JInternalFrameExample();
        }
}

In this example the JFrame has a regular JLabel added to the "North" and the JDesktopPane added to the "Center". The JDesktopPane object is the container for the JInternalFrame objects. In this case there is only one JInternalFramecalled internal1. In the creation of the JInternalFrame the title was set as "Frame 1" and it was set allowed to be resizable, closable, maximizable and iconifiable (yes that is a real word!). The size was set at 300 x 300 using the setSize()method and then the show() method was called to make the internal frame visible. The show() method must be called to show the internal frames. A Image object is created and added to an ImageIcon object, which is in turn added to a JLabeland then this is added to a JScrollPane container. The location of the internal frame is set at (50,50) using the setLocation() method and finally the JInternalFrame object is added to the JDesktopPane container.

The full code for this example is here - JTabbedPaneExample.java. This application assumes an image in the same directory called test.jpg - You can use this one if you wish test.jpg (as with all files you can right-click and choose "Save Target As..")

The JSplitPane Class.

The JSplitPane class allows two components to be added to the split pane with a divider between them. The divider can be dragged left and right, if a horizontal split is used and top and bottom if a vertical split is used. You should really use JScrollPane containers around the JPanel or component that you use, as when you move the split in the split pane the container will not be completely visible. Figure 9.19, “The JSplitPane Example Application. Split (a) centre right (b) more right of centre.” displays a JSplitPane container in action, where (a) and (b) show the split moved from left to right (note that the scrollbars move the container correctly). If you require more than two panes in the JSplitPane container, you can nest a JSplitPane container within another JSplitPane container.

Figure 9.19. The JSplitPane Example Application. Split (a) centre right (b) more right of centre.


Here is the code for the example in Figure 9.19, “The JSplitPane Example Application. Split (a) centre right (b) more right of centre.”, as below and as in JSplitPaneExample.java.

12345678910111213141516171819202122232425262728293031323334353637383940
/** Java Swing Examples - Written by Derek Molloy, Dublin City University, Ireland
* see: http://ee402.eeng.dcu.ie/
*/
package ee402;

import java.awt.Image;
import java.net.URL;
import javax.swing.*;

@SuppressWarnings("serial")
public class JSplitPaneExample extends JFrame {        
        
        public JSplitPaneExample() {
                super("JSplitPane Example");

                JScrollPane pane2 = new JScrollPane(new JTextArea("A test text area",20,20)
                        , JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                         JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

                URL imageURL = this.getClass().getResource("test.jpg");
                Image testImage = this.getToolkit().getImage(imageURL);
                
                JScrollPane pane1 = new JScrollPane(new JLabel(new ImageIcon(testImage))
                        , JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
                         JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

                JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
                         pane1, pane2);
                splitPane.setOneTouchExpandable(true);
                splitPane.setDividerLocation(400);
                
                this.getContentPane().add("Center", splitPane);
                this.setSize(600,400);        // set the size
                this.setVisible(true);
        }
        
        public static void main(String[] args) {
                new JSplitPaneExample();
        }
}

In this example two JScrollPane objects are added to the JSplitPane using the constructor of the object:

Constructors 
Constructor and Description
JSplitPane()
Creates a new JSplitPane configured to arrange the child components side-by-side horizontally, using two buttons for the components.
JSplitPane(int newOrientation)
Creates a new JSplitPane configured with the specified orientation.
JSplitPane(int newOrientation, boolean newContinuousLayout)
Creates a new JSplitPane with the specified orientation and redrawing style.
JSplitPane(int newOrientation, boolean newContinuousLayout, Component newLeftComponent, Component newRightComponent)
Creates a new JSplitPane with the specified orientation and redrawing style, and with the specified components.
JSplitPane(int newOrientation, Component newLeftComponent, Component newRightComponent)
Creates a new JSplitPane with the specified orientation and the specified components.

where JSplitPane.HORIZONTAL_SPLIT defines the orientation and next two objects are the JScrollPane components. When the setOneTouchExpandable() is passed a value of true then the divider displays two little arrows, when pressed on fully expand the left of right pane (you can see these arrows in Figure 9.19, “The JSplitPane Example Application. Split (a) centre right (b) more right of centre.” at the top of the divider). The divider location can be placed using the setDividerLocation().

There are other methods that are useful for the JSplitPane

  • setDividerSize(int) - Sets the width of the divider.

  • resetToPreferredSize() - Sets the size of the split pane based on the preferred size of the added components.

  • setResizeWeight(double) - Sets how the scroll pane should react when it is resized. A value of 0 specifies the right component gets all the new space, 1 specifies the left component gets all the new space - 0.5 gives both sides equal new space.

  • setRightComponent() - Allows you to specify a new component for the right hand side. setLeftComponent() allow you to specify a new component for the left hand side.

These notes are copyright Dr. Derek Molloy, School of Electronic Engineering, Dublin City University, Ireland 2013-present. Please contact him directly before reproducing any of the content in any way.
Comments