Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-4731797

Mouse click/drag zone is not read correctly from Win32

XMLWordPrintable

    • 03
    • x86
    • windows_2000

        aints.gridx = 3;
                constraints.gridy = 3;
                txfLocationClickY = new JTextField(3);
                txfLocationClickY.setEditable(false);
                txfLocationClickY.setBackground(Color.white);
                txfLocationClickY.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationClickY, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 4;
                constraints.gridy = 3;
                txfDifferenceClickX = new JTextField(3);
                txfDifferenceClickX.setEditable(false);
                txfDifferenceClickX.setBackground(Color.white);
                txfDifferenceClickX.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfDifferenceClickX, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 5;
                constraints.gridy = 3;
                txfDifferenceClickY = new JTextField(3);
                txfDifferenceClickY.setEditable(false);
                txfDifferenceClickY.setBackground(Color.white);
                txfDifferenceClickY.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfDifferenceClickY, constraints);

                // Layout, size, and position the frame.
                pack();
                Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
                Dimension frameSize = getSize();
                setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height
        - frameSize.height) / 2);
            }
        }

        ---------------------------------------------------------
        // MouseClickZones
        // written by Curtis Clauson for The Snake Pit - Development
        //
        // Native Win32 console C++ source.

        #include <windows.h>
        #include <iostream.h>
        #include <iomanip.h>


        int
        main()
        {
        int dragx = GetSystemMetrics(SM_CXDRAG);
        int dragy = GetSystemMetrics(SM_CYDRAG);
        int dblx = GetSystemMetrics(SM_CXDOUBLECLK);
        int dbly = GetSystemMetrics(SM_CYDOUBLECLK);

        cout << "Mouse Click Zone:" << endl
        << " Drag : " << dragx << ", " << dragy << endl
        << " Double: " << dblx << ", " << dbly << endl;
        return 0;
        }

        ---------- END SOURCE ----------

        CUSTOMER WORKAROUND :
        Developers have been using the MouseListener.mouseReleased
        instead of the MouseListener.mouseClicked event for Java on
        Win32. However, a lot of the JRE core classes do not, and
        most non-Win32 cross-platform Java component developers do
        not. This creates an inconsistent mouse behavior on Win32
        depending over what component the mouse was clicked.
        (Review ID: 160629)
        ======================================================================
        Name: gm110360 Date: 08/14/2002


        FULL PRODUCT VERSION :
        java version "1.4.0"
        and java version "1.4.1-beta"

        FULL OPERATING SYSTEM VERSION :
        Microsoft Windows 2000 [Version 5.00.2195]

        A DESCRIPTION OF THE PROBLEM :
        On Win32 platforms, Java does not correctly obtain the
        "Mouse Click Zone" metrics from the Windows OS. These
        metrics are obtained by the GetSystemMetrics() function
        using the SM_CXDRAG and SM_CYDRAG metrics. These define the
        maximum x and y pixels a mouse cursor can be dragged between
        a mouse pressed and mouse released operation and still be
        interpreted as a click event, and not start a drag event.

        This behavior is consistent in Java on Win32 platforms
        regardless of the set look and feel. It is not an OS
        problem, as a native application shows a different metric
        than what Java uses (For example: On my Win2KPro, I show a
        metric of {4, 4}, while Java uses {1, 1}).

        This bug has been has been complained about by users,
        developers, and customers since version 1.0. Bug ID 4218549
        is related but assumes that there is no Click Zone (or
        smudge factor). Whoever closed that bug simply assumed it
        was a Win32 problem without bothering to check.

        Note: The system metrics SM_CXDOUBLECLK and SM_CYDOUBLECLK
        are not used for click/drag differentiation, as was
        erroneously stated in that bug report, but are used along
        with a timer to differentiate between single and double clicks.

        This bug report specifies that the zone used by Java is not
        properly read from the underlying OS. Two sets of sample
        code are provided. The Java code proves the zone used is {1,
        1}. The native Win32 C++ code shows what the OS zone metric
        really is.

        This is a !!!VERY!!! serious problem, as it makes Java look
        like it is slow and unresponsive on Win32 platforms, giving
        false credence to the claims and myths that Java cannot be
        realistically used on anything but a Solaris platform. Also,
        it precludes any accessability modifications of that
        click/drag zone for people with infirmities that affect how
        steady they can hold or click a mouse.

        STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
        1. Find out what the native mouse click/drag zone is on
        Win32 using GetSystemMetrics() with SM_CXDRAG and SM_CYDRAG
        (run the MouseClickZones C++ sample).
        2. Run the MouseClickZone Java sample. Press the left mouse
        button in the white pad, drag the mouse for less than the OS
        reported metric, and release the mouse button.


        EXPECTED VERSUS ACTUAL BEHAVIOR :
        Expected: The click event will be fired when the pressed
        mouse is dragged for less than the OS reported mouse
        click/drag zone metric.

        Actual: The click event is not fired if the pressed mouse
        cursor is dragged by even 1 pixel in any direction.

        REPRODUCIBILITY :
        This bug can be reproduced always.

        ---------- BEGIN SOURCE ----------

        import java.awt.*;
        import java.awt.event.*;
        import java.io.*;
        import javax.swing.*;
        import javax.swing.event.*;
        import javax.swing.border.*;
        import javax.swing.text.html.*;


        /**
         * A simple Swing application to discover what the click/drag zone is for a
        mouse click.
         *
         * @author Curtis Clauson for <b>The Snake Pit - Development</b>
        (http://www.TheSnakePitDev.com)
         */
        public
        class MouseClickZone
        extends JFrame {
            /*
             * Class Methods
             */

            /**
             * Create and start a MouseClickZone frame.
             */
            public static
            void
            main(String[] args)
            {
                new MouseClickZone().show();
            }


            /*
             * Instance Data
             */

            /** The pad for mouse events. */
            protected JPanel pnlMousePad;

            /** X location of a mouse down event. */
            protected int pressX;
            /** Y location of a mouse down event. */
            protected int pressY;
            /** X location of a mouse up event. */
            protected int releaseX;
            /** Y location of a mouse up event. */
            protected int releaseY;
            /** X location of a mouse click event. */
            protected int clickX;
            /** Y location of a mouse click event. */
            protected int clickY;

            /** Text field to display the X location of a mouse move event. */
            protected JTextField txfLocationCursorX;
            /** Text field to display the Y location of a mouse move event. */
            protected JTextField txfLocationCursorY;
            /** Text field to display the X location of a mouse down event. */
            protected JTextField txfLocationPressX;
            /** Text field to display the Y location of a mouse down event. */
            protected JTextField txfLocationPressY;
            /** Text field to display the X location of a mouse up event. */
            protected JTextField txfLocationReleaseX;
            /** Text field to display the Y location of a mouse up event. */
            protected JTextField txfLocationReleaseY;
            /** Text field to display the X difference of a mouse up event from the
        mouse down event. */
            protected JTextField txfDifferenceReleaseX;
            /** Text field to display the Y difference of a mouse up event from the
        mouse down event. */
            protected JTextField txfDifferenceReleaseY;
            /** Text field to display the X location of a mouse click event. */
            protected JTextField txfLocationClickX;
            /** Text field to display the Y location of a mouse click event. */
            protected JTextField txfLocationClickY;
            /** Text field to display the X difference of a mouse click event from the
        mouse down event. */
            protected JTextField txfDifferenceClickX;
            /** Text field to display the Y difference of a mouse click event from the
        mouse down event. */
            protected JTextField txfDifferenceClickY;


            /*
             * Constructors
             */

            /**
             * Create a new MouseClickZone frame.
             */
            public
            MouseClickZone()
            {
                // Configure the frame.
                setDefaultCloseOperation(EXIT_ON_CLOSE);
                setTitle("Mouse Click Zone");
                setResizable(false);

                // Create a content panel.
                JPanel content = new JPanel();
                content.setLayout(new BoxLayout(content, BoxLayout.Y_AXIS));
                content.setBorder(new EmptyBorder(4, 4, 4, 4));
                setContentPane(content);

                // Create the mouse pad.
                pnlMousePad = new JPanel();
                content.add(pnlMousePad);
                Insets insets = pnlMousePad.getInsets();
                pnlMousePad.setLocation(new Point(0, 0));
                pnlMousePad.setPreferredSize(new Dimension(200 + insets.left +
        insets.right, 200 + insets.top + insets.bottom));
                pnlMousePad.setBackground(Color.white);
                pnlMousePad.addMouseMotionListener(new MouseMotionAdapter() {
                    public void mouseMoved(MouseEvent event) {
                        Dimension size = pnlMousePad.getSize();
                        Insets insets = pnlMousePad.getInsets();
                        int x = event.getX() - insets.left;
                        int y = event.getY() - insets.top;
                        if ( x < 0 || x >= size.width - (insets.left + insets.right )
                            || y < 0 || y >= size.height - (insets.top + insets.bottom)
                        ) return;
                        txfLocationCursorX.setText(Integer.toString(x));
                        txfLocationCursorY.setText(Integer.toString(y));
                    }
                });
                pnlMousePad.addMouseListener(new MouseAdapter() {
                    public void mousePressed(MouseEvent event) {
                        Dimension size = pnlMousePad.getSize();
                        Insets insets = pnlMousePad.getInsets();
                        pressX = event.getX() - insets.left;
                        pressY = event.getY() - insets.top;
                        if ( pressX < 0 || pressX >= size.width - (insets.left +
        insets.right )
                            || pressY < 0 || pressY >= size.height - (insets.top +
        insets.bottom)
                        ) return;
                        txfLocationPressX.setText(Integer.toString(pressX));
                        txfLocationPressY.setText(Integer.toString(pressY));
                        txfLocationReleaseX.setText(null);
                        txfLocationReleaseY.setText(null);
                        txfDifferenceReleaseX.setText(null);
                        txfDifferenceReleaseY.setText(null);
                        txfLocationClickX.setText(null);
                        txfLocationClickY.setText(null);
                        txfDifferenceClickX.setText(null);
                        txfDifferenceClickY.setText(null);
                    }
                    public void mouseReleased(MouseEvent event) {
                        Dimension size = pnlMousePad.getSize();
                        Insets insets = pnlMousePad.getInsets();
                        releaseX = event.getX() - insets.left;
                        releaseY = event.getY() - insets.top;
                        if ( releaseX < 0 || releaseX >= size.width - (insets.left +
        insets.right )
                            || releaseY < 0 || releaseY >= size.height - (insets.top +
        insets.bottom)
                        ) return;
                        txfLocationReleaseX.setText(Integer.toString(releaseX));
                        txfLocationReleaseY.setText(Integer.toString(releaseY));
                        txfDifferenceReleaseX.setText(Integer.toString(releaseX - pressX));
                        txfDifferenceReleaseY.setText(Integer.toString(releaseY - pressY));
                    }
                    public void mouseClicked(MouseEvent event) {
                        Dimension size = pnlMousePad.getSize();
                        Insets insets = pnlMousePad.getInsets();
                        clickX = event.getX() - insets.left;
                        clickY = event.getY() - insets.top;
                        if ( clickX < 0 || clickX >= size.width - (insets.left +
        insets.right )
                            || clickY < 0 || clickY >= size.height - (insets.top +
        insets.bottom)
                        ) return;
                        txfLocationClickX.setText(Integer.toString(clickX));
                        txfLocationClickY.setText(Integer.toString(clickY));
                        txfDifferenceClickX.setText(Integer.toString(clickX - pressX));
                        txfDifferenceClickY.setText(Integer.toString(clickY - pressY));
                    }
                });

                // Create the info panel.
                JPanel panel = new JPanel(new GridBagLayout());
                content.add(panel);
                panel.setBorder(new EmptyBorder(4, 0, 0, 0));

                JTextField textField;
                GridBagConstraints constraints;

                constraints = new GridBagConstraints();
                constraints.gridx = 0;
                constraints.gridy = 0;
                txfLocationCursorX = new JTextField(3);
                txfLocationCursorX.setEditable(false);
                txfLocationCursorX.setBackground(Color.white);
                txfLocationCursorX.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationCursorX, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 1;
                constraints.gridy = 0;
                txfLocationCursorY = new JTextField(3);
                txfLocationCursorY.setEditable(false);
                txfLocationCursorY.setBackground(Color.white);
                txfLocationCursorY.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationCursorY, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 2;
                constraints.gridy = 0;
                constraints.gridwidth = 2;
                panel.add(new JLabel("Position", JLabel.LEADING), constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 4;
                constraints.gridy = 0;
                constraints.gridwidth = 2;
                panel.add(new JLabel("Difference", JLabel.LEADING), constraints);

                constraints = new GridBagConstraints();
                constraints.gridx = 0;
                constraints.gridy = 1;
                constraints.gridwidth = 2;
                constraints.anchor = GridBagConstraints.WEST;
                panel.add(new JLabel("Press", JLabel.LEADING), constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 2;
                constraints.gridy = 1;
                txfLocationPressX = new JTextField(3);
                txfLocationPressX.setEditable(false);
                txfLocationPressX.setBackground(Color.white);
                txfLocationPressX.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationPressX, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 3;
                constraints.gridy = 1;
                txfLocationPressY = new JTextField(3);
                txfLocationPressY.setEditable(false);
                txfLocationPressY.setBackground(Color.white);
                txfLocationPressY.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationPressY, constraints);

                constraints = new GridBagConstraints();
                constraints.gridx = 0;
                constraints.gridy = 2;
                constraints.gridwidth = 2;
                constraints.anchor = GridBagConstraints.WEST;
                panel.add(new JLabel("Release", JLabel.LEADING), constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 2;
                constraints.gridy = 2;
                txfLocationReleaseX = new JTextField(3);
                txfLocationReleaseX.setEditable(false);
                txfLocationReleaseX.setBackground(Color.white);
                txfLocationReleaseX.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationReleaseX, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 3;
                constraints.gridy = 2;
                txfLocationReleaseY = new JTextField(3);
                txfLocationReleaseY.setEditable(false);
                txfLocationReleaseY.setBackground(Color.white);
                txfLocationReleaseY.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationReleaseY, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 4;
                constraints.gridy = 2;
                txfDifferenceReleaseX = new JTextField(3);
                txfDifferenceReleaseX.setEditable(false);
                txfDifferenceReleaseX.setBackground(Color.white);
                txfDifferenceReleaseX.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfDifferenceReleaseX, constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 5;
                constraints.gridy = 2;
                txfDifferenceReleaseY = new JTextField(3);
                txfDifferenceReleaseY.setEditable(false);
                txfDifferenceReleaseY.setBackground(Color.white);
                txfDifferenceReleaseY.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfDifferenceReleaseY, constraints);

                constraints = new GridBagConstraints();
                constraints.gridx = 0;
                constraints.gridy = 3;
                constraints.gridwidth = 2;
                constraints.anchor = GridBagConstraints.WEST;
                panel.add(new JLabel("Click", JLabel.LEADING), constraints);
                constraints = new GridBagConstraints();
                constraints.gridx = 2;
                constraints.gridy = 3;
                txfLocationClickX = new JTextField(3);
                txfLocationClickX.setEditable(false);
                txfLocationClickX.setBackground(Color.white);
                txfLocationClickX.setHorizontalAlignment(JTextField.TRAILING);
                panel.add(txfLocationClickX, constraints);
                constraints = new GridBagConstraints();
                constr

              bchristi Brent Christian
              gmanwanisunw Girish Manwani (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              0 Start watching this issue

                Created:
                Updated:
                Resolved:
                Imported:
                Indexed: