有时候我会用JavaFX的TitledPane来区分UI中的不同部分,像这样。
TitledPane tp1 = new TitledPane();
tp1.setCollapsible(false);
TitledPane tp2 = new TitledPane();
tp2.setCollapsible(false);
通过setCollapsible()
这个函数,让TitledPane不可折叠,然后用一个VBox把它们排好。
但是当我们把鼠标移动到TitledPane的标题栏上时,标题栏的背景颜色还是会变化,这就会给用户一种可以点击的错觉。经过一波操作之后,我发现可以通过修改TitledPane的css来解决这个问题。
tp1.setStyle("-fx-hover-base: -fx-base;");
解释:JavaFX默认使用的css文件叫做modena.css,存放在com.sun.javafx.scene.control.skin.modena包中,在这个css文件中关于TitledPane的部分为
/*******************************************************************************
* *
* TitledPane *
* *
******************************************************************************/
.titled-pane {
-fx-text-fill: -fx-text-base-color;
}
.titled-pane:focused {
-fx-color: -fx-base;
}
.titled-pane > .title {
-fx-background-color:
linear-gradient(to bottom,
derive(-fx-color,-15%) 95%,
derive(-fx-color,-25%) 100%
),
-fx-inner-border, -fx-body-color;
-fx-background-insets: 0, 1, 2;
-fx-background-radius: 3 3 0 0, 2 2 0 0, 1 1 0 0;
-fx-padding: 0.3333em 0.75em 0.3333em 0.75em; /* 4 9 4 9 */
}
/* alternative focus using the ring around the entire title area */
/*.titled-pane:focused > .title {
-fx-background-color: -fx-faint-focus-color, -fx-focus-color, -fx-inner-border, -fx-body-color;
-fx-background-insets: 0, 0.7, 2, 3;
}*/
/* focus purely on the arrow */
.titled-pane:focused > .title > .arrow-button > .arrow {
-fx-background-color: -fx-focus-color, -fx-mark-color;
-fx-background-insets: -1, 0;
-fx-effect: dropshadow(two-pass-box , -fx-focus-color, 5, 0.2 , 0, 0);
}
.titled-pane > .title > .arrow-button {
-fx-background-color: null;
-fx-background-insets: 0;
-fx-background-radius: 0;
-fx-padding: 0.0em 0.583em 0.0em 0.0em; /* 0 7 0 0 */
}
.titled-pane > .title > .arrow-button > .arrow {
-fx-background-color: -fx-mark-highlight-color, -fx-mark-color;
-fx-background-insets: 1 0 -1 0, 0;
-fx-padding: 0.25em 0.3125em 0.25em 0.3125em; /* 3 3.75 3 3.75 */
-fx-shape: "M 0 0 h 7 l -3.5 4 z";
}
.titled-pane > .title:hover {
-fx-color: -fx-hover-base;
}
/* alternative content using a border and a grad to transparent background - why should TitledPane content have a colour? */
.titled-pane > *.content {
-fx-border-color: -fx-box-border;
-fx-border-insets: -1 0 0 0;
-fx-background-color: linear-gradient(from 0px 0px to 0px 5px, derive(-fx-background, -6%), -fx-background);
}
其中的高亮部分便是用来实现鼠标悬浮功能的。-fx-hover-base是一个在前文中定义好的颜色设置,内容如下
-fx-hover-base: ladder(
-fx-base,
derive(-fx-base,20%) 20%,
derive(-fx-base,30%) 35%,
derive(-fx-base,40%) 50%
);
我没有继续深究-fx-base
是什么样子,尝试了一下-fx-hover-base: -fx-base
,奈斯,问题解决。
之前的代码有一个弊端,就是会让这个TitledPane中间的所有按钮也失去悬浮效果。为了解决这个问题,我又搞出了下面的代码。
Platform.runLater(() -> tp1.lookup(".title").setStyle("-fx-hover-base: -fx-base"));
Platform.runLater()
是让参量中的lambda表达式在程序跑起来之后再在UI线程执行,lookup()
函数会找到与参数中的css选择器对应的Node,在这个例子里就是标题栏所对应的HBox。然后我们对这个标题栏应用css,就不会影响TitledPane内部的东西了。当然如果你在标题栏放按钮还是会有问题,但是这种情况我暂时不考虑。
另一种解决方法就是在整个程序的css文件加上.titled-pane.static > .title:hover { -fx-color: -fx-base; }
然后再用tp1.getStyleClass().add("static");
给TitledPane标记为对应的css类。这样最直接。
JavaFX的很多问题都可以通过修改css来解决,之后可能会深入了解一下。