15 Implementing Java Swing User Interfaces

This chapter describes how to create graphical user interfaces (GUIs) for applications using the Swing components.

Using the Swing GUI builder in JDeveloper, you can quickly and easily assemble the elements of a user interface (UI) for a Java application using Swing components. You construct the UI with components selected from the Components window, such as buttons, text areas, lists, dialogs, and menus. Then, you set the values of the component properties and attach event-handler code to the component events.

Included is a description of the UI debugger, which is used to debug user interfaces specifically for AWT and Swing-based client applications. The UI Debugger offers an alternative way of debugging a GUI application.

This chapter includes the following sections:

15.1 About Applications Developed in Earlier Versions

Applications which use Swing which were developed in earlier versions of JDeveloper can be migrated and opened in this version of JDeveloper, and there is full support for working with previously designed visual classes. The legacy editor works with any class that has a jbInit() method.

You can visually edit forms in the old application using the old Java Visual Editor, however the way it worked and the way the new Swing GUI builder works are different, and there is no migration from one to another.

15.2 About Java Swing UI Components and Containers

Java Swing components include everything from buttons, tables, text components, and split panes. For example, the JCheckbox component is a square box used to display boolean (true/false) values. Many components are capable of sorting, printing, and drag and drop, as well as other supported features.

You can see examples of Java Swing in the tutorials, which are available at http://docs.oracle.com/javase/tutorial/uiswing/.

When you lay out a form to design the UI in JDeveloper, you use a container. Containers are also components. They hold and manage other components. You interact with them by getting and setting their properties, calling their methods, and responding to their events as with any other component. JDeveloper provides tools to help you generate your containers. See Chapter 15, "Working with Containers" for more information.

A layout manager automatically arranges the components in a container according to a particular set of rules specific to that layout manager. It determines the size and position of the components within a container. For example, the BorderLayout arranges a container's components in areas named First, Last, Before, After, Center.

Figure 15-1 BorderLayout

BorderLayout

15.3 Designing Java GUIs

The IDE's GUI Builder enables you to design GUI's (graphical user interfaces) visually. As you create and modify your GUI, the IDE automatically generates the Java code to implement the interface.

Whenever you open a GUI form, the IDE displays it with tabs enabling you to switch between Source and Design views. The Design view enables you to work with GUI forms visually while the Source view permits editing of the form's source code directly.

Typically, you add components to a form using the Components window and arrange them in the GUI Builder workspace. As you work, the GUI Builder automatically displays guidelines suggesting preferred alignment and anchoring for the components you add. Using the Properties window in conjunction with the Structure window, you can then examine and adjust properties of a form's components and layout managers, manage component event handlers, and define how code is generated.

Notes:

  • GroupLayout was added to version 6 of the Java Platform. You can set the version of GroupLayout in the property sheet for each form.

  • To use the GUI Builder, you must work with files that were created with the IDE's GUI form templates. You cannot use the GUI Builder to edit GUI forms (that is Java files) that were created outside of the IDE.

15.3.1 About Guarded Blocks

As you work with a form in the Design view, code is generated automatically by the GUI Builder and is displayed in the Source view with a grey background. This code is called guarded code and is not directly editable.

Note:

You can freely edit all the code that is not guarded. For example, you can write code for initialization or customization of the UI (in the constructor just after the initComponents() call).

All the components have assigned fields so they can be accessed from anywhere in the Java class.

Guarded text generated by the GUI Builder's includes:

  • Blocks of components' variable declarations.

  • The initComponents() method, in which form initialization is performed. This method is called from the form's constructor and though it is not editable manually, you can affect the way it is generated by editing the Code properties in the component's property sheet.

  • The header (and trailing brace) of all event handlers.

15.4 How to Create a Form

You can create forms within an existing project.

To create a new form:

  1. In the Applications window, select the project where you want to create the form.

  2. From the main menu, select New > From Gallery > Client Tier > Swing/AWT.

  3. Select the type of form you want to create.

  4. Complete the wizard and click OK.

  5. Scroll to the source file for the form in the Applications window, for example, NewPanel.java.

  6. Double-click the source file.

    The GUI builder displays where you can edit the form.

15.5 Understanding the Forms You Can Create

The following table contains the forms you can build in JDeveloper.

Form Description

JPanel Form

Creates a new Swing panel. Panels are frequently used to group together several other components into one place. A JPanel itself can be used as a component within a JFrame or JDialog.

JFrame Form

Creates a new Swing frame. Frames are typically used as stand-alone top level windows as the main user interface to the application. Most Swing applications are built starting from this form.

JDialog Form

Creates a new Swing dialog. Dialogs are modal or modeless windows that are typically used to prompt users for input.

JInternalFrame Form

Creates a new Swing internal frame that can be placed into a JDesktopPane to provide an MDI user interface.

Bean Form

Creates a new form based on any JavaBeans component (either visual or non-visual). You must specify the bean class in the wizard.

Panel Form

Creates a new AWT (Abstract Window Toolkit) panel. Panels are frequently used to group together several other components into one place.

AWT is the toolkit used in previous versions of JDeveloper. Swing is preferred now.

Frame Form

Creates a new AWT form. Frames are typically used as stand-alone top level windows as the main user interface to the application.

Dialog Form

Creates a new AWT dialog. Dialogs are modal or modeless windows that are typically used to prompt users for input


15.6 Adding Components

Once you have created a new form, you can add components for display and control. You can add components a few different ways:

To add a component from the Components window:

  1. Select a component in the Components window by clicking its icon.

  2. Without releasing the mouse button, drag the component to the desired location in the form.

  3. If you want to add a non-visual component, or a visual component, out of the visual hierarchy of the designed container, place it in the white area around the form. It will then appear under the Other Components node in the Structure window.

