【问题标题】:JavaFX ColorPicker show uncolor optionJavaFX ColorPicker 显示 uncolor 选项
【发布时间】:2016-03-20 11:00:36
【问题描述】:

我想在我的 ColorPicker 中显示非颜色选项。 怎么显示?

谢谢。

【问题讨论】:

    标签: javafx javafx-2 javafx-8


    【解决方案1】:

    该解决方案有点破解,但它避免使用私有 API。

    这些是必需的步骤:

    • 获取单击ColorPicker 时显示的弹出控件。

    您可以找到它herehere

    • 获取该弹出窗口中的方形颜色,以便我们更改其中一种。我会使用最后一个。

    一旦我们有了弹出窗口,我们将通过查找获得一组方形颜色:Set<Node> squares = popup.lookupAll(".color-rect");

    让我们使用最后一种颜色来添加我们自定义的“un-color”。

    • 了解如何绘制红色对角线。

    我想出了一个LinearGradient

    final LinearGradient redLine = new LinearGradient(0, 0, 1, 1, true, CycleMethod.NO_CYCLE, 
        new Stop(0, Color.WHITE), new Stop(0.45, Color.WHITE), 
        new Stop(0.46, Color.RED), new Stop(0.54, Color.RED), 
        new Stop(0.55, Color.WHITE), new Stop(1, Color.WHITE));
    

    效果很好,但遗憾的是渐变破坏了ColorPicker 控件,这是ComboBoxBase<Color> 的扩展,用于矩形的所有填充都将转换为Color 而不是Paint。这意味着我们必须在过渡期间使用一种颜色(例如 Color.TRANSPARENT)。

    • 解决其他问题,例如弹出窗口关闭时显示的方形颜色,或悬停时显示的方形颜色。

    为此,我们需要在颜色选择器和悬停的正方形中查找正方形颜色,当它们与我们的透明颜色匹配时,用渐变替换颜色。

    这是代码:

    public class UnColorPicker extends Application {
    
        private final LinearGradient redLine = new LinearGradient(0, 0, 1, 1, true, CycleMethod.NO_CYCLE, 
                                new Stop(0, Color.WHITE), new Stop(0.45, Color.WHITE), new Stop(0.46, Color.RED),
                                new Stop(0.54, Color.RED), new Stop(0.55, Color.WHITE), new Stop(1, Color.WHITE));
    
        @Override
        public void start(Stage primaryStage) {
            ColorPicker picker = new ColorPicker();
            StackPane root = new StackPane(picker);
            Scene scene = new Scene(root, 500, 400);
    
            primaryStage.setScene(scene);
            primaryStage.show();
    
            Rectangle rect = (Rectangle) root.lookup(".picker-color-rect");
            Label label = (Label) root.lookup(".color-picker-label");
            picker.showingProperty().addListener((obs, b, b1) -> {
                if (b1) {
                    PopupWindow popupWindow = getPopupWindow();
                    Node popup = popupWindow.getScene().getRoot().getChildrenUnmodifiable().get(0);
                    StackPane hover = (StackPane) popup.lookup(".hover-square");
                    Rectangle rectH = (Rectangle) hover.getChildren().get(0);
                    Set<Node> squares = popup.lookupAll(".color-rect");
                    squares.stream()
                            .skip(squares.size()-2)
                            .map(Rectangle.class::cast)
                            .findFirst()
                            .ifPresent(r -> {
                                r.getParent().setOnMousePressed(e -> {
                                    // avoid CastException
                                    r.setFill(Color.TRANSPARENT);
                                    e.consume();
                                });
                                r.getParent().setOnMouseReleased(e -> {
                                    Platform.runLater(() -> {
                                        rect.setFill(redLine);
                                        label.setText("Un-color");
                                    });
                                });
                                r.setFill(redLine);
                                Tooltip.install(r.getParent(), new Tooltip("Un-color"));
                            });
                    hover.visibleProperty().addListener((obs2, ov, nv) -> {
                        if (nv && rectH.getFill().equals(Color.TRANSPARENT)) {
                            Platform.runLater(() -> rectH.setFill(redLine));
                        }
                    });
                }
            });
        }
    
        private PopupWindow getPopupWindow() {
            @SuppressWarnings("deprecation") 
            final Iterator<Window> windows = Window.impl_getWindows();
            while (windows.hasNext()) {
                final Window window = windows.next();
                if (window instanceof PopupWindow) {
                    return (PopupWindow)window;
                }
            }
            return null;
        }
    
        public static void main(String[] args) {
            launch(args);
        }
    
    }
    

    【讨论】:

      【解决方案2】:

      上面发布的方法不再适合我,所以我想出了一个稍微不同的解决方案,尽管想法是一样的。它还避免使用已弃用的函数。

      我对@9​​87654321@ 类进行了子类化以构建我自己的CustomColorPicker,可以使用它来代替。

      这是我的代码:

      @SuppressWarnings("restriction")
      public class CustomColorPicker extends ColorPicker {
      
          final static LinearGradient RED_LINE = new LinearGradient(0, 0, 1, 1, true, CycleMethod.NO_CYCLE, 
                                                              new Stop(0, Color.WHITE), new Stop(0.45, Color.WHITE), 
                                                              new Stop(0.46, Color.RED), new Stop(0.54, Color.RED), 
                                                              new Stop(0.55, Color.WHITE), new Stop(1, Color.WHITE));
      
          @Override 
          protected Skin<?> createDefaultSkin() {
      
              final CustomColorPickerSkin skin = new CustomColorPickerSkin(this);
              final Label lbl = (Label)skin.getDisplayNode();
              final StackPane pane = (StackPane)lbl.getGraphic();
              final Rectangle rect = (Rectangle)pane.getChildren().get(0);
      
              // set initial color to red line if transparent is shown
              if (getValue().equals(Color.TRANSPARENT))
                  rect.setFill(RED_LINE);
      
              // set color to red line when transparent is selected
              rect.fillProperty().addListener((o, oldVal, newVal) -> {
                  if (newVal != null && newVal.equals(Color.TRANSPARENT))
                      rect.setFill(RED_LINE);     
              });
      
              return skin;
           }
      
          private class CustomColorPickerSkin extends ColorPickerSkin {
      
              private boolean initialized = false;
      
              public CustomColorPickerSkin(ColorPicker colorPicker) {
                  super(colorPicker);
              }
      
              @Override 
              protected Node getPopupContent() {
                  final ColorPalette popupContent = (ColorPalette)super.getPopupContent();
      
                  // make sure listeners and geometry are only created once
                  if (!initialized) {
                      final VBox paletteBox = (VBox)popupContent.getChildrenUnmodifiable().get(0);
                      final StackPane hoverSquare = (StackPane)popupContent.getChildrenUnmodifiable().get(1); // ColorSquare
                      final Rectangle hoverRect = (Rectangle)hoverSquare.getChildren().get(0); // ColorSquare
                      final GridPane grid = (GridPane)paletteBox.getChildren().get(0); // ColorPalette
                      final StackPane colorSquare = (StackPane)grid.getChildren().get(grid.getChildren().size()-1); // ColorSquare
                      final Rectangle colorRect = (Rectangle)colorSquare.getChildren().get(0);
      
                      // set fill color of original color rectangle to transparent
                      // (can't be set to red line gradient because ComboBoxBase<Color> tries to cast it to Color)
                      colorRect.setFill(Color.TRANSPARENT);
                      // put another rectangle with red line on top of it
                      colorSquare.getChildren().add(new Rectangle(colorRect.getWidth(), colorRect.getHeight(), RED_LINE));
                      // show red line gradient also in hover rectangle when the transparent color is selected
                      hoverRect.fillProperty().addListener((o, oldVal, newVal) -> {
                          if (newVal.equals(Color.TRANSPARENT))
                              hoverRect.setFill(RED_LINE);
                      });
      
                      initialized = true;
                  }
      
                  return popupContent;
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多