java - 从表格单元格内的文本字段捕获值

标签 java javafx textarea tableview enumeration

场景:我将逗号分隔值传递到表中。 2 列,一列包含原始值,一列包含文本字段,其中填充了值。它们排列整齐,以便我可以添加/更改值,并将更改复制到字符串中。

我不知道如何在将 TextField 数据放入表中后捕获它们。代码如下:

主要:

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;

public class Main extends Application {


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

    @Override
    public void start(Stage primaryStage) {
        try {
            Parent root = FXMLLoader.load(getClass().getResource("/application/MainFxml.fxml")); //this is the file that 
            Scene scene = new Scene(root,800,800); ////100,100 is width and height of window
            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
            primaryStage.setScene(scene);
            primaryStage.show();
        } catch(Exception e) {
            e.printStackTrace();
        }
    }
}

Controller :

import java.net.URL;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
import java.util.ResourceBundle;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Pos;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.TableColumn.CellEditEvent;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.HBox;

public class MainFxmlController implements Initializable {

    public static int count=-1;

    @FXML public TableView<tableClass> table = new TableView<tableClass>();
    @FXML private TableColumn<tableClass, String>col1;
    @SuppressWarnings({ "unchecked", "rawtypes" })
    @FXML public TableColumn<tableClass, Row> col2 = new TableColumn("Row");

    @FXML public TextField txt;
    @FXML public Button btn, btn2;
    @FXML public ListView<String> listView = new ListView<String>();
    public static ArrayList<String> input = new ArrayList<String>();

    final HBox hb = new HBox();
    public ObservableList<tableClass> obList = FXCollections.observableArrayList();  // each column contains an observable list object 
    public ObservableList<tableClass> loadTable(){
        return obList;   //return data object
    }////END loadData


    @Override
    public void initialize(URL url, ResourceBundle rb) {
            table.setEditable(true);
            col1.setCellValueFactory(cellData -> cellData.getValue().getCol1());  


            col2.setCellFactory((param) -> new TextFieldCell<tableClass, Row>(EnumSet.allOf(Row.class)));
            col2.setCellValueFactory(new PropertyValueFactory<tableClass, Row>("Row"));
            col2.setOnEditCommit(
                    new EventHandler<CellEditEvent<tableClass, Row>>() {
                        @Override
                        public void handle(CellEditEvent<tableClass, Row> t) {
                            ((tableClass) t.getTableView().getItems().get(
                                t.getTablePosition().getRow())
                                ).setCol2(t.getNewValue());
                        }
                    }
                );

            tableClass Entry = new tableClass(" ", Row.Row1); //create the table using getters/setters from Table Class
            table.getItems().addAll(Entry);         
            table.setItems(loadTable());

            col1.setCellFactory(TextFieldTableCell.<tableClass>forTableColumn()); //Makes the columns themselves editable
            col1.setOnEditCommit(
                    new EventHandler<CellEditEvent<tableClass, String>>() {
                        @Override
                        public void handle(CellEditEvent<tableClass, String> t) {
                            ((tableClass) t.getTableView().getItems().get( t.getTablePosition().getRow())).setCol1(t.getNewValue());
                        }              
                    }
                    );
            col1.setStyle( "-fx-alignment: BOTTOM-RIGHT;"); //to alight text next to textArea

            txt.setText("fsad,0,0,gfds,43,4,4,fdsg,rtewrtwe,0,67,3,4,4,,4,44,,4");  //TO BE ROMOVED UPON COMPLETION

    }//end initialize

    public void buttonAction(ActionEvent e){
        if(txt.getText() != ""){
            System.out.println(txt.getText());
            ArrayList<String> myList = new ArrayList<String>(Arrays.asList(txt.getText().split(",")));
            input = myList;     
        }

        for(int i =0; i< input.size(); i++){
            Row.Row1.equals(input.get(i).toString());
            obList.add(new tableClass(input.get(i).toString(), Row.Row1));
        }//end for

    }//end buttonAction