To add multiple components from the Components window:

  1. Select a component in the Components window by clicking its icon. Release the mouse button.

  2. While holding down the shift key, click each location in the form where you want to place an instance of the component you selected in the palette.

  3. Release the shift key when adding the last component, or press Esc or right click to cancel adding.

  4. If you want to add a non-visual component, or a visual component but out of the visual hierarchy of the designed container, place it in the white area around the form. It will then appear under the Other Components node in the Structure window.

To add a component using the context menu:

  1. In the Structure window, right-click the container to which you want to add a component.

  2. Choose the desired component from the Add From Palette submenu.

15.6.1 How to Set Component Properties

Once you have added a component to a form, you can adjust its behavior and appearance in the Properties window.

To edit a component's properties:

  1. Select the component in the GUI Builder or Structure window to display its properties in the Properties window. Note that if you select multiple components, their common properties are displayed and any modifications apply to all of the selected components.

  2. Edit the component's properties in the Properties window by selecting the property and entering the desired value.

  3. If the property you want to edit has an ellipsis (...) button, you can click it to open a special property editor that provides more advanced editing options (e.g. a color chooser for a color-type property), or alternate ways of specifying the property value (e.g. using a resource bundle for a text property), including a possibility to type directly the code that should represent the property value.

    Use this to edit a given property in another way than in the small in-place editor in the properties window. You can also choose from several ways how to enter the property value via the combo box at the top.

15.6.2 How to Select Components in Your User Interface

Before attempting to select an existing component in your UI, be sure the selection arrow in the GUI builder toolbar is depressed. Otherwise, you may accidentally place a component on your UI.

15.6.2.1 How to Select a Single Components

To select a single component, do one of the following:

  • Click the component in the GUI Builder.

  • With focus on the GUI Builder, tab to the component (Tab = forward; Shift+Tab = backward).

  • Select the component in the Structure window

15.6.2.2 How to Select Multiple Components

To select multiple components, hold down the Ctrl key and do one of the following:

  • Hold down the Ctrl key and click the components in the GUI builder or in the Structure window to add/remove components from selection one by one.

  • Click and drag around the outside of the components you want to select. As you drag, you surround the components with a rectangle, or "lasso." When this rectangle encloses all the components you want to select, release the mouse button. If necessary, you can then use Ctrl+click to individually add or remove components from the selected group.

    If you need to drag for selection inside a sub-container, you would normally drag the sub-container away. To prevent that, press and hold Shift during dragging.

  • Hold down shift holding Shift and click components in the Structure window to perform an interval selection. On design canvas clicking with Shift adds to selection one by one, but does not remove from selection.

15.6.3 How to Align Components

Once you have added components, you can adjust their alignment them to ensure that your form will appear as desired at runtime.

Most of the time, you can achieve the desired alignments by "snapping" components at the suggested positions when dragging. Then you can further adjust the alignment using alignment actions from the toolbar or context menu.

Note:

This applies only to Free Design (the default layout mode), not to other layout managers.

To align components:

  1. Select the components you want to align in the GUI Builder.

  2. Click the appropriate align button in the GUI Builder toolbar.

    Alternately, you can right-click either component and choose Align > Left in Column (or Align > Right in Column) from the pop-up menu.

    The IDE shifts the component positions so that the specified edges are aligned and the component anchoring relationships are updated.

15.6.4 How to Size Components

It is often beneficial to set several related components, such as buttons in modal dialogs to be the same size so they can be easily recognized as offering similar functionality. You can also adjust the resizing behavior of components to ensure that component relationships are maintained at runtime.

The Free Design mode allows you to size components using mouse any way you need. Do this with consideration, though. Resizing a component from its default size to a fixed size leads to setting the component with a hardcoded size in pixels that may go against the cross-platform layout principles. Typically you do not want to resize buttons or labels, their size should only be defined by their text. It is usually fine to resize components with no fixed content that are set to "Auto Resizing" because they can still accommodate their size in runtime (for example, text fields).

When working with null, AbsoluteLayout, or GridBagLayout, you can size components when you first place them in your UI, or you can resize and move components later.

Note:

This applies only to Free Design (the default layout mode), not to other layout managers.

To set components to the same size:

  1. Select all of the components you want to be the same size in the GUI Builder.

  2. Right-click any one of components, and choose Same Size > Set Width (or Same Size > Set Height) from the context menu.

To set component resizing behavior:

  1. Select the components whose auto resizing behavior you want to set.

  2. Right-click any one of the components and choose Auto Resizing > Horizontal (or Auto Resizing > Vertical) from the context menu.

    Alternatively, use the toolbar buttons.

    Component auto-resizing behavior is set to resize horizontally at runtime. The alignment guidelines and anchoring indicators are updated to indicate the new component relationships.

15.7 Working with Containers

Java GUIs are forms comprised of top-level containers within which are grouped sub-containers as well as the various components used to provide the desired information and control functionality.

It is often useful to focus work on single subcontainers rather than the entire form the GUI Builder generally displays. When working with large forms containing complex nested hierarchies of containers, changing the scope of the GUI Builder's focus enables you to concentrate on specific parts of your interface.

To change the GUI Builder's focus to a specific container:

  1. In the GUI Builder or Structure window, right-click the container you want to edit.

  2. Choose Design This Container from the contextual menu.

    The IDE adjusts display of the workspace such that the current container fills the work area and hides the form's other components. The form's entire hierarchy remains available in the Structure window.

