javafx Application Logic浅析

1.Scene Graph体系结构浅析

javafx以tree的形式组织nodes,每一个node就是一个control,即UI组件。

node分为leaf node与branch node, root node。

scene体系中最关键的类:

Scene:代表包含所有UI组件的顶级容器

Node:是一个抽象类,代表UI组件的基类

Parent:是一个抽象类,代表branch node的基类。

2.Properties与Binding

javafx的Property机制是基于javabean的,但是相比javabean作了一定的扩展。

javafx的property是java基元类型的包装。并且内嵌的绑定机制,我们可以绑定多个监听器到这个property,并由这个property负责通知他们。

秒懂javafx中property的规范:

final,property后缀,get,set与外界交互均为java基元类型。

package propertydemo;

import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;

class Bill {

    // Define a variable to store the property
    private DoubleProperty amountDue = new SimpleDoubleProperty();

    // Define a getter for the property‘s value
    public final double getAmountDue(){return amountDue.get();}

    // Define a setter for the property‘s value
    public final void setAmountDue(double value){amountDue.set(value);}

     // Define a getter for the property itself
    public DoubleProperty amountDueProperty() {return amountDue;}

}

理解监听机制:

 Bill electricBill = new Bill();

       electricBill.amountDueProperty().addListener(new ChangeListener(){
        @Override public void changed(ObservableValue o,Object oldVal,
                 Object newVal){
             System.out.println("Electric bill has changed!");
        }
      });

      electricBill.setAmountDue(100.00);

Bindings与property的关系

property是Bindings类的依赖,property的变化会影响到它的Bindings:

IntegerProperty num1 = new SimpleIntegerProperty(1);
        IntegerProperty num2 = new SimpleIntegerProperty(2);
        NumberBinding sum = num1.add(num2);
       //也可以是这种方式:NumberBinding sum = Bindings.add(num1,num2);

        System.out.println(sum.getValue());
        num1.set(2);
        System.out.println(sum.getValue());

Observable,ObservableValue,InvacationListener,ChangeListener


Observable与ObservableValue接口负责fire触发property改变通知。Observable触发InvacationListener,而ObservableValue负责触发ChangeListener.

我们知道几乎所有的javafx.beans.property包中的类都实现了ObservableValue接口,而ObservableValue接口又是Observable的子接口。所以每一个property类又是一个Observable(Value).

几点需要注意的:

Observable支持lazy compute懒提交。也就是当值改变之后,不会立即提交计算,只有当需要时在进行compute。

所以当值改变之后,该property就会处于invalid状态,会触发InvacationListener.

但是假如你的ObservableValue对象,添加的ChangeListener,这个lazy compute就会失效。

   NumberBinding total =
          Bindings.add(bill1.amountDueProperty().add(bill2.amountDueProperty()),
              bill3.amountDueProperty());
        total.addListener(new InvalidationListener() {

        @Override public void invalidated(Observable o) {
                System.out.println("The binding is now invalid.");
            }
        });

        // First call makes the binding invalid
        bill1.setAmountDue(200.00);

        // The binding is now invalid
        bill2.setAmountDue(100.00);
        bill3.setAmountDue(75.00);

        // Make the binding valid...
        System.out.println(total.getValue());

自定义Bindings:

当实现自定义Bindings时我们需要在构造器中super.bind(),同时覆盖父类的computeValue()已返回现在的值。你不需要判断是否invalid,父类会帮你做这些。

 final DoubleProperty a = new SimpleDoubleProperty(1);
        final DoubleProperty b = new SimpleDoubleProperty(2);
        final DoubleProperty c = new SimpleDoubleProperty(3);
        final DoubleProperty d = new SimpleDoubleProperty(4);

        DoubleBinding db = new DoubleBinding() {

            {
                super.bind(a, b, c, d);
            }

            @Override
            protected double computeValue() {
                return (a.get() * b.get()) + (c.get() * d.get());
            }
        };

        System.out.println(db.get());
        b.set(3);

3.javaFx Collections

javafx Collections是基于java基础类库中的集合框架的,只不过是结合了javafx中的Observable,使之成为可以观察变化的集合。便于javafx的模型数据维护。

javafx.collections包中的主要类:

接口:

ObservableList,             ObservableMap :被监听者集合

ListChangeListener  MapChangeListener
 监听器集合

类:

FXCollections:它是一个基于java.util.Collections的一比一复制品。只不过是做了一层javafx的本地化。但是它是最重要的类了,一切ObservableList/Map均由它的工厂方法产生。

ListChangeListener.Change              MapChangeListener.Change:包含者列表或map中的所有变化。可以进行迭代操作。

Change类包含的变化种类有:排序变化,添加删除变化,更新变化。并有对应的判断方法。

  // Use Java Collections to create the List.
        List<String> list = new ArrayList<String>();

        // Now add observability by wrapping it with ObservableList.
    ObservableList<String> observableList = FXCollections.observableList(list);
        observableList.addListener(new ListChangeListener() {

            @Override
            public void onChanged(ListChangeListener.Change change) {
                System.out.println("Detected a change! ");
            }
        });

        // Changes to the observableList WILL be reported.
        // This line will print out "Detected a change!"
        observableList.add("item one");