    public void captureText(ActionEvent e){

        /*
         * HERE I NEED TO CAPTURE VALUES FROM THE TEXT FIELDS
         * IN COL2
         */

    }



    public static enum Row { //enum for the dxTable radio button  if you want any other options, add another value and another radio buttton will be populated
        Row1;
    }


    public static class TextFieldCell<S,T extends Enum<T>> extends TableCell<S,T>{

        private EnumSet<T> enumeration;

        public TextFieldCell(EnumSet<T> enumeration) {
            this.enumeration = enumeration;
        }

        @Override
        protected void updateItem(T item, boolean empty)
        {
            super.updateItem(item, empty);
            if (!empty) 
            {
                // gui setup
                HBox hb = new HBox(7);
                hb.setAlignment(Pos.CENTER);


                // create a radio button for each 'element' of the enumeration
                for (Enum<T> enumElement : enumeration) {
                        try{
                        TextField textField = new TextField(input.get(count));
                        textField.setUserData(enumElement);
                        hb.getChildren().add(textField);
                        }catch(IndexOutOfBoundsException e){}
                }

                // issue events on change of the selected radio button

                setGraphic(hb);
                count++;
            } //end if
            else
                setGraphic(null);
        }//updateItem
    }//END TextFieldCell class


    public static class tableClass{              ///table object with getters and setters.
        public final SimpleStringProperty col1;
        public final SimpleObjectProperty<Row> col2 = new SimpleObjectProperty<Row>();      

        public tableClass(String col1, Row t) {   //uses an enum for the second type
          this.col1 = new SimpleStringProperty(col1);
          this.col2.setValue(t);
        }

        public StringProperty getCol1() {
            return col1;
        }

        public void setCol1(String i) {
            col1.set(i);
        }

        public void setCol2(Row t) {
            col2.set(t);
        }       

        public Row getCol2() {
            return col2.get();
        }
        public String getCol2(int index) {

            return "";
        }

      }//end table class
}//end controller

FXML:

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>

<AnchorPane prefHeight="800.0" prefWidth="800.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.MainFxmlController">
   <children>
      <Button fx:id="btn" layoutX="723.0" layoutY="26.0" mnemonicParsing="false" onAction="#buttonAction" text="btn" />
      <TextField fx:id="txt" layoutX="41.0" layoutY="26.0" prefHeight="25.0" prefWidth="647.0" />
      <TableView fx:id="table" editable="true" layoutX="41.0" layoutY="106.0" prefHeight="588.0" prefWidth="451.0">
        <columns>
          <TableColumn fx:id="col1" prefWidth="75.0" text="C1" />
          <TableColumn fx:id="col2" prefWidth="114.0" text="C2" />
        </columns>
      </TableView>
      <Button fx:id="btn2" layoutX="507.0" layoutY="669.0" mnemonicParsing="false" onAction="#captureText" text="Button" />
   </children>
</AnchorPane>

任何帮助将不胜感激。

最佳答案

我不确定到底要做什么,但我找到了一种在他们按 Enter 键时获取 TextField 的方法。

在您的 TextFieldCell 类中,我添加了 setOnAction 来获取用户在 TextField 中输入的内容。

TextField textField = new TextField(input.get(count));
textField.setUserData(enumElement);
textField.setOnAction(event -> {
   System.out.println("Gotcha");
});

您可以使用它而不是按钮来对输入的文本执行任何您想要的操作。

我不知道如何使用按钮以编程方式抓取 col2 中的所有 TextField 并抓取其文本。

但是,通过 setOnAction,您可以在其中添加您喜欢的任何内容,并希望完成您需要做的事情。

Edit 1 With some heavy editing of your work, I have done it! I will leave in the old answer, since it applies directly to your source code.

首先,我让 col2 看起来像这样。

@FXML public TableColumn<tableClass, TextField> col2;

