了解Java的Observable和JavaFX的Observable
作者:admin
分类:PHP, JAVA, .NET技术
时间:2016-08-18 16:38:33
点击量:1677
Observable及Observer对象在执行Java的模型 - 视图 - 控制器的结构具有重要作用。 他们通常在系统中使用,有一个对象需要通知其他相关的一些重要变化的发生。Observable是一个类和Observer是一个接口。 它们可以在java.util包内作为Java核心工具框架的一部分被找到。 然而,在JavaFX中找到Observable的实体是一个接口,并且是javafx.beans包的一部分。 其基本的思路是一样的,但在执行会有变化。
Java的Observable和Observer
扩展类可以在程序的其他部分由其他感兴趣的类进行观察。登记类被通知,只要任何变化被触发在可被观察的类中,而被观察到的类被注册。 这是可观察的类和观察类之间的关系。 Observer类只是Observer接口的实现。 该Observer接口提供了update()方法,当一个观察者被通知在所观察到对象中的变化。
如果它已经改变了,想要被观察到的一个类,或者扩展Observable类必须调用setChanged方法,必须通过调用notifyObservers()方法触发通告。 这反过来又调用观察者类的update()方法。 然而,如果一个对象调用notifyObserver()方法,而不调用setChanged()方法,没有动作会发生。 因此,可观察到的对象必须调用setChange()方法之前去调用notifyObservers()方法以针对任何事件变化。 该命令随后将无缝调用观察者类的update()方法。
一个简单的举例
该举例给出了如何观测和可观测实现的观点。 该PeopleObserver类执行Observer接口,以及PeopleObservable类扩展Observable类。 PeopleObservable对象被监测,通过由PeopleObserver类定义的可观察到的的列表进行。 一旦在观察的类出现一个变化时,它通知观察员作为观察对象被添加到列表中的addObserver()方法。 每次调用notifyObserver()触发调用观察者随后的update()方法。
package org.mano.example;
import java.util.Observable;
import java.util.Observer;
public class PeopleObserver implements Observer {
private String name;
public PeopleObserver() {
super();
}
public PeopleObserver(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
System.out.println(name + " got " +
((Integer) arg).intValue() + " winks");
}
}
package org.mano.example;
import java.util.Observable;
public class PeopleObservable extends Observable {
private String name;
public PeopleObservable() {
super();
}
public PeopleObservable(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
void wink(int count) {
setChanged();
notifyObservers(count);
}
}
package org.mano.example;
import java.util.Random;
public class Main {
public static void main(String[] args) {
PeopleObservable damsel = new PeopleObservable("Minnie");
PeopleObserver mickey = new PeopleObserver("Mickey");
PeopleObserver donald = new PeopleObserver("Donald");
PeopleObserver guffy = new PeopleObserver("Goofy");
damsel.addObserver(mickey);
damsel.addObserver(donald);
damsel.addObserver(goofy);
System.out.println("There are " + damsel.countObservers()
+ " observers of "
+ damsel.getName());
Random r = new Random();
damsel.wink(r.nextInt(10));
}
}
JavaFX的Observable
JavaFX的Observable接口是许多容器类的基本接口和JavaFX收集框架的接口。 例如,ObservableList和ObservableArray是两个基本Observable接口的常见实现。 Java核心集API已经包含了许多有用的容器类来代表通用的数据结构列表,设置和地图。 例如,java.util.ArrayList是一个可重组的数组实现的java.util.List接口以包含对象的列表。 然而,它们不能无缝的工作,当同步的功能被要求在列表模型和在GUI场景视图组件之间。
在JavaFX之前,Swing开发人员依靠ArrayList包含对象的列表,并随后以列表如UI控制,如JList来显示它们。 但是,ArrayList是太普通了,并且没有内置牢记同步的要求,当与视图组件相关联时。 其结果是,相当困难进行更新,添加,或从型号列表中删除对象,并同时反映视图组件的变化。 为了克服这个问题,JavaFX使用可观察到的接口及其实现,如ObserverList。
由于ObservableList坚持MVC的观察到的和观察范式的规则,如它提供的通知关于任何从型号列表对象中选择更新,添加或删除感兴趣的观察者,它成为一个事实上的容器使用任何列出了JavaFX的舞台。 在这里,在该模型数据表示和图被无缝同步。 JavaFX的ObserverList典型的应用于UI控件,如ListView和TableView。 让我们通过一个简单的例子来看看如何实际使用ObservableList。
这是一个简单举例,在此数据列表显示在被称为ListView 的JavaFXUI控制内。 所使用的隐含数据模型是ObservableList。 有两个ListView控制用于将数据从一个控制移动到另外一个,以及两个ObservableLists代表底层模型的数据。 数据不仅在视觉上从一个控制移动到另一个,但它也从一个模型移动到另一个。 这使得视图和模型层之间实现同步数据转换。
package org.mano.example;
import javafx.application.Application;
import javafx.collections.*;
import javafx.event.*;
import javafx.geometry.*;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.stage.Stage;
public class ObservableListdemo extends Application {
private final ObservableListcountries;
private final ObservableListcapitals;
private final ListViewcountriesListView;
private final ListViewcapitalsListView;
private final Button leftButton;
private final Button rightButton;
public ObservableListdemo() {
countries = FXCollections.observableArrayList("Australia",
"Vienna", "Canberra", "Austria", "Belgium","Santiago",
"Chile", "Brussels", "San Jose", "Finland", "India");
countriesListView = new ListView<>(countries);
capitals = FXCollections.observableArrayList("Costa Rica",
"New Delhi", "Washington DC", "USA", "UK", "London",
"Helsinki", "Taiwan", "Taipei", "Sweden", "Stockholm");
capitalsListView = new ListView<>(capitals);
leftButton = new Button(" < ");
leftButton.setOnAction(new ButtonHandler());
rightButton = new Button(" > ");
rightButton.setOnAction(new ButtonHandler());
}
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Arrange Countries and Capitals");
BorderPane root = new BorderPane();
Scene scene = new Scene(root, 500, 450);
GridPane gridPane = new GridPane();
gridPane.setPadding(new Insets(5));
gridPane.setHgap(10);
gridPane.setVgap(10);
ColumnConstraints column1 = new ColumnConstraints(150, 150,
Double.MAX_VALUE);
ColumnConstraints column2 = new ColumnConstraints(50);
ColumnConstraints column3 = new ColumnConstraints(150, 150,
Double.MAX_VALUE);
column1.setHgrow(Priority.ALWAYS);
column3.setHgrow(Priority.ALWAYS);
gridPane.getColumnConstraints().addAll(column1, column2, column3);
Label countriesLabel = new Label("Countries");
GridPane.setHalignment(countriesLabel, HPos.CENTER);
gridPane.add(countriesLabel, 0, 0);
Label capitalsLabel = new Label("Capitals");
GridPane.setHalignment(capitalsLabel, HPos.CENTER);
gridPane.add(capitalsLabel, 2, 0);
gridPane.add(countriesListView, 0, 1);
gridPane.add(capitalsListView, 2, 1);
VBox vbox = new VBox();
vbox.getChildren().addAll(rightButton, leftButton);
gridPane.add(vbox, 1, 1);
root.setCenter(gridPane);
GridPane.setVgrow(root, Priority.ALWAYS);
primaryStage.setScene(scene);
primaryStage.show();
}
private class ButtonHandler implements EventHandler{
@Override
public void handle(ActionEvent event) {
if (event.getSource().equals(leftButton)) {
String str = capitalsListView.getSelectionModel()
.getSelectedItem();
if (str != null) {
capitals.remove(str);
countries.add(str);
}
} else if (event.getSource().equals(rightButton)) {
String str = countriesListView.getSelectionModel()
.getSelectedItem();
if (str != null) {
countriesListView.getSelectionModel().clearSelection();
countries.remove(str);
capitals.add(str);
}
}
}
}
图形1.' 前面的代码输出
结论
Observable类和Observer接口提供了一个非常宝贵的推动力来实现基于模型 - 视图 - 控制器模式的复杂程序架构。 实际上,可观察到的和观察者概念不仅仅是MVC的。 一个很好理解的基本概念可以帮助创建更复杂的Java代码。 如果观察者和可观察到的部分Java核心程序框架展示原则,JavaFX可观察到的类和接口恰好表明这些原则如何能投入工作。
原文:
http://www.developer.com/java/data/understanding-java-observable-and-javafx-observable.html