Swing Extras

The following classes are Swing utilities classes.

Classes

License

This software is released under the GNU GPLv3 license

Copyright © 2010 Keang Ltd

Download

Download the Swing extras package


VariableGridLayout

The VariableGridLayout class is a very similar to the the java.awt.GridLayoutClass in that it positions component in a grid layout (ie rows and columns). This makes it very easy to use when laying out a grid of components such as for forms.

The difference between the two layouts is in the sizing of the rows and columns. GridLayout fixes all rows to the same height (that of the highest component) and all columns to the same width (that of the widest component), whereas VariableGridLayout sets each row to the height of the highest component in that row and each column to the width of the widest component in the column.

This makes GridLayout ideal for laying out grids of components which have to be all the same size such as on a noughts and crosses board but can produce clunky looking layouts when used for layouts which combine buttons, labels, text fields etc. VariableGridLayout solves this problem whilst maintaining the ease of use of GridLayout.

This class is used in the DateSelector GUI to layout the day buttons, week numbers and day names.


SelectableLineBorder

The SelectableLineBorder class is similar to the javax.swing.border.LineBorder class in that it draws a line border of the specified width and colour around the given component. However, with the SelectableLineBorder you can specify which sides to draw the line on. So, for example you can underline components, draw lines above and below components etc

This class is used in the DateSelector GUI to draw vertical lines either side of the week numbers and horizontal lines above and below the day names.

For example to draw lines above and below a component use:

JPanel p = new JPanel();
p.setBorder(new SelectableLineBorder(
    EnumSet.of(SelectableLineBorder.Side.BOTTOM, SelectableLineBorder.Side.TOP), Color.BLACK, 1));
    

To draw a double line above and a single line below a component use:

JPanel p = new JPanel();
p.setBorder(new CompoundBorder(new SelectableLineBorder(SelectableLineBorder.Side.TOP, Color.BLACK, 1),
    new SelectableLineBorder(EnumSet.of(SelectableLineBorder.Side.BOTTOM, SelectableLineBorder.Side.TOP),
    Color.BLACK, 1)));
    


HoverDetector

The HoverDetector class monitors a component to detect if the mouse is hovering over it and, if a hover is detected, the callable object is sent a notification.

When a HoverDetector is created it receives the component to monitor, a callable object to notify and optionally a time to wait for a hover in milliseconds. The callable object is called when a hover is detected so it can handle the hover action. If the hover action results in a Window being displayed, returning a reference to the Window via the callable's return value will allow the Hover Detector to automatically close the window if it loses focus.

This class is used in the DateSelectorTest GUI to popup a DateSelector panel if the mouse hovers over the label and to remove the popup if it loses focus.


Gestures

A gesture is a predefined movement of the mouse (or finger on a touch screen system) to signal a specific action is to be undertaken. For example a list of items could be sorted into descending order by dragging the mouse vertically downwards on the list, into ascending order by dragging the mouse vertically upwards or shuffled by an up down motion.

The Gesture class monitors a component to detect when a gesture occurs. A gesture is deemed to occur when the left mouse button is pressed and the mouse is dragged a given distance in a direction or combination of directions. The class supports two separate notification mechanisms:

Gestures are particularly useful for touch screen systems as there isn't a choice of mouse buttons, scroll wheels etc to prompt different actions. They are also useful as mouse shortcuts for example: actions that are regularly run by selecting a menu item from a popup menu could be assigned a gesture, then a quick movement could be used instead of having to use a right mouse click, a mouse movement to hover over the menu item and then a left click on the menu item.

Using the Gesture class is as simple as adding the components to be monitored and setting up the notification mechanism, either by adding listeners and handling the action yourself or mapping a gesture through to an Action object which is run in response to the mapped gesture. For example:

Using Listener Notification:

Gesture gesture = new Gesture();
gesture.addComponent(myComponent);
gesture.addGestureListener(new IGestureListener()
  {
  public void gestureRecognised(Direction[] g, JComponent src)
    {
    // add your gesture handling code here to detect the
    // actual gesture that occurred (ie the contents of 'g' array)
    }
  });
gesture.setEnabled(true);
    

Using Action Objects:

Gesture gesture = new Gesture();
gesture.addComponent(myComponent1);
gesture.addComponent(myComponent2);
gesture.addGestureActionMapping(Direction.TOP_LEFT_TO_BOTTOM_RIGHT, "Diagonal");
gesture.addGestureActionMapping(Direction.BOTTOM_RIGHT_TO_TOP_LEFT, "Diagonal");
gesture.addGestureActionMapping(Direction.LEFT, "Left");
gesture.addAction("Diagonal", new ActionListener()
    {
    @Override
    public void actionPerformed(ActionEvent e)
        {
        // This will be called if either a top left to botton right
        // or a bottom right to top left gesture is detected
        // on either myComponent1 or myComponent2

        // add your gesture action code here..
        }
    });
gesture.addAction("Left", new ActionListener()
    {
    @Override
    public void actionPerformed(ActionEvent e)
        {
        // This will be called if a move left gesture is
        // detected on either myComponent1 or myComponent2

        // add your gesture action code here..
        }
    });
gesture.setEnabled(true);
    

The distance, in pixels, the mouse has to travel for the movement to be registered as a gesture can be configured by calling the setMinMovement(..) method.


FocusAutoScroller

When a JScrollPane contains a panel of components, a number of the components maybe outside the viewable area. When tabbing to a component outside the visible area the component will remain hidden and so you can no longer see which component has the focus and you can't see how you are interacting with the component.

The FocusAutoScroller class solves this problem by auto scrolling the viewable area so the component with focus is always visible. The class allows you to bias the positioning of the component in the horizontal and vertical planes to either of the edges or to the centre of the panel. Additionally, insets can be specified so the component is positioned away from the edge if the parent panel has extra space around the component.

There is no requirement to fully build the panel before/after creating the FocusAutoScroller. Components can be added and/or removed from the scroll pane panel before and/or after the FocusAutoScroller has been created.

Using FocusAutoScroller:

    JScrollPane sp = new JScrollPane(panel);

    FocusAutoScroller fas = new FocusAutoScroller(sp);
    fas.setScrollInsets(5, 5, 5, 5);
    fas.setHorizontalBias(FocusAutoScroller.BiasH.LEFT);
    fas.setVerticalBias(FocusAutoScroller.BiasV.TOP);
    

When designing forms it is not unusual to group related fields in sub-panels. In such cases it may be desirable to scroll to the whole sub-panel when any of the components in the sub-panel become focused. FocusAutoScroller, by default, works at a component level but can be set to scroll to the focused component's parent as follows:

    FocusAutoScroller fas = new FocusAutoScroller(sp);
    fas.setScrollToParent(true);
    
 
Back to the Top