2013-02-23 61 views
8

Tôi muốn áp dụng kết cấu cho hình dạng tùy chỉnh. Tôi nghĩ rằng điều này sẽ hoạt động:Hình "-fx-shape" có tương thích với "-fx-background-image" không?

.myTextureShape { 
-fx-shape: "M0 0 L0 50 L25 25 L50 50 L50 0 Z"; 
-fx-background-image: url("resources/texture_bg.png"); 
-fx-background-repeat: repeat; 
} 

Nhưng nó không! Tôi có được hình dạng chính xác nhưng không có kết cấu. Tất cả các vùng khác của tôi được tạo họa tiết chính xác vì vậy tôi biết rằng cú pháp là chính xác. Tôi đoán đó là vì chúng là hình chữ nhật theo mặc định.

Nếu tôi sử dụng phong cách sau đây thay vì:

.myTextureShape { 
-fx-shape: "M0 0 L0 50 L25 25 L50 50 L50 0 Z"; 
-fx-background-color: red; 
} 

Sau đó, tôi nhận được một nền đỏ chính xác.

Nếu cả hai thuộc tính không tương thích, làm cách nào tôi có thể áp dụng kết cấu cho hình dạng đường dẫn SVG tùy chỉnh?

P.S: Tệp PNG kết cấu của tôi, là một raster 10 * 10 nhỏ mà tôi lặp lại để lấp đầy các vùng của mình bằng.

+0

Nó có hoạt động nếu bạn không đặt '-fx-shape' và chỉ để nó như hình chữ nhật? – Hbcdev

+0

Có, không có hình -fx hình nền được áp dụng cho toàn bộ hình chữ nhật. – Pigelvy

+1

