2014-12-07 5 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(); 
     } 
    } 

오류 때문에 최종 키워드로 발생되는 테스트했다.

첫 번째 예제와 두 번째 예제는 매우 혼동 스럽습니다.

답변

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; 
    } 
} 

자바 FX 속성을 사용하는 방법을 볼 수 JavaFX: Properties and Binding Tutorial를 참조하십시오. StringProperty 작품을 변경하는 방법

다음 그림은 명확해야합니다

reference someString (red) is final and cannot be changed

참조 someStringfinal과 빨간색 화살표 참조 (변경 될 수 없기 때문에 유형 B의 개체는 항상 같은 StringProperty 객체를 참조). 그러나 someString에 의해 참조되는 SimpleStringProperty 개체는 으로 변경 가능입니다. 예를 들어, String 개체를 가리 키도록 변경할 수있는 (녹색 화살표 참조)이라는 String 참조가 있습니다. setValue("second") (녹색 점선 화살표 참조)으로 전화하십시오.

+0

죄송합니다. 그리고 감사합니다. 그러나 아직도 나는 조금 얻지 않는다. 그래서 나는 "최종 값"을 ".set"으로 propertymethod (setString)을 통해 바꿀 수 있습니까? 최종 키워드는 변경할 수 없으므로 변경해서는 안된다는 것을 알았습니다. 그게 내가 혼란스러워하는 것. –

+0

아니요'someString' 참조를 변경할 수는 없지만 참조하는 객체는 변경할 수 있습니다. – isnot2bad

0

변수에 final이라는 레이블을 지정하면 값을 한 번만 할당 할 수 있습니다.

this.someString = new SimpleStringProperty(newString); 

이 허용되지 않는 setString(...) 방법은 여러 번 동일한 개체에서 호출 할 수 있기 때문에, : 당신이 setString(...) 방법 someString에 값을 할당하려고하기 때문에 두 번째 예에서는 컴파일 오류가 발생합니다.

대조적으로, 첫 번째 예에서는 final 변수 (인스턴스 필드)에 값이 할당 된 유일한 시간은 생성자에 포함되며 이는 주어진 개체에 대해 한 번만 호출 할 수 있습니다.기준에 값을 할당 차이가

참고

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

대상물의 상태 변화가되는 기준점 :

this.firstName.set(fName); 

번째 firstNamefinal 인 경우에도 완벽하게 정상입니다.

두 번째 예제에서 B 클래스를 작성하여 첫 번째 예의 Person 클래스와 동일한 패턴을 따르는 경우 제대로 작동합니다.

+0

나쁜 질문에 대해 사과드립니다. 그리고 감사합니다. 그러나 아직도 나는 조금 얻지 않는다. 그래서 나는 "최종 값"을 ".set"으로 propertymethod (setString)을 통해 바꿀 수 있습니까? –

+0

참조 값을 변경하지 않습니다. 참조가 가리키는 객체에 포함 된 문자열의 값을 변경하고 있습니다. 요점은'Person' 클래스에서'setEmail (...)'메소드는'email = ...'을 포함하지 않지만 클래스'B'에서'setString (...)'메소드는' 메소드에는'someString = ...;' –

+0

그림이 포함됩니다. 버킷의 StringProperty 종류입니까? 나는 '최종'때문에 양동이를 바꿀 수는 없지만 양동이의 내용 (someString)을 변경할 수 있습니다. 맞습니까? –