Тени в панели без отделки! В JavaFX
Whats вверх?
Ну, я пытаюсь сделать свою панель немного лучше, визуально, поэтому, что я делаю: установите мою сцену UNDECORATED (OK) и (пытается) добавить эффект тени (не ОК).
Я искал (много) таких вопросов через Интернет, нашел несколько похожих случаев (создание недекорированного этапа в javafx 2.0 и Как добавить тень в окно в JavaFX?) но ни то, ни другое не работает для меня.
кажется, что падение тень просто не устанавливается! Не могу понять, почему.
смотрите, что я получил:
public static int showConfirmDialog(Window father, String title, String body, String[] msgBtn)
{
System.out.println("La vai eu");
AnchorPane ap = createPaneWithButton(2, msgBtn,body);
ap.setEffect(initDropShadow());
Scene scene = new Scene(ap);
Stage stage = new Stage();
stage.setTitle(title);
scene.setFill(null);
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(scene);
stage.initStyle(StageStyle.UNDECORATED);
stage.show();
return 1;
}
private static AnchorPane createPaneWithButton(int qtBtn, String[] msgsBtn, String body) {
AnchorPane ap = createPane();
HBox laneBtn = new HBox(30);
VBox vbox = new VBox(20);
BorderPane layout = new BorderPane();
Button btn;
for(int i = 0; i < qtBtn; i++ ){
btn = new Button();
btn.setText(msgsBtn[i]);
laneBtn.getChildren().add(btn);
}
vbox.getChildren().add(new Text(body));
vbox.getChildren().add(laneBtn);
layout.setCenter(vbox);
ap.getChildren().add(layout);
return ap;
}
private static AnchorPane createPane() {
AnchorPane ap = new AnchorPane();
ap.setLayoutX(250);
ap.setLayoutY(50);
return ap;
}
Спасибо, ребята! Я с нетерпением жду ответа! (В то время как я буду продолжать пытаться, что могу).
PS:. Srry для английского, это не мой основной язык. Надеюсь, вы понимаете.
3 ответов
предыдущий пример работает для меня
на код поставляется для ответа на Как добавить тень в окно в JavaFX? отлично работает для меня (тень в диалоговом окне видна) на Java 8b96, Windows 7. Когда я написал его для JavaFX 2, он также работал в этой среде.
Я не мог точно сказать, что вам не хватает в вашем примере, поскольку вы не предоставили полный исполняемый файл код.
возможная проблема с вашим кодом
Я предполагаю, что вы не вставляете фоновое содержимое, чтобы в диалоговом окне было пространство для отображения тени. То есть вы заполняете диалоговое окно содержимым и не оставляете места в диалоговом окне вокруг содержимого для отображения эффекта. Пример ниже достигает insetting с правило CSS -fx-background-insets: 12;
Обновленный Образец Код
Я скопировал измененную версию кода примера в этот ответ, чтобы он не просто содержался в неясной ссылке gist от другого ответа. Изменения должны просто использовать стандартные вызовы API, поскольку построители, используемые в исходном ответе, устарели с момента создания исходного ответа.
ModalConfirmExample.java
import javafx.application.Application;
import javafx.beans.value.*;
import javafx.concurrent.Worker;
import javafx.event.*;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.effect.BoxBlur;
import javafx.scene.effect.Effect;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.web.WebView;
import javafx.stage.Modality;
import javafx.stage.*;
/**
* Application modal dialog with the following properties:
* translucent background
* drop-shadowed border
* non-rectangular shape
* blur effect applied to parent when dialog is showing
* configurable message text
* configurable yes and no event handlers
*/
class ModalDialog extends Stage {
private static final Effect parentEffect = new BoxBlur();
private final String messageText;
private final EventHandler<ActionEvent> yesEventHandler;
private final EventHandler<ActionEvent> noEventHandler;
public ModalDialog(
Stage parent,
String messageText,
EventHandler<ActionEvent> yesEventHandler,
EventHandler<ActionEvent> noEventHandler) {
super(StageStyle.TRANSPARENT);
this.messageText = messageText;
this.yesEventHandler = yesEventHandler;
this.noEventHandler = noEventHandler;
// initialize the dialog
initOwner(parent);
initParentEffects(parent);
initModality(Modality.APPLICATION_MODAL);
setScene(createScene(createLayout()));
}
private StackPane createLayout() {
StackPane layout = new StackPane();
layout.getChildren().setAll(
createGlassPane(),
createContentPane()
);
return layout;
}
private Pane createGlassPane() {
final Pane glassPane = new Pane();
glassPane.getStyleClass().add(
"modal-dialog-glass"
);
return glassPane;
}
private Pane createContentPane() {
final HBox contentPane = new HBox();
contentPane.getStyleClass().add(
"modal-dialog-content"
);
contentPane.getChildren().setAll(
new Label(messageText),
createYesButton(),
createNoButton()
);
return contentPane;
}
private Button createYesButton() {
final Button yesButton = new Button("Yes");
yesButton.setDefaultButton(true);
yesButton.setOnAction(yesEventHandler);
return yesButton;
}
private Button createNoButton() {
final Button noButton = new Button("No");
noButton.setOnAction(noEventHandler);
return noButton;
}
private Scene createScene(StackPane layout) {
Scene scene = new Scene(layout, Color.TRANSPARENT);
scene.getStylesheets().add(
getClass().getResource(
"modal-dialog.css"
).toExternalForm()
);
return scene;
}
private void initParentEffects(final Stage parent) {
this.showingProperty().addListener(new ChangeListener<Boolean>() {
@Override public void changed(ObservableValue<? extends Boolean> observableValue, Boolean wasShowing, Boolean isShowing) {
parent.getScene().getRoot().setEffect(
isShowing ? parentEffect : null
);
}
});
}
}
/**
* Demonstrates a modal confirm box in JavaFX.
* Dialog is rendered upon a blurred background.
* Dialog is translucent.
*/
public class ModalConfirmExample extends Application {
public static void main(String[] args) {
launch(args);
}
@Override
public void start(final Stage primaryStage) {
final WebView webView = new WebView();
final ModalDialog dialog = createWebViewPreferenceDialog(primaryStage, webView);
// show the preference dialog each time a new page is loaded.
webView.getEngine().getLoadWorker().stateProperty().addListener(new ChangeListener<Worker.State>() {
@Override
public void changed(ObservableValue<? extends Worker.State> observableValue, Worker.State state, Worker.State newState) {
if (newState.equals(Worker.State.SUCCEEDED)) {
dialog.show();
dialog.toFront();
}
}
});
webView.getEngine().load("http://docs.oracle.com/javafx/");
// initialize the stage
primaryStage.setTitle("Modal Confirm Example");
primaryStage.setScene(new Scene(webView));
primaryStage.show();
}
private ModalDialog createWebViewPreferenceDialog(final Stage primaryStage, final WebView webView) {
final EventHandler<ActionEvent> yesEventHandler =
new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
System.out.println("Liked: " + webView.getEngine().getTitle());
primaryStage.getScene().getRoot().setEffect(null);
Stage dialogStage = getTargetStage(actionEvent);
dialogStage.close();
}
};
final EventHandler<ActionEvent> noEventHandler =
new EventHandler<ActionEvent>() {
@Override public void handle(ActionEvent actionEvent) {
System.out.println("Disliked: " + webView.getEngine().getTitle());
primaryStage.getScene().getRoot().setEffect(null);
Stage dialogStage = getTargetStage(actionEvent);
dialogStage.close();
}
};
return new ModalDialog(primaryStage, "Will you like this Page?", yesEventHandler, noEventHandler);
}
private Stage getTargetStage(ActionEvent actionEvent) {
Node target = (Node) actionEvent.getTarget();
return ((Stage) target.getScene().getWindow());
}
}
модальный диалог.в CSS
.root {
-fx-opacity: 0.9;
}
.modal-dialog-glass {
-fx-effect: dropshadow(three-pass-box, derive(cadetblue, -20%), 10, 0, 4, 4);
-fx-background-color: derive(cadetblue, -20%);
-fx-background-insets: 12;
-fx-background-radius: 6;
}
.modal-dialog-content {
-fx-padding: 20;
-fx-spacing: 10;
-fx-alignment: center;
-fx-font-size: 20;
-fx-background-color: linear-gradient(to bottom, derive(cadetblue, 20%), cadetblue);
-fx-border-color: derive(cadetblue, -20%);
-fx-border-width: 5;
-fx-background-insets: 12;
-fx-border-insets: 10;
-fx-border-radius: 6;
-fx-background-radius: 6;
}
использовать a Библиотека Вместо
Также отметим, что для создания диалогов я настоятельно рекомендую использовать ControlsFX проект, а не создание собственной диалоговой системы. Если ControlsFX не хватает функций, которые вам требуются (например, поддержка Drop shadow), вы можете запрос для этого против проекта ControlsFX и при необходимости вернуться к этому ответу.
простой работающего пример.
здесь fxml
структура:
AnchorPane(200,200) // pane for space for shadow
\- AnchorPane(center) // appliction pane
\- Label // application content
реальные screen.fxml
:
<AnchorPane fx:id="shadowPane" prefHeight="200.0" prefWidth="200.0" xmlns="http://javafx.com/javafx/8.0.40" xmlns:fx="http://javafx.com/fxml/1">
<children>
<AnchorPane fx:id="rootPane" layoutX="56.0" layoutY="62.0">
<children>
<Label fx:id="someLabel" layoutX="30.0" layoutY="30.0" text="Label" textFill="#f20000" />
</children>
<padding>
<Insets bottom="20.0" left="20.0" right="20.0" top="20.0" />
</padding>
</AnchorPane>
</children>
</AnchorPane>
Main.java
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("/sample/screen.fxml"));
AnchorPane shadowPane = loader.load();
AnchorPane rootPane = (AnchorPane) shadowPane.lookup("#rootPane");
rootPane.setStyle("-fx-effect: dropshadow(gaussian, rgba(0, 0, 0, 0.4), 10, 0.5, 0.0, 0.0);" +
"-fx-background-color: white;"); // Shadow effect
Scene scene = new Scene(shadowPane);
stage.setScene(scene);
shadowPane.setBorder(new Border(new BorderStroke(Color.RED, BorderStrokeStyle.SOLID, null, null))); // Some borders for for clarity
shadowPane.setStyle("-fx-background-color: transparent;"); // Makes shadowPane transparent
scene.setFill(Color.TRANSPARENT); // Fill our scene with nothing
stage.initStyle(StageStyle.TRANSPARENT); // Important one!
stage.show();
}
Ну, я нашел очень просто решение. Может быть, это не поддерживается в более ранних версиях? Однако.. Код:
iconPane.setEffect(new DropShadow(2d, 0d, +2d, Color.BLACK));
изображение показывает результат - мое намерение состояло в том, чтобы показать значок в виде FAB