This repository has been archived by the owner on Jun 24, 2021. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 146
JDK-8088068; accelerators should be MenuItem specific #620
Comments
OP's code to reproduce import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TextArea;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class AcceleratorTest extends Application {
public void start(Stage primaryStage) {
TextArea ta1 = new TextArea();
TextArea ta2 = new TextArea();
MenuItem item1 = new MenuItem("Insert \"Hello\"");
item1.setOnAction((ActionEvent) -> ta1.setText("Hello"));
item1.setAccelerator(KeyCombination.keyCombination("Ctrl+I"));
MenuItem item2 = new MenuItem("Insert \"World!\"");
item2.setOnAction((ActionEvent) -> ta2.setText("World!"));
item2.setAccelerator(KeyCombination.keyCombination("Ctrl+I"));
ContextMenu context1 = new ContextMenu();
context1.getItems().add(item1);
ContextMenu context2 = new ContextMenu();
context2.getItems().add(item2);
ta1.setContextMenu(context1);
ta2.setContextMenu(context2);
VBox vBox = new VBox();
vBox.getChildren().add(ta1);
vBox.getChildren().add(ta2);
Scene scene = new Scene(vBox, 300, 300);
primaryStage.setTitle("Accelerator Test");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
|
note that this repo has been moved (unfortunately the new repo has the issues disabled ..) - added a reference to the bug report |
For what it's worth: I (the OP) have since used a subclass of Scene as a workaround that will install an event filter on key events, an check each keypress for a matching menuitem (only works with context menus).
|
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
This is my interpretation of https://bugs.openjdk.java.net/browse/JDK-8088068
The accelerator API appears to assume a kind of singleton menubar. The binding logic for accelerators uses the scene and is keyed only by the key combination. This is likely suitable for a large portion of users.
This has a surprising ramification for
contextMenu
s using accelerators: if you create multiple instances of aMenuItem
with an accelerator, one will overwrite the other, causing instance confusion.I don't believe there is an obvious fix for this: the existing implementation is on the scene, and is keyed only by the key-combination (not the instance or any extra meta about who registered that key combination). As such there are certain to be implementations that rely on this behavior for functionality; for them the lack of instance-specificity is a convenience.
my .02:
I'm wondering if the accelerator system could be updated to include "local" vs "global" accelerators, with the existing API being an alias for global accelerators. I would then change
MenuItem
to includelocalAccelerator
(is there a system for me to renameaccelerator
toglobalAccelerator
with backwards compatibility?) The binding logic could then traverse the node graph (specifically, the instigating event target's parent lineage) to find the most local accelerator, defaulting to the global accelerator.The text was updated successfully, but these errors were encountered: