0

I am trying to create a method in my JAVAFX controller which will show the preview of the data in table view. That table view has to be generic enough so that it can just take a list of objects and display it into the table. Here is my code.

In my controller i have TableView like this

@FXML
private TableView dataPreviewTableView; 

Down below in the same controller i have a method like this

public void loadScreen(Class<?> T){

TableColumn col;
TableViewHeader headerInfo =getHeaderInfoFromTemplate(fileTemplate);
List<String> headerNames = headerInfo.getHeaderNames();
dataPreviewTableView.getItems().clear();

 for(String headerName : headerNames){
        col = new TableColumn (headerName.toUpperCase());
        col.prefWidthProperty().bind(dataPreviewTableView.widthProperty().divide(headerNames.size()));
        col.setCellValueFactory(new PropertyValueFactory<**T,Integer**>(headerName));
        dataPreviewTableView.getColumns().add(col);
    }   
 this.lblFileName.setText(fileToImport.getPath()); 
 dataPreviewTableView.setItems(data);

}

The following line gives an error T cannot be resolved to a type

col.setCellValueFactory(new PropertyValueFactory<T,Integer>(headerName));
ATHER
  • 3,254
  • 5
  • 40
  • 63
  • Try `col = new TableColumn` and you should use S instead of T to match the javadoc. `TableView` where S is the underlying data type and T is the column data type. I'm not sure if this is your problem but I use it in my code. – brian Sep 03 '14 at 23:51
  • 1
    In the declaration of your method, you have `T` as the name of a parameter (i.e. variable) of type `Class>`. However later in the method, you have `T` as a type: `PropertyValueFactory`. It's not really clear what you are intending to do here: what is `T`? What is the type of the data (rows) in the `TableView`? – James_D Sep 04 '14 at 00:34

1 Answers1

0

I missed the part where you had Class<?> as James said in the comments. Maybe you plan to get the type with reflection somehow?

This is a snip from code that's similar to how I do it.

public class GenericTable<S> extends TableView {
    public GenericTable(ObservableList data, String col) {
        super(data);
        TableColumn<S, String> tc = new TableColumn<>(col);
        tc.setCellValueFactory(new PropertyValueFactory<>(col));
        getColumns().add(tc);
    }
}

I like using <S, String> because it will show most anything, strings, ints, reals.

Maybe you just need to do something like this, no type info required. I think the <S,T> is mainly for compile time checks. Since you want any type, it doesn't help you.

package tablegeneric;

import javafx.application.Application;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

public class TableGeneric extends Application {

    @Override
    public void start(Stage primaryStage) {
        ObservableList<Data1> data1s = FXCollections.observableArrayList();
        ObservableList<Data2> data2s = FXCollections.observableArrayList();
        data1s.addAll(new Data1("str1"), new Data1("str2"), new Data1("str3"));
        data2s.addAll(new Data2(1, 1), new Data2(2, 2), new Data2(3, 3));
        TableView tv = new TableView();
        Button btn = new Button("click to change table data");
        btn.setOnAction(evt -> {
            if (tv.getItems() == data1s) showScreen(tv, data2s, "i", "d");
            else showScreen(tv, data1s, "str");
        });
        Scene scene = new Scene(new VBox(tv, btn), 200, 300);

        primaryStage.setScene(scene);
        primaryStage.show();
    }

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

    public void showScreen(TableView tv, ObservableList data, String... cols) {
        tv.setItems(data);
        tv.getColumns().clear();
        for (String s : cols) {
            TableColumn tc = new TableColumn(s);
            tc.setCellValueFactory(new PropertyValueFactory(s));
            tv.getColumns().add(tc);
        }
    }

    public class Data1 {

        private SimpleStringProperty str;

        public Data1(String s) {
            this.str = new SimpleStringProperty(s);
        }

        public SimpleStringProperty strProperty() {
            return str;
        }
    }

    public class Data2 {

        private SimpleIntegerProperty i;
        private SimpleDoubleProperty d;

        public Data2(int i, double d) {
            this.i = new SimpleIntegerProperty(i);
            this.d = new SimpleDoubleProperty(d);
        }

        public SimpleIntegerProperty iProperty() {
            return i;
        }

        public SimpleDoubleProperty dProperty() {
            return d;
        }

    }

}
brian
  • 10,619
  • 4
  • 21
  • 79
  • You are almost there. GenericTable class will be used from within controller and loadScreen method. I need to pass in S while calling loadScreen method.Still not clear how would i do that. public void loadScreen(Class> S){ this.dataPreviewTableView = new GenericTable(this.data,this.col) dataPreviewTableView.loadTableView(); // this will actually set all columns and data to the underlying table view } – ATHER Sep 04 '14 at 18:40
  • No your new solution is not generic. Its not gonna work. I like your idea of creating a extended class GenericTable. The only thing is i need to figure out how to make it work when i am calling method loadScreen(Person) or loadScreen(Equipment) or loadScreen(Vehicle). Basically the idea is to load the Table view for any type that is passed in. – ATHER Sep 04 '14 at 19:30
  • The type passed in to loadScreen() method needs to go to your class GenericTable. – ATHER Sep 04 '14 at 19:33
  • If you know the types (person, equip, etc..) then a bunch of if or case statements will probably work better. I thought it was for showing random, or untyped, data. – brian Sep 04 '14 at 20:04
  • Maybe this question is what you want. http://stackoverflow.com/questions/3403909/get-generic-type-of-class-at-runtime – brian Sep 04 '14 at 20:06