从TextField编辑TableView的值

时间:2014-04-11 13:52:09

标签: java javafx-2

您好我正在尝试http://code.makery.ch/java/javafx-2-tutorial-intro/中示例的精神来创建一个类似的应用程序,其中TableView值可以通过一系列TextField而不是弹出窗体来编辑。之所以我愿意这样做是因为我在一个类似的应用程序中有很多字段我想开发,我想避免用户在TableView上编辑它们

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

我还尝试添加textProperty一个ChangeListener,所以当它更改为更新ObservableList的propoerties时,这也无法正常工作

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

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>

JavaFXDe​​moProject.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

任何帮助表示赞赏

1 个答案:

答案 0 :(得分:1)

我改变了你的控制器类

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

中的属性