--- old/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp 2016-03-18 11:47:07.326970765 +0530 +++ new/src/java.desktop/windows/native/libawt/windows/awt_TextArea.cpp 2016-03-18 11:47:06.994970765 +0530 @@ -225,31 +225,18 @@ /* * We consume WM_MOUSEMOVE while the left mouse button is pressed, - * so we have to simulate autoscrolling when mouse is moved outside - * of the client area. + * so we have to simulate selection autoscrolling when mouse is moved + * outside of the client area. */ POINT p; RECT r; - BOOL bScrollLeft = FALSE; - BOOL bScrollRight = FALSE; - BOOL bScrollUp = FALSE; BOOL bScrollDown = FALSE; p.x = msg->pt.x; p.y = msg->pt.y; VERIFY(::GetClientRect(GetHWnd(), &r)); - if (p.x < 0) { - bScrollLeft = TRUE; - p.x = 0; - } else if (p.x > r.right) { - bScrollRight = TRUE; - p.x = r.right - 1; - } - if (p.y < 0) { - bScrollUp = TRUE; - p.y = 0; - } else if (p.y > r.bottom) { + if (p.y > r.bottom) { bScrollDown = TRUE; p.y = r.bottom - 1; } @@ -269,32 +256,7 @@ EditSetSel(cr); } - - if (bScrollLeft == TRUE || bScrollRight == TRUE) { - SCROLLINFO si; - memset(&si, 0, sizeof(si)); - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; - - VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si)); - if (bScrollLeft == TRUE) { - si.nPos = si.nPos - si.nPage / 2; - si.nPos = max(si.nMin, si.nPos); - } else if (bScrollRight == TRUE) { - si.nPos = si.nPos + si.nPage / 2; - si.nPos = min(si.nPos, si.nMax); - } - /* - * Okay to use 16-bit position since RichEdit control adjusts - * its scrollbars so that their range is always 16-bit. - */ - DASSERT(abs(si.nPos) < 0x8000); - SendMessage(WM_HSCROLL, - MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos))); - } - if (bScrollUp == TRUE) { - SendMessage(EM_LINESCROLL, 0, -1); - } else if (bScrollDown == TRUE) { + if (bScrollDown == TRUE) { SendMessage(EM_LINESCROLL, 0, 1); } delete msg; --- old/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp 2016-03-18 11:47:07.998970765 +0530 +++ new/src/java.desktop/windows/native/libawt/windows/awt_TextField.cpp 2016-03-18 11:47:07.722970765 +0530 @@ -157,27 +157,12 @@ /* * We consume WM_MOUSEMOVE while the left mouse button is pressed, - * so we have to simulate autoscrolling when mouse is moved outside - * of the client area. + * so we have to simulate selection autoscrolling when mouse is moved + * outside of the client area. */ POINT p; - RECT r; - BOOL bScrollLeft = FALSE; - BOOL bScrollRight = FALSE; - BOOL bScrollUp = FALSE; - BOOL bScrollDown = FALSE; - p.x = msg->pt.x; p.y = msg->pt.y; - VERIFY(::GetClientRect(GetHWnd(), &r)); - - if (p.x < 0) { - bScrollLeft = TRUE; - p.x = 0; - } else if (p.x > r.right) { - bScrollRight = TRUE; - p.x = r.right - 1; - } LONG lCurPos = EditGetCharFromPos(p); if (GetStartSelectionPos() != -1 && @@ -193,32 +178,6 @@ EditSetSel(cr); } - - if (bScrollLeft == TRUE || bScrollRight == TRUE) { - SCROLLINFO si; - memset(&si, 0, sizeof(si)); - si.cbSize = sizeof(si); - si.fMask = SIF_PAGE | SIF_POS | SIF_RANGE; - - SendMessage(EM_SHOWSCROLLBAR, SB_HORZ, TRUE); - VERIFY(::GetScrollInfo(GetHWnd(), SB_HORZ, &si)); - SendMessage(EM_SHOWSCROLLBAR, SB_HORZ, FALSE); - - if (bScrollLeft == TRUE) { - si.nPos = si.nPos - si.nPage / 2; - si.nPos = max(si.nMin, si.nPos); - } else if (bScrollRight == TRUE) { - si.nPos = si.nPos + si.nPage / 2; - si.nPos = min(si.nPos, si.nMax); - } - /* - * Okay to use 16-bit position since RichEdit control adjusts - * its scrollbars so that their range is always 16-bit. - */ - DASSERT(abs(si.nPos) < 0x8000); - SendMessage(WM_HSCROLL, - MAKEWPARAM(SB_THUMBPOSITION, LOWORD(si.nPos))); - } delete msg; return mrConsume; } else if (msg->message == WM_KEYDOWN) { --- /dev/null 2016-03-18 10:45:29.027254000 +0530 +++ new/test/java/awt/TextArea/OverScrollTest/OverScrollTest.java 2016-03-18 11:47:08.454970765 +0530 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8149636 + @summary TextArea over scrolls to right when selecting text towards right. + @requires os.family == "windows" + @run main OverScrollTest + */ + +import java.awt.Frame; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.TextArea; +import java.awt.event.InputEvent; + +public class OverScrollTest { + Frame mainFrame; + TextArea textArea; + Robot robot; + + OverScrollTest() { + try { + robot = new Robot(); + } catch (Exception ex) { + throw new RuntimeException(ex.getMessage()); + } + + mainFrame = new Frame(); + mainFrame.setSize(400, 200); + mainFrame.setLocation(200, 200); + mainFrame.setLayout(new FlowLayout()); + + textArea = new TextArea(2, 10); + textArea.setSize(300, 100); + textArea.setText("123456 789123"); + mainFrame.add(textArea); + mainFrame.setVisible(true); + textArea.requestFocusInWindow(); + } + + public void dispose() { + if (mainFrame != null) { + mainFrame.dispose(); + } + } + + public void performTest() { + Point loc = textArea.getLocationOnScreen(); + Rectangle textAreaBounds = new Rectangle(); + textArea.getBounds(textAreaBounds); + + // Move mouse at center in first row of TextArea. + robot.mouseMove(loc.x + textAreaBounds.width / 2, loc.y + 5); + + // Perform selection by scrolling to right from end of char sequence. + robot.mousePress(InputEvent.BUTTON1_MASK); + for (int i = 0; i < textAreaBounds.width; i += 15) { + robot.mouseMove(i + loc.x + textAreaBounds.width / 2, loc.y + 5); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + // Perform double click on beginning word of TextArea + robot.mouseMove(loc.x + 5, loc.y + 5); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + dispose(); + if (!textArea.getSelectedText().contains("123456")) { + throw new RuntimeException ("TextArea over scrolled towards right. " + + "Selected text should contain: '123456' " + + "Actual selected test: '" + textArea.getSelectedText() + "'"); + } + } + + public static void main(String argv[]) throws RuntimeException { + OverScrollTest test = new OverScrollTest(); + test.performTest(); + } +} --- /dev/null 2016-03-18 10:45:29.027254000 +0530 +++ new/test/java/awt/TextField/OverScrollTest/OverScrollTest.java 2016-03-18 11:47:09.094970765 +0530 @@ -0,0 +1,109 @@ +/* + * Copyright (c) 2016, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +/* + @test + @bug 8149636 + @summary TextField over scrolls to right when selecting text towards right. + @requires os.family == "windows" + @run main OverScrollTest + */ + +import java.awt.Frame; +import java.awt.FlowLayout; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.TextField; +import java.awt.event.InputEvent; + +public class OverScrollTest { + Frame mainFrame; + TextField textField; + Robot robot; + + OverScrollTest() { + try { + robot = new Robot(); + } catch (Exception ex) { + throw new RuntimeException(ex.getMessage()); + } + + mainFrame = new Frame(); + mainFrame.setSize(400, 200); + mainFrame.setLocation(200, 200); + mainFrame.setLayout(new FlowLayout()); + + textField = new TextField(10); + textField.setSize(300, 100); + textField.setText("123456 789123"); + mainFrame.add(textField); + mainFrame.setVisible(true); + textField.requestFocusInWindow(); + } + + public void dispose() { + if (mainFrame != null) { + mainFrame.dispose(); + } + } + + public void performTest() { + Point loc = textField.getLocationOnScreen(); + Rectangle textFieldBounds = new Rectangle(); + textField.getBounds(textFieldBounds); + + // Move mouse at center in first row of TextField. + robot.mouseMove(loc.x + textFieldBounds.width / 2, loc.y + 5); + + // Perform selection by scrolling to right from end of char sequence. + robot.mousePress(InputEvent.BUTTON1_MASK); + for (int i = 0; i < textFieldBounds.width; i += 15) { + robot.mouseMove(i + loc.x + textFieldBounds.width / 2, loc.y + 5); + robot.delay(10); + } + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + // Perform double click on beginning word of TextField + robot.mouseMove(loc.x + 5, loc.y + 5); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.delay(100); + robot.mousePress(InputEvent.BUTTON1_MASK); + robot.mouseRelease(InputEvent.BUTTON1_MASK); + robot.waitForIdle(); + + dispose(); + if (!textField.getSelectedText().contains("123456")) { + throw new RuntimeException ("TextField over scrolled towards right. " + + "Selected text should contain: '123456' " + + "Actual selected test: '" + textField.getSelectedText() + "'"); + } + } + + public static void main(String argv[]) throws RuntimeException { + OverScrollTest test = new OverScrollTest(); + test.performTest(); + } +} --- old/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java 2016-03-18 11:47:10.074970765 +0530 +++ new/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.java 2016-03-18 11:47:09.766970765 +0530 @@ -1,5 +1,5 @@ /* - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1999, 2016, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -22,193 +22,240 @@ */ /* - test - @bug 4118621 - @summary tests that selected text isn't scrolled when there is enough room. - @author prs: area=TextField - @run applet/manual=yesno ScrollSelectionTest.html -*/ - -/** - * ScrollSelectionTest.java - * - * summary: tests that selected text isn't scrolled when there is enough room. + @test + @bug 4118621 8149636 + @summary Test the selection scrolling in TextField. + @run main/manual ScrollSelectionTest */ - -import java.applet.Applet; +import java.awt.Button; import java.awt.Dialog; +import java.awt.FlowLayout; import java.awt.Frame; -import java.awt.TextField; +import java.awt.Panel; import java.awt.TextArea; +import java.awt.TextField; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; -public class ScrollSelectionTest extends Applet - { +public class ScrollSelectionTest { - Frame frame = new Frame("ScrollSelectionTest frame"); - TextField tf = new TextField(40); + static Frame mainFrame; + static TextField textField; - public void init() - { - tf.setText("abcdefghijklmnopqrstuvwxyz"); - frame.add(tf); - tf.select(0, 20); - - String[] instructions = { - "INSTRUCTIONS:", - "This is a test for a win32 specific problem", - "If you see all the letters from 'a' to 'z' and", - "letters from 'a' to 't' are selected then test passes.", - "You may have to activate the frame to see the selection" - + " highlighted (e.g. by clicking on frame's title)." - }; - Sysout.createDialogWithInstructions( instructions ); - - }// init() - - public void start () - { - setSize (300,300); - setVisible(true); - - frame.setVisible(true); - frame.setBounds (400, 0, 300, 300); - - }// start() - - }// class ScrollSelectionTest - -/**************************************************** - Standard Test Machinery - DO NOT modify anything below -- it's a standard - chunk of code whose purpose is to make user - interaction uniform, and thereby make it simpler - to read and understand someone else's test. - ****************************************************/ + private static void init() throws Exception { + String[] instructions + = { + "INSTRUCTIONS: There are 2 Tests", + "Test1: Text visibility with Scroll", + "This is a test for a win32 specific problem", + "If you see all the letters from 'a' to 'z' and", + "letters from 'a' to 't' are selected then test passes.", + "You may have to activate the frame to see the selection", + "highlighted (e.g. by clicking on frame's title).", + ".", + "Test2: Flicker with selection scroll", + "Mouse press on the TextField text.", + "Move mouse towards left or right with selecting text.", + "Move mouse away outside the bounds of TextField.", + "No flicker should be observed.", + }; -/** - This is part of the standard test machinery. - It creates a dialog (with the instructions), and is the interface - for sending text messages to the user. - To print the instructions, send an array of strings to Sysout.createDialog - WithInstructions method. Put one line of instructions per array entry. - To display a message for the tester to see, simply call Sysout.println - with the string to be displayed. - This mimics System.out.println but works within the test harness as well - as standalone. - */ + Sysout.createDialog(); + Sysout.printInstructions(instructions); + } -class Sysout - { - private static TestDialog dialog; + public static void initTestWindow() { + mainFrame = new Frame("ScrollSelectionTest frame"); + mainFrame.setBounds(500, 0, 400, 200); + + textField = new TextField(40); + textField.setText("abcdefghijklmnopqrstuvwxyz"); + mainFrame.add(textField); + mainFrame.setLayout(new FlowLayout()); + textField.select(0, 20); + mainFrame.setVisible(true); + } - public static void createDialogWithInstructions( String[] instructions ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - dialog.printInstructions( instructions ); - dialog.show(); - println( "Any messages for the tester will display here." ); + public static void dispose() { + Sysout.dispose(); + mainFrame.dispose(); } - public static void createDialog( ) - { - dialog = new TestDialog( new Frame(), "Instructions" ); - String[] defInstr = { "Instructions will appear here. ", "" } ; - dialog.printInstructions( defInstr ); - dialog.show(); - println( "Any messages for the tester will display here." ); + /** + * *************************************************** + * Standard Test Machinery Section DO NOT modify anything in this section -- + * it's a standard chunk of code which has all of the synchronization + * necessary for the test harness. By keeping it the same in all tests, it + * is easier to read and understand someone else's test, as well as insuring + * that all tests behave correctly with the test harness. There is a section + * following this for test-defined classes + * **************************************************** + */ + private static boolean theTestPassed = false; + private static boolean testGeneratedInterrupt = false; + private static String failureMessage = ""; + private static Thread mainThread = null; + final private static int sleepTime = 300000; + + public static void main(String args[]) throws Exception { + mainThread = Thread.currentThread(); + try { + init(); + initTestWindow(); + } catch (Exception e) { + e.printStackTrace(); + } + try { + mainThread.sleep(sleepTime); + } catch (InterruptedException e) { + dispose(); + if (testGeneratedInterrupt && !theTestPassed) { + throw new Exception(failureMessage); + } + } + if (!testGeneratedInterrupt) { + dispose(); + throw new RuntimeException("Timed out after " + sleepTime / 1000 + + " seconds"); + } } + public static synchronized void pass() { + theTestPassed = true; + testGeneratedInterrupt = true; + mainThread.interrupt(); + } - public static void printInstructions( String[] instructions ) - { - dialog.printInstructions( instructions ); + public static synchronized void fail(String whyFailed) { + theTestPassed = false; + testGeneratedInterrupt = true; + failureMessage = whyFailed; + mainThread.interrupt(); } +} +// *********** End Standard Test Machinery Section ********** +/** + * ************************************************** + * Standard Test Machinery DO NOT modify anything below -- it's a standard chunk + * of code whose purpose is to make user interaction uniform, and thereby make + * it simpler to read and understand someone else's test. + * ************************************************** + */ +/** + * This is part of the standard test machinery. It creates a dialog (with the + * instructions), and is the interface for sending text messages to the user. To + * print the instructions, send an array of strings to Sysout.createDialog + * WithInstructions method. Put one line of instructions per array entry. To + * display a message for the tester to see, simply call Sysout.println with the + * string to be displayed. This mimics System.out.println but works within the + * test harness as well as standalone. + */ +class Sysout { + private static TestDialog dialog; + private static Frame frame; + + public static void createDialog() { + frame = new Frame(); + dialog = new TestDialog(frame, "Instructions"); + String[] defInstr = {"Instructions will appear here. ", ""}; + dialog.printInstructions(defInstr); + dialog.setVisible(true); + println("Any messages for the tester will display here."); + } - public static void println( String messageIn ) - { - dialog.displayMessage( messageIn ); + public static void printInstructions(String[] instructions) { + dialog.printInstructions(instructions); } - }// Sysout class + public static void println(String messageIn) { + dialog.displayMessage(messageIn); + } + + public static void dispose() { + dialog.dispose(); + frame.dispose(); + } +} /** - This is part of the standard test machinery. It provides a place for the - test instructions to be displayed, and a place for interactive messages - to the user to be displayed. - To have the test instructions displayed, see Sysout. - To have a message to the user be displayed, see Sysout. - Do not call anything in this dialog directly. - */ -class TestDialog extends Dialog - { - - TextArea instructionsText; - TextArea messageText; - int maxStringLength = 80; - - //DO NOT call this directly, go through Sysout - public TestDialog( Frame frame, String name ) - { - super( frame, name ); - int scrollBoth = TextArea.SCROLLBARS_BOTH; - instructionsText = new TextArea( "", 15, maxStringLength, scrollBoth ); - add( "North", instructionsText ); - - messageText = new TextArea( "", 5, maxStringLength, scrollBoth ); - add("South", messageText); - - pack(); - - show(); - }// TestDialog() - - //DO NOT call this directly, go through Sysout - public void printInstructions( String[] instructions ) - { - //Clear out any current instructions - instructionsText.setText( "" ); - - //Go down array of instruction strings - - String printStr, remainingStr; - for( int i=0; i < instructions.length; i++ ) - { - //chop up each into pieces maxSringLength long - remainingStr = instructions[ i ]; - while( remainingStr.length() > 0 ) - { - //if longer than max then chop off first max chars to print - if( remainingStr.length() >= maxStringLength ) - { - //Try to chop on a word boundary - int posOfSpace = remainingStr. - lastIndexOf( ' ', maxStringLength - 1 ); - - if( posOfSpace <= 0 ) posOfSpace = maxStringLength - 1; - - printStr = remainingStr.substring( 0, posOfSpace + 1 ); - remainingStr = remainingStr.substring( posOfSpace + 1 ); - } - //else just print - else - { - printStr = remainingStr; - remainingStr = ""; - } - - instructionsText.append( printStr + "\n" ); - - }// while - - }// for - - }//printInstructions() - - //DO NOT call this directly, go through Sysout - public void displayMessage( String messageIn ) - { - messageText.append( messageIn + "\n" ); + * This is part of the standard test machinery. It provides a place for the test + * instructions to be displayed, and a place for interactive messages to the + * user to be displayed. To have the test instructions displayed, see Sysout. To + * have a message to the user be displayed, see Sysout. Do not call anything in + * this dialog directly. + */ +class TestDialog extends Dialog implements ActionListener { + TextArea instructionsText; + TextArea messageText; + int maxStringLength = 80; + Panel buttonP; + Button failB; + Button passB; + + // DO NOT call this directly, go through Sysout + public TestDialog(Frame frame, String name) { + super(frame, name); + int scrollBoth = TextArea.SCROLLBARS_BOTH; + instructionsText = new TextArea("", 15, maxStringLength, scrollBoth); + add("North", instructionsText); + + messageText = new TextArea("", 5, maxStringLength, scrollBoth); + add("Center", messageText); + + buttonP = new Panel(); + passB = new Button("pass"); + passB.setActionCommand("pass"); + passB.addActionListener(this); + buttonP.add("East", passB); + + failB = new Button("Fail"); + failB.setActionCommand("fail"); + failB.addActionListener(this); + buttonP.add("West", failB); + + add("South", buttonP); + pack(); + setVisible(true); + } + + // DO NOT call this directly, go through Sysout + public void printInstructions(String[] instructions) { + instructionsText.setText(""); + String printStr, remainingStr; + for (int i = 0; i < instructions.length; i++) { + remainingStr = instructions[i]; + while (remainingStr.length() > 0) { + if (remainingStr.length() >= maxStringLength) { + int posOfSpace = remainingStr. + lastIndexOf(' ', maxStringLength - 1); + + if (posOfSpace <= 0) { + posOfSpace = maxStringLength - 1; + } + + printStr = remainingStr.substring(0, posOfSpace + 1); + remainingStr = remainingStr.substring(posOfSpace + 1); + } + else { + printStr = remainingStr; + remainingStr = ""; + } + instructionsText.append(printStr + "\n"); + } + } } - }// TestDialog class + public void displayMessage(String messageIn) { + messageText.append(messageIn + "\n"); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("pass")) { + ScrollSelectionTest.pass(); + } else { + ScrollSelectionTest.fail("User Clicked Fail"); + } + } +} --- old/test/java/awt/TextField/ScrollSelectionTest/ScrollSelectionTest.html 2016-03-18 11:47:10.718970765 +0530 +++ /dev/null 2016-03-18 10:45:29.027254000 +0530 @@ -1,43 +0,0 @@ - - - - - - ScrollSelectionTest - - - -

ScrollSelectionTest
4118621:

- -

See the dialog box (usually in upper left corner) for instructions

- - - -