Skip to content

Commit 3411f9d

Browse files
committedSep 24, 2024
8339995: Open source several AWT focus tests - series 6
Reviewed-by: prr
1 parent 40cde00 commit 3411f9d

5 files changed

+580
-0
lines changed
 

‎test/jdk/ProblemList.txt

+1
Original file line numberDiff line numberDiff line change
@@ -791,3 +791,4 @@ java/awt/Focus/FrameMinimizeTest/FrameMinimizeTest.java 8016266 linux-x64
791791
java/awt/Frame/SizeMinimizedTest.java 8305915 linux-x64
792792
java/awt/PopupMenu/PopupHangTest.java 8340022 windows-all
793793
java/awt/Focus/MinimizeNonfocusableWindowTest.java 8024487 windows-all
794+
java/awt/Focus/InactiveFocusRace.java 8023263 linux-all
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,197 @@
1+
/*
2+
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 4700276
27+
* @summary Peers process KeyEvents before KeyEventPostProcessors
28+
* @requires (os.family == "windows")
29+
* @library /java/awt/regtesthelpers
30+
* @build PassFailJFrame
31+
* @run main/manual ConsumedKeyEventTest
32+
*/
33+
34+
import java.awt.Canvas;
35+
import java.awt.Component;
36+
import java.awt.Color;
37+
import java.awt.Dimension;
38+
import java.awt.FlowLayout;
39+
import java.awt.Frame;
40+
import java.awt.Graphics;
41+
import java.awt.KeyboardFocusManager;
42+
import java.awt.KeyEventPostProcessor;
43+
import java.awt.event.KeyEvent;
44+
import java.awt.event.FocusAdapter;
45+
import java.awt.event.FocusEvent;
46+
import java.awt.event.FocusListener;
47+
import java.awt.event.MouseAdapter;
48+
import java.awt.event.MouseEvent;
49+
50+
public class ConsumedKeyEventTest implements KeyEventPostProcessor {
51+
52+
private static final String INSTRUCTIONS = """
53+
This is a Windows-only test.
54+
When the test starts, you will see a Frame with two components in it,
55+
components look like colored rectangles, one of them is lightweight, one is heavyweight.
56+
Do the following:
57+
1. Click the mouse on the left component.
58+
If it isn't yellow after the click (that means it doesn't have focus), the test fails.
59+
2. Press and release ALT key.
60+
In the output window, the text should appear stating that those key events were consumed.
61+
If no output appears, the test fails.
62+
3. Press space bar. If system menu drops down, the test fails.
63+
4. Click the right rectangle.
64+
It should become red after the click. If it doesn't, it means that it didn't get the focus, and the test fails.
65+
5. Repeat steps 2. and 3.
66+
6. If the test didn't fail on any of the previous steps, the test passes.""";
67+
68+
69+
public static void main(String[] args) throws Exception {
70+
PassFailJFrame.builder()
71+
.title("ConsumedKeyEventTest Instructions")
72+
.instructions(INSTRUCTIONS)
73+
.rows((int) INSTRUCTIONS.lines().count() + 5)
74+
.columns(35)
75+
.testUI(ConsumedKeyEventTest::createTestUI)
76+
.logArea()
77+
.build()
78+
.awaitAndCheck();
79+
}
80+
81+
private static Frame createTestUI() {
82+
KeyboardFocusManager.getCurrentKeyboardFocusManager().
83+
addKeyEventPostProcessor((e) -> {
84+
System.out.println("postProcessor(" + e + ")");
85+
// consumes all ALT-events
86+
if (e.getKeyCode() == KeyEvent.VK_ALT) {
87+
println("consumed " + e);
88+
e.consume();
89+
return true;
90+
}
91+
return false;
92+
});
93+
FocusRequestor requestor = new FocusRequestor();
94+
Frame frame = new Frame("Main Frame");
95+
frame.setLayout(new FlowLayout());
96+
97+
Canvas canvas = new CustomCanvas();
98+
canvas.addMouseListener(requestor);
99+
frame.add(canvas);
100+
canvas.requestFocus();
101+
102+
Component lwComp = new LWComponent();
103+
lwComp.addMouseListener(requestor);
104+
frame.add(lwComp);
105+
106+
frame.pack();
107+
108+
return frame;
109+
}
110+
111+
public boolean postProcessKeyEvent(KeyEvent e) {
112+
System.out.println("postProcessor(" + e + ")");
113+
// consumes all ALT-events
114+
if (e.getKeyCode() == KeyEvent.VK_ALT) {
115+
println("consumed " + e);
116+
e.consume();
117+
return true;
118+
}
119+
return false;
120+
}
121+
122+
static void println(String messageIn) {
123+
PassFailJFrame.log(messageIn);
124+
}
125+
}// class ConsumedKeyEventTest
126+
127+
class CustomCanvas extends Canvas {
128+
CustomCanvas() {
129+
super();
130+
setName("HWComponent");
131+
setSize(100, 100);
132+
addFocusListener(new FocusAdapter() {
133+
public void focusGained(FocusEvent fe) {
134+
repaint();
135+
}
136+
137+
public void focusLost(FocusEvent fe) {
138+
repaint();
139+
}
140+
});
141+
}
142+
143+
public void paint(Graphics g) {
144+
if (isFocusOwner()) {
145+
g.setColor(Color.YELLOW);
146+
} else {
147+
g.setColor(Color.GREEN);
148+
}
149+
g.fillRect(0, 0, 100, 100);
150+
}
151+
152+
}
153+
154+
class LWComponent extends Component {
155+
LWComponent() {
156+
super();
157+
setName("LWComponent");
158+
addFocusListener(new FocusAdapter() {
159+
public void focusGained(FocusEvent fe) {
160+
repaint();
161+
}
162+
163+
public void focusLost(FocusEvent fe) {
164+
repaint();
165+
}
166+
});
167+
}
168+
169+
public Dimension getPreferredSize() {
170+
return new Dimension(100, 100);
171+
}
172+
173+
public void paint(Graphics g) {
174+
if (isFocusOwner()) {
175+
g.setColor(Color.RED);
176+
} else {
177+
g.setColor(Color.BLACK);
178+
}
179+
g.fillRect(0, 0, 100, 100);
180+
}
181+
182+
}
183+
184+
class FocusRequestor extends MouseAdapter {
185+
static int counter = 0;
186+
public void mouseClicked(MouseEvent me) {
187+
System.out.println("mouseClicked on " + me.getComponent().getName());
188+
}
189+
public void mousePressed(MouseEvent me) {
190+
System.out.println("mousePressed on " + me.getComponent().getName());
191+
me.getComponent().requestFocus();
192+
}
193+
public void mouseReleased(MouseEvent me) {
194+
System.out.println("mouseReleased on " + me.getComponent().getName());
195+
}
196+
}
197+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
/*
2+
* Copyright (c) 2001, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 4464723
27+
* @summary Tests simple KeyAdapter / KeyListener on an empty, focusable window
28+
* @key headful
29+
* @run main EmptyWindowKeyTest
30+
*/
31+
32+
import java.awt.AWTEvent;
33+
import java.awt.Frame;
34+
import java.awt.event.KeyAdapter;
35+
import java.awt.event.KeyEvent;
36+
import java.awt.Robot;
37+
38+
public class EmptyWindowKeyTest {
39+
40+
static volatile boolean passed1, passed2;
41+
42+
public static void main(String[] args) throws Exception {
43+
Robot robot = new Robot();
44+
robot.setAutoDelay(100);
45+
MainFrame mainFrame = new MainFrame();
46+
mainFrame.setSize(50,50);
47+
mainFrame.addKeyListener(new KeyboardTracker());
48+
robot.waitForIdle();
49+
robot.delay(1000);
50+
robot.keyPress(KeyEvent.VK_A);
51+
robot.keyRelease(KeyEvent.VK_A);
52+
robot.waitForIdle();
53+
robot.delay(1000);
54+
if (!passed1 || !passed2) {
55+
throw new RuntimeException("KeyPress/keyRelease not seen," +
56+
"passed1 " + passed1 + " passed2 " + passed2);
57+
}
58+
}
59+
60+
static public class KeyboardTracker extends KeyAdapter {
61+
public KeyboardTracker() { }
62+
public void keyTyped(KeyEvent e) {}
63+
64+
public void keyPressed(KeyEvent e) {
65+
if (e.getKeyText(e.getKeyCode()).equals("A")) {
66+
passed1 = true;
67+
}
68+
}
69+
public void keyReleased(KeyEvent e) {
70+
if (e.getKeyText(e.getKeyCode()).equals("A")) {
71+
passed2 = true;
72+
}
73+
}
74+
}
75+
76+
static public class MainFrame extends Frame {
77+
78+
public MainFrame() {
79+
super();
80+
enableEvents(AWTEvent.KEY_EVENT_MASK);
81+
setVisible(true);
82+
}
83+
84+
}
85+
86+
}
87+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
/*
2+
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 4697451
27+
* @summary Test that there is no race between focus component in inactive window and window activation
28+
* @key headful
29+
* @run main InactiveFocusRace
30+
*/
31+
32+
import java.awt.Button;
33+
import java.awt.FlowLayout;
34+
import java.awt.Frame;
35+
import java.awt.KeyboardFocusManager;
36+
import java.awt.Point;
37+
import java.awt.Robot;
38+
import java.awt.Toolkit;
39+
import java.awt.event.FocusAdapter;
40+
import java.awt.event.FocusEvent;
41+
import java.awt.event.WindowAdapter;
42+
import java.awt.event.WindowEvent;
43+
import java.awt.event.InputEvent;
44+
45+
public class InactiveFocusRace {
46+
47+
static Frame activeFrame, inactiveFrame;
48+
Button activeButton, inactiveButton1, inactiveButton2;
49+
Semaphore sema;
50+
final static int TIMEOUT = 10000;
51+
52+
public static void main(String[] args) throws Exception {
53+
try {
54+
InactiveFocusRace test = new InactiveFocusRace();
55+
test.init();
56+
test.start();
57+
} finally {
58+
if (activeFrame != null) {
59+
activeFrame.dispose();
60+
}
61+
if (inactiveFrame != null) {
62+
inactiveFrame.dispose();
63+
}
64+
}
65+
}
66+
67+
public void init() {
68+
activeButton = new Button("active button");
69+
inactiveButton1 = new Button("inactive button1");
70+
inactiveButton2 = new Button("inactive button2");
71+
activeFrame = new Frame("Active frame");
72+
inactiveFrame = new Frame("Inactive frame");
73+
inactiveFrame.setLayout(new FlowLayout());
74+
activeFrame.add(activeButton);
75+
inactiveFrame.add(inactiveButton1);
76+
inactiveFrame.add(inactiveButton2);
77+
activeFrame.pack();
78+
activeFrame.setLocation(300, 10);
79+
inactiveFrame.pack();
80+
inactiveFrame.setLocation(300, 300);
81+
sema = new Semaphore();
82+
83+
inactiveButton1.addFocusListener(new FocusAdapter() {
84+
public void focusGained(FocusEvent e) {
85+
System.err.println("Button 1 got focus");
86+
}
87+
});
88+
inactiveButton2.addFocusListener(new FocusAdapter() {
89+
public void focusGained(FocusEvent e) {
90+
System.err.println("Button2 got focus");
91+
sema.raise();
92+
}
93+
});
94+
activeFrame.addWindowListener(new WindowAdapter() {
95+
public void windowActivated(WindowEvent e) {
96+
System.err.println("Window activated");
97+
sema.raise();
98+
}
99+
});
100+
}
101+
102+
public void start() {
103+
Robot robot = null;
104+
try {
105+
robot = new Robot();
106+
} catch (Exception e) {
107+
throw new RuntimeException("Unable to create robot");
108+
}
109+
110+
inactiveFrame.setVisible(true);
111+
activeFrame.setVisible(true);
112+
113+
// Wait for active frame to become active
114+
try {
115+
sema.doWait(TIMEOUT);
116+
} catch (InterruptedException ie) {
117+
throw new RuntimeException("Wait was interrupted");
118+
}
119+
if (!sema.getState()) {
120+
throw new RuntimeException("Frame doesn't become active on show");
121+
}
122+
sema.setState(false);
123+
124+
// press on second button in inactive frame
125+
Point loc = inactiveButton2.getLocationOnScreen();
126+
robot.mouseMove(loc.x+5, loc.y+5);
127+
robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
128+
robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
129+
130+
// after all second button should be focus owner.
131+
try {
132+
sema.doWait(TIMEOUT);
133+
} catch (InterruptedException ie) {
134+
throw new RuntimeException("Wait was interrupted");
135+
}
136+
if (!sema.getState()) {
137+
throw new RuntimeException("Button2 didn't become focus owner");
138+
}
139+
Toolkit.getDefaultToolkit().sync();
140+
robot.waitForIdle();
141+
if (!(KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner() == inactiveButton2)) {
142+
throw new RuntimeException("Button2 should be the focus owner after all");
143+
}
144+
145+
}
146+
147+
}
148+
149+
class Semaphore {
150+
boolean state = false;
151+
int waiting = 0;
152+
public Semaphore() {
153+
}
154+
public void doWait() throws InterruptedException {
155+
synchronized(this) {
156+
if (state) return;
157+
waiting++;
158+
wait();
159+
waiting--;
160+
}
161+
}
162+
public void doWait(int timeout) throws InterruptedException {
163+
synchronized(this) {
164+
if (state) return;
165+
waiting++;
166+
wait(timeout);
167+
waiting--;
168+
}
169+
}
170+
public void raise() {
171+
synchronized(this) {
172+
state = true;
173+
if (waiting > 0) {
174+
notifyAll();
175+
}
176+
}
177+
}
178+
public boolean getState() {
179+
synchronized(this) {
180+
return state;
181+
}
182+
}
183+
public void setState(boolean newState) {
184+
synchronized(this) {
185+
state = newState;
186+
}
187+
}
188+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2002, 2024, Oracle and/or its affiliates. All rights reserved.
3+
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4+
*
5+
* This code is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU General Public License version 2 only, as
7+
* published by the Free Software Foundation.
8+
*
9+
* This code is distributed in the hope that it will be useful, but WITHOUT
10+
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11+
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12+
* version 2 for more details (a copy is included in the LICENSE file that
13+
* accompanied this code).
14+
*
15+
* You should have received a copy of the GNU General Public License version
16+
* 2 along with this work; if not, write to the Free Software Foundation,
17+
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18+
*
19+
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20+
* or visit www.oracle.com if you need additional information or have any
21+
* questions.
22+
*/
23+
24+
/*
25+
* @test
26+
* @bug 4688591
27+
* @summary Tab key hangs in Native Print Dialog on win32
28+
* @library /java/awt/regtesthelpers
29+
* @build PassFailJFrame
30+
* @run main/manual InitialPrintDlgFocusTest
31+
*/
32+
33+
import java.awt.BorderLayout;
34+
import java.awt.Dialog;
35+
import java.awt.FlowLayout;
36+
import java.awt.Frame;
37+
import java.awt.JobAttributes;
38+
import java.awt.PageAttributes;
39+
import java.awt.PrintJob;
40+
import java.awt.Toolkit;
41+
42+
import java.awt.event.ActionEvent;
43+
import java.awt.event.ActionListener;
44+
45+
import javax.swing.JButton;
46+
import javax.swing.JFrame;
47+
48+
public class InitialPrintDlgFocusTest {
49+
50+
private static final String INSTRUCTIONS = """
51+
After the tests starts you will see a frame titled "PrintTest".
52+
Press the "Print" button and the print dialog should appear.
53+
If you are able to transfer focus between components of the Print dialog
54+
using the TAB key, then the test passes else the test fails.
55+
56+
Note: close the Print dialog before clicking on "Pass" or "Fail" buttons.""";
57+
58+
59+
public static void main(String[] args) throws Exception {
60+
PassFailJFrame.builder()
61+
.title("InitialPrintDlgFocusTest Instructions")
62+
.instructions(INSTRUCTIONS)
63+
.rows((int) INSTRUCTIONS.lines().count() + 2)
64+
.columns(35)
65+
.testUI(InitialPrintDlgFocusTest::createTestUI)
66+
.build()
67+
.awaitAndCheck();
68+
}
69+
70+
private static JFrame createTestUI() {
71+
return new PrintTest();
72+
73+
}
74+
}
75+
76+
class PrintTest extends JFrame implements ActionListener {
77+
78+
JButton b;
79+
JobAttributes jbattrib;
80+
Toolkit tk ;
81+
PageAttributes pgattrib;
82+
83+
public PrintTest() {
84+
setTitle("PrintTest");
85+
setSize(500, 400);
86+
87+
b = new JButton("Print");
88+
jbattrib = new JobAttributes();
89+
tk = Toolkit.getDefaultToolkit();
90+
pgattrib = new PageAttributes();
91+
getContentPane().setLayout(new FlowLayout());
92+
getContentPane().add(b);
93+
94+
b.addActionListener(this);
95+
96+
}
97+
98+
public void actionPerformed(ActionEvent ae) {
99+
if(ae.getSource()==b)
100+
jbattrib.setDialog(JobAttributes.DialogType.NATIVE);
101+
102+
PrintJob pjob = tk.getPrintJob(this, "Printing Test",
103+
jbattrib, pgattrib);
104+
105+
}
106+
}
107+

0 commit comments

Comments
 (0)
Please sign in to comment.