挑战:取代反思

时间:2012-11-11 10:07:31

标签: java reflection javafx

在写了几个javafx.scene.control.TableView并看到代码繁琐之后,我已经使这个实用程序成为静态函数:

public class TableViewHelper {
   public static <T,F> void addColumn(
      TableView<T>     table,
      TableColumn<T,F> column,
      final String     fieldName,
      boolean          sortable,
      double           width      )
   {
      column.setCellValueFactory(
         new Callback< CellDataFeatures<T,F>, ObservableValue< F >>(){
            @Override public ObservableValue< F > call( CellDataFeatures<T,F> p ){
               T t = p.getValue();
               ObservableValue< F > value = null;
/*HERE IT IS*/ Class<T> tc = (Class<T>)t.getClass();
/*HERE IT IS*/ try { value = (ObservableValue<F>)(tc.getDeclaredField( fieldName ).get( t )); }
/*HERE IT IS*/ catch( Throwable x ){ x.printStackTrace(); }
               return value;
            }});
      column.setSortable( sortable );
      column.setPrefWidth( width );
      table.getColumns().add( column );
   }
}

表行类:

public class ChatMessage {
   public ChatMessage( String sender, String message ) {
      _date   .set( new Date());
      _sender .set( sender );
      _message.set( message );
   }

   final SimpleObjectProperty< Date > _date    = new SimpleObjectProperty<>();
   final SimpleStringProperty         _sender  = new SimpleStringProperty();
   final SimpleStringProperty         _message = new SimpleStringProperty();
}

用法:

public class ChatView
   extends
      BorderPane
{
   ChatView() {
      TableViewHelper.addColumn(
         _view, new TableColumn<ChatMessage,Date  >( "Date"    ), "_date"   ,  100.0 );
      TableViewHelper.addColumn(
         _view, new TableColumn<ChatMessage,String>( "Sender"  ), "_sender" ,  100.0 );
      TableViewHelper.addColumn(
         _view, new TableColumn<ChatMessage,String>( "Message" ), "_message", 1200.0 );
      setCenter( _view );
   }
}

使用反射(标记为“HERE IT IS”注释)通过Java字段名称获取字段值但我希望不这样做,而不在“使用”部分添加代码。

您可以提出其他方法(使用代码),而不使用反射吗?

任何帮助表示感谢。

1 个答案:

答案 0 :(得分:0)

您可以创建一个界面

public interface Property<T, X>  {
    public X get(T object);
    public void set(T object, X value);
}

界面Property可用于当前使用反射的位置:

public static <T,F> void addColumn(
        TableView<T> table,
        TableColumn<T, F> column,
        final Property<T, ObservableValue<F>> property,
        boolean sortable,
        double width)
{
   column.setCellValueFactory(
      new Callback< CellDataFeatures<T,F>, ObservableValue< F >>(){
         @Override public ObservableValue< F > call( CellDataFeatures<T,F> p ){
            T t = p.getValue();
            return property.get(t);
         }
      });
   column.setSortable( sortable );
   column.setPrefWidth( width );
   table.getColumns().add( column );
}

嗯,不管是这样,还是我遗漏了一些说不能用JavaFX做的事情。