Статьи

Пользовательский элемент управления JavaFX — часть 3 термостата

Привет, после некоторых обсуждений с моими коллегами, я решил сегодня показать, что подход css — не единственный, который можно использовать для создания пользовательского элемента управления. Конечно, это позволяет предложить некоторую точку расширения внешнего вида, но тот же подход (работа с передачей svand в JavaFX) можно использовать с использованием API кода.

Вот метод графической инициализации, где я заменил код инициализации css (теперь закомментированный) вызовом API объектов JavaFX.

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
private void initGraphcis() {
    // frame = new Region();
    // frame.getStyleClass().setAll("frame");
    frame = new Circle();
    frame.setFill(FRAME_FILL);
 
    shadow = new DropShadow();
    shadow.setBlurType(BlurType.ONE_PASS_BOX);
    shadow.setColor(Color.rgb(0, 0, 0, 0.4));
    frame.setEffect(shadow);
 
    frame1 = new Circle();
    // frame1.getStyleClass().setAll("frame1");
    frame1.setFill(FRAME1_FILL);
    frame1.setStroke(FRAME1_STROKE);
    frame1.setStrokeWidth(2.0);
 
    frame2 = new Circle();
    // frame2.getStyleClass().setAll("frame2");
    frame2.setFill(FRAME2_FILL);
    frame2.setStroke(FRAME2_STROKE);
 
    frame3 = new Circle();
    // frame3.getStyleClass().setAll("frame3");
    frame3.setFill(Color.web("#c44f1a"));
 
    line = new SVGPath();
    // line.getStyleClass().setAll("line");
    line.setContent("M 0.75,1.806272 C 0.75,1.806272 67.422114,-2.659598 118.06708,1.085452 130.59357,2.011752 166.81696,11.039202 185.35089,11.189052 206.02921,11.356252 242.24677,2.052122 255.84883,1.085452 304.58057,-2.377808 372.89963,1.806272 372.89963,1.806272");
    line.setFill(Color.web("#ffffff00"));
    line.setStroke(Color.web("#4d4d4d"));
    line.setStrokeWidth(1.5);
 
    line1 = new SVGPath();
    // line.getStyleClass().setAll("line1");
    line1.setContent("M 0.75,1.806272 C 0.75,1.806272 67.422114,-2.659598 118.06708,1.085452 130.59357,2.011752 166.81696,11.039202 185.35089,11.189052 206.02921,11.356252 242.24677,2.052122 255.84883,1.085452 304.58057,-2.377808 372.89963,1.806272 372.89963,1.806272");
    line.setFill(Color.web("#ffffff00"));
    line.setStroke(Color.web("#141414"));
    line.setStrokeWidth(1.5);
 
    lightEffect = new Ellipse();
    lightEffect.setFill(Color.rgb(255, 255, 255, 0.7));
    lightEffect.setEffect(new BoxBlur(90, 90, 5));
    lightEffect.setCache(true);
 
    getChildren().setAll(frame, frame1, frame2, frame3, line, line1, lightEffect );
    }

И управление размером узлов осуществляется следующим образом (в любом случае то же самое должно быть сделано для подхода css).

01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
private void resize() {
    size = getWidth() < getHeight() ? getWidth() : getHeight();
    // frame.setPrefSize(size, size);
    frame.setRadius(size / 2.0);
    frame.setTranslateX(size / 2.0);
    frame.setTranslateY(size / 2.0);
 
    frame1.setRadius(frame1Ratio * size / 2.0);
    frame1.setTranslateX(size / 2.0);
    frame1.setTranslateY(size / 2.0);
    shadow.setOffsetX(size * shadowXOffset);
    shadow.setOffsetY(size * shadowYOffset);
    shadow.setRadius(size * shadowSizeOffset);
    shadow.setSpread(0.099);
 
    frame2.setRadius(frame2Ratio * size / 2.0);
    frame2.setTranslateX(size / 2.0);
    frame2.setTranslateY(size / 2.0);
 
    frame3.setRadius(frame3Ratio * size / 2.0);
    frame3.setTranslateX(size / 2.0);
    frame3.setTranslateY(size / 2.0);
 
    final double scaleRatio = size / initialSize;
    line1.setScaleX(scaleRatio);
    line1.setScaleY(scaleRatio);
    final double lineWidth = line1.getBoundsInLocal().getWidth();
    line1.setTranslateX(size / 2.0 - lineWidth / 2.0);
    line1.setTranslateY(size * 408.72054 / initialSize);
 
    line.setScaleX(scaleRatio);
    line.setScaleY(scaleRatio);
    line.setTranslateX(size / 2.0 - lineWidth / 2.0);
    line.setTranslateY(size * 410.08419 / initialSize);
 
    lightEffect.setRotate(lightEffectRotate);
    lightEffect.setTranslateX(lightEffectXRatio * size);
    lightEffect.setTranslateY(lightEffectYRatio * size);
    lightEffect.setRadiusX(lightEffectXRadiusRatio * size);
    lightEffect.setRadiusY(lightEffectYRadiusRatio * size);
    }

Следующим шагом будет смешать два подхода, чтобы предложить пользователям оба метода работы. Одни смогут использовать подход css для настройки представления Nest, другие смогут использовать подход API хорошего кода. Это позволит мне увидеть, как влияют на код (тяжело или не смешивать оба подхода), и если я сделаю выбор между CSS и API кода, прежде чем идти дальше, чтобы сохранить мой код как можно более простым.