Skip to main content

By clicking Submit, you agree to the developerWorks terms of use.

The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

All information submitted is secure.

  • Close [x]

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerworks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

By clicking Submit, you agree to the developerWorks terms of use.

All information submitted is secure.

  • Close [x]

Taming Tiger: AWT grows up

Mouse positioning and z-order

John Zukowski (jaz@zukowski.net), President, JZ Ventures, Inc.
Author photo
John Zukowski conducts strategic Java consulting with JZ Ventures, Inc. and is working with SavaJe Technologies to develop a next-generation mobile phone platform. His latest books are The Definitive Guide to Java Swing, Third Edition (Apress, June 2005) and Mastering Java 2, J2SE 1.4 (Sybex, April 2002)

Summary:  The Abstract Window Toolkit is the basis of the Swing component set. Follow along with John Zukowski as he discusses the aspects of AWT that changed with the 5.0 release of the Java™ 2 platform. These include PointerInfo and MouseInfo for recovering pointer position and z-order management for screens with overlaid components.

View more content in this series

Date:  24 May 2005
Level:  Introductory
Also available in:   Russian  Japanese

Activity:  6510 views
Comments:  

When it comes to discussing Java user interfaces, the Swing component set gets all the press. But there's more to GUIs than Swing. Just like with earlier releases of the Java platform, Swing is built on top of the Abstract Window Toolkit (AWT).

What does it mean by "on top of"? Nothing happens in Swing without underlying support in AWT. For instance, the original version of AWT had what is called peered components; when you created an AWT Button component, it created a native component. On a Microsoft Windows machines, it would create a Windows button component, and on a Solaris system, it would create a Motif button. Ten years ago, when the Java language was first introduced, native components seemed like the way to go.

Version 1.1 of the Java platform changed things. It added the ability to create peerless or lightweight components. Prior to these changes, Swing couldn't exist; the way to create a custom component was to subclass Canvas, which created a component native to the platform.

But I digress. This month's tip isn't about the origins of Swing or the Java language, it's about how AWT advanced with the 5.0 release. While Swing is typically the most visible change, it certainly isn't the only one. On to the AWT enhancements.

PointerInfo and MouseInfo

Two new classes added to the Java 5.0 platform are PointerInfo and MouseInfo. These classes help you locate the mouse on the desktop. Starting with the MouseInfo class, you get two static methods:

  • int getNumberOfButtons() tells you how many buttons are on your mouse. Depending on the number of mouse buttons, you may want to configure the available operations differently, as shown in Listing 1:


    Listing 1. Counting mouse buttons
    
    public class Mouse {
      public static void main(String args[]) {
        int count = MouseInfo.getNumberOfButtons();
        System.out.println("Mouse buttons = " + count);
      }
    }
    



  • PointerInfo getPointerInfo() returns a PointerInfo object.

The PointerInfo object returned has its own set of two methods:

  • GraphicsDevice getDevice() reports the device where the mouse is located, the actual GraphicsDevice object. On a system with multiple screens, call this method and get the associated GraphicsDevice object, specific to the mouse location.

  • Point getLocation() gets the physical location of the mouse on screen, as shown in Listing 2:


    Listing 2. Getting mouse position
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class Pos {
      public static void main(String args[]) {
        Runnable runnable = new Runnable() {
          public void run() {
            JFrame frame = new JFrame("Mouse Position");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          JLabel label = new JLabel();
            label.setHorizontalAlignment(JLabel.CENTER);
            MouseMotionListener mouseMotionListener = new MouseMotionListener() {
              public void mouseDragged(MouseEvent e) {
                showMousePos(e);
              }
    
              public void mouseMoved(MouseEvent e) {
                showMousePos(e);
              }
    
              private void showMousePos(MouseEvent e) {
                JLabel src = (JLabel)e.getComponent();
                PointerInfo pointerInfo = MouseInfo.getPointerInfo();
                Point point = pointerInfo.getLocation();
                src.setText(point.toString());
              }
            };
            label.addMouseMotionListener(mouseMotionListener);
            frame.add(label, BorderLayout.CENTER);
            frame.setSize(300, 300);
            frame.setVisible(true);
          }
        };
        EventQueue.invokeLater(runnable);
      }
    }
    

Figure 1 shows this code in action. Moving the mouse over the window changes the coordinate position.


Figure 1. Getting mouse position
Starting Screen

The Component class also has a getMousePosition() method that returns a Point object. The Point returned by getMousePosition() is the mouse position based off the component's coordinate space. Calling the getLocation() method of PointerInfo works in the coordinate space for the whole graphics device (that is, the screen) for a single screened system.

If you aren't familiar with the java.awt.Robot class, the Robot class allows you to move the mouse position. The class has been around since the 1.3 timeframe and includes an appropriately named mouseMove() method that has arguments for x and y coordinates. So now, not only can you move the mouse, but you can discover its position, too.


z-order and AlwaysOnTop

The concept of z-order describes a third dimension in which to place components and their windows. x and y positioning define the horizontal and vertical positions, respectively, with (0, 0) at the top-left corner of the screen. Adding z-order into the mix allows you to control how components are drawn on top of each other.

At the container level, you get two new methods, setComponentZOrder(Component c, int layer) and getComponentZOrder(Component c). The layer passed into the setComponentZOrder() method starts with 0 as the highest layer, drawn last, on top of everything else, with increasing numbers under that.

