I need to apply multiple effects ( mainly innershadow and dropshadow ) through CSS. But I'm not able to chain these effects.
Is there CSS equivalent for setInput() of javafx.scene.effect.Effect?
So far I found only this link. It indicates something about fixes but no details about how to use chaining.
EDIT: Further explanation if question is not clear:
to apply effect through css, -fx-effect
is used. I need to apply multiple effects to same node. How to "chain" these effects in CSS? This can be easily done through code using setInput() mentioned earlier.
TIA
问题:
回答1:
It's currently not possible in Java 7 nor in Java 8 to chain effects or apply multiple effects via CSS. See the Oracle CSS Documentation.
It's also mentioned in the CSS vs Code article.
回答2:
As @Lorand mentions, it's not possible to chain effects via CSS.
He also gives the link of a well known example of chaining effects via code.
I'll provide a solution with FXML, using that same example to compare results.
By (updated) code:
@Override
public void start(Stage primaryStage) throws IOException {
Circle circle = new Circle(64,64,48);
Paint fill = new LinearGradient(0, 0, 0, 1,
true, CycleMethod.NO_CYCLE,
new Stop(0.0, Color.rgb(207, 0, 58)),
new Stop(1.0, Color.rgb(129, 0, 33)));
circle.setFill(fill);
circle.setStroke(null);
InnerShadow innerShadow = new InnerShadow(BlurType.GAUSSIAN,Color.color(0, 0, 0, 0.65),5,0,0,-5);
InnerShadow innerGlow = new InnerShadow(BlurType.GAUSSIAN,Color.color(1, 1, 1, 0.65),5,0,0,5);
innerGlow.setInput(innerShadow);
DropShadow dropShadow = new DropShadow(BlurType.GAUSSIAN, Color.color(0, 0, 0, 0.65), 5, 0, 0, 0);
dropShadow.setInput(innerGlow);
circle.setEffect(dropShadow);
VBox vBox = new VBox(circle);
vBox.setAlignment(Pos.CENTER);
Scene scene = new Scene(vBox,200,200,Color.web("#a9a9a9"));
primaryStage.setTitle("Chain effect by code");
primaryStage.setScene(scene);
primaryStage.show();
}
Note that the effects are defined in reverse order of application. For the sake of clarity, we could also write this:
circle.setEffect(dropShadow);
dropShadow
.setInput(innerGlow);
innerGlow
.setInput(innerShadow);
Now let's use Scene Builder 2.0 to create an FXML file circle.fxml
.
Once we have the circle, we set the DropShadow
effect, and then we edit the effect, and select Replace Effect Input
option from the menu button:
Then choose InnerShadow
, define the effect, and select again Replace Effect Input
, selecting again InnerShadow
:
Define the effect, save and exit. This will be the source code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.effect.*?>
<?import javafx.scene.paint.*?>
<?import java.lang.*?>
<?import javafx.scene.shape.*?>
<VBox alignment="CENTER" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Circle radius="48.0" stroke="TRANSPARENT" strokeType="INSIDE" strokeWidth="1.0">
<fill>
<LinearGradient endX="0.0" endY="1" proportional="true" startX="0" startY="0">
<stops>
<Stop color="#cf003a" offset="0.0" />
<Stop color="#810021" offset="1.0" />
</stops>
</LinearGradient>
</fill>
<effect>
<DropShadow blurType="GAUSSIAN" color="#000000a6" radius="5.0">
<input>
<InnerShadow blurType="GAUSSIAN" color="#ffffffa6" offsetY="5.0" radius="5.0">
<input>
<InnerShadow blurType="GAUSSIAN" color="#000000a6" offsetY="-5.0" radius="5.0" />
</input>
</InnerShadow>
</input>
</DropShadow>
</effect>
</Circle>
</children>
</VBox>
Finally, loading this file in our scene:
@Override
public void start(Stage primaryStage) throws IOException {
VBox vBox = FXMLLoader.load(getClass().getResource("circle.fxml"));
Scene scene = new Scene(vBox,200,200,Color.web("#a9a9a9"));
primaryStage.setTitle("Chain effect by FXML");
primaryStage.setScene(scene);
primaryStage.show();
}
This will be the result: