【问题标题】:How to Get First Column Value on click in JavaFX TableView like JTable in swing?java - 如何在JavaFX TableView中单击时获取第一列值,如JTable in swing?
【发布时间】:2014-04-01 01:05:15
【问题描述】:

我想获得第一列的值,因为我们可以在 Jtable 中使用 swing 来实现。下面是我的 jtable 代码和图像。

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

正如您在图片中看到的,当我点击 Name 列值 8 时,它会给出第一列值,例如 8。但我选择名称列

那么如何使用 TableView Componenet 在 JavaFX 中实现这一点。

我从 TableView 中获取选定的值,如下图所示。

   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 中的第一列数据与我们在 Jtable 中获得的相同?那么如何获得该 NO 值.. 使用我上面的代码我在控制台中获得所选单元格 that is 8 print 的值.. 但我想获得第一列价值..帮助我彻底前进。

谢谢..

表格视图数据填充代码更新

   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();

【问题讨论】:

  • 您的代码对我有用。我只是想知道setCellSelectionEnabled(true)setSelectionMode(SelectionMode.SINGLE) 是否有所作为。
  • @brian:你这边的输出是什么?哪种代码适合您?
  • 当我点击一个单元格时,你的监听器会给我单元格中的值。在您的示例中,这将是 8。请注意,您有一条蓝线突出显示该行中的所有单元格。如果您使用 tableView.setCellSelectionEnabled(true) ,则只会选择一个单元格。如果您不单击新行,侦听器将不起作用,但它会在单击的单元格中给出值。
  • @brian: 没有人,我想要基于第二列的选择第一列的值.. 选定的单元格也适用于我!!
  • 好的,如果您总是想要第一列的值,这并不难。 Object val = tableView.getColumns().get(0).getCellData(newVal);

标签: java swing javafx javafx-2 tableview


【解决方案1】:

解决方案

您可以通过调用与所选行对应的模型对象上的getter来检索相关字段。

在下面的代码中,newValue.getId() 调用是关键。

没有 Java 8 lambda:

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());
        }
    }
);

使用 Java 8 lambda:

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

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

示例代码

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;
        }
    }
} 

其他问题的答案

检查我更新的问题,所以我不能使用这个?

因此,在您的更新中,您可以看到每行数据的类型是 ObservableList&lt;String&gt;,而在我的回答中,类型是 IdentifiedName。要使发布的解决方案适用于您的数据类型,更改是微不足道的。 newValue.getId() 的等效项是 newValue.get(0),以返回列表中所选行的第一项。

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));
    }
);

或者是否可以使用identifiedname 类?那怎么办?

可以,但是您必须对数据库获取代码进行大量更改,才能将创建的数据加载到 IdentifiedName 类而不是 ObservableList&lt;String&gt; 中,这样做会失去数据库加载代码的通用性.

我将你的代码实现到我得到的项目中...java.lang.ClassCastException:

您需要为您的数据类型正确设置表和列的类型,而不是我为我的用例提供的示例。

替换这些类型:

TableView<IdentifiedName>
TableColumn<IdentifiedName, Integer>

使用这些类型:

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

小建议

我建议通过阅读Java Generics Trail 来复习一下。 JavaFX 中的表在使用泛型方面非常复杂,但是在表代码中使用正确的泛型可以使其更容易编写(只要您使用的 IDE 擅长在需要时猜测泛型)。

您可能还想向minimal, complete, tested and readable example 提供未来此类问题(并非所有问题)。建造一个可以帮助您更快地解决问题。此外,确保您的代码具有一致的缩进使其更易于阅读。

【讨论】:

  • @jewelsea: 如何使用 identiedname 类?因为我从数据库中动态填充表格视图?所以我这边没有 getter setter 吗?
  • @jewelsea:检查我更新的问题,所以我不能使用这个?还是可以使用identifiedname 类?那怎么办?
  • 当我在我的项目中实现你的代码时,我得到了异常Exception in thread "JavaFX Application Thread" java.lang.ClassCastException: com.sun.javafx.collections.ObservableListWrapper cannot be cast to myprojectpackage.CreateModeController$IdentifiedName
  • @jewelsea SSCCE is strictly refured on this forum 由无尽和白痴*** 那里的规则,我也不同意那里的结果,现在这里是 MCVE/MCTRE
  • @mKorbel thx 获取信息。 Meta 和 MCVE 是有用的资源。更新了参考 MCVE 而不是 SSCCE 的答案。
【解决方案2】:

你必须看看底层的ObservableList。对我有用的代码是:

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

在我的测试中返回一个Person 对象(我写的POJO),它必须包含一个get() 方法。

【讨论】:

  • 它给了我像Selected value is [8, Eight] 这样的输出,但我只想要8?
  • 这是你的 IdentifiedName 对象的 toString() 输出。这个类应该有一个getNumber() 方法。 tableView.getItems().get(tableView.getSelectionModel().getSelectedIndex()).getNumber()
  • 没有像getNumber()这样的方法吗?
  • 我刚刚在你的代码中找到了这个类。试试tableView.getItems().get(tableView.getSelectionModel().getSelectedIndex()).getId()
  • 我的课堂上没有getID() 方法??你在我的课上哪里来的?
【解决方案3】:

我可以使用下面的代码获取第一列的值:

tableview.getSelectionModel().selectedItemProperty().addListener(new ChangeListener() {
            @Override
            public void changed(ObservableValue observableValue, Object oldValue, Object newValue) {
                //Check whether item is selected and set value of selected item to Label
                if (tableview.getSelectionModel().getSelectedItem() != null) {
                    TableView.TableViewSelectionModel selectionModel = tableview.getSelectionModel();
                    ObservableList selectedCells = selectionModel.getSelectedCells();

                    TablePosition tablePosition = (TablePosition) selectedCells.get(0);


                    tablePosition.getTableView().getSelectionModel().getTableView().getId();
                    //gives you selected cell value..
                    Object GetSinglevalue = tablePosition.getTableColumn().getCellData(newValue);

                    getbothvalue = tableview.getSelectionModel().getSelectedItem().toString();
                //gives you first column value..
                    Finalvaluetablerow = getbothvalue.toString().split(",")[0].substring(1);
                    System.out.println("The First column value of row.." + Finalvaluetablerow);
                }
            }
        });

谢谢..

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-30
    • 1970-01-01
    • 2016-10-15
    相关资源
    最近更新 更多