然后,我利用了这一点,setCellValueFactory如下所示:

col2.setCellValueFactory(new PropertyValueFactory<>("col2"));

col2 有关的所有内容,我都必须更新/删除才能使其与 TextField 一起使用,并且我最终得到了一个更短的源代码,可以做你想做的事。示例位于captureText 方法中。 我编辑了 tableClass 以使用 TextField,我完全删除了 cellFactory 类。希望这会有所帮助。

@FXML public TableView<tableClass> table;
@FXML private TableColumn<tableClass, String>col1;
@SuppressWarnings({ "unchecked", "rawtypes" })
@FXML public TableColumn<tableClass, TextField> col2;

@FXML public TextField txt;
@FXML public Button btn, btn2;
public static ArrayList<String> input = new ArrayList<String>();

public static Group hb = new Group();
public ObservableList<tableClass> obList = FXCollections.observableArrayList();  // each column contains an observable list object
public ObservableList<tableClass> loadTable(){
    return obList;   //return data object
}////END loadData


@Override
public void initialize(URL url, ResourceBundle rb) {
    table.setEditable(true);
    col1.setCellValueFactory(cellData -> cellData.getValue().col1Property());


    col2.setCellValueFactory(new PropertyValueFactory<>("col2"));

    table.setItems(loadTable());

    col1.setCellFactory(TextFieldTableCell.<tableClass>forTableColumn()); //Makes the columns themselves editable
    col1.setOnEditCommit(
            new EventHandler<CellEditEvent<tableClass, String>>() {
                @Override
                public void handle(CellEditEvent<tableClass, String> t) {
                    ((tableClass) t.getTableView().getItems().get( t.getTablePosition().getRow())).setCol1(t.getNewValue());
                }
            }
    );
    col1.setStyle( "-fx-alignment: BOTTOM-RIGHT;"); //to alight text next to textArea

    txt.setText("fsad,0,0,gfds,43,4,4,fdsg,rtewrtwe,0,67,3,4,4,,4,44,,4");  //TO BE ROMOVED UPON COMPLETION

}//end initialize

public void buttonAction(ActionEvent e){
    if(txt.getText() != ""){
        System.out.println(txt.getText());
        ArrayList<String> myList = new ArrayList<String>(Arrays.asList(txt.getText().split(",")));
        input = myList;
    }

    for(int i =0; i< input.size(); i++){
        obList.add(new tableClass(input.get(i),input.get(i)));
    }//end for

}//end buttonAction


public void captureText(ActionEvent e) {
    obList.forEach(event -> {
        event.setCol1(event.getCol2().getText());
    });
    /*
     * HERE I NEED TO CAPTURE VALUES FROM THE TEXT FIELDS
     * IN COL2
     */
}


public static class tableClass{              ///table object with getters and setters.
    public final SimpleStringProperty col1;
    public final TextField col2;

    public tableClass(String col1, String col2) {   //uses an enum for the second type
        this.col1 = new SimpleStringProperty(col1);
        this.col2 = new TextField(col2);
    }

    public StringProperty col1Property() {
        return col1;
    }
    public String getCol1(){
        return col1.get();
    }

    public void setCol1(String i) {
        col1.set(i);
    }

    public void setCol2(String tx) {
        col2.setText(tx);
    }

    public TextField getCol2() {
        return col2;
    }

}//end table class

关于java - 从表格单元格内的文本字段捕获值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40166580/

相关文章:

scroll - 如何在 setText 之后滚动 JavaFX TextArea

Java 套接字 - 为什么我需要 PrintWriter 来完成这项工作?

java - Vertx.io GET 无提示失败

javafx - 标签的格式文本

javafx - JavaFX 支持哪些图像格式?

html - 如何将悬停效果添加到文本区域占位符?

java - junit中测试类的通用@before和@after

java - Eclipse 不断崩溃

java - 如何在 JavaFX 中使用 try-catch?

javascript - 如何设置文本区域滚动条的样式