To demonstrate, the program in Listing 3 creates three components and places them one on top of another. Working with z-order involves several steps. First, you need to disable the layout manager for the container: setLayout(null). If you don't, and add components with the z-order set, it won't matter as there will be no overlapping of components. Of course, if you are using a custom layout manager that overlaps components, that works, too.

Next, you add the components to the container, without any layout constraints. You then set the z-order by calling setComponentZOrder() for each component in the container. As an additional step, for the overlapping components to draw correctly, the container containing the overlapping components must have their optimized drawing disabled, by having their isOptimizedDrawingEnabled() method return false. This last bit is done by creating a JPanel subclass, as there is no setOptimizedDrawingEnabled() method.


Listing 3. z-order and AlwaysOnTop

import java.awt.*;
import javax.swing.*;

public class Zs {

  public static void main(String args[]) {
    Runnable runnable = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("Z-Ordering");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JButton top = new JButton("Top");
        JButton middle = new JButton("Middle");
        JButton bottom = new JButton("Bottom");

        int x=25;
        int y=75;
        int width=100;
        int height=50;
        int overlap = 25;
        int widthDelta = width - overlap;
        int heightDelta = height - overlap;

        top.setBounds(x, y, width, height);
        middle.setBounds(x + widthDelta, y - heightDelta,
          width, height);
        bottom.setBounds(x + (widthDelta) * 2, y - (heightDelta) * 2,
          width, height);

        JPanel contentPane = new JPanel() {
          public boolean isOptimizedDrawingEnabled() {
            return false;
          }
        };
        contentPane.setLayout(null);
        contentPane.add(top);
        contentPane.add(middle);
        contentPane.add(bottom);
        contentPane.setComponentZOrder(top, 0);
        contentPane.setComponentZOrder(middle, 1);
        contentPane.setComponentZOrder(bottom, 2);
        frame.setContentPane(contentPane);
        frame.setSize(300, 200);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runnable);
  }
}

Figure 2 shows the results of the code in Listing 3.


Figure 2. z-order
Z-Ordering

Not only can you control the z-order for individual components within a container, but you can also manage z-order of windows, or at least say which one should go on top. Sure, you can call the toFront() method to make a particular window move to the front, but now with the Java 5.0 platform, you have the new setAlwaysOnTop() method of the Window class. When a window has its alwaysOnTop property set to true, it will always appear on top of other windows. The other windows can still have their components selected, but those windows with alwaysOnTop set to false (the default setting) will remain in the background.

Listing 4 demonstrates this behavior:


Listing 4. z-order and AlwaysOnTop

import java.awt.*;
import javax.swing.*;

public class Top {

  public static void main(String args[]) {
    Runnable runnable = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("Topper");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JDialog one = new JDialog(frame, "One");
        one.add(new JButton("One"), BorderLayout.CENTER);
        one.setSize(100, 100);
        one.setLocation(25, 25);
        one.setVisible(true);

        JDialog two = new JDialog(frame, "Two");
        two.add(new JButton("Two"), BorderLayout.CENTER);
        two.setSize(100, 100);
        two.setLocation(50, 50);
        two.setVisible(true);

        JDialog three = new JDialog(frame, "Three");
        three.add(new JButton("Three"), BorderLayout.CENTER);
        three.setSize(100, 100);
        three.setLocation(75, 75);
        three.setVisible(true);

        two.setAlwaysOnTop(true);

        frame.setSize(300, 200);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runnable);
  }
}

Figure 3 shows the results of Listing 4.


Figure 3. Layering windows
Z-Ordering

Untrusted applications need an AWTPermission in their policy file with a target name of setWindowAlwaysOnTop, which prevents malicious users from overriding the whole desktop, making it appear real while the underlying application fishes for information.

Only one active window should have the alwaysOnTop property to true. If multiple windows are set to true, behavior is undefined and likely to be platform-specific.


Resources

About the author

Author photo

John Zukowski conducts strategic Java consulting with JZ Ventures, Inc. and is working with SavaJe Technologies to develop a next-generation mobile phone platform. His latest books are The Definitive Guide to Java Swing, Third Edition (Apress, June 2005) and Mastering Java 2, J2SE 1.4 (Sybex, April 2002)

Report abuse help

Report abuse

Thank you. This entry has been flagged for moderator attention.


Report abuse help

Report abuse

Report abuse submission failed. Please try again later.


developerWorks: Sign in


Need an IBM ID?
Forgot your IBM ID?


Forgot your password?
Change your password

By clicking Submit, you agree to the developerWorks terms of use.

 


The first time you sign into developerWorks, a profile is created for you. Select information in your profile (name, country/region, and company) is displayed to the public and will accompany any content you post. You may update your IBM account at any time.

Choose your display name

The first time you sign in to developerWorks, a profile is created for you, so you need to choose a display name. Your display name accompanies the content you post on developerWorks.

Please choose a display name between 3-31 characters. Your display name must be unique in the developerWorks community and should not be your email address for privacy reasons.

(Must be between 3 – 31 characters.)

By clicking Submit, you agree to the developerWorks terms of use.

 


Rate this article

Comments

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=1
Zone=Java technology
ArticleID=83808
ArticleTitle=Taming Tiger: AWT grows up
publish-date=05242005
author1-email=jaz@zukowski.net
author1-email-cc=jaloi@us.ibm.com