【问题标题】:Editing numbers in javafx TableView cells在 javafx TableView 单元格中编辑数字
【发布时间】:2015-09-02 12:57:35
【问题描述】:

我正在为朋友制作一个相当复杂的桌面应用程序,作为学习 Java 的一种方式,尤其是 Java 8 和 JavaFX。该应用程序将有很多表格,并且像一个高度具体的电子表格一样工作,并且与估算运输成本有关。到目前为止,我已经学会了使用 Scene Builder,使用 css 结构,并设计了自己的类来表示表中的数据。 这是我的 Vessel 课程的精简版:

    import javafx.beans.property.*; 

public class Vessel
{
    private  StringProperty name;
    private  FloatProperty deadWeight;

    public Vessel(){
        this.name = new SimpleStringProperty("ENTER SHIP NAME");
        this.deadWeight = new SimpleFloatProperty(0);
    }

    public Vessel(String name, float deadWeight){
        this.name = new SimpleStringProperty(name);
    }

    public void setName(String name){this.name.set(name);}
    public void setDeadWeight(float deadWeight){this.deadWeight.set(deadWeight);}   

    public String getName(){
        if ( !(name.get().equals("")) || (name.get()==null) || (name.get().trim().equals("ENTER SHIP NAME")) )
            return name.get();
      return null;
    }

    public float getDeadWeight(){return  deadWeight.get();} 

    public StringProperty nameProperty() { return name;}
    public FloatProperty deadWeightProperty() { return deadWeight;}

    public void clear(){
            this.name.set("ENTER SHIP NAME");
            this.deadWeight.set(0);
    }
}

我需要直接编辑 TableView 中的单元格,这些单元格可以是浮点数或字符串。根据我在此站点上收集的信息,我可以使用字符串来执行此操作,但无法弄清楚如何进行浮动。

这里是控制器文件 VesselController.java:

    import javafx.fxml.FXML;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.AnchorPane; 
import javafx.beans.property.SimpleFloatProperty;
import javafx.beans.value.*;
import javafx.scene.control.TreeTableColumn.CellDataFeatures;

 public class VesselController {  

    @FXML  private AnchorPane root;
    @FXML  private TableView<Vessel> vesselTable;
    @FXML  private TableColumn<Vessel, String> vesselTableNameCol;
    @FXML  private TableColumn<Vessel, Number> vesselTableDWTCol;

    // Reference to the main application.
    private MyMain mainApp;

    //The constructor, it is called before the initialize() method.
    public VesselController() {}

    //Initializes the controller class. This method is automatically called after the fxml file has been loaded.
    @FXML
    private void initialize() {
        // Initialize the vessel table with the columns.
      vesselTableNameCol.setCellValueFactory(cellData -> cellData.getValue().nameProperty());
        vesselTableNameCol.setCellFactory(column -> EditCell.createStringEditCell());

      vesselTableDWTCol.setCellValueFactory(cellData -> cellData.getValue().deadWeightProperty());

        // vesselTableDWTCol.setCellFactory(column -> EditCell.createStringEditCell()); //not working, as it needs to reurn a SimpleFloatProperty type
        //so tried this, but don't have a clear idea of what I'm doing
        vesselTableDWTCol.setCellValueFactory(new Callback<CellDataFeatures<Vessel, Number>, ObservableValue<Number>>() {
                @Override
                public ObservableValue<Number> call(CellDataFeatures<Vessel, Number> p) {
                return new SimpleFloatProperty(p.getValue().deadWeightProprerty());
                } 
            });

    }

    //Is called by the main application to give a reference back to itself.
    public void setMainApp(MyMain mainApp) {
      this.mainApp = mainApp;
      vesselTable.setItems(mainApp.getVesselData());   // Add observable list data to the table
        vesselTable.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
       vesselTable.setEditable(true);
    }
}

这是显示错误的类,我不知道为什么——我需要实现回调吗?如果是这样,我该怎么做? 我从this post 收集到的一些代码,试图让它与 Numbers 一起工作。 我从James_D's repository下载的EditCell类。

这是运行它的 MyMain.java:

    import java.io.*;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Scene; 
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.collections.ObservableList;
import javafx.collections.FXCollections;

public class MyMain extends Application {
    private Stage primaryStage;

    //The data as an observable list of Persons.
    private ObservableList<Vessel> vesselData = FXCollections.observableArrayList();

    //Constructor
   public MyMain() {          // Add some sample data
         vesselData.add(new Vessel()); //init empty row
    }

    // Returns the data as an observable list of Vessels (in this case a single row) 
    public ObservableList<Vessel> getVesselData() { return vesselData; }

    // Shows the vessel overview inside the root layout.
    @Override
    public void start(Stage primaryStage) { 
        this.primaryStage = primaryStage;
        this.primaryStage.setTitle("My Vessel");      
        show();
     }

    //Initializes the root layout. 
    public void show() {
        try {          
            FXMLLoader loader = new FXMLLoader(); // Load root layout from fxml file.
            loader.setLocation(MyMain.class.getResource("MyUI.fxml"));
            AnchorPane root = (AnchorPane) loader.load();

                // Give the controller access to the main app.
                VesselController controller = loader.getController();
                controller.setMainApp(this);

            // Show the scene containing the root layout.
            Scene scene = new Scene(root);
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (IOException e) { e.printStackTrace();}
    } 

    // Returns the main stage.
    public Stage getPrimaryStage() {
        return primaryStage;
    }

    public static void main(String[] args) { 
        Application.launch(MyMain.class, (java.lang.String[])null);
    }
}

我很确定我需要修改 EditCell 类,并且我尝试创建自己的“NumberConverter”但没有任何运气——我不完全理解泛化,但我很确定我需要由于应用程序的整体最终复杂性,请沿着这条路走下去。为这么长的帖子道歉。

如果有人能提供一些指导,那就太好了。

【问题讨论】:

    标签: java uitableview java-8 javafx-8


    【解决方案1】:

    我认为你不需要使用EditCell 类。或者,您可以使用TextFieldTableCell 类。 您需要为vesselTableDWTCol 列调用setcellfactory(...) 方法(您可以对vesselTableNameCol 列执行相同的操作)。

    使用下面的sn-p代码:

    // this line allow you to edit  cells in `vesselTableNameCol` column 
        vesselTableNameCol.setCellFactory(TextFieldTableCell.forTableColumn());
    // this line allow you to edit  cells in `vesselTableDWTCol` column
        vesselTableDWTCol.setCellFactory(TextFieldTableCell.forTableColumn(new FloatStringConverter()));
    

    【讨论】:

    • 谢谢,这对我来说很简单——我确实需要更改我的私有 TableColumn
    • 再次感谢@Win.ubuntu,编辑:--澄清我确实需要在 VesselController 类中将我的private TableColumn&lt;Vessel, Number&gt; 声明更改为private TableColumn&lt;Vessel, Float&gt;。我还必须创建自己的FloatStringConverter,它可以处理用户输入字符串而不会引发异常(并将负数转换为零),否则没问题!
    猜你喜欢
    • 1970-01-01
    • 2014-02-22
    • 2013-11-29
    • 2013-10-20
    • 1970-01-01
    • 2014-10-14
    • 2014-09-04
    • 2014-07-01
    • 1970-01-01
    相关资源
    最近更新 更多