How to Get First Column Value on click in JavaFX TableView like JTable in swing?


Question

I want to get First column value as we can achieve in Jtable using swing. below is my code and image for jtable.

String Table_Clicked = jTable1.getModel().getValueAt(row, 0).toString();

Jtable

As you can see in image when i click to the Name column value eight it gives me first column value like 8. But I select Name Column

So how to achieve this in JavaFX with TableView Componenet.

I get the selected Value from the TableView as you can see in image below with the code.

   tableview.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
        @Override
        public void changed(ObservableValue observableValue, Object oldValue, Object newValue) {
         if(tableview.getSelectionModel().getSelectedItem() != null) 
            {  
                TableViewSelectionModel selectionModel = tableview.getSelectionModel();
                ObservableList selectedCells = selectionModel.getSelectedCells();
                TablePosition tablePosition = (TablePosition) selectedCells.get(0);
                Object val = tablePosition.getTableColumn().getCellData(newValue);
                System.out.println("Selected value IS :" + val);
            }

         }
     });

TableView Of JavaFX

So I want the same in tableview First column data as we can get in Jtable? so how to get that NO value.. as using my above code I get the value of selected Cell that is eight print in console.. but I want to get First Column Value.. Help me to go thorough Ahead.

Thanks..

UPDATE FOR DATA FILLING CODE OF TABLEVIEW

   PreparedStatement psd = (PreparedStatement) conn.prepareStatement("SELECT No,name FROM FieldMaster");
    psd.execute();
    ResultSet rs = psd.getResultSet();

    for(int i=0 ; i<rs.getMetaData().getColumnCount(); i++){
            //We are using non property style for making dynamic table
            final int j = i;                
            namecol = new TableColumn(rs.getMetaData().getColumnName(i+1));
            namecol.setCellValueFactory(new Callback<CellDataFeatures<ObservableList, String>, ObservableValue<String>>()
            {
            @Override
            public ObservableValue<String> call(CellDataFeatures<ObservableList, String> param) 
            {
                return new SimpleStringProperty(param.getValue().get(j).toString());
            }
        });

            tableview.getColumns().addAll(namecol); 
            System.out.println("Column ["+i+"] ");


        }

            while(rs.next())
            {
            //Iterate Row
            ObservableList<String> row = FXCollections.observableArrayList();
            for(int i=1 ; i<=rs.getMetaData().getColumnCount(); i++)
            {
                //Iterate Column
                row.add(rs.getString(i));
            }
            System.out.println("Row [1] added "+row );
            data.add(row);

        }
        tableview.setItems(data);
        conn.close();
1
1
2/28/2014 8:56:01 AM

Accepted Answer

Solution

You can retrieve the relevant field by calling the getter on the model object corresponding to the selected row.

In the code below the newValue.getId() call is the key.

Without Java 8 lambdas:

final Label selected = new Label();
table.getSelectionModel().selectedItemProperty().addListener(
    new ChangeListener<IdentifiedName>() {
        @Override
        public void changed(
            ObservableValue<? extends IdentifiedName> observable, 
            IdentifiedName oldValue, 
            IdentifiedName newValue
        ) {
            if (newValue == null) {
                selected.setText("");
                return;
            }

            selected.setText("Selected Number: " + newValue.getId());
        }
    }
);

With Java 8 lambdas:

final Label selected = new Label();
table.getSelectionModel().selectedItemProperty().addListener(
    (observable, oldValue, newValue) -> {
        if (newValue == null) {
            selected.setText("");
            return;
        }

        selected.setText("Selected Number: " + newValue.getId());
    }
);

Sample Code

selected

import javafx.application.Application;
import javafx.collections.*;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.*;
import javafx.stage.Stage;

public class TableViewSample extends Application {

    private TableView<IdentifiedName> table = new TableView<>();
    private final ObservableList<IdentifiedName> data =
        FXCollections.observableArrayList(
            new IdentifiedName(3, "three"),
            new IdentifiedName(4, "four"),
            new IdentifiedName(7, "seven"),
            new IdentifiedName(8, "eight"),
            new IdentifiedName(9, "nineses")
        );

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

    @Override
    public void start(Stage stage) {
        TableColumn<IdentifiedName, Integer> idColumn = new TableColumn<>("No");
        idColumn.setMinWidth(100);
        idColumn.setCellValueFactory(
                new PropertyValueFactory<>("id")
        );

        TableColumn<IdentifiedName, String> nameColumn = new TableColumn<>("Name");
        nameColumn.setMinWidth(100);
        nameColumn.setCellValueFactory(
                new PropertyValueFactory<>("name")
        );

        table.setItems(data);
        table.getColumns().setAll(idColumn, nameColumn);
        table.setPrefHeight(180);

        final Label selected = new Label();
        table.getSelectionModel().selectedItemProperty().addListener((observable, oldValue, newValue) -> {
            if (newValue == null) {
                selected.setText("");
                return;
            }

            selected.setText("Selected Number: " + newValue.getId());
        });

        final VBox layout = new VBox(10);
        layout.setPadding(new Insets(10));
        layout.getChildren().addAll(table, selected);
        VBox.setVgrow(table, Priority.ALWAYS);

        stage.setScene(new Scene(layout));
        stage.show();
    }

    public static class IdentifiedName {
        private final int    id;
        private final String name;

        private IdentifiedName(int id, String name) {
            this.id   = id;
            this.name = name;
        }

        public int getId() {
            return id;
        }

        public String getName() {
            return name;
        }
    }
} 

Answers to Additional Questions

check my updated question so I can't use this?

So in your update you can see that the type of each row's data is ObservableList<String>, whereas in my answer the type is IdentifiedName. To get the posted solution to work for your data type, the change is trivial. The equivalent of newValue.getId() would be newValue.get(0), to return the first item in your list for the selected row.

final Label selected = new Label();
table.getSelectionModel().selectedItemProperty().addListener(
    (observable, oldValue, newValue) -> {
        if (newValue == null) {
            selected.setText("");
            return;
        }

        selected.setText("Selected Number: " + newValue.get(0));
    }
);

or is it possible to use identifiedname class? then how?

Yes you could, but you would have to make extensive changes to your database fetching code to load the data created into an IdentifiedName class rather than an ObservableList<String> and doing so would lose the generic nature of your database loading code.

I implement your code into my project I got ... java.lang.ClassCastException:

You need to setup the type of your Table and columns correctly for your data types, not the sample ones I provided for my use case.

Replace these types:

TableView<IdentifiedName>
TableColumn<IdentifiedName, Integer>

With these types:

TableView<ObservableList<String>>
TableColumn<ObservableList<String>, String>

Minor advice

I advise taking a refresher by reading up on the Java Generics Trail. Tables in JavaFX are pretty complicated in their use of generics, but using correct generics in your table code can make it easier to write (as long as you are using a good IDE which is good at guessing the generics when needed).

You also might want to provide an minimal, complete, tested and readable example with future questions of this type (not all questions). Construction of one could help you solve your issues quicker. Also, ensuring your code has consistent indentation makes it easier to read.

7
5/23/2017 12:06:30 PM

You have to take a look at the underlying ObservableList. The code that works for me was:

tableView.getItems().get(tableView.getSelectionModel().getSelectedIndex())

In my test that returns a Person object (POJO i wrote) which has to contain a get() method.


Licensed under: CC-BY-SA with attribution
Not affiliated with: Stack Overflow
Icon