To return the GUI Builder's display focus to the entire form:

  1. Right-click the container in the GUI Builder.

  2. Choose Design Top Container from the contextual menu.

    The IDE adjusts the work area display such that the entire form is visible. If the Design Top Container menu item is dimmed, you are already designing the entire form.

15.7.1 Reordering Components Within a Container

The order of components in a container follows the sequence in which components are added. If the layout manager you have chosen for a container does not use constraints (FlowLayout, BoxLayout, and GridLayout), the order of components also determines how they are arranged visually. You can, however, reorder the components using the Structure window or by dragging them in the form itself.

With layout managers that use constraints (BorderLayout, GridBagLayout, CardLayout, AbsoluteLayout, and Null Layout), the order of components in the container does not determine the order in which the components appear. For these containers, you can only rearrange the component order in the Structure window. Although GridBagLayout uses constraints to determine how components are arranged, component order determines the layout when the Grid X and Grid Y constraints are not used.

15.8 Working with Layout Managers

A Java program can be deployed on more than one platform. If you use standard UI design techniques of specifying absolute positions and sizes for your UI components, your UI might not look good on all platforms. For this reason, you should not use AbsoluteLayout and null layout in production UI. These are not suitable for cross-platform UI, should be used only for prototyping or with awareness of their restrictions.What looks fine on your development system might be unusable on another platform. To solve this problem, Java provides a system of portable layout managers. Layout managers allow you to specify rules and constraints for the layout of your UI in a way that will be portable.

Layout managers enable you to control the way in which visual components are arranged in GUI forms by determining the size and position of components within containers. This is accomplished by implementing the LayoutManager interface.

Use JDeveloper's layout managers to control how components are located and sized in the container each time it is displayed. A layout manager automatically arranges the components in a container according to a particular set of rules specific to that layout manager.

Layout managers give you the following advantages:

  • Correctly positioned components that are independent of fonts, screen resolutions, and platform differences.

  • Intelligent component placement for containers that are dynamically resized at runtime.

  • Ease of translation with different sized strings. If a string increases in size, the components stay properly aligned.

The layout manager sets the sizes and locations of the components based on various factors such as:

  • the layout manager's layout rules

  • the layout manager's property settings, if any

  • certain properties common to all components, such as preferredSize, minimumSize, maximumSize, alignmentX, and alignmentY

  • the size of the container

Normally, when coding your UI manually, you override the default layout manager before adding components to the container. To change a layout manager on the container, right click it in the designer area or in the Structure window, go to Set Layout menu and select the desired layout manager. For more information, see Section 15.8.1, "How to Set the Layout Manager."

When using the GUI builder (or visual editor), you can change the layout whenever you like. JDeveloper will adjust the code as needed.

Note:

If you want to change the properties for a layout manager using the GUI builder, you must explicitly specify a layout for a container so its properties will be accessible in the Properties window.

Choose a layout manager based on the overall design you want for the container. Some layouts can be difficult to work with in the GUI builder because they immediately take over placement and resizing of a component as soon as you add it to the container. To alleviate this problem during initial layout prototyping, JDeveloper provides a layout called null, which leaves the components exactly where you place them and at the size you specify. Starting with null makes prototyping easier in your container. Later, after adding components to the container, you can switch to an appropriate portable layout for your design.

If you cannot get what you need with the Free Design mode, experiment with different layouts to see their effect on the container's components. For example, a viable alternative of an complex layout is the GridBagLayout. For more information, see Section 15.8.8.3, "How to Use the GridBag Customizer." If you find the layout manager you've chosen doesn't give you the results you want, try a different one, or try nesting multiple panels with different layouts to get the desired effect.

15.8.1 How to Set the Layout Manager

When you create a new container, it is generally created using a default layout so that you can take advantage of the IDE's Free Design features. If necessary, you can change the layout of most containers using the GUI Builder or the Structure window.

To set the layout manager from the GUI Builder:

  1. Right-click the container whose layout you wish to change.

  2. Select Set Layout and a layout menu

To set the layout manager from the Structure window:

  1. Right-click the node for the container whose layout you wish to change.

  2. In the contextual menu, choose the desired layout from the Set Layout submenu.

When you change layouts, the IDE remembers the properties of the discarded layout manager. If you then revert back the to the previous layout manager, the form also returns to its prior state.

15.8.2 Understanding FreeDesign Layout

FreeDesign lays out your form using visual guidelines that automatically suggest optimal alignment and spacing. As you work, the GUI Builder translates your design decisions into a functional UI without requiring you to specify a layout manager. Because Free Design employs a dynamic layout model, whenever you resize the form or switch locales, the GUI adjusts to accommodate your changes without changing the relationships between components.

  • You can combine FreeDesign containers and containers using other layout managers together in the same form. Free Design enables you to lay out your form using visual guidelines that automatically suggest optimal alignment and spacing of components.

15.8.3 How to Set Layout Properties

You can modify the appearance of your forms by adjusting general layout manager properties as well as properties specific to components.

You can modify:

  • General layout properties which affect all components in a container, such as alignment of components and gaps between the components.

  • Layout properties specific to a component that is managed by a particular layout manager and which apply to that component alone. These type of properties are also known as constraints.

To set general layout manager properties:

  1. Select the layout manager's node in the Structure window.

  2. In the Properties window, select the property you want to edit and enter the desired value. Note that the properties vary depending on the layout manager and that some layout managers do not have any properties.

To set layout properties of components:

  1. Select the component in the Structure window.

  2. In the Properties window, scroll down to Layout, select the property you want to edit and enter the desired value.

    Note:

    You can edit the custom code of a component in a more natural way by selecting Customize Code from context menu of the component and then edit its custom code in more natural way.

15.8.4 Understanding Layouts Provided with JDeveloper

