如何在JavaFX ColorPicker中更改或覆盖工具提示 [英] How to change or override the tooltip in JavaFX ColorPicker

查看:58
本文介绍了如何在JavaFX ColorPicker中更改或覆盖工具提示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在应用程序中使用JavaFX ColorPicker.根据我的要求,我已将颜色选择器上的默认颜色映射到一个数字.我希望此数字作为鼠标悬停在颜色上而不是颜色的十六进制值时的工具提示显示.我该如何实现?

I am using JavaFX ColorPicker in my application. As per my requirements, I have mapped the default colors on the color picker to a number. I want this number to be displayed as tooltip on hover over the color instead of hex value of the color. How can I achieve this?

//部分代码

public void handleNodes(Circle circleNode){

public void handleNodes(Circle circularNode) {

    final Delta offset = new Delta();

    circularNode.setOnMouseEntered(new EventHandler<MouseEvent>() {
        @Override 
        public void handle(MouseEvent event) {
            ((Circle)(event.getSource())).setCursor(Cursor.HAND);
        }
    });

    circularNode.setOnMousePressed(new EventHandler<MouseEvent>() {
        @Override 
        public void handle(MouseEvent event) {
                    if(event.getButton().equals(MouseButton.SECONDARY)) {
                System.out.println("Right click");

                Circle parent = ((Circle)(event.getSource()));

                final ContextMenu contextMenu = new ContextMenu();
                MenuItem editLabel = new MenuItem("Edit Label");
                editLabel.setOnAction(new EventHandler<ActionEvent>() {
                    @Override
                    public void handle(ActionEvent event) {
                      System.out.println("Edit Label");

                      final ColorPicker colorPicker = new ColorPicker();
                      colorPicker.setStyle("-fx-border-radius: 10 10 10 10;" 
                                            + "-fx-background-radius: 10 10 10 10;");
                      colorPicker.setValue((Color) parent.getFill());
                                      colorPicker.showingProperty().addListener((obs,b,b1)->{
                          if(b1){
                              PopupWindow popupWindow = getPopupWindow();
                              javafx.scene.Node popup =            popupWindow.getScene().getRoot().getChildrenUnmodifiable().get(0);
                              popup.lookupAll(".color-rect").stream()
                                  .forEach(rect->{
                                      Color c = (Color)((Rectangle)rect).getFill();
                                      Tooltip.install(rect.getParent(), new Tooltip("Custom tip for "+c.toString()));
                                  });
                          }
                      });

                      panelMain.getChildren().add(colorPicker);                       
                    }
                });

推荐答案

基于OP在我的第一个答案后发布的代码,并且由于所解决问题的实质性变化,我添加了一个新的答案,涵盖了两种情况:

Based on the code posted by the OP after my first answer, and due to the substancial changes in the problem addressed, I'm adding a new answer that covers both situations:

  • ColorPicker作为常规节点嵌入在主场景中
  • ColorPicker嵌入在ContextMenu
  • The ColorPicker is embedded in the main scene, as a regular node
  • The ColorPicker is embedded in a ContextMenu

在第二种情况下,针对第一种解决方案的建议解决方案不再有效,因为找到的窗口将是具有上下文菜单的解决方案.

In the second situation, the proposed solution for the first one is no longer valid, since the window found will be the one with the context menu.

需要一个任务来继续寻找窗口,直到找到带有ComboBoxPopupControl的窗口为止.

A task is required to keep looking for windows until the one with the ComboBoxPopupControl is found.

这是一个完全可运行的示例:

This is a full runnable example:

public class ColorPickerFinder extends Application {

    ExecutorService findWindowExecutor = createExecutor("FindWindow");

    @Override
    public void start(Stage primaryStage) {

        AnchorPane panCircles = new AnchorPane();
        Scene scene = new Scene(panCircles, 400, 400);

        final Random random = new Random();
        IntStream.range(0,5).boxed().forEach(i->{
            final Circle circle= new Circle(20+random.nextInt(80), 
                Color.rgb(random.nextInt(255),random.nextInt(255),random.nextInt(255)));
            circle.setTranslateX(100+random.nextInt(200));
            circle.setTranslateY(100+random.nextInt(200));
            panCircles.getChildren().add(circle);
        });
        panCircles.setPrefSize(400, 400);
        ColorPicker colorPicker = new ColorPicker();

        panCircles.getChildren().add(colorPicker);
        primaryStage.setScene(scene);
        primaryStage.show();

        // We add listeners AFTER showing the stage, as we are looking for nodes 
        // by css selectors, these will be available only after the stage is shown
        colorPicker.showingProperty().addListener((obs,b,b1)->{
            if(b1){
                // No need for task in this case
                getPopupWindow();
            }
        });

        panCircles.getChildren().stream()
                .filter(c->c instanceof Circle)
                .map(c->(Circle)c)
                .forEach(circle->{
            circle.setOnMouseClicked(e->{
                if(e.getButton().equals(MouseButton.SECONDARY)){
                    // We need a task, since the first window found is the ContextMenu one
                    findWindowExecutor.execute(new WindowTask());

                    final ColorPicker picker = new ColorPicker();
                    picker.setStyle("-fx-border-radius: 10 10 10 10;" 
                                          + "-fx-background-radius: 10 10 10 10;");
                    picker.setValue((Color)(circle.getFill()));
                    picker.valueProperty().addListener((obs,c0,c1)->circle.setFill(c1));

                    final ContextMenu contextMenu = new ContextMenu();
                    MenuItem editLabel = new MenuItem();
                    contextMenu.getItems().add(editLabel);
                    editLabel.setGraphic(picker);
                    contextMenu.show(panCircles,e.getScreenX(),e.getScreenY());
                }
            });
        });

    }

    private PopupWindow getPopupWindow() {
        @SuppressWarnings("deprecation") 
        final Iterator<Window> windows = Window.impl_getWindows();

        while (windows.hasNext()) {
            final Window window = windows.next();
            if (window instanceof PopupWindow) {
                if(window.getScene()!=null && window.getScene().getRoot()!=null){ 
                    Parent root = window.getScene().getRoot();
                    if(root.getChildrenUnmodifiable().size()>0){
                        Node popup = root.getChildrenUnmodifiable().get(0);
                        if(popup.lookup(".combo-box-popup")!=null){

                            // only process ComboBoxPopupControl
                            Platform.runLater(()->{
                                popup.lookupAll(".color-rect").stream()
                                    .forEach(rect->{
                                        Color c = (Color)((Rectangle)rect).getFill();
                                        Tooltip.install(rect.getParent(), 
                                            new Tooltip("Custom tip for "+c.toString()));
                                    });
                            });
                            return (PopupWindow)window;
                        }
                    }
                }

                return null;
            }
        }
        return null;
    }

    private class WindowTask extends Task<Void> {

        @Override
        protected Void call() throws Exception {
            boolean found=false;
            while(!found){
                try {
                    Thread.sleep(500);
                } catch (InterruptedException e) {
                }
                found=(getPopupWindow()!=null);
            }
            return null;
        }

    } 

    private ExecutorService createExecutor(final String name) {
        ThreadFactory factory = r -> {
            Thread t = new Thread(r);
            t.setName(name);
            t.setDaemon(true);
            return t;
        };
        return Executors.newSingleThreadExecutor(factory);
    }

    public static void main(String[] args) {
        launch(args);
    }

}

这将是在右键单击一个圆并单击颜色选择器之后的结果:

This will be the result after right clicking on a circle, and clicking on the color picker:

这篇关于如何在JavaFX ColorPicker中更改或覆盖工具提示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