Create a scrollable virtual desktop
in Swing
Tutorial Details:
Create a scrollable virtual desktop in Swing
Create a scrollable virtual desktop in Swing
By: By Tom Tessier
Enhance your Java GUIs with the JScrollableDesktopPane class
he JDesktopPane class, first introduced in JDK 1.2 as a subsidiary to Swing's GUI component series, lets you create a virtual desktop or Multiple Document Interface (MDI) in Java applications. JInternalFrame 's various child windows or internal frames populate this desktop, and because those frames are internal, they are clipped at the boundary of the JDesktopPane container class (as opposed to JFrame 's external frames, which are painted without regard to container boundaries).
This clipping, demonstrated in Figure 1, exemplifies one of JDesktopPane 's inherent limitations: a user cannot view an internal frame's hidden portion without dragging the frame back within the virtual desktop boundary, or resizing the JDesktopPane container itself. Needless to say, such actions are not conducive to navigability and usability.
Figure 1. Internal frame clipped by the virtual desktop. Click on thumbnail to view full-size image.
JDesktopPane 's second limitation is that it doesn't provide a simple method to switch between internal frames; instead, you must click upon the frame title bar. Should internal frames obscure one another, the user must drag each frame aside before the next one becomes accessible. This work becomes tedious if several internal frames overlap, as is possible in any MDI environment.
Introducing JScrollableDesktopPane
The JScrollableDesktopPane class presented in this article offers a solution to the aforementioned clipping and overlap problems, and mimics the interface of the original JDesktopPane class in order to easily upgrade your application. Figure 2 depicts the scrollable desktop pane in action. As Figure 2 shows, JScrollableDesktopPane involves three main subcomponents: a virtual desktop, a toolbar, and a menu.
Figure 2. The JScrollableDesktopPane class in action. Click on thumbnail to view full-size image.
The virtual desktop comprises the main display area. When internal frames are positioned outside the virtual desktop's boundary, scroll bars update to provide access to the cropped internal frames, solving the clipping problem.
A toolbar provides a lengthwise set of toggle buttons above the virtual desktop, with each button mapped to a corresponding internal frame. The toolbar contents automatically size to fit as you add or remove buttons. When you click a button, the associated frame centers upon the virtual desktop and positions atop all other internal frames, solving the accessibility problem.
You may register a menu bar with JScrollableDesktopPane so that your application can offer an alternative solution to the accessibility problem. Upon registration, a Window menu is added to the main application's menu bar. This menu contains Tile , Cascade , Auto , and Close options along with a set of radio buttons that serve as dynamic shortcuts to the internal frames. Tile saturates the desktop with a tiled version of all internal frames, as shown in Figure 3.
Figure 3. Internal frames displayed in Tile mode. Click on thumbnail to view full-size image.
Cascade positions each internal frame in diagonal succession, as shown in Figure 4.
Figure 4. Internal frames displayed in Cascade mode. Click on thumbnail to view full-size image.
Auto allows the user to automatically tile or cascade new internal frames (default is auto-cascade), and Close disposes of the active internal frame.
Implement JScrollableDesktopPane
As you read the implementation details that follow, keep the UML class diagram in Figure 5 handy. You can click on the image for the full implementation details.
Figure 5. UML class diagram of JScrollableDesktopPane at a conceptual level. Click on thumbnail to view the implementation-level UML class diagram.
The JScrollableDesktopPane class is a JPanel subclass built upon five major GUI components: the BaseDesktopPane , DesktopScrollPane , BaseInternalFrame , DesktopResizableToolbar , and DesktopMenu component classes. These GUI components are labeled in Figure 6.
Figure 6. JScrollableDesktopPane with major GUI components labeled. Click on thumbnail to view full-size image.
The BaseDesktopPane and DesktopScrollPane classes comprise the virtual desktop. BaseDesktopPane , a JDesktopPane subclass, is located within a container of DesktopScrollPane , a JScrollPane subclass. The JScrollPane Swing component provides a scrollable view replete with horizontal and vertical scroll bars. When you move or resize an internal frame within the BaseDesktopPane class, a ComponentListener event fires. This event updates the DesktopScrollPane class's scroll bars via manipulation of the BaseDesktopPane preferred size (set via the setPreferredSize() method). The dimensions of this preferred size are determined from the minimum and maximum extents of all internal frames upon the desktop:
Rectangle viewP = getViewport().getViewRect();
int maxX=viewP.width+viewP.x, maxY=viewP.height+viewP.y;
int minX=viewP.x, minY=viewP.y;
JInternalFrame f = null;
JInternalFrame[] frames = getAllFrames();
for (int i=0; i < frames.length; i++) {
f = frames[i];
if (f.getX() < minX) { // get min X
minX = f.getX();
}
if ((f.getX() + f.getWidth()) > maxX) { // get max X
maxX = f.getX() + f.getWidth();
}
if (f.getY() < minY) { // get min Y
minY = f.getY();
}
if ((f.getY() + f.getHeight()) > maxY) { // get max Y
maxY = f.getY() + f.getHeight();
}
}
This technique is similar to that employed by the ScrollDemo2 example found in The Java Tutorial .
Internal frames added to the virtual desktop are of class BaseInternalFrame , a JInternalFrame subclass. The BaseInternalFrame class provides the getter and setter methods necessary to fetch any associated toggle and menu buttons (i.e., get/setAssociatedMenuButton() and get/setAssociatedButton() methods). When you minimize an internal frame, a blank image replaces the icon, as you access minimized frames via the toolbar's toggle buttons and any icon images only clutter the desktop.
The DesktopResizableToolbar class comprises the toolbar in Figure 6. A ResizableToolBar (not depicted in Figures 5 and 6) subclass, DesktopResizableToolbar renders a generic toolbar whose contents automatically size to fit as you add or remove buttons. ResizeableToolBar itself subclasses JToolBar , a Swing component class that provides a container for toolbar buttons. Upon a button's addition or removal (or a toolbar resizing), the ResizeableToolBar class dynamically determines the width of the remaining buttons by dividing the total container width by the button number:
int containerWidth =
getWidth() - getInsets().left - getInsets().right;
int numButtons = getButtonCount();
float buttonWidth = containerWidth / numButtons;
Each toggle button is of class BaseToggleButton , a subclass of Swing's JToggleButton component class. The BaseToggleButton class provides the necessary getter and setter methods to fetch the associated BaseInternalFrame class (i.e., get/setAssociatedFrame() methods).
DesktopMenu , a JMenu subclass, comprises the Window menu in Figure 6. Each dynamic menu shortcut (those numbered sequentially in Figure 6) is of class BaseRadioButtonMenuItem , a subclass of Swing's JRadioButtonMenuItem . Like BaseToggleButton , the BaseRadioButtonMenuItem class provides the necessary getter and setter methods to fetch the associated BaseInternalFrame class (i.e., get/setAssociatedFrame() methods). When an internal frame is destroyed, the DesktopMenu class renumbers the dynamic menu shortcuts to prevent any gaps in their sequence:
Enumeration e = frameRadioButtonMenuItemGroup.getElements();
int displayedCount = 1;
int currentMenuCount = 0;
BaseRadioButtonMenuItem b = null;
while (e.hasMoreElements()) {
b = (BaseRadioButtonMenuItem)e.nextElement();
// compute the key mnemonic based upon the currentMenuCount
currentMenuCount = displayedCount;
// derive the mnemonic from the first digit only..
if (currentMenuCount > 9) {
currentMenuCount/=10;
}
b.setMnemonic(KeyEvent.VK_0 + currentMenuCount);
b.setText(displayedCount +
" " + b.getAssociatedFrame().getTitle());
displayedCount++;
}
Note that if an application does not register a menu bar with the scrollable desktop, then DesktopMenu is not created. As such, DesktopMenu is listed with a 0..1 cardinality in Figure 5's UML diagram.
I should mention some of the package's non-GUI classes. Figure 5's DesktopListener provides a shared event class for various system objects. It implements a ComponentListener interface for the virtual desktop and internal frames, as well as an ActionListener interface for the toggle and menu buttons. Action commands differentiate between the varying source buttons:
public void actionPerformed(ActionEvent e) {
String actionCmd = e.getActionCommand();
if (actionCmd.equals("Tile")) {
desktopMediator.tileInternalFrames();
}
else if (actionCmd.equals("Cascade")) {
desktopMediator.cascadeInternalFrames();
}
...
Figure 5's DesktopMediator class coordinates state changes between other package objects per the Mediator design pattern. It reduces coupling between the coordinated classes (coupling being the number of objects a given class references and depends upon). For more information on these and other classes comprising JScrollableDesktopPane , refer to the source code and javadoc in Resources .
Note that JScrollableDesktopPane requires JDK 1.3 or greater to operate. If you use JDK 1.2, you must supplant the setDragMode() method in the BaseDesktopPane class with a call to the putClientProperty() method (see the comments in the BaseDesktopPane.java source code). Also, you must replace the getButtonCount() method in the ResizableToolBar class with a custom routine.
I tested JScrollableDesktopPane under Java 2 JDK 1.3.1-beta24 on Linux and JDK 1.3_02 on Windows and Intel Solaris.
Using JScrollableDesktop
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Create a scrollable virtual desktop
in Swing
View Tutorial: Create a scrollable virtual desktop
in Swing
Related
Tutorials:
Programming Java threads in the
real world, Part
5 - JavaWorld -
February 1999
Programming Java threads in the
real world, Part
5 - JavaWorld -
February 1999 |
Java Tip 72: Press
Escape to close your Swing dialog windows
Java Tip 72: Press
Escape to close your Swing dialog windows |
How to drag and drop with
Java 2, Part 2 - JavaWorld August
1999
How to drag and drop with
Java 2, Part 2 - JavaWorld August
1999 |
Enhance your Java application with Java Native Interface (JNI)
Enhance your Java application with Java Native Interface (JNI) |
Embed Java code into your
native apps -
JavaWorld May 2001
Embed Java code into your
native apps -
JavaWorld May 2001 |
Conquer
Swing deficiencies in MDI development - JavaWorld May 2001
Conquer
Swing deficiencies in MDI development - JavaWorld May 2001 |
Create a scrollable virtual desktop
in Swing
Create a scrollable virtual desktop
in Swing |
Take control with the Proxy design pattern
Take control with the Proxy design pattern |
Remote-control
Java
Remote-control
Java |
Java is here to stay (JavaWorld / January 2000 / by John Rommel)
Java is here to stay (JavaWorld / January 2000 / by John Rommel) |
J2ME devices:
Real-world performance
J2ME devices:
Real-world performance |
JXMLAppKit 2.0
JXMLAppKit is a pure Swing java framework for editing an XML document with multiple XML editors. |
WebOnSwing 1.0 beta
WebOnSwing 1.0 beta
WebOnSwing is a revolutionary multiple environment application framework that allows you to create web applications in the same way you develope a desktop one. You dont need to use JSP files, special tags, XML files, requests, posts |
Data Models for Desktop Apps
Data Models for Desktop Apps
This is the third article in a series that presents the prototype of a Java desktop application called JImaging. The first article described the three major Java GUI toolkits: AWT, Swing, and SWT. In the second article, I int |
Creating Custom Desktop Components
This article presents a drawing component used by an image-annotation application named JImaging. Some of the JImaging code has already been described in two other articles, titled "Prototyping Desktop Applications" and "Data Models for Desktop Apps." |
InfoNode (Java Components)
InfoNode Docking Windows is a pure Java Swing based docking windows framework. The best way to see features of InfoNode Docking Windows is to try the Web Start demos.
|
Ease Swing development with the TableModel Free framework
This article introduces the TableModel Free (TMF) framework which eliminates the need to use TableModels with Swing JTables. The TMF framework allows for more configurable JTables by moving all of table-specific data outside of the compiled code and into |
Java Tech: Acquire Images with TWAIN and SANE, Part 1
Scanners, digital cameras, and other image-acquisition devices are part of the computing landscape. Despite their ubiquity, however, Java does not provide a standard API for interacting with these devices. And yet there certainly is a desire to have a sta |
Advanced Synth
Take an in-depth look at the Synth look and feel, the newest addition to Swing introduced in Java 5.0. Synth lets developers rapidly create and deploy custom looks for an application by introducing the concept of a "skin" to Java UI programming. |
Creating Wizard Dialogs with Java Swing
Wizard dialogs are ubiquitous in today's desktop applications. This article creates a framework for a simple wizard dialog, complete with Back, Next, and Cancel buttons that you can extend for use in your applications as necessary. |
|
|
|