2017-08-02 111 views
0

我再次努力設計一個彈出窗口,該窗口在自定義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()); 

的換膚功能覆蓋了userAgentStylesheet:

@Override 
public String getUserAgentStylesheet() { 
    return Stylesheets.getDefaultStylesheet(); 
} 

但是,無論是風格,也不是的styleClass也沒有任何的styleClass應用於popupContentPane的任何子節點也有一定效果。

如果我正確理解the documentation,彈出窗口應該使用ownerNode(此處爲可換膚)的樣式表。

的問題是有點類似我的一個老問題,它並沒有在那個時候得到任何答案:Custom control & opaque popup

我怎樣才能樣式彈出?

更新

這裏遵循一定的SSCCE [〜wzbergers]提示,雖然它看起來很奇怪的是需要一個皮膚彈出以及。造型仍然不能正常工作:

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; 
    } 

} 

樣式表:

包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

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; 
    } 
} 
+0

請參閱我的SSCCE。 IT採用這種方法,但造型仍然沒有效果。 – Puce

+0

您必須重寫彈出式內容窗格的#getUserAgentStylesheet。 公共類MinimalPopupContentPane延伸BorderPane { @覆蓋 公共字符串getUserAgentStylesheet() { 返回Stylesheets.getDefaultStylesheet(); } .... – wzberger