Liên kết theo dõi vấn đề: [RT-28825 -fx-shape không tương thích với hình ảnh -fx-background] (http://javafx-jira.kenai.com/browse/RT-28825) – jewelsea

Trả lời

4

Theo như tôi quan tâm -fx-shape-fx-background-image không hoạt động cùng nhau. JavaFX CSS cung cấp nhiều tùy chọn tạo kiểu tóc ... tuy nhiên có một số hạn chế và một số thứ chỉ có thể thực hiện với lập trình. JavaFX CSS sử dụng impl_setShape() để thô lớp Vùng thành hình dạng được xác định (là thị trường không được chấp nhận trong api nhưng bạn vẫn có thể dùng thử trong javafx 2.2 - mà tôi đang sử dụng tại thời điểm này). Việc thêm hình nền sẽ bỏ qua hình dạng và lấp đầy toàn bộ khung/vùng, điều tương tự cũng xảy ra nếu bạn sử dụng addChildren để thêm các đối tượng ImageView vào nó. Vì vậy, chuỗi css sẽ không chuyển thành kết quả bạn muốn.

Vì vậy, tôi có thể nghĩ ra ít nhất 2 cách áp dụng mẫu cho hình dạng SVGPath tùy chỉnh. Điều tôi sẽ sử dụng được thực hiện bằng ImagePattern. Đầu tiên xây dựng hình dạng như

SVGPath shape = new SVGPath(); 
shape.setContent("M0 0 L0 50 L25 25 L50 50 L50 0 Z"); 

hoặc sử dụng hình dạng builder này

SVGPath shape = SVGPathBuilder.create() 
    .content("M0 0 L0 50 L25 25 L50 50 L50 0 Z") 
    .build(); 

và sau đó thiết lập mô hình hình ảnh như điền

Image img = new Image("myjavafxapp/resources/texture_bg.png"); 
shape.setFill(new ImagePattern(img,0,0,10,10,false)); 

Một thay thế sẽ sử dụng cắt (thêm một hình dạng tùy chỉnh đoạn vào ngăn có hình ảnh -fx-nền được đặt theo kiểu css), trông giống như thế này

Pane test = new Pane(); 
test.setStyle(" -fx-background-image: url(\"myjavafxapp/res/index.jpeg\");"); 
SVGPath shape = new SVGPath(); 
shape.setContent("M0 0 L0 50 L25 25 L50 50 L50 0 Z"); 
test.setClip(shape); 

Một trong những điều này nên thực hiện thủ thuật - bạn có được hình dạng của bạn với nền kết cấu. Đây là tương đương với những gì bạn mong chờ từ một khu vực hoặc Pane lớp với phong cách

.myTextureShape { 
    -fx-shape: "M0 0 L0 50 L25 25 L50 50 L50 0 Z"; 
    -fx-scale-shape: false; 
    -fx-background-image: url("myjavafxapp/resources/texture_bg.png"); 
    -fx-background-repeat: repeat; 
} 

Vì vậy, hình dạng SVGPath cũng giống như tất cả các lớp Shape nonresizable, trái ngược với khu vực/Pane, đây là lý do tại sao tôi đặt ở đây -fx-scale-shape thuộc tính sai. Cách bạn có nó là với thiết lập mặc định - thiết lập nó thành true - làm cho hình dạng điền vào toàn bộ đối tượng cha mẹ ... từ đó tôi đoán rằng đây cũng sẽ là kết quả mong muốn của bạn. ... bây giờ lại có nhiều cách để tạo thang hình thành đối tượng cha.

Tôi đã làm việc này bằng cách sử dụng Nhóm để nhúng hình dạng và với phương pháp dịch nhóm (kích thước hình ảnh cần phải được điều chỉnh trong ImagePattern, do đó kết cấu không được chia tỷ lệ với hình dạng). Tôi đang thêm một ứng dụng hoạt động nhỏ mà tôi đã sử dụng để xem trên ví dụ trên nếu tôi nhớ mọi thứ chính xác.(Nếu bạn muốn hình dạng để mở rộng quy mô tương ứng, bạn sử dụng các yếu tố cùng một tỷ lệ thay vì scaleX và sclaey trong phương pháp addScale)

package myjavafxapp; 

    import javafx.application.Application; 
    import javafx.application.Platform; 
    import javafx.beans.value.ChangeListener; 
    import javafx.beans.value.ObservableValue; 
    import javafx.scene.Group; 
    import javafx.scene.Node; 
    import javafx.scene.Scene; 
    import javafx.scene.layout.Pane; 
    import javafx.scene.layout.StackPane; 
    import javafx.scene.shape.SVGPath; 
    import javafx.scene.shape.SVGPathBuilder; 
    import javafx.scene.image.Image; 
    import javafx.scene.paint.*; 
    import javafx.scene.transform.Scale; 
    import javafx.scene.transform.Translate; 
    import javafx.stage.Stage; 
    /** 
    * @author martint 
    */ 
    public class MyJavaFXApp extends Application { 

      private final static String svg = "M0 0 L0 50 L25 25 L50 50 L50 0 Z"; 
      private SVGPath shape; 
      private Image img; 
      private Pane resizePane; 
      private Group shapeGroup; 
      private Node content; 

     @Override 
     public void start(final Stage primaryStage) { 

      //build the SVGPath shape 
      shape = SVGPathBuilder.create().content(svg).build(); 
      img = new Image("myjavafxapp/res/index.jpeg"); 
      resizePane = new Pane(); 
      shapeGroup = new Group(); 
      resizePane.getChildren().add(shapeGroup); 

      StackPane root = new StackPane(); 
      root.getChildren().add(resizePane); 

      Scene scene = new Scene(root, 200, 200); 
      primaryStage.setScene(scene); 
      primaryStage.show(); 
      //fill node content 
      content = nodeCont(); 
      shapeGroup.getChildren().add(content); 
      //resizing listening 
      resizePane.widthProperty().addListener(new ChangeListener<Number>(){ 
          @Override 
          public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
            addScaling(); 
          }}); 
      resizePane.heightProperty().addListener(new ChangeListener<Number>(){ 
          @Override 
          public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) { 
            addScaling(); 
          }}); 
      Platform.runLater(new Runnable() {   
          @Override 
          public void run() { 
            addScaling(); 
          } 
        }); 
      } 
      private Node nodeCont() { 
        Group cont = new Group(); 
        cont.getChildren().add(shape); 
        return cont; 
      } 
      private void addScaling() { 
        shapeGroup.getTransforms().clear();   
        //shape boundary 
        double cx = content.getBoundsInParent().getWidth(); 
        double cy = content.getBoundsInParent().getHeight(); 
        //resizePane boundary 
        double px = resizePane.getWidth(); 
        double py = resizePane.getHeight(); 
        //if pane set 
        if (px > 0.0 && py > 0.0) { 
          //scale 
          double scalex = px/cx; 
          double scaley = py/cy; 
          //center 
          double centerx = 0.5 * (px - cx*scalex); 
          double centery = 0.5 * (py - cy*scaley);    
          //transform 
          shapeGroup.getTransforms().add(new Translate(centerx, centery)); 
          shapeGroup.getTransforms().add(new Scale(scalex, scaley)); 
          shape.setFill(new ImagePattern(img,0,0,10/scalex,10/scaley,false)); 
        } 
      } 
      public static void main(String[] args) { 
        launch(args); 
      } 

    } 