You can choose from the following Layout Managers in the IDE:

  • FlowLayout

    FlowLayout arranges components in a container like words on a page. It fills the top line from left to right until no more components can fit, continuing the same way on each successive line below.

  • BorderLayout

    BorderLayout arranges components along the edges or the middle of their container. Using BorderLayout, you can place components in five possible positions relative to the ComponentOrientation of the container:

    • First, which correspond to BorderLayout.PAGE_START

    • Last, which correspond to BorderLayout.PAGE_END

    • Before, which correspond to BorderLayout.LINE_START

    • After, which correspond to BorderLayout.LINE_END

    • Center, which corresponds to interior area.

  • GridLayout

    GridLayout places components in a grid of equally sized cells, adding them to the grid from left to right and top to bottom.

  • GridBagLayout

    GridBagLayout is a powerful layout manager that provides precise control over all aspects of the layout even when the container is resized, using a complex set of component properties called "constraints." It is particularly useful for multiplatform Java applications as it enables you to create a free-form layout that maintains a consistent appearance across platforms.

    GridBagLayout places components in a grid of rows and columns in which grid cells do not all have to be the same size. In addition, components can span multiple rows, columns, or both.

  • CardLayout

    CardLayout provides a means of managing two or more components occupying the same display area. When using CardLayout each component is like a card in a deck, where all cards are the same size and only the top card is visible at any time. Since the components share the same display space, at design time you must select individual components using the Structure window.

  • BoxLayout

    BoxLayout allows multiple components to be arranged either vertically or horizontally, but not both. Components managed by BoxLayout are arranged from left to right or top to bottom in the order they are added to the container. Components in BoxLayout do not wrap to a second row or column when more components are added or even when the container is resized.

  • AbsoluteLayout

    AbsoluteLayout enables components to be placed exactly where you want them in the form, move them around in the IDE, and resize them using their selection borders. It is particularly useful for making prototypes since there are no formal limitations and you do not have to enter any property settings. However, it is not recommended for production applications since the fixed locations and sizes of components do not change with the environment.

  • Null Layout

    The Null Layout is used to design forms without any layout manager at all. Like the AbsoluteLayout, it is useful for making quick prototypes but is not recommended for production applications, as the fixed locations and sizes of components do not change when the environment changes.

15.8.5 Using BorderLayout

BorderLayout arranges a container's components in areas named First, Last, Before, After, Center.

  • The components in First and Last are given their preferred height and are stretched across the full width of the container.

  • The components in Before and After are given their preferred width and are stretched vertically to fill the space between the first and last areas.

  • A component in the Center expands to fill all remaining space.

Figure 15-2 BorderLayout

Border layout

The BorderLayout that appears in Figure 15-2 is good for forcing components to one or more edges of a container, and for filling up the center of the container with a component. It is also the layout you want to use to cause a single component to completely fill its container.

You will probably find BorderLayout to be the most useful layout manager for the larger containers in your UI. By nesting a panel inside each area of the BorderLayout, then populating each of those panels with other panels of various layouts, you can achieve quite complicated UI designs.

Components are positioned in one of five areas within a BorderLayout, based on the constraints property. You can set the constraints property for the component in the Properties window to one of the following values: First, Last, Before, After, Center.

For example, to put a toolbar across the top of a BorderLayout container, you could create a FlowLayout panel of buttons and place it in the First area of the container. You do this by selecting the panel and choosing First for its constraints property in the Properties window.

Each of the five areas can contain any number of components (or panel of components). However, unless the topmost component is not opaque, any lower components in the same area will be covered by the topmost one.

The following are some general guidelines for working with multiple components and BorderLayout:

  • Make sure the container has no more than five components.

  • If you need more components in one area of the BorderLayout, use the Enclose In context menu option to group the selected components into a sub-panel.

Note:

BorderLayout ignores the order in which you add components to the container.

By default, a BorderLayout puts no gap between the components it manages. However, you can use the Properties window to specify the horizontal or vertical gap in pixels for a BorderLayout associated with a container.

To modify the gap surrounding BorderLayout components, select the BorderLayout object in the Structure window (displayed immediately below the container it controls), then modify the pixel value in the Properties window for the horizontal gap and vertical gap properties.

15.8.6 Using CardLayout

CardLayout places components (usually panels) on top of each other in a stack like a deck of cards. You see only one at a time, and you can flip through the panels by using another control to select which panel comes to the top.

Figure 15-3 Card layout

Card Layout

CardLayout is a good layout to use when you have an area that can contain different components at different times. This gives you a way to manage two or more panels that need to share the same display space.

By selecting CardLayout in the Structure window you can then you can then specify the amount of horizontal and vertical gap surrounding stack of components in the Properties window.

15.8.7 Using FlowLayout

FlowLayout arranges components in rows from left to right, and then top to bottom using each component's preferredSize. FlowLayout lines up as many components as it can in a row, then moves to a new row. Typically, FlowLayout is used to arrange buttons on a panel.

Figure 15-4 FlowLayout

FlowLayout

You can choose how to arrange the components in the rows of a FlowLayout container by specifying an alignment justification of left, right, or center. You can also specify the amount of gap (horizontal and vertical spacing) between components and rows. Use the Properties window to change both the alignment and gap properties when you're in the GUI builder.

15.8.7.1 Changing the Alignment

To change the alignment, select the FlowLayout object in the Structure window, then specify a value in the Properties window for the alignment property.

15.8.7.2 Changing the Gap

The default gap between components in a FlowLayout is 5 pixels.

To change the horizontal or vertical gap, select the FlowLayout object in the Structure window, then modify the pixel value of the horizontal gap or vertical gap property in the Properties window.

