Other | Other |
---|---|
1.4.1_03 03Fixed | 1.4.2Fixed |
Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
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
|