Tutorial 12 - UI Design/Implementation
User interfaces are created from GUI widgets arranged in a logical and graphically appealing way with a layered approach and appropriate layout managers. User interfaces should be well planned before implementation. A good starter tutorial is UI techniques.
Warning: Swing GUI is not multithreaded. Stackoverflow offers a tutorial in creating multithreaded Swing apps.
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. The MVC model is used to isolate view coding from 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, see event listeners.
Layout managers are classes that control the size, positioning and alignment of widgets within a container so that they neither crowd each other nor overlap. Containers are widgets and can be layered (ie layout managers within layout managers). Layout managers range from simple: BoxLayout, FlowLayout and GridLayout to special purpose: BorderLayout, CardLayout and OverlayLayout to the precise: GridBagLayout and SpringLayout. Use setLayout() to reset a content pane to a specific layout manager. Each layout manager scales widgets on resize in a different manner.Use setPreferedSize(w,h) on a widget to preset its size. Use setMinimumSize(w,h) on an object to prevent wrap or loss of widget 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. To set BoxLayout to row alignment:
JPanel p=new JPanel(); // make pane first p.setLayout(new BoxLayout(p,BoxLayout.X_AXIS)); setContentPane(p);
BoxGUI and Box2GUI demo here.
FlowLayout places widgets in rows across the width of a container. FlowLayout widgets automatically wrap or move to the next row when required. When using FlowLayout, each widget retains its default size (i.e. a JButton will be large enough to hold its text), unlike BorderLayout where the widgets fill their regions. Also, with FlowLayout, when the window is resized, each widget retains its size (but it might become partially obscured or change position or wrap). 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 widgets are center justified by default. For justification, reset the layout alignment with:
FlowGUI demo here.
GridLayout uses a row and column grid metaphor for layout. All widgets 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));
GridLayout demo here.
BorderLayout is used when you want to add widgets 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 widgets in a container and use BorderLayout, each widget fills one entire region. When the program runs, the compiler determines the exact size of each widget based on it's contents. When you resize a container that has BorderLayout, the regions also change in size. When you place less than five widgets in a container and use BorderLayout, any empty widget regions disappear and the remaining widgets expand to fill the available space. BorderGUI demo here.
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 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. CardLayoutGUI demo here.
OverlayLayout allows precise positioning of overlays based on some alignment points. OverlayLayoutGUI demo here.
GridBagLayout allows precise placing and sizing of each widget. Use the properties: anchor, gridheight, gridwidth, gridx, gridy, fill, ipadx, ipady, weightx and weighty. The GridBagConstraints object allows tighter control of widget placement. GridBagGUI demo here.
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.
GUI builders are tools to assist in designing application interfaces. The main advantage of using a builder is that design, visual rendering and coding stages can be separated. Human factors specialists and analysts are the best people for GUI 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. Programmers add action 'code' to the builder's framework. However, the resulting code will never be as efficient, elegant or as easy to maintain as code-from-scratch methods.
Tutorial Source Code
Source code for BoxGUI, Box2GUI, FlowGUI, GridGUI, BorderGUI, CardLayoutGUI, OverlayGUI and GridBagGUI using MVC. Compile each demo and note how the scaling on resize works.