15.8.7.3 Changing the Order of Components

To change the order of the components in a FlowLayout container, drag the component to the new location, or right-click a component and choose Move Up or Move Down.

15.8.8 Using GridBagLayout

GridBagLayout is an extremely flexible and powerful layout that provides more control than GridLayout in laying out components in a grid. GridBagLayout positions components horizontally and vertically on a dynamic rectangular grid. The components do not have to be the same size, and they can fill up more than one cell.

Figure 15-5 GridBagLayout

GridBagLayout

GridBagLayout determines the placement of its components based on each component's constraints and minimum size, plus the container's preferred size.

In the following discussion:

  • A component's cell refers to the entire set of grid cells the component occupies.

  • A component's display area refers to all the space of the cell that it occupies which is not taken up by the component's external padding (insets).

While GridBagLayout can accommodate a complex grid, it will behave more successfully (and more predictably) if you organize your components into smaller panels, nested inside the GridBagLayout container. These nested panels can use other layouts, and can contain additional panels of components if necessary. This method has two advantages:

  • It gives you more precise control over the placement and size of individual components because you can use more appropriate layouts for specific areas, such as button bars.

  • It uses fewer cells, simplifying the GridBagLayout and making it much easier to control.

On the other hand, GridBagLayout requires more containers, and therefore your program uses more memory than if you used other layout managers.

15.8.8.1 Adding Components to a GridBagLayout Container

When you add components to the design canvas they appear in one row by default. You cannot position them using the mouse. Instead, you must use the GridBag customizer. For more information, see Section 15.8.8.3, "How to Use the GridBag Customizer."

15.8.8.2 How to Set GridBagConstraints in the Properties Window

Using the Properties window, you can specify some of the GridBagConstraints.

Figure 15-6 Layout Properties in Properties Window

Layout properties in Properties window

If you want all the buttons in your GridBagLayout container to use the same internal padding, you can hold down the Ctrl key while you select each one, then edit the corresponding layout constraint property.

To set layout properties in the Properties window: 

  1. Select the component(s) within the GridBagLayout container you want to modify, either in the Structure window or in the GUI builder.

  2. In the Properties window, select Layout.

  3. Select a value for the constraints property in the Properties window.

  4. Set the desired constraints in the property editor, then press OK.

15.8.8.3 How to Use the GridBag Customizer

The GridBag customizer enables you to visually adjust the placement and constraints of components in a GridBagLayout.

Figure 15-7 Customize Layout Dialog

Customize Layout Dialog

It includes a property sheet for GridBag constraints, buttons for adjusting the constraints, and a rough depiction of the layout of the components. The GUI Builder more closely reflects how the components will look at runtime.

To use the GridBag customizer:

  1. Add the components you require to your form and ensure the GridBagLayout is set for it.

  2. To open the customizer, right-click the GridBagLayout node in the Structure window and choose Customize from the contextual menu.

  3. Drag the components in the right pane to reposition them as desired.

    As you drag a component, its Grid X and Grid Y properties change to reflect its new position.

  4. Once the approximate layout of the components has been established, select a component and adjust its constraints as desired in the left pane.

    Note that you can either enter the values directly or use the provided buttons to adjust the component's constraints.

    While editing:

    • You may need the Redo, Undo, Pad, and Test Layout buttons in the toolbar above the right pane.

    • You can right click the column/row headers and add or remove columns/rows.

    • You can also right click an empty cell and add a new component (so you do not have to close the GridBag customizer dialog in order to access the palette).

    If after several rows, your design has fit nicely into a certain number of columns, and you suddenly have a row that requires an odd number of components, then consider dropping a panel into that row that takes up the entire row, and use a different layout inside that panel to achieve the look you want.

  5. Once you are satisfied with the layout, click Close to exit the customizer.

15.8.9 Using GridLayout

GridLayout places components in a grid of cells that are in rows and columns. GridLayout expands each component to fill the available space within its cell. Each cell is exactly the same size and the grid is uniform. When you resize a GridLayout container, GridLayout changes the cell size so the cells are as large as possible, given the space available to the container.

Figure 15-8 GridLayout

GridLayout

You can specify the number of columns and rows in the grid, but only one of the rows or columns can be zero. You must have a value in at least one so the GridLayout manager can calculate the other.

For example, if you specify four columns and zero rows for a grid that has 15 components, GridLayout creates four columns of four rows, with the last row containing three components. Or, if you specify three rows and zero columns, GridLayout creates three rows with five full columns.

In addition to number of rows and columns, you can specify the number of pixels between the cells by modifying the horizontal gap and vertical gap properties. The default horizontal and vertical gap is zero.

To change the property values for a GridLayout container, select the GridLayout object in the Structure window, then edit the values for the rows, columns, horizontal gap and vertical gap properties in the Properties window.

15.8.10 Previewing a User Interface

To quickly test how your GUI will display when it is compiled and run, click the Preview Design button in the GUI Builder toolbar. A dialog box is displayed with the components arranged as they would actually appear on your form.

When you click in the previewed GUI form, mouse events are delivered to the actual components and you can see the components "in action." Thus, for example, you can move sliders, type into text fields, and buttons look "pressed" when you click them, however, cross-component and event handling code is not executed.

15.9 How to Create Accessible Forms

To ensure that your GUI forms and the components contained within them meet accessibility requirements, you can adjust their accessibility properties. A GUI is considered accessible when it works with various assistive technologies, such as screen readers.

The following properties can be edited to aid accessibility:

  • Accessible Name - Sets the name for the component. By default, the name is set to the component's text property value.

  • Accessible Description - Sets the description for the component.

  • Accessible Parent - Sets the name of the accessible parent component.