// This code will work with any of the previous ObservableList examples
observableList.addListener(new ListChangeListener() {

@Override
public void onChanged(ListChangeListener.Change change) {
    System.out.println("Detected a change! ");
    while (change.next()) {
        System.out.println("Was added? " + change.wasAdded());
        System.out.println("Was removed? " + change.wasRemoved());
        System.out.println("Was replaced? " + change.wasReplaced());
        System.out.println("Was permutated? " + change.wasPermutated());
        }
    }
});

 ObservableList theList = ...;

 theList.addListener(new ListChangeListener<Item>() {
     public void onChanged(Change<tem> c) {
         while (c.next()) {
             if (c.wasPermutated()) {
                     for (int i = c.getFrom(); i < c.getTo(); ++i) {
                          //permutate
                     }
                 } else if (c.wasUpdated()) {
                          //update item
                 } else {
                     for (Item remitem : c.getRemoved()) {
                         remitem.remove(Outer.this);
                     }
                     for (Item additem : c.getAddedSubList()) {
                         additem.add(Outer.this);
                     }

但你要注意的是对这些集合的操作并不是线程安全的。所以你需要在必要时确保线程安全性。

时间: 2024-10-12 21:29:10

javafx Application Logic浅析的相关文章

JavaFX Application应用实例

下面代码演示的是JavaFX进程命令行参数的实例.大家可以参阅一下. /*原文地址:http://www.manongjc.com/article/134.html */ import java.util.List; import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Group; import javafx.scene.Scene; import javafx.sce

错误: 在类 Main 中找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.application.Application

错误: 在类 Main 中找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args)否则 JavaFX 应用程序类必须扩展javafx.application.Application 出现这种错误的原因其中一种就是 导包时错把其他的String包导入,以至于找不到main(String[ ]  args) 原文地址:https://www.cnblogs.com/mibloom/p/9497357.html

IDEA 开发javafx: error: java:package javafx.application does not exist

1)jdk使用1.8, 1.7中未包含javafx相关内容. 2)确保classpath中加入了javafx包路径. 在“file” --> "project structure" -->"Platform Settings" 下的 "SDKs"选项中,添加dk 正确加载后可以看到: 若是经过上述步骤,问题仍没有解决,在ubuntu16.04下,添加javafx库. 命令为: sudo apt-get install openjfx

eclipse 运行错误:在类XXX中找不到 main 方法, 请将 main 方法定义为: public static void main(String[] args) 否则 JavaFX 应用程序类必须扩展javafx.application.Application

新建了一个类Hello: 代码: 第一次运行报错: 点击关闭该类的界面时出现: 点击是,然后再次打开,可以正确执行,结果为: 这是为什么....

Using JavaFX UI Controls 12 Table View

原文链接地址:http://docs.oracle.com/javafx/2/ui_controls/table-view.htm#CJAGAAEE 在这一章,你将学习如:添加一个表格表.数据填充.编辑表格行等格组件 JavaFx的基本操作. 很多JavaFX SDK API种的类为在表格表单中呈现数据.在JavaFX 应用中对创建表格最重要的是TableView, TableColumn和TableCell这三个类. 你可以通过实现数据模型(data model) 和 实现  单元格工厂(ce

JavaFX上手--第1天

1.第一个JavaFX Application JavaFX 使用Java来制作可视化图形,可以做动画和3D效果,JavaFX从JDK中直接使用. package application; import javafx.application.Application; import javafx.stage.Stage; import javafx.scene.Scene; import javafx.scene.layout.BorderPane; public class Main exten

Using JavaFX UI Controls 18 超链接

原网页地址:http://docs.oracle.com/javafx/2/ui_controls/hyperlink.htm#CIHGADBG 这一章讲述用来将文本转换为超链接的 Hyperlink 组件 Hyperlink 类 是 Labeled 类的另一种形式. 图18-1 展示了默认超链接实现的3中状态 图 18-1 超链接组件的3中状态 创建一个超链接 例 18-1 中展示创建超链接的代码片段 <em>例18-1 典型的超链接 </em>Hyperlink link =

冯斌:JavaFx实例(六)“ShowImage”

javafx.scene.image.Image类的作用是从文件或者网站显示一个图片,例如:new Image("image/us.gif")为图形文件us.gif创建一个Image对象. javafx.scene.image.ImageView是显示图片的node.一个ImageView能从一个Image对象创建.例如: Image image = new Image("image/us.gif"); ImageView imageView = new Image

冯斌:JavaFx实例(七)“ShowFlowPane”

FlowPane将node从左到右水平或从上到下垂直放置在pane中,分别用到Orientation.HORIZONTAL和Orientation.VERTICAL方法. 我们也可以设置node之间的距离,下面的例子演示FlowPane的用法: import javafx.application.Application; import javafx.geometry.Insets; import javafx.scene.Scene; import javafx.scene.control.La