私に関する限り-fx-shape
、-fx-background-image
一緒に仕事をしていません。JavaFX CSSは多くのスタイリングオプションを提供します...しかし、いくつかの制限があり、いくつかのことはプログラミングでのみ可能です。JavaFX CSSはimpl_setShape()
、Regionクラスを定義された形状に粗くするために使用します(これは、APIで非推奨として市場に出回っていますが、現在使用しているjavafx 2.2でも試すことができます)。背景画像を追加すると、形状が無視され、ペイン/領域全体が塗りつぶされます。addChildrenを使用してImageViewオブジェクトを追加した場合も、同じことが起こります。つまり、css文字列は希望する結果に変換されません。
したがって、カスタムSVGPathシェイプにパターンを適用する方法は少なくとも2つ考えられます。私が使用するのはImagePatternで行われます。まず、このような形を作ります
SVGPath shape = new SVGPath();
shape.setContent("M0 0 L0 50 L25 25 L50 50 L50 0 Z");
またはシェイプビルダーを使用する
SVGPath shape = SVGPathBuilder.create()
.content("M0 0 L0 50 L25 25 L50 50 L50 0 Z")
.build();
次に、画像パターンを塗りつぶしとして設定します
Image img = new Image("myjavafxapp/resources/texture_bg.png");
shape.setFill(new ImagePattern(img,0,0,10,10,false));
別の方法として、クリッピング(cssスタイルで-fx-background-imageが設定されたペインにカスタムシェイプクリップを追加する)を使用します。これは、次のようになります。
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);
これらの1つでうまくいくはずです。テクスチャのある背景で形を整えます。これは、スタイルのあるRegionまたはPaneクラスに期待するものと同等です。
.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;
}
したがって、SVGPathシェイプは、Region / Paneとは対照的に、サイズ変更不可能なすべてのShapeクラスと同様です。これが、ここで-fx-scale-shape
属性をfalseに設定した理由です。デフォルト設定(trueに設定)を使用した場合、シェイプは親オブジェクト全体を塗りつぶします...これも望ましい結果になると思います。...ここでも、親オブジェクトに合わせて形状を拡大縮小する方法が複数あります。
Groupを使用して形状を埋め込み、グループを変換する方法で動作するようになりました(ImagePatternで画像サイズを調整して、テクスチャが形状に比例しないようにする必要があります)。私は小さな動作するアプリを追加しています。これは、すべてを正しく覚えていれば、上記の例で見たものです。(形状を比例的にスケーリングする場合は、addScaleメソッドでscalexとsclaeyの代わりに同じスケール係数を使用します)
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);
}
}