To edit a form or component's accessibility properties:

  1. In the Structure window, select the form or component whose accessibility properties you want to modify.

  2. In the Properties window, scroll down to the Accessibility properties.

  3. Click the ellipsis (...) button to open the Property Editor and then enter the desired value.

    Alternately, you can click the current property value to select it and enter a new value.

15.10 Working with Event Handling

Use UI design tools in JDeveloper to attach event handler code to component and menu events.

In building your Java program, you can think of your code as being divided into two categories: initialization code and event-handling code.

  • Initialization code is executed when the UI components are created. You can think of this primarily as "start up" code for the components. This initialization code includes anything in the initComponents() method that all JDeveloper-designed GUI classes have. JDeveloper generates this code based on your UI design. For example, JDeveloper generates a button1.setLabel("OK") method call because you set the text property of a button, using the Properties window, to "OK".

  • Event-handling code is the code that is executed when the user performs an action, such as pressing a button or using a menu item. JDeveloper creates the stub (empty) event-handling method for you when you enter an event name in the Structure window for that component and press Enter. In that stub, you write code to handle the actual action caused by the event.

Your entire program consists of the initialization code, which says how things should look when they first appear, and the event-handling code, which says what should happen in response to user input.

15.10.1 How to Attach Event Handling Code to Menu Events

In Swing, a menu item has actionPerformed events and CheckboxMenuItems have itemStateChanged events. Code that you add to the actionPerformed event for a menu item is executed whenever the user chooses that menu item or uses its accelerator keys.

To add code to a menu item's event:

  1. Open a JFrame form in the visual editor.

  2. Add a menubar to your UI frame and insert menus and menu items into the menubar. Alternatively, you can open a file that already contains a menu.

  3. Select a menu item in the Menu Editor or the Structure window.

  4. In the Properties window, expand the Events node and click the desired event value field.

  5. Type the stub name of the event into the event value field and press Enter to create an event-handling method stub in the source code with the supplied name.

    When you enter a name in the event value field, JDeveloper open the Code Editor and displays the source code in the Structure window. The cursor is positioned in the body of the newly created event-handling method, ready for you to enter code.

  6. Inside the open and close braces, enter the code you want to have executed when the user clicks the menu command.

15.10.2 How to Attach Event-Handling Code to a Component Event

Using the Events category in the Properties window, you can attach handlers to component events and delete existing event handlers.

To attach event-handling code to a component event:

  1. Select the component in the GUI builder or in the Structure window.

  2. In the Properties window, select the Events tab to display the Events for that component and click the desired event value field.

  3. Type the stub name of the event into the event value field and press Enter to create an event-handling method stub in the source code with the supplied name.

    JDeveloper creates an event handler with the new name and switches to that event handler in the source code. JDeveloper also inserts some additional code into your class, called an adapter, to make the connection from the event to your event handling method.

  4. Inside the stub of the event handler write the code that specifies the response to that component event.

15.10.3 How to Quickly Create an Event Handler for a Component's Default Event

You can create an event handler in the GUI builder.

To quickly create an event handler for a component's default event:

  1. Select a component on the Components window and add it to your UI.

  2. Double-click the component in the GUI builder. An event stub is created and focus switches to that event handler in the source code.

  3. Add the necessary code to the event handler to complete it.

Note:

The default event is defined by BeanInfo, or as actionPerformed if none was specified.

15.11 How to Modify GUI Source Code

The IDE automatically generates grey guarded blocks of code as you create your GUI form in the GUI Builder. However, you can modify the way initialization code is generated and even write custom code to be placed within the initialization code.

You can modify the way initialization code is generated for a component, form, or component property by editing its Code properties in the Properties window. In addition, you can write custom code and specify where it should be placed within the initialization code.

To modify a form component's guarded block:

  1. In the Structure window, select the component whose initialization code you want to edit.

  2. Scroll down to Code Generation group of properties that lists individual properties for adding custom code to be generated for given component in the guarded code.

    Alternatively, right click the component itself and from context menu choose Customize Code which opens a dialog where the custom code of all types can be edited in a more comfortable way.

Note:

You can freely edit all the other code in the Java class that is not guarded, and so customize the UI to your needs. All components have fields, so can be further modified from anywhere. The best place is in the constructor just after the initComponents() call. In most cases it is sufficient to write the code here, and it's much easier than trying to get the piece of the code appear inside initComponents() by entering it in the correct code property in the GUI builder. That should be left only for really special cases.

15.11.1 Modifying GUI Form Code Outside of the IDE

In the IDE each form is comprised of two files:

  • A .java file, which contains the form's Java source code.

  • A .form file, which stores the information that is used to generate the .java file when you make changes to the form in the GUI Builder. This file does not need to be distributed with your application. If you delete this file, you can no longer use the GUI Builder to change the form.

You can edit the .java files using external editors (not while the form is being edited in the IDE), with the following exceptions:

  • Do not modify the content of the initComponents() method. The body of this method is always regenerated when the form is opened in the IDE.

  • Do not remove or modify any of the special comments placed in the source by the IDE's GUI Builder (// GEN-...). They are required for the form to open correctly. These comments are not visible inside the IDE's Source Editor.

  • Do not modify the headers or footers of event handlers.

15.11.2 How to Modify Code Generation for a Property

A property value can be set as custom code.

To modify code generation:

  1. Select the component in the GUI Builder or Structure window to display its properties in the Properties window. Note that if you select multiple components, their common properties are displayed and any modifications apply to all of the selected components.

  2. Edit the component's properties in the Properties window by selecting the property and entering the desired value.

  3. If the property you want to edit has an ellipsis (...) button, you can click it to open a special property editor that provides more advanced editing options (e.g. a color chooser for a color-type property), or alternate ways of specifying the property value (e.g. using a resource bundle for a text property), including a possibility to type directly the code that should represent the property value.

    Use this to edit a given property in another way than in the small in-place editor in the properties window. You can also choose from several ways how to enter the property value via the combo box at the top.

