2

JavaFX 2.1 の TableView で問題に直面しています。データに基づいて TableRow を無効にしたい。

例:

public class RowData() {
private String name;
private boolean used;

public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public boolean isUsed(){
return this.used;
}
public void setUsed(boolean used) {
this.used = used;
}

}

プログラム内:

    public class ViewController implements Initializable {
    @FXML
        private TableView<RowData> tableAttribute;
    public void initialize(URL location, ResourceBundle resources) {
    List<RowData> data = new ArrayList<RowData>();
            // datatype col
            TableColumn<DataRow, String> attNameCol = new TableColumn<DataRow, DataRow>(
            "Name");
            attNameCol 
            .setCellValueFactory(new PropertyValueFactory<DataRow, String>(
                    "name"));
            attNameCol .setMinWidth(110.0);
            tableComponent.getColumns().addAll(attNameCol );
    loadData(data);

    tableAttribute.setItems(FXCollections.observableList(data));

    //I want to disable row which used = true, enable otherwise

    }
}

それを達成するにはどうすればよいですか?

4

1 に答える 1

6

行フィールドの値に基づいて行を無効にする方法の例:

  1. 必要に応じて、行のコンテンツを無効にするrowFactoryを使用します。
  2. テーブルが表示されたら、すべての TableRows を参照し、必要に応じて無効にします。

2 番目の原則を使用するサンプル アプリを作成します。

サンプルの重要なロジックは、テーブルがアクティブなステージに表示された後に実行される次のコードです。これにより、必要に応じて行が有効または無効になります (必要に応じて個別にスタイルを設定できるように、各行にスタイル クラスが適用されます)。このアプローチでは、テーブル内の行が変更または並べ替えられた場合、テーブルが正しくスタイル設定されるように、テーブルが再レンダリングされた後にルックアップおよび有効化/無効化コードをテーブルに対して再実行する必要があることに注意してください。行の正しい無効化されたプロパティがあります。

// highlight the table rows depending upon whether we expect to get paid.
int i = 0;
for (Node n: table.lookupAll("TableRow")) {
  if (n instanceof TableRow) {
    TableRow row = (TableRow) n;
    if (table.getItems().get(i).getWillPay()) {
      row.getStyleClass().add("willPayRow");
      row.setDisable(false);
    } else {
      row.getStyleClass().add("wontPayRow");
      row.setDisable(true);
    }
    i++;
    if (i == table.getItems().size())
      break;
  }
}

fxml コントローラーを使用すると、lookupAll は 0 の "TableRow" ノードを返します。table.setItems(data) の後、ルックアップ行が入力されるのはなぜですか?

これに答える前に、ルックアップを使用するよりも、rowFactory を使用することがこの質問に対する好ましい解決策であることに注意してください。理由のいくつかは、この回答の残りの部分で明らかになります。rowFactory アプローチのサンプルについては、このリンクされたサンプル コード by james-dを参照してください。

ルックアップは CSS 操作であり、ルックアップされるノードに css が適用されている必要があります。css を明示的に適用するには、ノードがシーンに配置された後にapplyCssを呼び出します。

コントローラーの問題点は、初期化呼び出しで、ノードがまだシーンにない可能性があることです。この問題を回避するには、次のパターンを適用できます。

Pane parent = (Pane) table.getParent();
parent.getChildren().remove(table);
Scene applyCssScene = new Scene(table);
table.applyCss();
table.layout();
applyCssScene.setRoot(null);
if (parent != null) {
    // Assumes that the original order in the parent does not matter.
    // If it did, you would also need to keep track of the child list position.
    parent.getChildren().add(table);
}
. . .
// perform css based lookup operation on the table.

これにより、テーブルを含むダミー ホルダー シーンが作成され、CSS が適用され (その後、CSS ベースのルックアップ操作が機能します)、シーンからテーブルが削除されるため、後で実際のシーンに追加できます。テーブルを元の親に戻します。お気づきかもしれませんが、これは少し紛らわしいです。上記で概説した CSS アプリケーション プロセスを、FXML コントローラーを使用したサンプル アプリケーションで実際に実行しようとしたわけではありませんが、うまくいくと思います。

私がリンクしたルックアップを使用するサンプル アプリでは、テーブルを含むステージが最初に表示されたにルックアップが行われるため、上記の複雑さは必要ありません。stage.show() 呼び出しは暗黙的にレイアウトを実行し、css アプリケーションは表示されるシーンを渡します (最初のシーンの計算されたサイズに基づいてステージの初期サイズを決定するために、おそらく他の理由でこれを行う必要があります)。

于 2012-06-07T06:06:01.850 に答える