考慮使用ControlsFX
的ControlsFX庫有一個名爲「輕量級對話」功能,執行此相同的對話框疊加效應。對於這種解決方案使用預構建的庫通常比滾動您自己的實現更好。
如果選擇推出自己的解決方案,而不是使用ControlsFX,然後閱讀。 。 。
解決方案
放置在一個Group你StackPane的疊加子窗格。
StackPane stack = new StackPane(mainPane, new Group(popupPane));
爲什麼這個作品
A組是不可調整大小,所以效果將是在mainPane是可調整大小的,並且popupPane將假設它的內部優選尺寸和放置在組內,這將是集中在StackPane的mainPane頂部。
示範
在一個項目中,我寫了一個很久以前的DialogFactory演示了這種方法來覆蓋上的WebView的頂部對話框。下面的屏幕截圖顯示了在Java 8下運行willow-0.3-prerelease-jar並導航到http://www.w3schools.com/js/tryit.asp?filename=tryjs_alert的輸出,然後單擊「嘗試」按鈕。它所做的是覆蓋警戒框(在JavaFX中呈現並編程,而不是JavaScript),該警報框以顯示警報時禁用和變暗的WebView控件爲中心。
這是從willow project選擇的源樣品來源,它不是獨立的,但你需要稍微調整它它採用您的情況。代碼只是在這裏展示的技術和模式。
/**
* Overlay a dialog on top of the WebView.
*
* @param dialogNode the dialog to overlay on top of the view.
*/
private void overlayView(Node dialogNode) {
// if the view is already overlaid we will just ignore this overlay call silently . . . todo probably not the best thing to do, but ok for now.
if (!(webView.getParent() instanceof BorderPane)) return;
// record the view's parent.
BorderPane viewParent = (BorderPane) webView.getParent();
// create an overlayPane layering the popup on top of the webview
StackPane overlayPane = new StackPane();
overlayPane.getChildren().addAll(webView, new Group(dialogNode));
webView.setDisable(true);
// overlay the popup on the webview.
viewParent.setCenter(overlayPane);
}
/**
* Removes an existing dialog overlaying a WebView.
*/
private void removeViewOverlay() {
BorderPane viewParent = (BorderPane) webView.getParent().getParent();
viewParent.setCenter(webView);
}
public EventHandler<WebEvent<String>> createAlertHandler() {
return stringWebEvent -> {
AlertHandler alertHandler = new AlertHandler(
stringWebEvent.getData(),
event -> {
webView.setDisable(false);
removeViewOverlay();
}
);
overlayView(alertHandler);
// todo block until the user accepts the alert.
};
}
. . .
// add an effect for disabling and enabling the view.
getView().disabledProperty().addListener(new ChangeListener<Boolean>() {
final BoxBlur soften = new BoxBlur();
final ColorAdjust dim = new ColorAdjust();
{
dim.setInput(soften);
dim.setBrightness(-0.5);
}
@Override
public void changed(ObservableValue<? extends Boolean> observableValue, Boolean oldValue, Boolean newValue) {
if (newValue) {
getView().setEffect(dim);
} else {
getView().setEffect(null);
}
}
});
. . .
public class AlertHandler extends VBox {
public AlertHandler(String message, EventHandler<ActionEvent> confirmHandler) {
super(14);
// add controls to the popup.
final Label promptMessage = new Label(message);
final ImageView alertImage = new ImageView(ResourceUtil.getImage("alert_48.png"));
alertImage.setFitHeight(32);
alertImage.setPreserveRatio(true);
promptMessage.setGraphic(alertImage);
promptMessage.setWrapText(true);
promptMessage.setPrefWidth(350);
// action button text setup.
HBox buttonBar = new HBox(20);
final Button confirmButton = new Button(getString("dialog.continue"));
confirmButton.setDefaultButton(true);
buttonBar.getChildren().addAll(confirmButton);
// layout the popup.
setPadding(new Insets(10));
getStyleClass().add("alert-dialog");
getChildren().addAll(promptMessage, buttonBar);
final DropShadow dropShadow = new DropShadow();
setEffect(dropShadow);
// confirm and close the popup.
confirmButton.setOnAction(confirmHandler);
}
}
. . .
getView().getEngine().setOnAlert(dialogFactory.createAlertHandler());
真的,我上面寫代碼的唯一原因是因爲當時沒有可用的ControlsFX的等效庫。如果我從頭開始開發一個項目,我會首先嚐試使用ControlsFX。
什麼是一個良好的,好的和堅實的答案!而且速度也很快;-)。我將研究ControlsFX,似乎可以幫助您解決JavaFX帶來的一些困難。我不知道解決方案很簡單。謝謝jewelsea,你是最棒的! – d0ggy
好貼,非常感謝! – Flipbed