2016-03-20 16 views

cevap

1

Çözüm, bir kesmekle bitiştir, ancak özel API kullanılmasını engeller.

  • Eğer ColorPicker tıkladığınızda gösterir Popup kontrolünü bul:

    Bu

    gerekli adımlardır.

Bunu here veya here bulabilirsiniz.

  • Bu pencerede kare renkleri alın, böylece bunlardan birini değiştirebiliriz. Sonunu kullanacağım.

biz pop-up sahip olduktan sonra biz aramalarını kullanarak kare renklerin kümesi alırsınız:

Set<Node> squares = popup.lookupAll(".color-rect"); en özelleştirilmiş 'un-renk' eklemek için son bir renk kullanalım.

  • Kırmızı çapraz çizginin nasıl çizileceğini öğrenin.

ben ile geldim bir LinearGradient:

çalışıyor, ama ne yazık ki degrade ColorPicker kontrolünü kırar
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)); 

, o ComboBoxBase<Color> bir uzantısıdır ve tüm dolguları dikdörtgenler için kullanılan Paint yerine Color'a dökülecektir. Bu, geçişler sırasında bir rengi (örneğin Color.TRANSPARENT) kullanmamız gerektiği anlamına gelir.

  • Pop-up kapandığında görülecek kare renk veya gezinme sırasında görünen kare renk gibi diğer sorunları çözün.

Bunun için, hem renk seçicideki hem de kare karedeki kare rengini aramalıyız ve bunlar bizim şeffaf olanla eşleştiğinde, rengi degradeyle değiştirin.

Bu

kodudur:

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); 
    } 

} 

Uncolor picker

+0

, Pereda teşekkür ederim:

İşte benim kodudur! – MartinJoo

1

fikri aynı olsa ben, biraz farklı bir çözüm geldi bu yüzden artık beni tatmin etmedi yukarıda yayınlanan yaklaşım. Ayrıca, kullanımdan kaldırılmış işlevlerin kullanılmasını da önler.

ColorPicker sınıfını, kendi CustomColorPicker oluşturmak için alt sınıflara ayırarak kullanıyorum.

@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; 
     } 
    } 
}