2

I'm trying to copy a symbol form an old java swing Application. This is the Old one:

enter image description here

And this is my attempt to copy this symbol: enter image description here

beside that the two ellipses are not in the same dimension - If the Mouse isn't over the Textfield I want them to be displayed as Label but as soon as the mouse hovers about the Textfield it should show up.

Anyone any ideas how to implement ? Is there a css-style for something like this ?

My ( temporary ) solution looks like this:

public class CustomTextField {
    private Group group;

    private Label label;
    private TextField textField;

    public StdeTextField(String text){
        label = new Label(text);
        label.relocate(5,2.5);
        textField = new TextField(text);

        label.setOnMouseEntered(event -> {
            group.getChildren().remove(label);
            group.getChildren().add(textField);

            textField.setText(label.getText());
        });

        textField.setOnMouseExited(event -> {
            group.getChildren().remove(textField);
            group.getChildren().add(label);

            label.setText(textField.getText());
        });

        group = new Group();
        group.getChildren().addAll(label);
    }

    public Group getGroup() {
        return group;
    }
}

The Label and the Text field has a offset, because I can't figure out how to get the Size of an Node if it's not rendered.

Meeresgott
  • 431
  • 3
  • 17
  • CSS alone won’t cover it. While you can use a hover selector to make the TextField appear, you certainly don’t want it to disappear when the mouse is moved away from it. You probably want it to revert to a Label only when the user presses Enter or Esc, or clicks somewhere else… like an editable Cell in a tree, table, or list. – VGR Sep 13 '19 at 23:34
  • yes this is exact what I want! A hover selector can cover it ? I'll learn how to use it. – Meeresgott Sep 13 '19 at 23:41
  • I made a point of saying that a hover selector will not do the job properly. – VGR Sep 14 '19 at 00:39
  • Related question: [How do I create an editable Label in javafx 2.2](https://stackoverflow.com/questions/25572398/how-do-i-create-an-editable-label-in-javafx-2-2). – jewelsea Sep 16 '19 at 18:59

1 Answers1

3

You could achieve this without having to replace the node using CSS only. There is one difference though: The text is still moved/clipped as in a fully visible TextField:

group.getStyleClass().add("custom-text-field");
...
scene.getStylesheets().add("/my/stylesheet/location.css");

Unfortunately since :not() is not available in javafx, we have to copy the default look over from modena.css. This allows us to hide the TextField's decorations for TextField, unless the group is hovered or the TextField pressed (changing selection).

Stylesheet

/* "default" style when hovered/pressed */
.custom-text-field>.text-field:hover,
.custom-text-field>.text-field:pressed {
    -fx-background-color: linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
        linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background);

    -fx-highlight-fill: dodgerblue;      
    -fx-highlight-text-fill: white;
    -fx-display-caret: true;
}

.custom-text-field>.text-field:hover:focused,
.custom-text-field>.text-field:pressed:focused {
    -fx-background-color:
        -fx-focus-color,
        -fx-control-inner-background,
        -fx-faint-focus-color,
        linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background);

    -fx-highlight-fill: dodgerblue;      
    -fx-highlight-text-fill: white;
    -fx-display-caret: true;
}

/* Hide everything but text when neither hovered nor pressed */
.custom-text-field>.text-field,
.custom-text-field>.text-field:focused {
    -fx-background-color:
        null, null, null, null;
    -fx-highlight-fill: null;    
    -fx-highlight-text-fill: black;
    -fx-display-caret: false;
}
.custom-text-field:hover>.text-field:focused,
.custom-text-field>.text-field:pressed:focused {
    -fx-background-color:
        -fx-focus-color,
        -fx-control-inner-background,
        -fx-faint-focus-color,
        linear-gradient(from 0px 0px to 0px 5px, derive(-fx-control-inner-background, -9%), -fx-control-inner-background);

    -fx-highlight-fill: dodgerblue;      
    -fx-highlight-text-fill: white;
    -fx-display-caret: true;
}

.custom-text-field>.text-field,
.custom-text-field>.text-field:focused {
    -fx-background-color:
        null, null, null, null;
    -fx-highlight-fill: null;    
    -fx-highlight-text-fill: black;
    -fx-display-caret: false;
}

If you want to go with your initial approach, you could simply make the TextField invisible, instead of changing the contents of the group. This way layout is still done for it; it's just not rendered. Furthermore a binding could be used to synchronize text and visiblity:

label.textProperty().bind(textField.textProperty());
label.visibleProperty().bind(textField.visibleProperty().not());

// replace listeners with bindings to hover/pressed
textField.visibleProperty().bind(textField.hoverProperty().or(textField.pressedProperty()));
fabian
  • 80,457
  • 12
  • 86
  • 114
  • I get some errors with this cssfile. Everytime the Method 'derive' is called. The error Message is: Mismatched parameters `([[from to | to ] ,]? [[repeat | reflect] ,]? [, ]+)`. Do you know how to fix them ? - It compiles but the TextField doesn't change appearance. – Meeresgott Sep 14 '19 at 10:08
  • My Bad! I added the styleclass to the Textfield not to the textfield's group! – Meeresgott Sep 14 '19 at 10:23