Skip to content

Conversation

@mstr2
Copy link
Collaborator

@mstr2 mstr2 commented Nov 25, 2025

This enhancement allows Stage to be placed on the screen similar to a popup window, where a user-specified positioning anchor defines a point on the stage that should coincide with a given location on the screen. For this purpose, the following new methods are added to Stage:

public class Stage {
    public void show(double anchorX, double anchorY, AnchorPoint);
    public void show(double anchorX, double anchorY, AnchorPoint, ClampPolicy, Insets screenPadding);
    public void showAndWait(double anchorX, double anchorY, AnchorPoint);
    public void showAndWait(double anchorX, double anchorY, AnchorPoint, ClampPolicy, Insets screenPadding);
}

AnchorPoint is a point that is either specified in absolute coordinates, or relative to the stage:

var anchor1 = AnchorPoint.proportional(0.5, 0.5); // center of the stage
var anchor2 = AnchorPoint.absolute(100, 100); // absolute coordinates within stage

For example, a stage that sits flush with the bottom-right corner of the screen can be shown as follows:

var bounds = Screen.getPrimary().getBounds();
var anchor = AnchorPoint.proportional(1, 1); // or use the AnchorPoint.BOTTOM_RIGHT constant
stage.show(bounds.getMaxX(), bounds.getMaxY(), anchor);

The position of the stage is automatically adjusted (depending on ClampPolicy) so that it doesn't extend beyond the edges of the screen; this is similar to how PopupWindow with autoFix works. This feature is mainly intended for stages that are positioned relative to a reference point, for example windows that are invoked from the system tray. These windows are top-level windows, but they are positioned like a popup window.

ClampPolicy can be either NONE, HORIZONTAL, VERTICAL, or BOTH.

When clamping is used, the screenPadding parameter specifies how much space should be mainainted beween the edges of the window and the edges of the screen.


Progress

  • Change must be properly reviewed (1 review required, with at least 1 Reviewer)
  • Change must not contain extraneous whitespace
  • Commit message must refer to an issue

Issue

  • JDK-8372530: Easier placement of stages with positioning anchor (Enhancement - P4)

Reviewing

Using git

Checkout this PR locally:
$ git fetch https://git.openjdk.org/jfx.git pull/1986/head:pull/1986
$ git checkout pull/1986

Update a local copy of the PR:
$ git checkout pull/1986
$ git pull https://git.openjdk.org/jfx.git pull/1986/head

Using Skara CLI tools

Checkout this PR locally:
$ git pr checkout 1986

View PR using the GUI difftool:
$ git pr show -t 1986

Using diff file

Download this PR as a diff file:
https://git.openjdk.org/jfx/pull/1986.diff

@bridgekeeper
Copy link

bridgekeeper bot commented Nov 25, 2025

👋 Welcome back mstrauss! A progress list of the required criteria for merging this PR into master will be added to the body of your pull request. There are additional pull request commands available for use with this pull request.

@openjdk
Copy link

openjdk bot commented Nov 25, 2025

❗ This change is not yet ready to be integrated.
See the Progress checklist in the description for automated requirements.

*
* @since 26
*/
public static final class Anchor {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be a record too

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it could, but I don't like the boolean parameter that it would expose. Boolean parameters are usually not a good idea, as they lead to "boolean blindness" at the call site. I've moved this entire class to javafx.geometry, as it might be useful for other code in the future, and I don't want to proliferate two nested versions of an anchor point (one in Stage, the other in PopupWindow).

0, 0);
}

// Give subclasses a chance to adjust the window bounds
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this Enhancement, but I wonder if the centerOnScreen line before could also be rewritten using this system (at one point). Now, it looks like he might be centering the Window, and then fix the bounds to something else, wasting some time.

* @throws NullPointerException if {@code anchor} is {@code null}
* @since 26
*/
public final void show(double anchorX, double anchorY, AnchorPoint anchor) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would it make more sense to move these new methods to Window, so they can also work for the Popup and its hierarchy ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PopupWindow works differently, it has a anchorLocation property which is a bit limited. We also couldn't move PopupWindow.AnchorLocation anywhere else (as this would be a breaking change), which would make the signature of the show() method very awkward: On Stage.show(x, y, PopupWindow.AnchorLocation) you'd have a parameter that is declared on an unrelated class.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, this is unfortunate.
Can we do anything to make the positioning of Popups and its hierarchy easier? Maybe add another show() with a ClampPolicy argument?

Use case: I want to open a PopupWindow below the owner node, but: if the popup cannot be placed there because the whole thing is too close to the bottom of the screen, I want the popup to be above the node, and not on top of it as it works currently.

*
* @since 26
*/
public enum ClampPolicy {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe call it RelocationPolicy?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants