#java #javafx #textarea #tableview #enumeration
#java #javafx #текстовое поле #просмотр таблицы #перечисление
Вопрос:
Сценарий: Я передаю значения, разделенные запятыми, в таблицу. 2 столбца, один с исходным значением, другой с текстовым полем со значениями, заполненными внутри. Они выстроены в ряд, чтобы я мог добавлять / изменять значения и копировать изменения в строку.
Я не могу понять, как захватить данные текстового поля после того, как они помещены в таблицу. Приведенный ниже код:
Главная:
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>
Любая помощь была бы высоко оценена.
Ответ №1:
Я не уверен точно, что они пытаются сделать, но я нашел способ получить TextField
, когда они нажимают enter.
В вашем TextFieldCell
классе я добавил setOnAction
, чтобы захватить то, что пользователь вводит в TextField
.
TextField textField = new TextField(input.get(count));
textField.setUserData(enumElement);
textField.setOnAction(event -> {
System.out.println("Gotcha");
});
Вы можете использовать это вместо кнопки, чтобы делать с введенным текстом все, что захотите.
Я понятия не имею, как использовать вашу кнопку, чтобы программно захватить все TextField
in col2
и захватить их текст.
Но с 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
Комментарии:
1. Целью событий captureText action является захват всех текстовых полей и объединение их в одну строку. Я попробую то, что вы придумали. Спасибо!
2. Да, я так и думал, к сожалению, я не смог найти способ захватить их все. Может быть, кто-то еще может.
3. Я заставил это работать, но мне пришлось сильно модифицировать ваш код.
4. Потрясающе! отлично работает. Я знаю, что мой код был неаккуратным. Я собрал это очень быстро. я ценю вашу помощь.