+0

Lỗi [RT-28825] (http://javafx-jira.kenai.com/browse/RT -28825) nói rằng điều này là có thể trong JavaFX 8. Kinh nghiệm của tôi là với 2.2.6. Bạn đã sử dụng phiên bản nào? – Pigelvy

+0

Tôi đang sử dụng phiên bản mới nhất của javafx, mà tôi tin là 2.2.7. Tôi đã không thử truy cập sớm của JDK8 được nêu ra, vì vậy tôi không biết nếu nó bao gồm một css javafx đã được cải thiện, nhưng lộ trình của họ nói JDK8 sẽ bao gồm javafx 8. Mong cho 8 cải thiện css và hỗ trợ html5 - nhưng cho đến khi đó workaround của tôi nên làm điều đó cho bạn =) Nhưng tôi sẽ thêm công cụ để trả lời của tôi khi tôi tìm ra một cái gì đó mới. –

4

Các inablity để áp dụng một kết cấu nền cho một hình dạng tùy chỉnh thông qua css là một platform bug với JavaFX 2.2 (Java 7).

Trong Java 8, lỗi nền tảng được khắc phục.

mẫu css:

/** 
* file textured-shape.css 
* place in same directory as TexturedShape.java and ensure build system copies 
* this file to the build output directory. 
*/ 
.textured-shape { 
    /** (a square with the bottom triangle chunk taken out of it) */ 
    -fx-shape: "M0 0 L0 50 L25 25 L50 50 L50 0 Z"; 
    -fx-background-image: url('http://icons.iconarchive.com/icons/tooschee/misc/128/Present-icon.png'); 
    /** 
    * Image license: 
    * CC Attribution-Noncommercial 3.0 http://creativecommons.org/licenses/by-nc/3.0/ 
    * Buy commercial license here: http://tooschee.com/portfolio?worksCategory=icons 
    */ 
} 

mẫu App:

import static javafx.application.Application.launch; 
import javafx.application.*; 
import javafx.scene.Scene; 
import javafx.scene.layout.Pane; 
import javafx.stage.Stage; 

public class TexturedShape extends Application { 
    @Override public void start(Stage stage) { 
    Pane pane = new Pane(); 
    pane.setPrefSize(128, 128); 
    pane.getStyleClass().add("textured-shape"); 

    Scene scene = new Scene(pane); 
    scene.getStylesheets().add(
     getClass().getResource("textured-shape.css").toExternalForm() 
    ); 
    stage.setScene(scene); 
    stage.show(); 
    } 

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

Chạy mã mẫu trên Java 7, hình dạng không được áp dụng cho các kết cấu nền:

java7sample

Chạy cùng mã mẫu trên Java 8b80, sha pe được áp dụng cho kết cấu nền:

java8sample

Các vấn đề liên quan