From cdd96bdfb8b28832fe794e812a0acc4d40ff8c04 Mon Sep 17 00:00:00 2001 From: creme332 <65414576+creme332@users.noreply.github.com> Date: Sat, 10 Aug 2024 17:38:49 +0400 Subject: [PATCH] focus first textfield in dialog --- .../canvas/transform/Reflector.java | 8 +++-- .../controller/canvas/transform/Rotator.java | 10 ++++-- .../controller/canvas/transform/Scaler.java | 20 ++++++----- .../controller/canvas/transform/Shearer.java | 8 +++-- .../canvas/transform/Translator.java | 8 +++-- .../creme332/utils/RequestFocusListener.java | 36 +++++++++++++++++++ 6 files changed, 73 insertions(+), 17 deletions(-) create mode 100644 src/main/java/com/github/creme332/utils/RequestFocusListener.java diff --git a/src/main/java/com/github/creme332/controller/canvas/transform/Reflector.java b/src/main/java/com/github/creme332/controller/canvas/transform/Reflector.java index 29a3e87..84f49da 100644 --- a/src/main/java/com/github/creme332/controller/canvas/transform/Reflector.java +++ b/src/main/java/com/github/creme332/controller/canvas/transform/Reflector.java @@ -8,6 +8,7 @@ import com.github.creme332.model.AppState; import com.github.creme332.model.Mode; import com.github.creme332.model.ShapeWrapper; +import com.github.creme332.utils.RequestFocusListener; import com.github.creme332.view.Canvas; /** @@ -60,11 +61,14 @@ private double[] requestReflectionLine() { JTextField gradientField = new JTextField(5); JTextField yInterceptField = new JTextField(5); JPanel panel = new JPanel(); - panel.add(new JLabel("Gradient (m):")); + panel.add(new JLabel("Gradient")); panel.add(gradientField); - panel.add(new JLabel("Y-Intercept (b):")); + panel.add(new JLabel("Y-Intercept")); panel.add(yInterceptField); + // Request focus on the textfield when dialog is displayed + gradientField.addHierarchyListener(new RequestFocusListener()); + int result = JOptionPane.showConfirmDialog(canvas, panel, "Enter Line of Reflection", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); diff --git a/src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java b/src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java index 9dc85da..cf91356 100644 --- a/src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java +++ b/src/main/java/com/github/creme332/controller/canvas/transform/Rotator.java @@ -14,6 +14,7 @@ import com.github.creme332.model.AppState; import com.github.creme332.model.Mode; import com.github.creme332.model.ShapeWrapper; +import com.github.creme332.utils.RequestFocusListener; import com.github.creme332.view.Canvas; public class Rotator extends AbstractTransformer { @@ -30,6 +31,9 @@ public void handleShapeSelection(int shapeIndex) { // Request rotation details from the user RotationDetails rotationDetails = requestRotationDetails(); + // Request focus again otherwise keyboard shortcuts will not work + canvas.getTopLevelAncestor().requestFocus(); + // Calculate rotation angle in radians double radAngle = Math.toRadians(rotationDetails.angle * (rotationDetails.isClockwise ? -1 : 1)); @@ -91,6 +95,9 @@ private RotationDetails requestRotationDetails() { JTextField pivotXField = new JTextField("0", 5); JTextField pivotYField = new JTextField("0", 5); + // Request focus on the textfield when dialog is displayed + angleField.addHierarchyListener(new RequestFocusListener()); + JRadioButton clockwiseButton = new JRadioButton("clockwise"); JRadioButton counterClockwiseButton = new JRadioButton("counterclockwise"); counterClockwiseButton.setSelected(true); @@ -112,9 +119,6 @@ private RotationDetails requestRotationDetails() { int result = JOptionPane.showConfirmDialog(canvas, panel, "Rotate About Point", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); - // Request focus again otherwise keyboard shortcuts will not work - canvas.getTopLevelAncestor().requestFocus(); - if (result == JOptionPane.OK_OPTION) { try { double angle = Double.parseDouble(angleField.getText()); diff --git a/src/main/java/com/github/creme332/controller/canvas/transform/Scaler.java b/src/main/java/com/github/creme332/controller/canvas/transform/Scaler.java index c748c23..ada5cb1 100644 --- a/src/main/java/com/github/creme332/controller/canvas/transform/Scaler.java +++ b/src/main/java/com/github/creme332/controller/canvas/transform/Scaler.java @@ -9,6 +9,7 @@ import com.github.creme332.model.AppState; import com.github.creme332.model.Mode; import com.github.creme332.model.ShapeWrapper; +import com.github.creme332.utils.RequestFocusListener; import com.github.creme332.view.Canvas; /** @@ -59,20 +60,23 @@ public boolean shouldDraw() { * cancelled. */ private double[] requestScaleData() { - JTextField xField = new JTextField(5); - JTextField yField = new JTextField(5); + JTextField xField = new JTextField("0", 5); + JTextField yField = new JTextField("0", 5); JTextField sxField = new JTextField(5); JTextField syField = new JTextField(5); JPanel panel = new JPanel(); - panel.add(new JLabel("X:")); - panel.add(xField); - panel.add(new JLabel("Y:")); - panel.add(yField); - panel.add(new JLabel("Scale X:")); + panel.add(new JLabel("Scale X")); panel.add(sxField); - panel.add(new JLabel("Scale Y:")); + panel.add(new JLabel("Scale Y")); panel.add(syField); + panel.add(new JLabel("X")); + panel.add(xField); + panel.add(new JLabel("Y")); + panel.add(yField); + + // Request focus on the textfield when dialog is displayed + sxField.addHierarchyListener(new RequestFocusListener()); int result = JOptionPane.showConfirmDialog(canvas, panel, "Enter scaling data", JOptionPane.OK_CANCEL_OPTION, diff --git a/src/main/java/com/github/creme332/controller/canvas/transform/Shearer.java b/src/main/java/com/github/creme332/controller/canvas/transform/Shearer.java index 2063cad..6fe8485 100644 --- a/src/main/java/com/github/creme332/controller/canvas/transform/Shearer.java +++ b/src/main/java/com/github/creme332/controller/canvas/transform/Shearer.java @@ -8,6 +8,7 @@ import com.github.creme332.model.AppState; import com.github.creme332.model.Mode; import com.github.creme332.model.ShapeWrapper; +import com.github.creme332.utils.RequestFocusListener; import com.github.creme332.view.Canvas; /** @@ -54,11 +55,14 @@ private double[] requestShearFactors() { JTextField sxField = new JTextField(5); JTextField syField = new JTextField(5); JPanel panel = new JPanel(); - panel.add(new JLabel("Shear X:")); + panel.add(new JLabel("Shear X")); panel.add(sxField); - panel.add(new JLabel("Shear Y:")); + panel.add(new JLabel("Shear Y")); panel.add(syField); + // Request focus on the textfield when dialog is displayed + sxField.addHierarchyListener(new RequestFocusListener()); + int result = JOptionPane.showConfirmDialog(canvas, panel, "Enter shear factors", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); diff --git a/src/main/java/com/github/creme332/controller/canvas/transform/Translator.java b/src/main/java/com/github/creme332/controller/canvas/transform/Translator.java index 294b767..bd33ffe 100644 --- a/src/main/java/com/github/creme332/controller/canvas/transform/Translator.java +++ b/src/main/java/com/github/creme332/controller/canvas/transform/Translator.java @@ -13,6 +13,7 @@ import com.github.creme332.model.AppState; import com.github.creme332.model.Mode; import com.github.creme332.model.ShapeWrapper; +import com.github.creme332.utils.RequestFocusListener; import com.github.creme332.view.Canvas; /** @@ -92,11 +93,14 @@ private Point2D requestTranslationVector() { JTextField rxField = new JTextField(5); JTextField ryField = new JTextField(5); JPanel panel = new JPanel(); - panel.add(new JLabel("X:")); + panel.add(new JLabel("X")); panel.add(rxField); - panel.add(new JLabel("Y:")); + panel.add(new JLabel("Y")); panel.add(ryField); + // Request focus on the textfield when dialog is displayed + rxField.addHierarchyListener(new RequestFocusListener()); + int result = JOptionPane.showConfirmDialog(null, panel, "Enter translation vector", JOptionPane.OK_CANCEL_OPTION, JOptionPane.PLAIN_MESSAGE); diff --git a/src/main/java/com/github/creme332/utils/RequestFocusListener.java b/src/main/java/com/github/creme332/utils/RequestFocusListener.java new file mode 100644 index 0000000..dda3fb5 --- /dev/null +++ b/src/main/java/com/github/creme332/utils/RequestFocusListener.java @@ -0,0 +1,36 @@ +package com.github.creme332.utils; + +import java.awt.Component; +import java.awt.Window; +import java.awt.event.HierarchyEvent; +import java.awt.event.HierarchyListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +import javax.swing.SwingUtilities; + +/** + * Focuses a component in a JOptionPane. By default, it is not possible to + * request focus to a component inside a JOptionPane. + * Reference: + * https://bugs.openjdk.org/browse/JDK-5018574?focusedId=12217314&page=com.atlassian.jira.plugin.system.issuetabpanels%3Acomment-tabpanel#comment-12217314 + * + */ +public class RequestFocusListener implements HierarchyListener { + + @Override + public void hierarchyChanged(HierarchyEvent e) { + final Component c = e.getComponent(); + if (c.isShowing() && (e.getChangeFlags() & + HierarchyEvent.SHOWING_CHANGED) != 0) { + Window toplevel = SwingUtilities.getWindowAncestor(c); + toplevel.addWindowFocusListener(new WindowAdapter() { + @Override + public void windowGainedFocus(WindowEvent e) { + c.requestFocus(); + } + }); + + } + } +}