悬停效果对所选文本

时间:2015-03-26 23:30:32

标签: javafx javafx-2 javafx-8

我遇到了一个问题,我无法通过悬停效果解决问题。

Text t1 = new Text();

Text t2 = new Text();

Text t3 = new Text();

Text t4 = new Text();

当我选择一个文本时,我想将背景更改为灰色。但是,我不知道如何解决的棘手问题是我如何从之前选择的文本中删除背景颜色?它应该像Toggle按钮一样工作,但是有Text。

2 个答案:

答案 0 :(得分:5)

Text对象是Shape,它定义了一组比控件更有限的样式属性;例如,它没有背景。如果您想在UI中设置文本样式,则应该更喜欢Label而不是Text。另一种选择是将Text包裹在某种Region(例如StackPane)中并将背景应用于该区域。这会使你的代码变得复杂一点。

以下是一些解决方案:第一个不使用CSS并使用Label,只需根据需要设置样式。第二种方法使用不同的方法,您可以使用ToggleButton中已定义的“选择行为”,但使切换按钮看起来像纯文本。这可能是最好的解决方案,因为它使用现有功能,只是使用CSS更改外观。第三个是第一个的改进,你可以将样式分解为CSS,但是自己实现选择。

解决方案1:所有Java:

创建一个属性来存储所选文本:

ObjectProperty<Label> selectedText = new SimpleObjectProperty<>();

使用属性注册侦听器以重置先前所选文本的样式并设置新选定文本的样式:

selectedText.addListener((obs, oldSelectedText, newSelectedText) -> {
    if (oldSelectedText != null) {
        oldSelectedText.setStyle("");
    }
    if (newSelectedText != null) {
        newSelectedText.setStyle("-fx-background-color: lightgray;");
    }
});

为每个文本注册鼠标侦听器,使它们在单击时成为所选文本:

Label t1 = new Label("One");

Label t2 = new Label("Two");

Label t3 = new Label("Three");

Label t4 = new Label("Four");

Stream.of(t1, t2, t3, t4).forEach(t -> 
    t.setOnMouseClicked(event -> selectedText.set(t)));

解决方案2:使用切换按钮设置为纯文本格式:

这实际上是我首选的解决方案:使用已为ToggleButton定义的选择行为,并使用CSS更改切换按钮的外观。

ToggleButton t1 = new ToggleButton("One");
ToggleButton t2 = new ToggleButton("Two");
ToggleButton t3 = new ToggleButton("Three");
ToggleButton t4 = new ToggleButton("Four");

ToggleGroup tg = new ToggleGroup();
Stream.of(t1, t2, t3, t4).forEach(t -> t.setToggleGroup(tg));

使用以下外部样式表:

.toggle-button, .toggle-button:selected , .toggle-button:hover,
.toggle-button:armed, .toggle-button:focused, .toggle-button:selected:focused {

    -fx-color: -fx-base ;
    -fx-background-color: transparent ;
    -fx-background-insets: 0 ;
    -fx-background-radius: 0 ;
    -fx-padding: 0 ;
    -fx-text-fill: -fx-text-background-color ;
}

.toggle-button:selected, .toggle-button:selected:focused {
    -fx-background-color: lightgray ;
}

解决方案3:带有css伪类的Java:

在第一个解决方案中使用所选文本的属性,但直接操作样式类而不是样式:

ObjectProperty<Label> selectedText = new SimpleObjectProperty<>();
PseudoClass selected = PseudoClass.getPseudoClass("selected");

selectedText.addListener((obs, oldSelectedText, newSelectedText) -> {
    if (oldSelectedText != null) {
        oldSelectedText.pseudoClassStateChanged(selected, false);
    }
    if (newSelectedText != null) {
        newSelectedText.pseudoClassStateChanged(selected, true);
    }
});

创建文本对象,在其上设置样式类,并像以前一样注册鼠标侦听器:

Label t1 = new Label("One");

Label t2 = new Label("Two");

Label t3 = new Label("Three");

Label t4 = new Label("Four");

Stream.of(t1, t2, t3, t4).forEach(t -> 
    t.setOnMouseClicked(event -> selectedText.set(t)));

然后使用外部样式表,并将所需的样式应用于所选文本:

.label:selected {
    -fx-background-color: lightgray ;
}

使用这些解决方案中的任何一种,您都可以根据需要编辑样式。

答案 1 :(得分:1)

首先创建一个css类。

.text:hover { 
    -fx-fill: blue;   
}

.text:pressed { 
   -fx-fill: blue;   
}

.text-selected { 
    -fx-fill: blue;
}

然后创建一个全局变量。

Text selectText;

然后添加:

scene.getStylesheets().add(Teste.class.getResource("text.css").toExternalForm();

t1.getStyleClass().add("text");
t2.getStyleClass().add("text");

t1.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent arg0) {
        if (selectText != null) {
            selectText.getStyleClass().remove("text-selected");
        }
        t1.getStyleClass().add("text-selected");
        selectText = t1;
    }
});

t2.setOnMouseClicked(new EventHandler<MouseEvent>() {
    @Override
    public void handle(MouseEvent arg0) {
        if (selectText != null) {
            selectText.getStyleClass().remove("text-selected");
        }
        t2.getStyleClass().add("text-selected");
        selectText = t2;
    }
});