15.12 Working with the UI Debugger

In addition to JDeveloper's standard Java and PL/SQL debugger facilities, JDeveloper also provides support for debugging graphical user interfaces (GUIs) specifically for AWT and Swing-based client applications and applets.

The UI Debugger offers an alternative way of debugging a GUI application. Traditional debuggers let you examine the data structure and track program flow. Instead, the UI Debugger lets you examine the GUI structure and the event sequences. The UI debugger helps you to see the relationship between UI components displayed on the screen with the actual data. It will also show you the events that are fired by the UI components, and the listeners that receive the events.

To use the UI Debugger, you need to first download it by choosing Help > Check for Updates and following the instructions in the wizard.

There are no additional special prerequisites for the using the UI Debugger beyond those requirements for using the JDeveloper debugger, other than ensuring that the JDeveloper Runtime library, jdev-remote.jar, is selected in the Project Properties - Libraries page.

Debugging a GUI application can be a challenge since most traditional debuggers do not let you easily examine the tree structure of a GUI application, nor do they display the details of what is displayed by your application.

To start debugging, select a project and choose Run > UI Debug <projectname>.jpr to start debugging.

15.12.1 Working with UI Debugger Windows

You can use the UI Debugger features which are exposed in JDeveloper via three dockable windows. The UI Tree and the UI Outline windows appear automatically when the UI Debugger is started. The Events window appears the first time you track events. You can toggle all three windows by choosing View > UI Debugger - <UI_debugger_window>.

Note:

No information is displayed in the UI Debugger windows until you take a snapshot. Click the Snapshot (F5) button to populate the UI Tree and the UI Outline windows.

  • UI Tree: Displays a hierarchical structure of your application's components and sub-components and their parent-child relationships. Select a component from the tree and right-click to display the context menu options. You will notice that the component is also selected in the UI Outline window.

  • UI Outline: Displays an image or outline image of the application's GUI. Select a component from the graphical representation of the GUI application and right-click to display the context menu options.

    Note:

    Since AWT components may not be painted correctly, Oracle recommends that you work in Outline mode for non-Swing based applications.

  • Events: Displays information about those events you've selected to listen to from the Listeners dialog. The Listener dialog displays when you choose the Events context menu option from either the UI Tree or UI Outline windows. When you select an event in this window, its source component is selected in the tree and outline windows.

15.12.2 How to Start the UI Debugger

Before performing any UI Debugger task, you must first start the UI Debugger.

To start the UI debugger:

  1. Select the project in the Applications window that you want to debug.

  2. Select a run configuration. For more information, see Section 14.3, "Configuring a Project for Running."

  3. Choose Run > UI Debug <projectname>.jpr to start the project's default target and to run the application.

    JDeveloper starts the UI Debugger. The application is launched and the UI Tree and UI Outline windows automatically appear. However, no information is displayed in the UI Debugger windows yet.

  4. After the application is completely launched, go to the dialog or window you want to debug and select it.

  5. From either UI Debugger windows, click the Snapshot (F5) button.

    JDeveloper displays a hierarchical structure of the application in the UI Tree window and displays a graphical representation of the application's user interface in the UI Outline window.

15.12.3 Examining the Application Component Hierarchy

The information in the UI Tree and the UI Outline windows and the relationship between them are always synchronized. Since the information in the UI Tree and the UI Outline windows is identical (only the way they are presented is different), whenever you select a component in the UI Tree hierarchy, JDeveloper locates and highlights the same object in the UI Outline window, and vice versa.

Before examining the application component hierarchy, you must start the UI Debugger and take a snapshot. Whenever the UI of the application is updated, you must click Snapshot again to update the information displayed by the UI Debugger windows.

To examine the application component hierarchy:

  • Use the tree of the UI Tree window to explore the hierarchical structure of the components or use the UI Outline window to locate the components visually.

  • Use the Image and Outline checkboxes at the top of the UI Outline window to toggle respectively the image and the borders of the components.

  • Use the icons at the bottom of the UI Outline window to zoom in or zoom out of the application image. If the image is larger than the window, you can pan across by clicking and dragging the image.

  • Note that the components that are not selected in the UI Outline window are shaded red.

  • Note that hidden components are represented by gray text in the UI Tree.

  • Right-click a component in either windows to display the context menu options. See UI Tree or UI Outline for more information.

15.12.4 How to Display Component Information in the Watches Window

To examine the data associated to a component, you can choose to watch the component in the JDeveloper Watches window. A watch enables you to monitor the changing values of variables or expressions as your program runs.

To display component information in the Watches window:

  1. If not already done, start the UI Debugger and take a snapshot.

  2. Right-click a component either in the UI Tree or the UI Outline window and choose Watch from the context menu.

    The Watches window opens as a tab in the Smart Data window (if it is not already open), and a tree representing the component's structure is displayed in it.

15.12.5 How to Inspect a UI Component in an Properties window

You can view the state of a UI component in a JDeveloper Properties window.

To display a UI component in an Properties window:

  1. If not already done, start the UI Debugger and take a snapshot.

  2. Right-click a component either in the UI Tree or the UI Outline window and choose Inspect from the context menu.

    The Inspect window opens as a tab in the Smart Data window (if it is not already open), and a tree representing the component's structure is displayed in it.

15.12.6 How to Trace Events Generated by Components

