从TextField编辑TableView的值



嗨,我正本着http://code.makery.ch/java/javafx-2-tutorial-intro/制作一个类似的应用程序,其中TableView值可以通过一系列TextField而不是弹出式表单进行编辑。我不想这样做的原因是,我想开发的类似应用程序中有许多字段,我希望避免用户在TableView 上编辑它们

TableView显示人员列表,其中每个I记录姓名、姓氏和国家。我尝试在Personbean的name属性和TextField的textProperty()之间创建一个bidirectionalBinding,但这不起作用。

我还试图在textProperty中添加一个ChangeListener,所以当它更改为更新比例的ObservableList时,也不起作用

显然我做错了什么,到目前为止我有以下代码:

FXDocumentController.java

    public class FXMLDocumentController implements Initializable {
    private static final Logger logger = Logger.getLogger(FXMLDocumentController.class.getName());
private ObservableList<Person> data;
    @FXML
    private TableView<Person> tableview;
    @FXML
    private TableColumn<Person, String> colName;
    @FXML
    private TableColumn<Person, String> colSurname;
    @FXML
    private TableColumn<Person, String> colCountry;
    @FXML
    private TextField name;
    @Override
    public void initialize(URL url, ResourceBundle rb) {
        assert tableview != null : "fx:id="tableview" was not injected: check your FXML file 'UserMaster.fxml'.";
     colName.setCellValueFactory(
        new PropertyValueFactory<Person,String>("name"));        
    colSurname.setCellValueFactory(                
        new PropertyValueFactory<Person,String>("surname"));
    colCountry.setCellValueFactory(
        new PropertyValueFactory<Person,String>("country"));       
    DBClass objDbClass = new DBClass();
    try{
        con = objDbClass.getConnection();
        buildData();
       tableview.setOnMouseClicked(new EventHandler<MouseEvent>() {
      @Override
        public void handle(MouseEvent mouseEvent) {
          if (mouseEvent.getButton().equals(MouseButton.PRIMARY)) {
            if (mouseEvent.getClickCount() == 1) {
                Person p = tableview.getSelectionModel().getSelectedItem();
                //name.textProperty().setValue(p.getName());
                name.textProperty().bindBidirectional(p.name);
                //name.textProperty().bind(p.name);

          }
        }
      }
    });
       name.textProperty().addListener(new ChangeListener(){
            @Override
            public void changed(ObservableValue ov, Object t, Object t1) {
                System.out.println("Value changed!"); 
                /** Tried also this but this wont work
                name.textProperty().setValue((String)t1);
                int index = tableview.getSelectionModel().getSelectedIndex();
                data.get(index).name.setValue( (String) t1);
                tableview.setItems(data);
                * */
            }
                    }
               );
    }
    catch(ClassNotFoundException ce){
        logger.info(ce.toString());
    }
    catch(SQLException ce){
        logger.info(ce.toString());
    }
    }    //initialize

    private void buildData() {
            data = FXCollections.observableArrayList();
    try{ 
        data.add(new Person("Jon", "Doe", "USA"));
        data.add(new Person("Lars", "Andersson", "Sweden"));
        tableview.setItems(data);
    }
    catch(Exception e){
          e.printStackTrace();
          System.out.println("Error on Building Data");            
    }
    }
    }

Person.java

public class Person {
public SimpleStringProperty name = new SimpleStringProperty();
public SimpleStringProperty surname = new SimpleStringProperty();
public SimpleStringProperty country = new SimpleStringProperty();
public Person(String name, String surname, String country){
    this.name.set(name);
    this.surname.set(surname);
    this.country.set(country);
}
public String getName(){
    return name.get();
}
public String getSurname(){
    return surname.get();
}
public String getCountry(){
    return country.get();
}
}

为了完整起见,我给出了fxml文件(非常丑陋,但我正在尝试功能;)和启动器

FXMLDocument.fxml

