JavaFX SortedList:监听列表更改和列表项更新事件 [英] JavaFX SortedList: listen the list changes and the list items updated event

查看:237
本文介绍了JavaFX SortedList:监听列表更改和列表项更新事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用案例:


  • 有序的ListView(或TableView)

  • 插入后的插入显示

  • 显示后更新密钥

启动时列表:

添加18后:

更新后:

您可以看到没有任何变化!

As you can see nothing change!

代码:

public final class SortedListTest extends Application {

   @Override
   public void start( Stage stage ) throws Exception {
      final ObservableList<IntegerProperty> il =
         FXCollections.observableArrayList();
      il.add( new SimpleIntegerProperty( 12 ));
      il.add( new SimpleIntegerProperty( 24 ));
      il.add( new SimpleIntegerProperty( 36 ));
      final Button add    = new Button( "Add 18" );
      final Button update = new Button( "Update 24 to 8" );
      final HBox   ctrl   = new HBox( 4.0, add, update );
      final ListView<IntegerProperty> listVw =
         new ListView<>( new SortedList<>( il, (l,r)-> l.get() - r.get()));
      stage.setScene(
         new Scene(
            new BorderPane( listVw, ctrl, null, null, null ), 180, 120 ));
      stage.show();
      add.setOnAction( e -> {
         il.add( new SimpleIntegerProperty( 18 ));
         System.err.println( "--------------" );
         il.stream().forEach( System.err::println );
      });
      update.setOnAction( e -> {
         il.get( 1 ).set( 8 );
         System.err.println( "--------------" );
         il.stream().forEach( System.err::println );
      });
   }

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

控制台:

--------------
IntegerProperty [value: 12]
IntegerProperty [value: 24]
IntegerProperty [value: 36]
IntegerProperty [value: 18]
--------------
IntegerProperty [value: 12]
IntegerProperty [value: 8]
IntegerProperty [value: 36]
IntegerProperty [value: 18]

我们可以看到模型已正确更新但不是视图,为什么?

(在接受James_D非常简单但很好的答案之后:)

这是一个完整的示例,其中包含用于说明解决方案的属性记录:

Here is a full sample with a record of properties to illustrate the solution:

public final class SortedListTest extends Application {

   class Record {

      final IntegerProperty _key   = new SimpleIntegerProperty();
      final StringProperty  _value = new SimpleStringProperty();

      Record( int k, String v ) {
         _key  .set( k );
         _value.set( v );
      }

      @Override
      public String toString() {
         return "Key = " + _key.get() + ", value = " + _value.get();
      }
   }

   @Override
   public void start( Stage stage ) throws Exception {
      final ObservableList<Record> il =
         FXCollections.observableArrayList(
            rec -> new Observable[]{ rec._key });
      il.add( new Record( 12, "Douze" ));
      il.add( new Record( 24, "Vingt quatre" ));
      il.add( new Record( 36, "Trente six" ));
      final Button add    = new Button( "Add 18" );
      final Button update = new Button( "Update 24 to 8" );
      final HBox   ctrl   = new HBox( 4.0, add, update );
      final SortedList<Record> sortedList =
         il.sorted((l,r)-> Integer.compare(l._key.get(), r._key.get()));
      final ListView<Record> listVw = new ListView<>( sortedList );
      stage.setScene( new Scene(
         new BorderPane( listVw, ctrl, null, null, null ), 200, 140 ));
      stage.show();
      add.setOnAction( e -> {
         il.add( new Record( 18, "Dix huit" ));
         System.err.println( "--------------" );
         il.stream().forEach( System.err::println );
      });
      update.setOnAction( e -> {
         il.get( 1 )._key.set( 8 );
         System.err.println( "--------------" );
         il.stream().forEach( System.err::println );
      });
   }

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

结果:

推荐答案

SortedList 观察其基础 ObservableList 。因此,只有在基础列表触发更改事件时,它才会更新其顺序。

The SortedList observes its underlying ObservableList. Thus it will only update its order if the underlying list fires change events.

对于一个可观察列表,当其中一个元素的状态发生变化时触发更新事件(与列表添加,删除或重新排序元素相反),它必须是观察相应的属性。除非您使用提取器。提取器是一个函数,它将列表中的元素映射到应该观察到的属性数组:如果这些属性发生更改,列表将触发更新事件。在您的方案中,列表是排序列表的基础列表,这将允许排序列表重新排序。

For an observable list to fire update events when the state of one of its elements changes (as opposed to the list adding, removing, or reordering elements), it must be observing the corresponding properties. This won't happen unless you tell it to do so, using an extractor. The extractor is a function which maps an element in the list to an array of properties that should be observed: if those properties change the list will fire update events. In your scenario, where the list is the underlying list for a sorted list, this will allow the sorted list to reorder itself.

因此,您需要创建基础列表为

So you need to create your underlying list as

final ObservableList<IntegerProperty> il =
   FXCollections.observableArrayList(
      ( IntegerProperty intProp ) -> new Observable[]{ intProp });

(即您要观察的属性是元素本身)。

(ie. the property you want to observe is the element itself).

这篇关于JavaFX SortedList:监听列表更改和列表项更新事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