【问题标题】:Capture values from a TextField within a table cell从表格单元格中的 TextField 捕获值
【发布时间】:2016-10-21 00:31:20
【问题描述】:

场景:我将逗号分隔的值传递给表格。 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();
        }
    }
}

控制器:

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>

任何帮助将不胜感激。

【问题讨论】:

    标签: java javafx textarea tableview enumeration


    【解决方案1】:

    我不确定到底要做什么,但我找到了一种方法,可以在他们按 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,您可以在其中添加您喜欢的任何内容,并希望做您需要做的事情。

    编辑 1 通过对您的工作进行大量编辑,我已经完成了! 我将保留旧答案,因为它直接适用于您的源代码。

    首先,我让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
    

    【讨论】:

    • captureText 动作事件的目的是捕获所有文本字段,并连接到一个字符串。生病试试你想出什么。谢谢!
    • 是的,我想了这么多,遗憾的是我无法想出一个方法来抓住它们。也许其他人可以。
    • 我让它工作了,但我不得不大量修改你的代码。
    • 太棒了!效果很好。我知道我的代码很草率。我很快就把它放在一起了。感谢您的帮助。
    猜你喜欢
    • 1970-01-01
    • 2013-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多