2014-12-07 20 views
0

我想學習Tableview並得到一些例子。如何更改javaFX中StringProperty類型的最終值?

我沒有得到如何StringProperty的作品。

雖然Person類的字段是最後instanace,

setEmailButton可以改變它的值。

import javafx.application.Application; 
    import javafx.beans.property.*; 
    import javafx.collections.*; 
    import javafx.event.*; 
    import javafx.geometry.Insets; 
    import javafx.scene.*; 
    import javafx.scene.control.*; 
    import javafx.scene.control.cell.PropertyValueFactory; 
    import javafx.scene.layout.VBox; 
    import javafx.scene.text.Font; 
    import javafx.stage.Stage; 

    public class PropertyBasedTableView extends Application { 
     private TableView<Person> table = new TableView<Person>(); 
     private final ObservableList<Person> data = FXCollections.observableArrayList(); 
     private void initData() { 
     data.setAll(
      new Person("Jacob", "Smith", "[email protected]"), 
      new Person("Isabella", "Johnson", "[email protected]"), 
      new Person("Ethan", "Williams", "[email protected]") 
     ); 
     } 

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

     @Override public void start(Stage stage) { 
     initData(); 

     stage.setTitle("Table View Sample"); 
     stage.setWidth(450); 
     stage.setHeight(500); 

     final Label label = new Label("Address Book"); 
     label.setFont(new Font("Arial", 20)); 

     TableColumn firstNameCol = new TableColumn("First Name"); 
     firstNameCol.setMinWidth(100); 
     firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName")); 

     TableColumn lastNameCol = new TableColumn("Last Name"); 
     lastNameCol.setMinWidth(100); 
     lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName")); 

     TableColumn emailCol = new TableColumn("Email"); 
     emailCol.setMinWidth(200); 
     emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email")); 

     table.setItems(data); 
     table.getColumns().addAll(firstNameCol, lastNameCol, emailCol); 
     table.setPrefHeight(300); 

     final Button setEmailButton = new Button("Set first email in table to [email protected]"); 
     setEmailButton.setOnAction(new EventHandler<ActionEvent>() { 
      @Override public void handle(ActionEvent event) { 
      if (data.size() > 0) { 
       data.get(0).setEmail("[email protected]"); 
      } 
      } 
     }); 


     final VBox vbox = new VBox(10); 
     vbox.setPadding(new Insets(10, 0, 0, 10)); 
     vbox.getChildren().addAll(label, table, setEmailButton); 

     stage.setScene(new Scene(new Group(vbox))); 
     stage.show(); 
     } 

     public static class Person { 
     private final StringProperty firstName; 
     private final StringProperty lastName; 
     private final StringProperty email; 

     private Person(String fName, String lName, String email) { 
      this.firstName = new SimpleStringProperty(fName); 
      this.lastName = new SimpleStringProperty(lName); 
      this.email = new SimpleStringProperty(email); 
     } 

     public String getFirstName() { return firstName.get(); } 
     public void setFirstName(String fName) { firstName.set(fName); } 
     public StringProperty firstNameProperty() { return firstName; } 
     public String getLastName() { return lastName.get(); } 
     public void setLastName(String lName) { lastName.set(lName); } 
     public StringProperty lastNameProperty() { return lastName; } 
     public String getEmail() { return email.get(); } 
     public void setEmail(String inMail) { email.set(inMail); } 
     public StringProperty emailProperty() { return email; } // if this method is commented out then the tableview will not refresh when the email is set. 
     } 
    } 

然後,我做出結論,自己「找到了!最後StringProperty類型值是可以改變的!」

,所以我不得不測試

package zzzzDelete; 

    import javafx.application.Application; 
    import javafx.beans.property.SimpleStringProperty; 
    import javafx.beans.property.StringProperty; 
    import javafx.stage.Stage; 

    class A{ 

     void someTest(){ 
      B insB = new B("why"); 
      System.out.println(insB.getString()); 
      insB.setString("omg"); 
      System.out.println(insB.getString()); 
     } 

     class B{ 
      private final StringProperty someString; 
      private B(String someString){ 
       this.someString = new SimpleStringProperty(someString); 
      } 

      public String getString(){ 
       return someString.get(); 
      } 

      public void setString(String newString){ 
       this.someString = new SimpleStringProperty(newString);  // error 
      } 

     } 
    } 

    public class SomeTest { 
     public static void main(String[] args){ 
      A a = new A(); 
      a.someTest(); 
     } 
    } 

錯誤是因爲final關鍵字發生。

我很困惑第一個和第二個例子。

回答

0

在初始化(在構造函數中發生)後,您無法更改不可變的(final)字段。相反,只是通過setValue(String)設置StringProperty值:

class B { 
    private final StringProperty someString; 

    private B(String someString){ 
     this.someString = new SimpleStringProperty(someString); 
    } 

    public String getString(){ 
     return someString.get(); 
    } 

    public void setString(String newString){ 
     this.someString.setValue(newString); 
    } 

    public StringProperty stringProperty() { 
     return this.someString; 
    } 
} 

閱讀JavaFX: Properties and Binding Tutorial看到如何使用JavaFX的屬性。

下面的圖片應該闡明如何改變StringProperty作品:

reference someString (red) is final and cannot be changed

B類型的對象總是引用相同StringProperty對象,因爲參考someStringfinal,不能改變(見紅色箭頭)。但someString引用的SimpleStringProperty對象是可變的。它包含一個名爲valueString參考(請參閱綠色箭頭),該參考可以更改爲指向另一個String對象,例如,通過撥打setValue("second")(見綠色虛線箭頭)。

+0

對不起的問題。謝謝。但我仍然沒有得到什麼。所以我可以通過propertymethod(setString)用「.set」更改「最終值」?我瞭解到final關鍵字不能改變,不應該改變。這就是我很困惑。 – 2014-12-07 03:00:18

+0

不,你不能改變引用'someString',但你可以改變它所引用的對象。 – isnot2bad 2014-12-07 04:02:36

0

當您將變量標記爲final時,它只能被賦值一次。在第二個例子中,你會得到一個編譯錯誤,因爲你試圖在setString(...)方法的值賦給someString

this.someString = new SimpleStringProperty(newString); 

這是不允許的,因爲setString(...)方法可以在同一對象上多次調用。

相比之下,在你的第一個例子中,只有任何一個final變量(實例字段)被分配了值纔在構造函數中,對於任何給定的對象當然只能被調用一次。

注有一參考分配值之間的差:

this.someString = new SimpleStringProperty(...); 

改變對象的狀態,以該參考點

this.firstName.set(fName); 

第二即使firstNamefinal也完全正常。

如果您在第二個示例中編寫了B類,以跟第一個示例中Person類的模式相同,它將正常工作。

+0

對不起的問題。謝謝。但我仍然沒有得到什麼。所以我可以通過propertymethod(setString)用「.set」更改「最終值」? – 2014-12-07 02:58:05

+0

您不會更改參考值。您正在更改參考點所在對象所包含的字符串的值。重點在於'Person'類中,'setEmail(...)'方法不包含'email = ...',但是在你的類'B'中,'setString(...)方法包括'someString = ...;' – 2014-12-07 02:59:44

+0

調整音量。是StringProperty類的桶?我不能因爲'最終'而改變桶,但我可以改變桶中的內容(someString)。這是正確的想法嗎? – 2014-12-07 03:06:22

相關問題