Относительный вопрос новичка в Java.
Я пытаюсь установить цвет фона TableRow
в зависимости от того, выбран он или нет и / или истинно ли логическое значение в модели данных.
Я нашел способы сделать каждый, но не оба вместе в одном и том же setRowFactory
.
В итоге я хотел бы получить следующее (хотя и с ужасными цветами для примератолько!):
Как мне добиться этого?
Это то, что я нашел, не меняя цвет строки на основевыбор.Это адаптировано из ответа пользователя James_D здесь https://community.oracle.com/thread/3528543.
final ObservableSet<Integer> selectedRowIndexes = FXCollections.observableSet();
table.getSelectionModel().getSelectedCells().addListener((Change<? extends TablePosition> change) -> {
selectedRowIndexes.clear();
selectedRowIndexes.add( (table.getSelectionModel().getSelectedCells().get(0)).getRow() );
});
table.setRowFactory(tv -> {
TableRow<TestModel> row = new TableRow<>();
BooleanBinding selected = Bindings.createBooleanBinding(() ->
selectedRowIndexes.contains(new Integer(row.getIndex())), row.indexProperty(), selectedRowIndexes);
row.styleProperty().bind(Bindings.when(selected)
.then("-fx-background-color: green;")
.otherwise(""));
return row;
});
И это то, что я нашел при изменении цвета строки на основе значения ячейки.Это адаптировано из ответа пользователя kleopatra здесь TreeTableView: установка строки недоступна для редактирования .
table.setRowFactory(tv -> {
TableRow<TestModel> row = new TableRow<TestModel>() {
@Override
public void updateItem(TestModel testmodel, boolean empty) {
super.updateItem(testmodel, empty);
boolean locked = false;
if ( getItem() != null ) {
locked = getItem().lockedProperty().get();
setEditable( ! locked);
}
if (!isEmpty() && locked ) {
setStyle("-fx-background-color: red;");
}else{
setStyle(null);
}
}
};
return row;
});
Однако я получил две фабрики строк и не смог выяснитькак объединить их в один.
Если это поможет, вот MVCE, с которым я играл.У этого есть две фабрики ряда.Я не включил свои (многие!) Попытки объединить их, поскольку ни одна из них не сработала.
Я использую JavaFX8 (JDK1.8.0_181), NetBeans 8.2 и Scene Builder 8.3.
package test31;
import java.util.Arrays;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.Observable;
import javafx.beans.binding.Bindings;
import javafx.beans.binding.BooleanBinding;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.collections.ObservableSet;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.SelectionMode;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
import javafx.util.converter.BooleanStringConverter;
public class Test31 extends Application {
private Parent createContent() {
TableView<TestModel> table = new TableView<>();
ObservableList<TestModel> olTestModel = FXCollections.observableArrayList(testmodel -> new Observable[] {});
olTestModel.add(new TestModel("1", true));
olTestModel.add(new TestModel("2", false));
olTestModel.add(new TestModel("3", false));
olTestModel.add(new TestModel("4", true));
olTestModel.add(new TestModel("5", false));
TableColumn<TestModel, String> colText = new TableColumn<>("textfield");
colText.setCellValueFactory(cb -> cb.getValue().textFieldProperty());
colText.setCellFactory(TextFieldTableCell.forTableColumn());
TableColumn<TestModel, Boolean> colBoolean = new TableColumn<>("locked");
colBoolean.setCellValueFactory(cb -> cb.getValue().lockedProperty());
colBoolean.setCellFactory(TextFieldTableCell.forTableColumn(new BooleanStringConverter()));
table.getSelectionModel().setCellSelectionEnabled(true);
table.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
table.setEditable(true);
table.getColumns().addAll(Arrays.asList(colText, colBoolean));
table.setItems(olTestModel);
//****************************************************************************************
//First row factory: Set background colour based on whether or not the row is selected
final ObservableSet<Integer> selectedRowIndexes = FXCollections.observableSet();
table.getSelectionModel().getSelectedCells().addListener((Change<? extends TablePosition> change) -> {
selectedRowIndexes.clear();
selectedRowIndexes.add( (table.getSelectionModel().getSelectedCells().get(0)).getRow() );
});
table.setRowFactory(tv -> {
TableRow<TestModel> row = new TableRow<>();
BooleanBinding selected = Bindings.createBooleanBinding(() ->
selectedRowIndexes.contains(new Integer(row.getIndex())), row.indexProperty(), selectedRowIndexes);
row.styleProperty().bind(Bindings.when(selected)
.then("-fx-background-color: green;")
.otherwise(""));
return row;
});
//****************************************************************************************
//Second row factory: Set background colour based on the value of a boolean property
table.setRowFactory(tv -> {
TableRow<TestModel> row = new TableRow<TestModel>() {
@Override
public void updateItem(TestModel testmodel, boolean empty) {
super.updateItem(testmodel, empty);
boolean locked = false;
if ( getItem() != null ) {
locked = getItem().lockedProperty().get();
setEditable( ! locked);
}
if (!isEmpty() && locked ) {
setStyle("-fx-background-color: red;");
}else{
setStyle(null);
}
}
};
return row;
});
BorderPane content = new BorderPane(table);
return content;
}
public class TestModel {
private StringProperty textField;
private BooleanProperty locked;
public TestModel() {
this("", false);
}
public TestModel(
String textField,
boolean locked
) {
this.textField = new SimpleStringProperty(textField);
this.locked = new SimpleBooleanProperty(locked);
}
public String getTextField() {
return textField.get().trim();
}
public void setTextField(String textField) {
this.textField.set(textField);
}
public StringProperty textFieldProperty() {
return textField;
}
public boolean getLocked() {
return locked.get();
}
public void setLocked(boolean locked) {
this.locked.set(locked);
}
public BooleanProperty lockedProperty() {
return locked;
}
}
@Override
public void start(Stage stage) throws Exception {
stage.setScene(new Scene(createContent()));
stage.setTitle("Test");
stage.setWidth(500);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}