Use the event tracing feature to monitor the firing of selected events generated by UI components. Use this information to determine the content of events, and their sequence.

To trace events generated by components:

  1. If not already done, start the UI Debugger and take a snapshot.

  2. Right-click a component either in the UI Tree or the UI Outline window and choose Trace Events from the context menu.

    The Trace Events dialog opens, displaying a list of the listeners that receive the event types fired by the component.

    Note:

    Event listeners are listed only for UI components that were visible when the snapshot was taken. If subsequent execution have added or removed UI components, the change will not be seen in the list.

  3. (Optional) Select Include Children to also show additional event types fired by the children of the selected component.

  4. In the Listeners dialog, select which event listener(s) you want to trace. For example, if you select FocusListener, all focus events will be traced.

  5. Click OK.

  6. The events fired by the selected listeners are displayed in the Events window. Right-click in the window to Clear the contents of the window or to Remove a specific Listener.

15.12.7 How to Show Event Listeners

Use the show listeners feature to find the recipients of events fired by UI components. Use this information to determine the extent of UI events.

Caution:

Event listeners are listed only for UI components that were visible when the snapshot was taken. If subsequent execution have added or removed UI components, the change will not be seen in the list.

To trace events generated by components:

  1. If not already done, start the UI Debugger and take a snapshot.

  2. Right-click a component either in the UI Tree or the UI Outline window and choose Show Listeners from the context menu.

    The Listeners dialog opens for the selected component, displaying a list of listener types informed by the component, the classes of the registered listeners for each listener type, and the event methods implemented by each class.

    Note:

    The debugger's tracing filter is applied to the listener's list. A listener whose class is excluded by the filter will not be shown.

  3. Select a method.

  4. Click Go To Source.

    An edit window opens, showing the source code for the selected method.

15.12.8 Remote Debugging GUI Applications

JDeveloper supports remote debugging of GUI applications via the command line. To achieve this, you must manually launch the program you want to debug. Once the program is launched and the JDeveloper debugger is attached to it, remote debugging is very similar to local debugging.

Performing remote UI debugging is similar to remote debugging any application. Just make sure that the following requirements are met first:

  • Add the JDeveloper runtime, jdev-remote.jar, to the libraries

  • Specify the UI Debugger agent's main class before your application's main class

15.12.8.1 How to Remote Debug GUI Applications

You can remote debugging a GUI application by entering commands on the command line.

To remote debug GUI applications: 

  1. Configure your project for debugging, making sure to enable it for remote debugging.

  2. Start your application manually as follows by executing:

    java -XXdebug -cp ...\jdev\lib\jdev-remote.jar 
    oracle.jdevimpl.runner.uidebug.debuggee.Debuggee <MainClass>
    

    where

    • ...\jdev\lib\jdev-remote.jar is the JDeveloper Runtime Library classpath which you must add to the command.

    • oracle.jdevimpl.runner.uidebug.debuggee.Debuggee is the name of the main class of the UI Debugger's agent.

  3. A message similar to the following is printed in the command window:

    *** Port is 4000 ***
    *** Waiting for JVM debugger connection. ***
    
  4. The UI Debugger uses a socket to interact with your application. The default port number for the socket is 4030 but you can specify another port number by inserting -uidport,<port> before the application's main class as follows:

    java -XXdebug -cp ...\jdev\lib\jdev-remote.jar
    oracle.jdevimpl.runner.uidebug.debuggee.Debuggee -uidport,5678 
    mypackage1.Application1
    

    In this case, you will also have to specify the port number when you start the UI Debugger in the JDeveloper IDE.

15.12.8.2 How to start the JDeveloper IDE for Remote UI Debugging

You can use the JDeveloper IDE to remote UI debug a project.

To start the JDeveloper IDE for remote UI debugging: 

  1. Select a run configuration that has been set up for remote debugging (Run > Choose Active Run Configuration).

  2. Choose Debug, then UI Debug <project_name>.jpr.

    The main method of your Java application is started.

  3. The Attach to JPDA dialog appears, prompting you to specify a host name and a UI debugger port.

    Unless you have used the -uidport option, you should leave this value as the default, 4030.

  4. Your UI debugging session will now behave as if it were performing local UI debugging. You can begin performing any UI debugger task.

15.12.9 Automatic Discovery of Listeners

The list of events that can be tracked by the UI Debugger is not hard-coded but is dynamically discovered at runtime. It is therefore possible to track events fired by any listener, provided that they adhere to the following guidelines:

  • The component class must have public methods to add and remove a listener.

  • The name of the methods must start with add or remove and end with Listener.

  • The return type must be void.

  • The methods must have only one argument.

  • The type of the argument must be an interface that extends java.util.EventListener.

  • The name of the method must be equal to the name of the interface preceded by add or remove.

  • The return type of each method in the specified interface must be void.

  • The method can only have one argument (the event).

  • The type of the argument must be a class accessible as a bean.

  • The return values of the getters can be anything except void. If the type is a non-primitive type, the value that will be shown in the UI Debugger will be the string obtained by calling the object's toString() method.

Examples

  • For example, if you want to define a new event listener of type Xxx, your component must have methods with the following signatures:

    public void addXxxListener(XxxListener); 
    public void removeXxxListener(XxxListener);
    
  • An example of an XxxListener interface could be:

    public interface XxxListener extends java.util.EventListener
    {
       public void methodOne(XxxEvent xxxEvent);
       public void methodTwo(XxxEvent xxxEvent);
       public void methodThree(XxxEvent xxxEvent);
    }
    
  • An example of a XxxEvent class could be:

    public class XxxEvent 
    {
       public int getA(){...} 
       public String getB(){...} 
       public OtherType getC(){...}