1
要件: はtableMenuButtonにカスタムメニュー項目を追加(RLにカスタムするtableHeaderで行われる)と、それらのメニューアイテムがTableView:コーナーメニューでアクセラレータを有効にする方法は?
問題アクセラレータによってアクセス可能である必要があります: メニューアイテムを追加することは簡単ですが、アクセラレータは
を働いていません以下は、menuItemをコーナーメニューに追加し、比較のためだけにテーブルのcontextMenuに別のものを追加する例です:後者はアクセラレータを押すことによってトリガされ、後者はアクセラレータではありません。
私には不足しているバグや機能はありますか?どのようにそれを動作させるために微調整する任意のアイデア?
import com.sun.javafx.scene.control.skin.TableHeaderRow;
import com.sun.javafx.scene.control.skin.TableViewSkin;
import javafx.application.Application;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.MenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.input.KeyCombination;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.FlowPane;
import javafx.stage.Stage;
/**
* Problem: accelerator in table's corner menu not working.
*
* @author Jeanette Winzenburg, Berlin
*/
public class TableViewAccelerator extends Application {
private Parent getContent() {
TableView table = new TableView<>();
TableColumn first = new TableColumn<>("first");
table.getColumns().addAll(first);
table.setTableMenuButtonVisible(true);
Button addMenu = new Button("add MenuItem to corner");
addMenu.setOnAction(e -> {
TableViewSkin skin = (TableViewSkin) table.getSkin();
TableHeaderRow header = skin.getTableHeaderRow();
ContextMenu menu = (ContextMenu) invokeGetFieldValue(
TableHeaderRow.class,
header, "columnPopupMenu");
MenuItem item = new MenuItem("do stuff");
item.setOnAction(me -> {
LOG.info("from corner");
});
item.setAccelerator(KeyCombination.valueOf("F3"));
menu.getItems().add(item);
addMenu.setDisable(true);
});
ContextMenu menu = new ContextMenu();
MenuItem contextItem = new MenuItem("initial");
contextItem.setOnAction(e -> {
LOG.info("from initial");
});
contextItem.setAccelerator(KeyCombination.valueOf("F4"));
menu.getItems().addAll(contextItem);
table.setContextMenu(menu);
Button addToContext = new Button("add MenuItem to context");
addToContext.setOnAction(e -> {
MenuItem added = new MenuItem("added");
added.setOnAction(me -> LOG.info("from added"));
added.setAccelerator(KeyCombination.valueOf("F5"));
menu.getItems().addAll(added);
addToContext.setDisable(true);
});
BorderPane pane = new BorderPane(table);
FlowPane buttons = new FlowPane(10, 10);
buttons.getChildren().addAll(addMenu, addToContext);
pane.setBottom(buttons);
return pane;
}
@Override
public void start(Stage primaryStage) throws Exception {
primaryStage.setScene(new Scene(getContent(), 600, 400));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
public static Object invokeGetFieldValue(Class declaringClass, Object target, String name) {
try {
Field field = declaringClass.getDeclaredField(name);
field.setAccessible(true);
return field.get(target);
} catch (NoSuchFieldException | SecurityException | IllegalArgumentException | IllegalAccessException e) {
e.printStackTrace();
}
return null;
}
@SuppressWarnings("unused")
private static final Logger LOG = Logger
.getLogger(TableViewAccelerator.class.getName());
}
ノートのカップル:
- registration via ControlAccelaratorSupport作品完全
- これがすべてでは必要とされているという事実は予想外であるが、conscious design decision、
- 文書化されていないサポートされているがhidden API is a bug、特にfx9でアクセスできないので
doooohhhh:それが動作するように取得するには、手動で
ControlAcceleratorSupport
クラスを使用してそれらを添付することができます – kleopatra