HTML Markup | JavaScript | Java | Home & Links

Tutorial 12 - UI Design/Implementation

User interfaces are created from GUI widgets (aka controls) arranged in a logical and graphically appealing way using a layered approach and appropriate layout managers. Design of a user interface should be thought out before implemented. A general design tutorial can help you focus. A good starter tutorial is UI techniques.

Layered Design

Layered design is an architectural pattern that structures applications so they can be decomposed into groups of subtasks such that each group of subtasks is at a particular level of abstraction. Most GUI interfaces use nested layers of panes, often with different layout managers. A two column layout is shown as an example of layered design. The left column is a set of input selections. The right column is a set of 'go' buttons. A two column GridLayout is not used as it assumes both columns and rows will be equal sized. Instead we split the screen with a BorderLayout and then use two single column GridLayouts. The left GridLayout is further split using FlowLayout for captioning. Cut and paste the following to a file called Layer.java, compile and run to view the effect. Note: The MVC model is used to isolate view coding from model action coding.

NOTE: The buttons created by this demo do not provide their implied functions but simply print a message and end the program. To fully implement button action, consult either basic event listeners with nested if constructs or advanced event listeners.

Layout Managers

Layout managers are classes that control the size, positioning and alignment of components within a container so that they neither crowd each other nor overlap. Containers are components and can be layered (ie layout managers within layout managers). Java provides layout managers that range from simple: BoxLayout, FlowLayout and GridLayout to special purpose: BorderLayout, CardLayout and OverlayLayout to the precise GridBagLayout and SpringLayout

Use the setLayout() method to reset a content pane to a specific layout manager. Use setPreferedSize(w,h) on a component to preset its size. Each layout manager scales components on resize in a different manner. Use setMinimumSize(w,h) on an object to prevent wrap or loss of component display.

BoxLayout places items in a single row or column. Glue can be added as a flexible space filler using the methods Box.createGlue(), Box.createHorizontalGlue() and Box.createVerticalGlue(). Struts can be added as a fixed space filler using the methods createRigidArea(dim), createHorizontalStrut(w) and createVerticalStrut(h). Note: BoxLayout is unusual in that it must use a pane and not a frame as its container. An example of setting the BoxLayout to row alignment is:

JPanel p=new JPanel();  // make the pane first
p.setLayout(new BoxLayout(p,BoxLayout.X_AXIS));
setContentPane(p);

FlowLayout places components in rows across the width of a container. FlowLayout components automatically wrap or move to the next row when required. When using FlowLayout, each component retains its default size (i.e. a JButton will be large enough to hold its text), unlike BorderLayout where the components fill their regions. Also, with FlowLayout, when the window is resized, each component retains its size (but it might become partially obscured or change position or wrap). If you need to force a wrap (such as using <br> in HTML), use two containers, one for each line. FlowLayout is the default for JPanel objects. FlowLayout components are center justified by default. For component justification, reset the layout alignment with:

setLayout(new FlowLayout(FlowLayout.LEFT));

GridLayout uses a simple row and column grid metaphor for layout. All components are of the same width and height and scale similarly when resized. The constructor format is:

setLayout(new GridLayout(rows, cols, x-spacing, y-spacing));

BorderLayout is used when you want to add components to a maximum of five sections arranged in North, South, East, West and Center positions. BorderLayout is the default manager for all content panes. If you place exactly five components in a container and use BorderLayout, each component fills one entire region. When the program runs, the compiler determines the exact size of each component based on the component's contents. When you resize a container that has BorderLayout, the regions also change in size. When you place less than five components in a container and use BorderLayout, any empty component regions disappear and the remaining components expand to fill the available space.

CardLayout presents widgets stacked similar to a deck of cards. It can be used to maintain a static pane of control buttons and another pane that is more dynamic in nature. A common use is a slideshow viewer where the controls are static and the picture frame is actually a set of card panes that are presented as buttons are pressed or a timer is called.

OverlayLayout allows precise positioning of overlays based on some alignment points.

GridBagLayout allows precise placing and sizing of each widget. Use the properties: anchor, gridheight, gridwidth, gridx, gridy, fill, ipadx, ipady, weightx and weighty.

SpringLayout is a complex layout manager that uses the concepts of springs and struts to help design well-positioned containers. Normally an IDE such as NetBeans is used for coding but tutorials like those at Oracle and Java2s.com can be helpful to a hand coder.

Look and Feel

Swing allows three rendering modes: a unified 'Java' look and feel [the default], the native platform look, or a specific platform's look. If you want to change from the default to the native platform look, add the following at the start of the driver class main method:

  try {UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());}
  catch (Exception e) { }

If you want to use a look other than the default or the native one, you must first check for what's available. For copyright reasons, the Mac view is not available in Windows and vice versa. To check what is available use:

UIManager.LookAndFeelInfo[] laf=UIManager.GetInstalledLookAndFeels();
for (int i=0;i<laf.length;i++)
    { System.out.println("Class name: "+laf[i].getClassName());
      System.out.println("Name: "+laf[i].getName());}

If you want to change the look after starting (for example letting the user select the look) be sure to make all components update their appearance. Call the SwingUtilities class method updateComponentTreeUI(Component) with the main user interface component such as a JFrame object as the argument.

GUI Builders

The complexity of designing Java GUI interfaces from scratch beg for GUI builders. The advantage of using a builder is that design, visual rendering and coding stages can be isolated. Human factors specialists and analysts are the best people for design. Artists are the best for rendering the look. And of course programmers for the coding. Prototype or demo screens can be rapidly developed or modified to client needs prior to hard coding. The tradeoff is that the resulting code will never be as efficient or elegant or as easy to maintain as coded from scratch methods.

Three strategies exist in menu builder utilities: visual drag/drop templates, scripting and XML files made by a visual design program such as QtDesigner. Each method generates a framework that the programmer adds action 'code' to.

Visual designers can be stand-alone utilities such as jGoodies Forms and FormLayoutMaker or embedded in an IDE such as NetBeans and JBuilder.

Tutorial Source Code

Obtain source for AddWidget, Audio, BoxGUI, Box2GUI, FlowGUI, GridGUI, BorderGUI, CardLayoutGUI, OverlayGUI and GridBagGUI using MVC here. Compile each demo and note how the scaling on resize works.



JR's HomePage | Comments [jatutorc.htm:2014 07 13]