This discussion is archived
6 Replies Latest reply: Jan 31, 2013 2:25 PM by Puce RSS

Custom control & opaque popup

Puce Newbie
Currently Being Moderated
Hi,

I'm developing a custom control. I've create a custom Skin for this control where I layout a TextField and a Button. When the button gets clicked a Popup windows should be opened.

For this I've created an anonymous sublcass of PopupControl in the Skin implementation.

The trouble I'm having is that the PopupControl is transparent. How can I make it opaque? I tried to configure the background in the css but without success:

.my-control .popup-control{
-fx-background-color: yellow;
}

Any other way? Or should I use a Popup instead of PopupControl? (I understand that PopupControl is stylable, where Popup isn't, so I guess I should use PopupControl?)
  • 1. Re: Custom control & opaque popup
    David Grieve Pro
    Currently Being Moderated
    And you are not using MenuButton because...?
    Have you looked at using ContextMenu instead of PopupControl for the popup?

    In answer to your question, a PopupControl gets its styles from the "anchor" node's Scene, but is not a child of the anchor node. In other words, the selector ".my-control .popup-control" doesn't match anything. Give your PopupControl an extra style-class or an id and use that in the selector:
    PopupControl myButtonPopup = new PopupControl();
    myButtonPopup.getStyleClass().add("my-button-popup");
    Then use ".my-button-popup" as a selector.
  • 2. Re: Custom control & opaque popup
    Puce Newbie
    Currently Being Moderated
    Hi David,

    Thanks for your response.

    I guess you could get some similar effect using a MenuButton and a CustomMenuItem, but if feels more like a "misuse" since I don't want to create a menu. And it's also visually a bit different than I want it.

    I tried you PopupControl suggestion, but still without success.

    Here is about what I have (the PopupControl is used inside a Skin):
    public class SomeControlSkin implements Skin<SomeControl> {
    
        private SomeControl control;
      
        private OtherControl otherControl = new OtherControl();
        private PopupControl popupControl = new PopupControl() {
            { // instance initializer of PopupControl
    
                setSkin(new Skin<PopupControl>() {
                    private PopupControl skinnable = popupControl;
                    private Node node = otherControl;
                    @Override
                    public PopupControl getSkinnable() {
                        return skinnable;
                    }
    
                    @Override
                    public Node getNode() {
                        return node;
                    }
    
                    @Override
                    public void dispose() {
                        skinnable = null;
                        node = null;
                    }
                });
    
                getStyleClass().add("some-control-popup");
            }
        };
    
       public SomeControlSkin(SomeControl someControl){
          this.someControl = someControl;
          otherControl.fooProperty().bind(someControl.fooProperty());
          ...
       }
    
    ...
    
    }
    .some-control { 
        -fx-skin: "somePackage.SomeControlSkin";
    }
    
    .some-control .popup-control{ 
        -fx-background-color: yellow;
    }
    
    .some-control-popup{
        -fx-background-color: aliceblue;
    }
    
    .some-control .some-control-popup{
        -fx-background-color: yellow;
    }
    I'm not sure how to get the content to the PopupControl. Is setting a custom skin really the right way? The content is shown, but the background stays transparent.

    Edited by: Puce on 28.01.2013 15:29
  • 3. Re: Custom control & opaque popup
    David Grieve Pro
    Currently Being Moderated
    This is pretty wonky. The popup should get its stylesheets from the scene of the owner node. It may be that the owner node's scene doesn't have any stylesheets at the time the popup is created and the popup doesn't listen for changes in the owner's scene's stylesheets (there is a bug against this).

    As a workaround, you can listen to the ownerNode property of the popup and grab the ownerNode's scene's stylesheets when the owner node is set.
    ownerNodeProperty().addListener(new ChangeListener<Node>() {
    
        @Override
        public void changed(ObservableValue<? extends Node> ov, Node t, Node t1) {
            popupControl.getScene().getStylesheets().addAll(t1.getScene().getStylesheets());
        }
    });
    getStyleClass().add("some-control-popup");
    It would be helpful if you could file a JIRA issue at http://javafx-jira.kenai.com
  • 4. Re: Custom control & opaque popup
    Puce Newbie
    Currently Being Moderated
    I'm writing a library. The scene and its styesheets are defined by the user of the library and are thus out of my control.

    The relevant code is inside a Skin implemenation of a custom control.
    The CSS is referenced by the getUserAgentStylesheet() method of the custom control.
    The custom control has the styleClass "custom-control".

    Basically the Skin says:
    - render the cutom control as a TextField and a Button
    - if this button (part of the Skin) gets pressed: pop up a window with another custom control (which has it own Skin etc.)

    I'm not sure if PopupControl is the right thing to use here, though. I also tried with Popup but it didn't work either:
    public class SomeControlSkin implements Skin<SomeControl> {
     
        private SomeControl control;
      
        private OtherControl otherControl = new OtherControl();
        private Popup popup = new Popup();
     
       public SomeControlSkin(SomeControl someControl){
          this.someControl = someControl;
          otherControl.fooProperty().bind(someControl.fooProperty());
    
          ...
    
          popupControl.getContent().add(otherControl);   
    
          ...
       }
     
    ...
     
    }
    and
    .some-control { 
        -fx-skin: "somePackage.SomeControlSkin";
    }
     
    .some-control .popup{ 
        -fx-background-color: yellow;
    }
    
    .some-control .other-control{ 
        -fx-background-color: yellow;
    }
    (there is no styleClass property for Popup)
  • 5. Re: Custom control & opaque popup
    Puce Newbie
    Currently Being Moderated
    Note: I cross-posted this question here: http://stackoverflow.com/questions/14610639/custom-control-opaque-popup
  • 6. Re: Custom control & opaque popup
    Puce Newbie
    Currently Being Moderated
    I managed to get a small step further. The following will fill the Popup:
    popupControl.getScene().setFill(Color.YELLOW);
    But how can I do this with CSS?

    I even tried:
    .some-control { 
        -fx-skin: "somePackage.SomeControlSkin";
        -fx-background-color: black;
        -fx-background-insets: 0;
        -fx-fill: black;
    }
    
    .other-control { 
        -fx-skin: "somePackage.OtherControlSkin";
        -fx-background-color: black;
        -fx-background-insets: 0;
        -fx-fill: black;
    }
    But it didn't change the background no matter if I added the control to a Popup or to the main scene!? (I'm not sure if fill or background should do the trick and I'm not sure if I have to set the insets and to what value, though).

    I also tried to add a styleClass:
       popupControl.getContent().add(otherControl);
       otherControl.getStyleClass().add("other-control-popup");
    and
    .other-control-popup {
        -fx-background-color: black;
        -fx-background-insets: 0;
        -fx-fill: black;
    }
    But this didn't work either.

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points