+{"files":[{"patch":"@@ -93,0 +93,2 @@\n+ \"alt UP\", DefaultEditorKit.beginLineUpAction,\n+ \"alt DOWN\", DefaultEditorKit.endLineDownAction,\n","filename":"src\/java.desktop\/macosx\/classes\/com\/apple\/laf\/AquaKeyBindings.java","additions":2,"deletions":0,"binary":false,"changes":2,"status":"modified"},{"patch":"@@ -645,0 +645,14 @@\n+ \/**\n+ * Name of the <code>Action<\/code> for moving the caret\n+ * to the end of a line and logically upward one position.\n+ * @see #getActions\n+ *\/\n+ public static final String beginLineUpAction = \"caret-begin-line-and-up\";\n+\n+ \/**\n+ * Name of the <code>Action<\/code> for moving the caret\n+ * to the end of a line and logically downward one position.\n+ * @see #getActions\n+ *\/\n+ public static final String endLineDownAction = \"caret-end-line-and-down\";\n+\n@@ -801,0 +815,2 @@\n+ new BeginLineUpAction(beginLineUpAction, false,\n+ SwingConstants.NORTH),\n@@ -802,0 +818,2 @@\n+ new EndLineDownAction(endLineDownAction, false,\n+ SwingConstants.SOUTH),\n@@ -2043,0 +2061,209 @@\n+ \/*\n+ * Position the caret to the end of the line and down one line.\n+ * @see DefaultEditorKit#endLineAction\n+ * @see DefaultEditorKit#selectEndLineAction\n+ * @see DefaultEditorKit#getActions\n+ *\/\n+ @SuppressWarnings(\"serial\") \/\/ Superclass is not serializable across versions\n+ static class EndLineDownAction extends TextAction {\n+\n+ \/**\n+ * Create this action with the appropriate identifier.\n+ * @param nm the name of the action, Action.NAME.\n+ * @param select whether to extend the selection when\n+ * changing the caret position.\n+ * @param direction the direction to move the caret\n+ *\/\n+ EndLineDownAction(String nm, boolean select, int direction) {\n+ super(nm);\n+ this.select = select;\n+ this.direction = direction;\n+ firstTime = true;\n+ }\n+\n+ \/** The operation to perform when this action is triggered. *\/\n+ @SuppressWarnings(\"deprecation\")\n+ public void actionPerformed(ActionEvent e) {\n+ System.out.println(\"EndLineDownAction\");\n+ JTextComponent target = getTextComponent(e);\n+ if (target != null) {\n+ try {\n+ int offs = target.getCaretPosition();\n+ int endOffs = Utilities.getRowEnd(target, offs);\n+ if (offs != endOffs) {\n+ if (select) {\n+ target.moveCaretPosition(endOffs);\n+ } else {\n+ target.setCaretPosition(endOffs);\n+ }\n+ } else {\n+ Caret caret = target.getCaret();\n+ DefaultCaret bidiCaret = (caret instanceof DefaultCaret) ?\n+ (DefaultCaret) caret : null;\n+ int dot = caret.getDot();\n+ Position.Bias[] bias = new Position.Bias[1];\n+ Point magicPosition = caret.getMagicCaretPosition();\n+\n+ if (magicPosition == null && (direction == SwingConstants.NORTH || direction == SwingConstants.SOUTH)) {\n+ Rectangle r = (bidiCaret != null) ?\n+ target.getUI().modelToView(target, dot,\n+ bidiCaret.getDotBias()) :\n+ target.modelToView(dot);\n+ magicPosition = new Point(r.x, r.y);\n+ }\n+ NavigationFilter filter = target.getNavigationFilter();\n+\n+ if (filter != null) {\n+ dot = filter.getNextVisualPositionFrom\n+ (target, dot, (bidiCaret != null) ?\n+ bidiCaret.getDotBias() :\n+ Position.Bias.Forward, direction, bias);\n+ } else {\n+ dot = target.getUI().getNextVisualPositionFrom\n+ (target, dot, (bidiCaret != null) ?\n+ bidiCaret.getDotBias() :\n+ Position.Bias.Forward, direction, bias);\n+ }\n+ if (bias[0] == null) {\n+ bias[0] = Position.Bias.Forward;\n+ }\n+ if (bidiCaret != null) {\n+ if (select) {\n+ bidiCaret.moveDot(dot, bias[0]);\n+ } else {\n+ bidiCaret.setDot(dot, bias[0]);\n+ }\n+ } else {\n+ if (select) {\n+ caret.moveDot(dot);\n+ } else {\n+ caret.setDot(dot);\n+ }\n+ }\n+ if (magicPosition != null &&\n+ (direction == SwingConstants.NORTH ||\n+ direction == SwingConstants.SOUTH)) {\n+ target.getCaret().setMagicCaretPosition(magicPosition);\n+ }\n+ offs = target.getCaretPosition();\n+ endOffs = Utilities.getRowEnd(target, offs);\n+ if (select) {\n+ target.moveCaretPosition(endOffs);\n+ } else {\n+ target.setCaretPosition(endOffs);\n+ }\n+ }\n+ } catch (BadLocationException ex) {\n+ }\n+ }\n+ }\n+\n+ private boolean select;\n+ private int direction;\n+ private boolean firstTime;\n+ }\n+\n+ \/*\n+ * Position the caret to the start of the line and up one line.\n+ * @see DefaultEditorKit#beginLineAction\n+ * @see DefaultEditorKit#selectBeginLineAction\n+ * @see DefaultEditorKit#getActions\n+ *\/\n+ @SuppressWarnings(\"serial\") \/\/ Superclass is not serializable across versions\n+ static class BeginLineUpAction extends TextAction {\n+\n+ \/**\n+ * Create this action with the appropriate identifier.\n+ * @param nm the name of the action, Action.NAME.\n+ * @param select whether to extend the selection when\n+ * changing the caret position.\n+ * @param direction the direction to move the caret\n+ *\/\n+ BeginLineUpAction(String nm, boolean select, int direction) {\n+ super(nm);\n+ this.select = select;\n+ this.direction = direction;\n+ }\n+\n+ \/** The operation to perform when this action is triggered. *\/\n+ @SuppressWarnings(\"deprecation\")\n+ public void actionPerformed(ActionEvent e) {\n+ JTextComponent target = getTextComponent(e);\n+ if (target != null) {\n+ try {\n+ int offs = target.getCaretPosition();\n+ int begOffs = Utilities.getRowStart(target, offs);\n+ if (offs != begOffs) {\n+ if (select) {\n+ target.moveCaretPosition(begOffs);\n+ } else {\n+ target.setCaretPosition(begOffs);\n+ }\n+ } else {\n+ if (select) {\n+ target.moveCaretPosition(begOffs);\n+ } else {\n+ target.setCaretPosition(begOffs);\n+ }\n+ Caret caret = target.getCaret();\n+ DefaultCaret bidiCaret = (caret instanceof DefaultCaret) ?\n+ (DefaultCaret) caret : null;\n+ int dot = caret.getDot();\n+ Position.Bias[] bias = new Position.Bias[1];\n+ Point magicPosition = caret.getMagicCaretPosition();\n+\n+ if (magicPosition == null &&\n+ (direction == SwingConstants.NORTH ||\n+ direction == SwingConstants.SOUTH)) {\n+ Rectangle r = (bidiCaret != null) ?\n+ target.getUI().modelToView(target, dot,\n+ bidiCaret.getDotBias()) :\n+ target.modelToView(dot);\n+ magicPosition = new Point(r.x, r.y);\n+ }\n+\n+ NavigationFilter filter = target.getNavigationFilter();\n+\n+ if (filter != null) {\n+ dot = filter.getNextVisualPositionFrom\n+ (target, dot, (bidiCaret != null) ?\n+ bidiCaret.getDotBias() :\n+ Position.Bias.Forward, direction, bias);\n+ } else {\n+ dot = target.getUI().getNextVisualPositionFrom\n+ (target, dot, (bidiCaret != null) ?\n+ bidiCaret.getDotBias() :\n+ Position.Bias.Forward, direction, bias);\n+ }\n+ if (bias[0] == null) {\n+ bias[0] = Position.Bias.Forward;\n+ }\n+ if (bidiCaret != null) {\n+ if (select) {\n+ bidiCaret.moveDot(dot, bias[0]);\n+ } else {\n+ bidiCaret.setDot(dot, bias[0]);\n+ }\n+ } else {\n+ if (select) {\n+ caret.moveDot(dot);\n+ } else {\n+ caret.setDot(dot);\n+ }\n+ }\n+ if (magicPosition != null &&\n+ (direction == SwingConstants.NORTH ||\n+ direction == SwingConstants.SOUTH)) {\n+ target.getCaret().setMagicCaretPosition(magicPosition);\n+ }\n+ }\n+ } catch (BadLocationException ex) {\n+ }\n+ }\n+ }\n+\n+ private boolean select;\n+ private int direction;\n+ private boolean firstLine;\n+ }\n+\n","filename":"src\/java.desktop\/share\/classes\/javax\/swing\/text\/DefaultEditorKit.java","additions":227,"deletions":0,"binary":false,"changes":227,"status":"modified"},{"patch":"@@ -0,0 +1,118 @@\n+\/*\n+ * Copyright (c) 2022, Oracle and\/or its affiliates. All rights reserved.\n+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.\n+ *\n+ * This code is free software; you can redistribute it and\/or modify it\n+ * under the terms of the GNU General Public License version 2 only, as\n+ * published by the Free Software Foundation.\n+ *\n+ * This code is distributed in the hope that it will be useful, but WITHOUT\n+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or\n+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License\n+ * version 2 for more details (a copy is included in the LICENSE file that\n+ * accompanied this code).\n+ *\n+ * You should have received a copy of the GNU General Public License version\n+ * 2 along with this work; if not, write to the Free Software Foundation,\n+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.\n+ *\n+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA\n+ * or visit www.oracle.com if you need additional information or have any\n+ * questions.\n+ *\/\n+\n+\/* @test\n+ @bug 8267374\n+ @key headful\n+ @requires (os.family == \"mac\")\n+ @summary Verifies ALT+Up\/ALT+Down keypress move cursor to start\/end of textline.\n+ @run main TestAltUpDown\n+ *\/\n+\n+import java.awt.Robot;\n+import java.awt.event.KeyEvent;\n+import javax.swing.JFrame;\n+import javax.swing.JTextArea;\n+import javax.swing.SwingUtilities;\n+import javax.swing.text.BadLocationException;\n+import javax.swing.text.Utilities;\n+\n+public class TestAltUpDown {\n+ private static JFrame frame;\n+ private static JTextArea textArea;\n+ volatile static int caretPosition;\n+ volatile static int rowEnd;\n+ volatile static int rowStart;\n+\n+ public static void main(String[] args) throws Exception {\n+ try {\n+ SwingUtilities.invokeAndWait(() -> {\n+ textArea = new JTextArea(20, 40);\n+ textArea.setLineWrap(true);\n+ textArea.setText(\"This is first line\\n\" +\n+ \"This is second line\\n\" +\n+ \"This is thrid line\");\n+ textArea.setCaretPosition(0);\n+ frame = new JFrame(\"Alt-Arrow Bug\");\n+ frame.add(textArea);\n+ frame.pack();\n+ frame.setLocationRelativeTo(null);\n+ frame.setVisible(true);\n+ });\n+\n+ Robot robot = new Robot();\n+ robot.waitForIdle();\n+ robot.delay(1000);\n+ robot.keyPress(KeyEvent.VK_ALT);\n+ robot.keyPress(KeyEvent.VK_DOWN);\n+ robot.keyRelease(KeyEvent.VK_DOWN);\n+ robot.keyRelease(KeyEvent.VK_ALT);\n+\n+ SwingUtilities.invokeAndWait(() -> {\n+ caretPosition = textArea.getCaretPosition();\n+ try {\n+ rowEnd = Utilities.getRowEnd(textArea, caretPosition);\n+ } catch (BadLocationException ex) {\n+ throw new RuntimeException(ex);\n+ }\n+ System.out.println(\"caretPosition\" + caretPosition + \" rowEnd \" + rowEnd);\n+ });\n+ if (caretPosition != rowEnd) {\n+ throw new RuntimeException(\"Option+Down doesn't move the cursor\");\n+ }\n+\n+ robot.delay(1000);\n+ robot.keyPress(KeyEvent.VK_ALT);\n+ robot.keyPress(KeyEvent.VK_DOWN);\n+ robot.keyRelease(KeyEvent.VK_DOWN);\n+ robot.keyRelease(KeyEvent.VK_ALT);\n+ robot.delay(1000);\n+ robot.keyPress(KeyEvent.VK_ALT);\n+ robot.keyPress(KeyEvent.VK_UP);\n+ robot.keyRelease(KeyEvent.VK_UP);\n+ robot.keyRelease(KeyEvent.VK_ALT);\n+ robot.delay(1000);\n+ robot.keyPress(KeyEvent.VK_ALT);\n+ robot.keyPress(KeyEvent.VK_UP);\n+ robot.keyRelease(KeyEvent.VK_UP);\n+ robot.keyRelease(KeyEvent.VK_ALT);\n+\n+ caretPosition = textArea.getCaretPosition();\n+ try {\n+ rowStart = Utilities.getRowStart(textArea, caretPosition);\n+ } catch (BadLocationException bex) {\n+ throw new RuntimeException(bex);\n+ }\n+ System.out.println(\"caretPosition\" + caretPosition + \" rowStart \" + rowStart);\n+ if (caretPosition != 0) {\n+ throw new RuntimeException(\"Option+Up doesn't move the cursor\");\n+ }\n+ } finally {\n+ SwingUtilities.invokeAndWait(() -> {\n+ if (frame != null) {\n+ frame.dispose();\n+ }\n+ });\n+ }\n+ }\n+}\n","filename":"test\/jdk\/javax\/swing\/JTextArea\/TestAltUpDown.java","additions":118,"deletions":0,"binary":false,"changes":118,"status":"added"}]}
0 commit comments