-
Bug
-
Resolution: Fixed
-
P4
-
1.4.0, 1.4.1
-
03
-
x86
-
windows_2000
Issue | Fix Version | Assignee | Priority | Status | Resolution | Resolved In Build |
---|---|---|---|---|---|---|
JDK-2057492 | 5.0 | Brent Christian | P4 | Resolved | Fixed | tiger |
JDK-2057491 | 1.4.2 | Brent Christian | P4 | Resolved | Fixed | b20 |
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
- backported by
-
JDK-2057491 Mouse click/drag zone is not read correctly from Win32
- Resolved
-
JDK-2057492 Mouse click/drag zone is not read correctly from Win32
- Resolved
- duplicates
-
JDK-4774787 Reopen Bug ID 4218549: Double click not accepted in JFileChooser
- Closed
- relates to
-
JDK-4226646 Lost mouseClicked events for JButton
- Closed
-
JDK-4415175 No easy way to globally change the DND gesture motion threshold
- Resolved
-
JDK-6404008 REGRESSION: Mouse dragged events obey drag sensitivity
- Resolved
-
JDK-4842062 Win32: when used, SM_CXDRAG and SM_CYDRAG should be reduced to a half
- Resolved
-
JDK-5039416 REGRESSION: Extra mouse click dispatched after press-drag- release sequence.
- Closed
-
JDK-6455716 XAWT: should ignore smudge factor while mouse is hovering or dragging
- Closed