Skip to content

Commit

Permalink
8317116: Provide layouts for multiple test UI in PassFailJFrame
Browse files Browse the repository at this point in the history
Backport-of: 85f0442727201e0d36ed0a71d2199e602501c98d
  • Loading branch information
GoeLin committed Nov 4, 2024
1 parent 4fed6e6 commit d5b90a3
Show file tree
Hide file tree
Showing 2 changed files with 319 additions and 4 deletions.
86 changes: 82 additions & 4 deletions test/jdk/java/awt/regtesthelpers/PassFailJFrame.java
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ public final class PassFailJFrame {
private static final int ROWS = 10;
private static final int COLUMNS = 40;

/**
* A gap between windows.
*/
public static final int WINDOW_GAP = 8;

/**
* Prefix for the user-provided failure reason.
*/
Expand Down Expand Up @@ -1007,13 +1012,13 @@ private static void positionInstructionFrame(final Position position) {

switch (position) {
case HORIZONTAL:
int newX = ((screenSize.width / 2) - frame.getWidth());
int newX = (((screenSize.width + WINDOW_GAP) / 2) - frame.getWidth());
frame.setLocation((newX + screenInsets.left),
(frame.getY() + screenInsets.top));
break;

case VERTICAL:
int newY = ((screenSize.height / 2) - frame.getHeight());
int newY = (((screenSize.height + WINDOW_GAP) / 2) - frame.getHeight());
frame.setLocation((frame.getX() + screenInsets.left),
(newY + screenInsets.top));
break;
Expand Down Expand Up @@ -1061,13 +1066,13 @@ public static void positionTestWindow(Window testWindow, Position position) {
switch (position) {
case HORIZONTAL:
case TOP_LEFT_CORNER:
testWindow.setLocation((frame.getX() + frame.getWidth() + 5),
testWindow.setLocation((frame.getX() + frame.getWidth() + WINDOW_GAP),
frame.getY());
break;

case VERTICAL:
testWindow.setLocation(frame.getX(),
(frame.getY() + frame.getHeight() + 5));
(frame.getY() + frame.getHeight() + WINDOW_GAP));
break;
}
}
Expand Down Expand Up @@ -1370,6 +1375,7 @@ public Builder testUI(WindowCreator windowCreator) {
return this;
}


/**
* Adds an implementation of {@link PositionWindows PositionWindows}
* which the framework will use to position multiple test UI windows.
Expand All @@ -1393,6 +1399,77 @@ public Builder positionTestUI(PositionWindows positionWindows) {
return this;
}

/**
* Positions the test UI windows in a row to the right of
* the instruction frame. The top of the windows is aligned to
* that of the instruction frame.
*
* @return this builder
*/
public Builder positionTestUIRightRow() {
return position(Position.HORIZONTAL)
.positionTestUI(WindowLayouts::rightOneRow);
}

/**
* Positions the test UI windows in a column to the right of
* the instruction frame. The top of the first window is aligned to
* that of the instruction frame.
*
* @return this builder
*/
public Builder positionTestUIRightColumn() {
return position(Position.HORIZONTAL)
.positionTestUI(WindowLayouts::rightOneColumn);
}

/**
* Positions the test UI windows in a column to the right of
* the instruction frame centering the stack of the windows.
*
* @return this builder
*/
public Builder positionTestUIRightColumnCentered() {
return position(Position.HORIZONTAL)
.positionTestUI(WindowLayouts::rightOneColumnCentered);
}

/**
* Positions the test UI windows in a row to the bottom of
* the instruction frame. The left of the first window is aligned to
* that of the instruction frame.
*
* @return this builder
*/
public Builder positionTestUIBottomRow() {
return position(Position.VERTICAL)
.positionTestUI(WindowLayouts::bottomOneRow);
}

/**
* Positions the test UI windows in a row to the bottom of
* the instruction frame centering the row of the windows.
*
* @return this builder
*/
public Builder positionTestUIBottomRowCentered() {
return position(Position.VERTICAL)
.positionTestUI(WindowLayouts::bottomOneRowCentered);
}

/**
* Positions the test UI windows in a column to the bottom of
* the instruction frame. The left of the first window is aligned to
* that of the instruction frame.
*
* @return this builder
*/
public Builder positionTestUIBottomColumn() {
return position(Position.VERTICAL)
.positionTestUI(WindowLayouts::bottomOneColumn);
}


/**
* Adds a {@code WindowListCreator} which the framework will use
* to create a list of test UI windows.
Expand Down Expand Up @@ -1495,6 +1572,7 @@ public Builder testUI(PanelCreator panelCreator) {
return this;
}


/**
* Adds a {@code PanelCreator} which the framework will use
* to create a component with test UI and display it in a split pane.
Expand Down
237 changes: 237 additions & 0 deletions test/jdk/java/awt/regtesthelpers/WindowLayouts.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,237 @@
/*
* Copyright (c) 2023, 2024, 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.
*/

import java.awt.Component;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.Insets;
import java.awt.Point;
import java.awt.Window;
import java.util.List;

import static java.awt.GraphicsEnvironment.getLocalGraphicsEnvironment;
import static java.awt.Toolkit.getDefaultToolkit;

/**
* A utility class which provides standard window layouts for multi-window
* manual tests using the {@link PassFailJFrame} framework.
* The layout methods {@code right-} and {@code bottom-} implement the
* {@link PassFailJFrame.PositionWindows PositionWindows} interface and
* can be used directly or via builder methods.
* <p>
* There are several helper methods, such as
* {@link #getScreenCenter() getScreenCenter}, which could help you
* implement customized windows layouts.
*/
public final class WindowLayouts {

/** Private constructor to prevent instantiating the utility class. */
private WindowLayouts() {
}

/** A gap between windows. (Local copy makes expressions shorter.) */
private static final int WINDOW_GAP = PassFailJFrame.WINDOW_GAP;

/**
* Lays out the window list in one row to the right of
* the instruction frame. The top of the windows is aligned to
* that of the instruction frame.
*
* @param windows the list of windows to lay out
* @param instructionUI information about the instruction frame
*/
public static void rightOneRow(final List<Window> windows,
final PassFailJFrame.InstructionUI instructionUI) {
layoutRow(instructionUI.getLocation().x
+ instructionUI.getSize().width
+ WINDOW_GAP,
instructionUI.getLocation().y,
windows);
}

/**
* Lays out the window list in one column to the right of
* the instruction frame. The top of the first window is aligned to
* that of the instruction frame.
*
* @param windows the list of windows to lay out
* @param instructionUI information about the instruction frame
*/
public static void rightOneColumn(final List<Window> windows,
final PassFailJFrame.InstructionUI instructionUI) {
layoutColumn(instructionUI.getLocation().x
+ instructionUI.getSize().width
+ WINDOW_GAP,
instructionUI.getLocation().y,
windows);
}

/**
* Lays out the window list in one column to the right of
* the instruction frame centering the stack of the windows.
*
* @param windows the list of windows to lay out
* @param instructionUI information about the instruction frame
*/
public static void rightOneColumnCentered(final List<Window> windows,
final PassFailJFrame.InstructionUI instructionUI) {
layoutColumn(instructionUI.getLocation().x
+ instructionUI.getSize().width
+ WINDOW_GAP,
getScreenCenter().y
- getWindowListHeight(windows) / 2,
windows);
}


/**
* Lays out the window list in one row to the bottom of
* the instruction frame. The left of the first window is aligned to
* that of the instruction frame.
*
* @param windows the list of windows to lay out
* @param instructionUI information about the instruction frame
*/
public static void bottomOneRow(final List<Window> windows,
final PassFailJFrame.InstructionUI instructionUI) {
layoutRow(instructionUI.getLocation().x,
instructionUI.getLocation().y
+ instructionUI.getSize().height
+ WINDOW_GAP,
windows);
}

/**
* Lays out the window list in one row to the bottom of
* the instruction frame centering the row of the windows.
*
* @param windows the list of windows to lay out
* @param instructionUI information about the instruction frame
*/
public static void bottomOneRowCentered(final List<Window> windows,
final PassFailJFrame.InstructionUI instructionUI) {
layoutRow(getScreenCenter().x
- getWindowListWidth(windows) / 2,
instructionUI.getLocation().y
+ instructionUI.getSize().height
+ WINDOW_GAP,
windows);
}

/**
* Lays out the window list in one column to the bottom of
* the instruction frame. The left of the first window is aligned to
* that of the instruction frame.
*
* @param windows the list of windows to lay out
* @param instructionUI information about the instruction frame
*/
public static void bottomOneColumn(final List<Window> windows,
final PassFailJFrame.InstructionUI instructionUI) {
layoutColumn(instructionUI.getLocation().x,
instructionUI.getLocation().y
+ instructionUI.getSize().height
+ WINDOW_GAP,
windows);
}


/**
* Lays out the window list in one row starting at
* ({@code x0}, {@code y}).
*
* @param x0 the starting <var>x</var> coordinate of the windows
* @param y the <var>y</var> coordinate of the windows
* @param windows the list of windows to lay out
*/
public static void layoutRow(final int x0,
final int y,
final List<Window> windows) {
int x = x0;
for (Window w : windows) {
w.setLocation(x, y);
x += w.getWidth() + WINDOW_GAP;
}
}

/**
* Lays out the window list in one column starting at
* ({@code x}, {@code y0}).
*
* @param x the <var>x</var> coordinate of the windows
* @param y0 the starting <var>y</var> coordinate of the windows
* @param windows the list of windows to lay out
*/
public static void layoutColumn(final int x,
final int y0,
final List<Window> windows) {
int y = y0;
for (Window w : windows) {
w.setLocation(x, y);
y += w.getHeight() + WINDOW_GAP;
}
}


/**
* {@return the center point of the main screen}
*/
public static Point getScreenCenter() {
GraphicsConfiguration gc = getLocalGraphicsEnvironment()
.getDefaultScreenDevice()
.getDefaultConfiguration();
Dimension size = gc.getBounds()
.getSize();
Insets insets = getDefaultToolkit()
.getScreenInsets(gc);

return new Point((size.width - insets.left - insets.right) / 2,
(size.height - insets.top - insets.bottom) / 2);
}

/**
* {@return width of the windows in the list, taking into account
* the gap between windows}
*
* @param windows the list of windows to get the width of
*/
public static int getWindowListWidth(final List<Window> windows) {
return windows.stream()
.mapToInt(Component::getWidth)
.sum()
+ WINDOW_GAP * (windows.size() - 1);
}

/**
* {@return height of the windows in the list, taking into account
* the gap between windows}
*
* @param windows the list of windows to get the height of
*/
public static int getWindowListHeight(final List<Window> windows) {
return windows.stream()
.mapToInt(Component::getHeight)
.sum()
+ WINDOW_GAP * (windows.size() - 1);
}
}

0 comments on commit d5b90a3

Please sign in to comment.