<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" blendMode="SRC_OVER" cache="false" disable="false" focusTraversable="false" prefHeight="576.0" prefWidth="1024.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="javafxdemoproject.FXMLDocumentController">
  <children>
    <SplitPane dividerPositions="0.3336594911937378" focusTraversable="true" layoutX="0.0" layoutY="55.0" prefHeight="521.0" prefWidth="1024.0">
      <items>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="410.0" prefWidth="297.0">
          <children>
            <TableView fx:id="tableview" editable="true" prefHeight="520.0" prefWidth="338.0" tableMenuButtonVisible="true" AnchorPane.bottomAnchor="178.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
              <columns>
                <TableColumn prefWidth="75.0" text="Name" fx:id="colName" />
                <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="154.0" text="Surname" fx:id="colSurname" />
                <TableColumn maxWidth="5000.0" minWidth="10.0" prefWidth="112.0" text="Country" fx:id="colCountry" />
              </columns>
            </TableView>
          </children>
        </AnchorPane>
        <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="404.0" prefWidth="460.0">
          <children>
            <Accordion layoutX="0.0" layoutY="0.0" prefHeight="520.0" prefWidth="262.0">
              <expandedPane>
                <TitledPane fx:id="personalTp" animated="false" text="Personal Details">
                  <content>
                    <AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                      <children>
                        <TextField fx:id="name" layoutX="44.0" layoutY="27.0" prefWidth="200.0" />
                      </children>
                    </AnchorPane>
                  </content>
                </TitledPane>
              </expandedPane>
              <panes>
                <fx:reference source="personalTp" />
                <TitledPane fx:id="x2" animated="false" text="Positions held">
                  <content>
                    <AnchorPane id="Content" minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
                      <children>
                         <ListView prefHeight="621.0" prefWidth="454.0" AnchorPane.bottomAnchor="-2.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="74.0" />
                      </children>
                    </AnchorPane>
                  </content>
                </TitledPane>
              </panes>
            </Accordion>
          </children>
        </AnchorPane>
      </items>
    </SplitPane>
    <MenuBar layoutY="0.0" AnchorPane.rightAnchor="908.0">
      <menus>
        <Menu mnemonicParsing="false" text="File">
          <items>
            <MenuItem mnemonicParsing="false" text="Close" />
          </items>
        </Menu>
        <Menu mnemonicParsing="false" text="Edit">
          <items>
            <MenuItem mnemonicParsing="false" text="Delete" />
          </items>
        </Menu>
        <Menu mnemonicParsing="false" text="Help">
          <items>
            <MenuItem mnemonicParsing="false" text="About" />
          </items>
        </Menu>
      </menus>
    </MenuBar>
    <ToolBar layoutY="24.0" AnchorPane.leftAnchor="0.0">
      <items>
        <Button mnemonicParsing="false" text="Button" />
      </items>
    </ToolBar>
  </children>
</AnchorPane>

JavaFXDemoProject.java

public class JavaFXDemoProject extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml"));
        Scene scene = new Scene(root);
        stage.setScene(scene);
        stage.show();
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        launch(args);
    }
}

问题

1) 我想做的事情有可能吗?

2) 为什么bidirectionalBinding 不起作用

感谢的任何帮助

我像这个一样更改了您的控制器类

public void initialize(URL url, ResourceBundle rb) {
    assert tableview != null : "fx:id="tableview" was not injected: check your FXML file 'UserMaster.fxml'.";
 colName.setCellValueFactory(
    new PropertyValueFactory<Person,String>("name"));        
colSurname.setCellValueFactory(                
    new PropertyValueFactory<Person,String>("surname"));
colCountry.setCellValueFactory(
    new PropertyValueFactory<Person,String>("country"));     
buildData();
tableview.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Person>() {
        @Override
        public void changed(ObservableValue<? extends Person> observable, Person oldValue, Person newValue) {
            if (oldValue !=null) name.textProperty().unbindBidirectional(oldValue.nameProperty());
            if (newValue !=null) name.textProperty().bindBidirectional(newValue.nameProperty());
        }
    });
}    //initialize

和你的人类有点

public class Person {
private StringProperty name = new SimpleStringProperty();
private StringProperty surname = new SimpleStringProperty();
private StringProperty country = new SimpleStringProperty();
public Person(String name, String surname, String country){
    this.name.set(name);
    this.surname.set(surname);
    this.country.set(country);
}
public StringProperty nameProperty(){return name;}
public StringProperty surnameProperty(){return surname;}
public StringProperty countryProperty(){return country;}
}

现在TextField可以绑定到Person 中的属性

相关内容