我正在努力设置一个弹出窗口,它会在自定义skin中创建。
我想我必须使用PopupControl,而不是Popup。
PopupControl popup = new PopupControl();
popup.getScene().setRoot(popupContentPane);
popup.setAutoHide(true);
popup.setAnchorLocation(PopupWindow.AnchorLocation.WINDOW_BOTTOM_LEFT);
popup.setStyle("-fx-background-color: red;");
popup.getStyleClass().add("my-popup");
popup.show(getSkinnable(), screenLocation.getX(), screenLocation.getY());
skinnable会覆盖userAgentStylesheet:
@Override
public String getUserAgentStylesheet() {
return Stylesheets.getDefaultStylesheet();
}
但是样式,styleClass和应用于popupContentPane的任何子节点的styleClass都没有效果。
如果我正确理解the documentation,弹出窗口应该使用ownerNode的样式表(这里是skinnable)。
这个问题有点类似于我的一个老问题,当时没有得到任何答案:Custom control & opaque popup
如何设置弹出窗口的样式?
更新
这里有一个跟随[〜wzbergers]提示的SSCCE,虽然它看起来很奇怪,弹出窗口也需要一个皮肤。样式仍然不起作用:
MinimalApplication:
package test;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class MinimalApplication extends Application {
@Override
public void start(Stage primaryStage) {
MinimalControl minimalControl = new MinimalControl();
minimalControl.setText("test");
BorderPane root = new BorderPane(minimalControl);
Scene scene = new Scene(root, 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
MinimalControl:
package test;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Control;
import javafx.scene.control.Skin;
import test.skin.MinimalControlSkin;
import test.skin.Stylesheets;
public class MinimalControl extends Control {
private static final String DEFAULT_STYLE_CLASS = "minimal-control";
private final StringProperty text = new SimpleStringProperty(this, "text");
public MinimalControl() {
getStyleClass().setAll(DEFAULT_STYLE_CLASS);
}
@Override
public String getUserAgentStylesheet() {
return Stylesheets.getDefaultStylesheet();
}
@Override
protected Skin<?> createDefaultSkin() {
return new MinimalControlSkin(this);
}
public final String getText() {
return textProperty().get();
}
public final void setText(String text) {
textProperty().set(text);
}
public StringProperty textProperty() {
return text;
}
}
MinimalControlSkin:
package test.skin;
import javafx.geometry.Bounds;
import javafx.scene.control.Label;
import javafx.scene.control.SkinBase;
import javafx.scene.layout.BorderPane;
import javafx.stage.PopupWindow;
import test.MinimalControl;
public class MinimalControlSkin extends SkinBase<MinimalControl> {
private final Label label = new Label();
private final BorderPane contentPane = new BorderPane(label);
private final MinimalPopup popup = new MinimalPopup();
public MinimalControlSkin(MinimalControl control) {
super(control);
getChildren().add(contentPane);
label.textProperty().bind(control.textProperty());
label.setOnMouseClicked(event -> openPopup());
popup.setAutoHide(true);
popup.setAnchorLocation(PopupWindow.AnchorLocation.WINDOW_BOTTOM_LEFT);
}
private void openPopup() {
Bounds localBounds = label.getBoundsInLocal();
Bounds screenBounds = label.localToScreen(localBounds);
popup.show(label, screenBounds.getMinX(), screenBounds.getMinY());
}
}
MinimalPopup:
package test.skin;
import javafx.scene.control.PopupControl;
import javafx.scene.control.Skin;
public class MinimalPopup extends PopupControl {
private static final String DEFAULT_STYLE_CLASS = "minimal-popup";
public MinimalPopup() {
getStyleClass().setAll(DEFAULT_STYLE_CLASS);
}
@Override
protected Skin<?> createDefaultSkin() {
return new MinimalPopupSkin(this);
}
}
MinimalPopupContentPane:
package test.skin;
import javafx.beans.property.StringProperty;
import javafx.scene.control.Label;
import javafx.scene.layout.BorderPane;
public class MinimalPopupContentPane extends BorderPane {
private final Label label = new Label("some popup text");
public MinimalPopupContentPane() {
setCenter(label);
}
public final String getText() {
return textProperty().get();
}
public final void setText(String text) {
textProperty().set(text);
}
public StringProperty textProperty() {
return label.textProperty();
}
}
MinimalPopupSkin:
package test.skin;
import javafx.scene.Node;
import javafx.scene.control.Skin;
public class MinimalPopupSkin implements Skin<MinimalPopup> {
private final MinimalPopup popup;
private MinimalPopupContentPane contentPane = new MinimalPopupContentPane();
public MinimalPopupSkin(MinimalPopup popup) {
this.popup = popup;
contentPane.idProperty().bind(popup.idProperty());
contentPane.styleProperty().bind(popup.styleProperty());
contentPane.getStyleClass().addAll(popup.getStyleClass());
}
@Override
public MinimalPopup getSkinnable() {
return popup;
}
@Override
public Node getNode() {
return contentPane;
}
@Override
public void dispose() {
contentPane = null;
}
}
样式表:
package test.skin;
public class Stylesheets {
private Stylesheets() {
}
public static String getDefaultStylesheet(){
return Stylesheets.class.getResource("modena/modena.css").toExternalForm();
}
}
测试/皮肤/摩德纳/ modena.css:
.minimal-control {
-fx-skin: "test.skin.MinimalControlSkin";
}
.minimal-control .popup {
-fx-border-color: black; /* -fx-box-border; */
-fx-border-width: 1px;
-fx-background-color: red;
}
.minimal-control PopupControl {
-fx-border-color: black; /* -fx-box-border; */
-fx-border-width: 1px;
-fx-background-color: blue;
}
.minimal-popup {
-fx-border-color: black; /* -fx-box-border; */
-fx-border-width: 1px;
-fx-background-color: yellow;
}
.minimal-control .minimal-popup {
-fx-border-color: black; /* -fx-box-border; */
-fx-border-width: 1px;
-fx-background-color: green;
}
答案 0 :(得分:0)
PopupControl不是一个节点 - 所以你必须设置它的内容窗格样式,或者更好地提供一个将样式绑定到内容窗格的外观,就像下面的例子一样。
PopupControl popup = new PopupControl() {
@Override
protected Skin<?> createDefaultSkin() {
return new PopupControlSkin(this, popupContentPane);
}
};
...
public class PopupControlSkin implements Skin<PopupControl> {
private PopupControl popup;
private Pane content;
public PopupControlSkin(final PopupControl control, final Pane content) {
this.popup = control;
this.content = content;
content.idProperty().bind(popup.idProperty());
content.styleProperty().bind(popup.styleProperty());
content.getStyleClass().addAll(popup.getStyleClass());
}
@Override
public Node getNode() {
return content;
}
@Override
public void dispose(){
}
@Override
public PopupControl getSkinnable(){
return popup;
}
}