gpt4 book ai didi

swing - 在 JavaFX GUI 设计中利用观察者模式

转载 作者:行者123 更新时间:2023-12-03 15:58:58 30 4
gpt4 key购买 nike

如前所述here在 Swing 环境中,GUI 设计经常使用 observer pattern .经常使用 EventListenerList 中规定的方案,有没有Java FX的例子,比如 Converter ,专注于模式本身?

最佳答案

如前所述here ,JavaFX 体系结构倾向于通过实现 Observable 的类来绑定(bind) GUI 元素。界面。为此,Irina Fedortsova 改编了原版 Converter JavaFX for Swing Developers 第 5 章中的 JavaFX:Implementing a Swing Application in JavaFX .
image
我已经概括了下面的程序,更新到 Java 8并移除对现在 deprecated builder API 的依赖.在下面的变体中,

  • 一个 DoubleProperty 命名为 meters用作应用程序的Observable模型。
  • Control 的实例,如 TextField , ComboBoxSlider ,每个功能都作为模型的 View ,以及为用户提供一种控制交互的方式。
  • ConversionPanel 内, 一个 InvalidationListener添加到 ComboBox更新 TextField根据需要查看模型以反射(reflect)当前选择的 Unit ;一个类似的监听器添加到 TextField在用户键入时更新模型本身。
  • ConversionPanel 的实例之间共享相同的模型由 Slider ,链接 slider 和任何监听模型的控件。
      slider.valueProperty().bindBidirectional(meters);
  • 每个ComboBox还有一个型号, ObservableList ,用户可以从中选择 Unit 的实例.

  • 代码:
    /*
    * Copyright (c) 1995, 2013, Oracle and/or its affiliates. All rights reserved.
    *
    * Redistribution and use in source and binary forms, with or without
    * modification, are permitted provided that the following conditions
    * are met:
    *
    * - Redistributions of source code must retain the above copyright
    * notice, this list of conditions and the following disclaimer.
    *
    * - Redistributions in binary form must reproduce the above copyright
    * notice, this list of conditions and the following disclaimer in the
    * documentation and/or other materials provided with the distribution.
    *
    * - Neither the name of Oracle or the names of its
    * contributors may be used to endorse or promote products derived
    * from this software without specific prior written permission.
    *
    * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
    * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
    * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
    * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
    * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
    * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
    * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
    * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
    * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
    * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
    * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
    */
    package converter;

    /**
    * @see http://docs.oracle.com/javafx/2/swing/port-to-javafx.htm
    */
    public class Unit {

    String description;
    double multiplier;

    Unit(String description, double multiplier) {
    super();
    this.description = description;
    this.multiplier = multiplier;
    }

    @Override
    public String toString() {
    String s = "Meters/" + description + " = " + multiplier;
    return s;
    }
    }
    /*
    * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    */
    package converter;

    /**
    * @see http://docs.oracle.com/javafx/2/swing/port-to-javafx.htm
    */
    import java.text.NumberFormat;
    import javafx.beans.InvalidationListener;
    import javafx.beans.Observable;
    import javafx.beans.property.DoubleProperty;
    import javafx.collections.ObservableList;
    import javafx.scene.control.*;
    import javafx.scene.layout.HBox;
    import javafx.scene.layout.VBox;
    import javafx.util.StringConverter;

    public class ConversionPanel extends TitledPane {

    private static final int MAX = 10000;
    private static final int DIGITS = 3;

    private final TextField textField = new TextField();
    private final Slider slider = new Slider(0, MAX, 0);
    private final ComboBox<Unit> comboBox;
    private NumberFormat numberFormat = NumberFormat.getNumberInstance();
    private DoubleProperty meters;

    {
    numberFormat.setMaximumFractionDigits(DIGITS);
    }

    private InvalidationListener fromMeters = (Observable o) -> {
    if (!textField.isFocused()) {
    textField.setText(numberFormat.format(meters.get() / getMultiplier()));
    }
    };

    private InvalidationListener toMeters = (Observable o) -> {
    if (textField.isFocused()) {
    try {
    Number n = numberFormat.parse(textField.getText());
    meters.set(n.doubleValue() * getMultiplier());
    } catch (Exception ignored) {
    }
    }
    };

    public ConversionPanel(String title, ObservableList<Unit> units, DoubleProperty meters) {
    setText(title);
    setCollapsible(false);
    comboBox = new ComboBox<>(units);
    comboBox.getSelectionModel().select(0);
    comboBox.setConverter(new StringConverter<Unit>() {

    @Override
    public String toString(Unit t) {
    return t.description;
    }

    @Override
    public Unit fromString(String string) {
    throw new UnsupportedOperationException("Not supported yet.");
    }
    });
    setContent(new HBox(new VBox(textField, slider), comboBox));

    this.meters = meters;
    meters.addListener(fromMeters);
    comboBox.valueProperty().addListener(fromMeters);
    textField.textProperty().addListener(toMeters);
    slider.valueProperty().bindBidirectional(meters);
    fromMeters.invalidated(null);
    }

    /**
    * Returns the multiplier for the currently selected unit of measurement.
    */
    public double getMultiplier() {
    return comboBox.getValue().multiplier;
    }
    }
    /*
    * Copyright (c) 2012, 2013 Oracle and/or its affiliates. All rights reserved.
    * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    */
    package converter;

    import javafx.application.Application;
    import javafx.beans.property.DoubleProperty;
    import javafx.beans.property.SimpleDoubleProperty;
    import javafx.collections.FXCollections;
    import javafx.collections.ObservableList;
    import javafx.scene.Scene;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;

    /**
    * @see https://stackoverflow.com/a/31909942/230513
    * @see http://docs.oracle.com/javafx/2/swing/port-to-javafx.htm
    */
    public class Converter extends Application {

    public static void main(String[] args) {
    launch(args);
    }

    private final ObservableList<Unit> metricDistances;
    private final ObservableList<Unit> usaDistances;
    private final DoubleProperty meters = new SimpleDoubleProperty(1);

    public Converter() {
    //Create Unit objects for metric distances, and then
    //instantiate a ConversionPanel with these Units.
    metricDistances = FXCollections.observableArrayList(
    new Unit("Centimeters", 0.01),
    new Unit("Meters", 1.0),
    new Unit("Kilometers", 1000.0));

    //Create Unit objects for U.S. distances, and then
    //instantiate a ConversionPanel with these Units.
    usaDistances = FXCollections.observableArrayList(
    new Unit("Inches", 0.0254),
    new Unit("Feet", 0.3048),
    new Unit("Yards", 0.9144),
    new Unit("Miles", 1609.34));
    }

    @Override
    public void start(Stage stage) {
    stage.setScene(new Scene(new VBox(
    new ConversionPanel("Metric System", metricDistances, meters),
    new ConversionPanel("U.S. System", usaDistances, meters))));
    stage.show();
    }
    }

    关于swing - 在 JavaFX GUI 设计中利用观察者模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31909941/

    30 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com