繁体   English   中英

如何在 JavaFX 中为 slider 的部分着色

[英]How to color portion of a slider in JavaFX

我正在创建一个视频播放器,我只想为 slider 中的一部分(具有自定义值)着色,如下所示:

在此处输入图像描述

我能怎么做?

到目前为止,我已经为整个条形图着色,但我不能只为不同的部分着色:

            StackPane trackPane = (StackPane) seekSlider.lookup(".track");
            trackPane.setStyle("-fx-background-color: #e5e5e5");

我建议您使用线性渐变,我认为这些可以解决您的问题:

-fx-background-color: linear-gradient(from 30% 30% to 23% 30%, repeat,  #e9967a 62%, #ff8c00 88%);

有关更多信息,您可以查看文档: https://docs.oracle.com/javafx/2/api/javafx/scene/doc-files/cssref.html

根据我对这个问题的评论,这里有一些代码可以解决问题。 只需稍微修改 Slider 的“轨道”元素的样式即可使其透明,然后 rest 就位。

顺便说一句:这是 Kotlin,但您应该能够弄清楚它是如何工作的,如果您有任何疑问,我可以通过一些解释更新它:

class FancySlider : Application() {
   override fun start(stage: Stage) {
      stage.scene = Scene(createContent()).apply {
         FancySlider::class.java.getResource("/css/default.css")?.toString()?.let { stylesheets += it }
      }
      stage.show()
   }

   private fun createContent(): Region {
      val stackPane = StackPane().apply {
         val slider = Slider().apply {
            minWidth = 300.0
            styleClass += "fancy-slider"
         }
         val pane = Pane().apply {
            val heightAdjust = 8.0
            val widthAdjust = 10.0
            maxHeightProperty().bind(slider.heightProperty().subtract(heightAdjust))
            minHeightProperty().bind(slider.heightProperty().subtract(heightAdjust))
            maxWidthProperty().bind(slider.widthProperty().subtract(widthAdjust))
            minWidthProperty().bind(slider.widthProperty().subtract(widthAdjust))
            children += createRectangle(this.widthProperty(), 0.43, 0.08)
            children += createRectangle(this.widthProperty(), 0.12, 0.15)
            children += createRectangle(this.widthProperty(), 0.75, 0.03)
         }
         children += listOf(pane, slider)
         minHeight = 60.0
         padding = Insets(20.0)
      }
      return stackPane
   }

   fun createRectangle(sliderWidthProperty: ReadOnlyDoubleProperty, startPos: Double, duration: Double) = Rectangle(1.0, 7.0).apply {
      layoutXProperty().bind(sliderWidthProperty.multiply(startPos))
      widthProperty().bind(sliderWidthProperty.multiply(duration))
      fill = Color.DARKBLUE
      styleClass += "fancy-slider-rectangle"
   }
}

fun main() {
   Application.launch(FancySlider::class.java)
}

CSS 看起来像这样:

.fancy-slider .track {
    -fx-background-color: transparent;
    -fx-border-color: derive(-fx-text-box-border, -10%);
    -fx-background-insets: 2;
    -fx-border-radius: 0.25em;
    -fx-background-radius: 0.25em
    -fx-padding: 0.25em; /* 3 */
}

.fancy-slider-rectangle {
  -fx-arc-width: 6.0;
  -fx-arc-height: 6.0;
}

一些注意事项:

  1. 这仅适用于水平滑块,您必须为垂直 Slider 重新处理它。

  2. Pane 的宽度和高度绑定是通过硬编码调整设置的,我不确定如果您能以某种方式更改 Slider 的高度会发生什么。

  3. StackPane 使所有内容都很好地排列,因为它默认居中,只要您获得正确的 Pane 高度和宽度就应该很好地对齐。

  4. 您可以将其实现为自定义 Node 并公开一个 addRectangle() 方法,该方法可以很好地处理 Slider 对其值的转换。

无论如何,它看起来像这样:

在此处输入图像描述

如果您不是很在意弯曲的高光,下面是您可以尝试的一种方法。 这与@Nina Koninckx 建议的相同。

总体思路是,我们使用线性渐变色标绘制轨道颜色。

假设默认轨道颜色为white ,您需要用blue突出显示部分(50%-70% 和 80%-90%)。 您使用百分比值定义所有单独的部分。 喜欢

  • 白色 50%(默认从 0% 开始,因此无需指定)
  • 蓝色 50%, 蓝色 70%,
  • 白色 70%, 白色 80%,
  • 蓝色 80%, 蓝色 90%,
  • 白色 90%,白色 100%

结合所有,线性渐变样式将是这样的:

linear-gradient(from 0% 0% to 100% 0% , white 50% , blue 50% , blue 70% , white 70% , white 80% , blue 80% , blue 90% , white 90% , white 100% )

然后我们在 CSS 中为 slider 创建一个变量(假设 -track -track-color ),并在 java 代码中更新该变量。

下面是示例的快速演示:

import javafx.application.Application;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Slider;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class SliderStylingDemo extends Application {
    @Override
    public void start(Stage primaryStage) throws Exception {
        Slider slider = new Slider(0, 100, 30) ;
        slider.setMajorTickUnit(10);
        slider.setShowTickMarks(true);
        slider.setShowTickLabels(true);
        String style = "-track-color: linear-gradient(from 0% 0% to 100% 0% , white 50% , blue 50% , blue 70% , white 70% , white 80% , blue 80% , blue 90% , white 90% , white 100% )";
        slider.setStyle(style);
        VBox root = new VBox(slider);
        root.setAlignment(Pos.CENTER);
        root.setPadding(new Insets(20));
        root.setSpacing(20);
        Scene scene = new Scene(root, 600, 100);
        scene.getStylesheets().add(getClass().getResource("sliderstyle.css").toExternalForm());
        primaryStage.setScene(scene);
        primaryStage.setTitle("Slider Styling Demo");
        primaryStage.show();
    }
}

CSS 代码:

.slider {
    -track-color: -fx-control-inner-background;
}
.slider .track {
      -fx-background-color:
          -fx-shadow-highlight-color,
          linear-gradient(to bottom, derive(-fx-text-box-border, -10%), -fx-text-box-border),
          -track-color;
}

在此处输入图像描述

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM