Как указано here в контексте Swing, дизайн GUI часто использует observer pattern. Часто используемая схема, предписанная в EventListenerList
, есть ли пример Java FX, такой как Converter
, который фокусируется на самом шаблоне?Использование шаблона наблюдателя в дизайне GUI JavaFX
ответ
Как указано here, архитектура JavaFX имеет тенденцию способствовать связыванию элементов GUI через классы, реализующие интерфейс Observable
. С этой целью Ирина Федорцова адаптировала оригинал Converter
к JavaFX в главе 5 JavaFX для разработчиков Swing: Implementing a Swing Application in JavaFX.
Я кратко изложил ниже программы, обновления до Java 8 и устраняя зависимость от ныне deprecated builder API. В приведенной ниже вариации,
А
DoubleProperty
имениmeters
функций какObservable
модель приложения.Экземпляры
Control
, такие, какTextField
,ComboBox
иSlider
, каждая функция в качестве зрения от модели, а также обеспечивает способ для пользователя, чтобы управления взаимодействия.В
ConversionPanel
,InvalidationListener
добавлен кComboBox
обновляетTextField
вид из модели по мере необходимости, чтобы отразить текущий выбранныйUnit
; аналогичный слушатель, добавленный вTextField
, обновляет модель сам по себе, как пользователь.То же модели разделяются между экземпляров
ConversionPanel
по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();
}
}
- 1. Неправильное использование шаблона наблюдателя?
- 2. Использование шаблона наблюдателя с EJB и AJAX
- 3. Избегание dynamic_cast в дизайне GUI
- 4. Предложение шаблона наблюдателя
- 5. О прототипе шаблона наблюдателя
- 6. стратегия для шаблона наблюдателя?
- 7. образец класса шаблона наблюдателя
- 8. Класс шаблона наблюдателя (JAVA)
- 9. Перегрузка шаблона наблюдателя
- 10. pygame - ошибка шаблона наблюдателя
- 11. Реализация шаблона наблюдателя в C++
- 12. Спецификация шаблона в доменном дизайне
- 13. Реализация шаблона наблюдателя с событиями
- 14. Реализация шаблона наблюдателя с @Dependent
- 15. Использование наблюдателя в двигателе
- 16. Использование наблюдателя в Fragment
- 17. JavaFx включает несколько gui в main gui
- 18. Выровнять ярлык в дизайне стильного GUI
- 19. Назначение guihandles в программном дизайне GUI Matlab
- 20. Использование шаблона наблюдателя для удаления наблюдателя при удалении объекта в Python
- 21. Реализация шаблона наблюдателя над RMI
- 22. Дизайн шаблона наблюдателя против «Слушателей»
- 23. Реализация шаблона MVC и наблюдателя
- 24. Образец наблюдателя против шаблона реактора
- 25. Основная реализация наблюдаемого шаблона наблюдателя
- 26. Обновить вид из шаблона наблюдателя
- 27. модульное тестирование для шаблона наблюдателя
- 28. Обертка шаблона наблюдателя с Cython
- 29. Реализация шаблона наблюдателя с winforms
- 30. JavaFX Использование шаблона Netbeans Приложение Javfx FML