如何从 JavaFX8 中的 TableView 焦点模型获取 <S, T> 类型的 TableColumn 并仍然获得干净的编译?
How to get a TableColumn of type <S, T> from a TableView's focus model in JavaFX8 and still get a clean compile?
又一个亲戚Java菜鸟问题
我正在清理我的代码,正在处理最后两个编译器问题。两者都涉及需要从对 tableView.getFocusModel().getFocusedCell()
的调用中获取 <S, T>
类型的 TableColumn
。我收到编译器警告,但尚未能够解决它们。
我认为这些警告源于 TableView
的焦点模型对原始 TablePosition
类型的使用,如果我理解正确的话,这意味着任何 TableColumn
基于调用 tableView.getFocusModel().getFocusedCell()
返回的 TablePosition
has 声明为 raw 类型,以便干净编译的代码。
即。如果我这样做:
TablePosition pos = tableView.getFocusModel().getFocusedCell();
那么如果我这样做,我将永远得到一个干净的编译:
TableColumn col = pos.getTableColumn();
TablePosition.java 在 Java 文档中说 pos.getTableColumn()
returns TableColumn<S,T>
我想它可以' 如果焦点模型返回原始 TablePosition
类型,则执行此操作。我明白了。
但是,如果我必须将 TableColumn
声明为原始的,我如何 "convert" 将其键入 <S, T>
(或绕过泛型? ) 这样我最终得到 TableColumn<S, T>
并且仍然得到一个干净的编译 ?一旦我知道了这一点,我希望能够解决最后两个编译器问题。
我用 and while that works, suppressing compiler errors isn't what I want to do. I also tried using the TableView
's selection model rather than the focus model but it seems that table.getSelectionModel().getSelectedCells().get(0)
returns a raw TablePosition
, too. The focus model's use of raw TablePosition
was explained by user Jai in the reply to an earlier question I asked 中接受的答案进行了试验。
如果有帮助,这是我正在尝试解决最后两个编译器问题的 MVCE。两者都涉及需要在每个 getFocussedColumn()
和 getGraphic()
方法中获得 <S, T>
类型的 TableColumn
。我留下了我的评论,这样你就可以看到我试过的东西。此外,为了重现问题,MVCE 必须使用我的应用程序使用的自定义复选框单元格。我已经尽可能多地修剪它以尽可能保持它 "M"。
我正在使用 JavaFX8 (JDK1.8.0_181)、NetBeans 8.2 和 Scene Builder 8.3.
我正在使用“-Xlint:unchecked”进行编译。
package test28;
import java.util.function.BiConsumer;
import java.util.function.Function;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Test28 extends Application {
static TableView<TestModel> table = new TableView<>();
ToggleGroup tgRadios = new ToggleGroup();
private Parent createContent() {
ObservableList<TestModel> olTestModel = FXCollections.observableArrayList();
olTestModel.add(new TestModel(false));
olTestModel.add(new TestModel(true));
olTestModel.add(new TestModel(false));
table.setItems(olTestModel);
Platform.runLater(() -> table.getSelectionModel().selectFirst());
//Column with a custom cell that renders as a CheckBox
TableColumn<TestModel, Boolean> colCheckbox = createCheckBoxColumn("checkbox", TestModel::checkboxProperty, TestModel::setCheckbox);
table.getSelectionModel().setCellSelectionEnabled(true);
table.setEditable(true);
table.getColumns().add(colCheckbox);
Button btnGetFocussedCol = new Button("get focussed col");
btnGetFocussedCol.setOnAction(event -> {
TableColumn<TestModel, Boolean> col = getFocussedColumn();
System.out.println("col = " + col);
});
Button btnGetGraphic = new Button("get graphic");
btnGetGraphic.setOnAction(event -> {
Node node = getGraphic();
System.out.println("node = " + node);
});
BorderPane content = new BorderPane(table);
HBox hb = new HBox();
hb.setPadding(new Insets(10,10,10,10));
hb.setSpacing(20.0);
hb.getChildren().addAll(btnGetFocussedCol, btnGetGraphic);
content.setTop(hb);
return content;
}
//*************************************************************************************
//First of two remaining compiler issues to resolve
private static <S, T> TableColumn<S, T> getFocussedColumn() {
//getFocusedCell() returns a RAW TablePosition
TablePosition pos = table.getFocusModel().getFocusedCell();
//pos.getTableColumn() should be returning TableColumn<S,T>, however, pos is a RAW type
//so I guess that's why I'm getting an unchecked conversion warning on the following line
//TableColumn<S, T> col = pos.getTableColumn();
//Casting it generates an unchecked cast warning
//TableColumn<S, T> col = (TableColumn<S, T>) pos.getTableColumn();
//Using a RAW TableColumn type fixes the warnings on the TableColumn declaration
//but generates an unchecked conversion warning on the "return col" line
TableColumn col = pos.getTableColumn();
//table.getColumns() returns ObservableList<TableColumn<S,?>>, so I cannot use the following
//TableColumn<S, T> col = table.getColumns().get(pos.getColumn());
//getFocusedCell().getTableColumn() returns TableColumn<S,?>, so I cannot do the following
//return table.getFocusModel().getFocusedCell().getTableColumn();
//unchecked conversion warning generated on this line when TableColumn is raw
//==> HOW CAN I "CONVERT" A RAW TABLECOLUMN TO TABLECOLUMN<S, T>?
return col;
}
//*************************************************************************************
//Second of two remaining compiler issues to resolve
public <S, T> Node getGraphic() {
TablePosition pos = table.getFocusModel().getFocusedCell();
//Declaring TableColumn as a raw type generates an "unchecked call to call(P) as a member of the raw type Callback"
//warning on the TableCell declaration below
TableColumn col = pos.getTableColumn();
//getCellFactory().call() expects CellDataFeatures<S,T> and returns ObservableValue<T>
//unchecked call to call(P) warning generated on this line when TableColumn is raw
//==> HOW CAN I "CONVERT" A RAW TABLECOLUMN TO TABLECOLUMN<S, T>?
TableCell cell = (TableCell) col.getCellFactory().call(col);
Node cellGraphic = cell.getGraphic();
return cellGraphic;
}
//*************************************************************************************
//Create a custom checkbox
public <S> TableColumn<S, Boolean> createCheckBoxColumn(String title,
Function<S, BooleanProperty> methodGetCheckBoxFieldProperty,
BiConsumer<? super S, ? super Boolean> methodSetCheckBoxField) {
TableColumn<S, Boolean> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> methodGetCheckBoxFieldProperty.apply(cellData.getValue()));
col.setCellFactory(column -> CheckBoxCell.createCheckBoxCell());
col.setOnEditCommit(event -> {
Boolean masterCode = event.getNewValue();
S dataModel = event.getRowValue();
methodSetCheckBoxField.accept(dataModel, masterCode);
});
return col;
}
//*************************************************************************************
//The custom CheckBoxCell class
public static class CheckBoxCell<S, T> extends TableCell<S, T> {
private final CheckBox checkBox = new CheckBox();
public CheckBoxCell() {
setGraphic(checkBox);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
public static <S> CheckBoxCell<S, Boolean> createCheckBoxCell() {
return new CheckBoxCell<S, Boolean>();
}
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setText( ((Boolean) item).toString());
checkBox.setSelected( (Boolean) item);
setGraphic(checkBox);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
}
//*************************************************************************************
public class TestModel {
private BooleanProperty checkbox;
public TestModel() {
this(false);
}
public TestModel(
boolean checkbox
) {
this.checkbox = new SimpleBooleanProperty(checkbox);
}
public boolean getCheckbox() {
return checkbox.get();
}
public void setCheckbox(boolean checkbox) {
this.checkbox.set(checkbox);
}
public BooleanProperty checkboxProperty() {
return checkbox;
}
}
@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);
}
}
感谢用户 Jai 的帮助,答案是从对 tableView.getFocusModel().getFocusedCell();
的调用中获取 TableColumn<S, T>
并获得干净编译的唯一方法是使用 @SuppressWarnings("unchecked")
注释.
这是因为:
TableView
API 被写入 return 来自 getFocusedCell()
的原始 TablePosition
类型。
- 无法将原始类型 "convert" 转换为
<S, T>
(或任何其他)类型。它们是非常不同的东西。
因此,我的问题中 MVCE 中突出显示的编译器问题是这样解决的:
@SuppressWarnings("unchecked")
private static <S, T> TableColumn<S, T> getFocussedColumnx() {
TablePosition<S, T> pos = (TablePosition<S, T>) table.getFocusModel().getFocusedCell();
TableColumn<S, T> col = (TableColumn<S, T>) pos.getTableColumn();
return col;
}
还有这个:
@SuppressWarnings("unchecked")
public <S, T> Node getGraphic() {
TablePosition<S, T> pos = (TablePosition<S, T>) table.getFocusModel().getFocusedCell();
TableColumn<S, T> col = (TableColumn<S, T>) pos.getTableColumn();
TableCell<S, T> cell = (TableCell<S, T>) col.getCellFactory().call(col);
Node cellGraphic = cell.getGraphic();
return cellGraphic;
}
谢谢 Jai 为我指明了正确的方向。
又一个亲戚Java菜鸟问题
我正在清理我的代码,正在处理最后两个编译器问题。两者都涉及需要从对 tableView.getFocusModel().getFocusedCell()
的调用中获取 <S, T>
类型的 TableColumn
。我收到编译器警告,但尚未能够解决它们。
我认为这些警告源于 TableView
的焦点模型对原始 TablePosition
类型的使用,如果我理解正确的话,这意味着任何 TableColumn
基于调用 tableView.getFocusModel().getFocusedCell()
返回的 TablePosition
has 声明为 raw 类型,以便干净编译的代码。
即。如果我这样做:
TablePosition pos = tableView.getFocusModel().getFocusedCell();
那么如果我这样做,我将永远得到一个干净的编译:
TableColumn col = pos.getTableColumn();
TablePosition.java 在 Java 文档中说 pos.getTableColumn()
returns TableColumn<S,T>
我想它可以' 如果焦点模型返回原始 TablePosition
类型,则执行此操作。我明白了。
但是,如果我必须将 TableColumn
声明为原始的,我如何 "convert" 将其键入 <S, T>
(或绕过泛型? ) 这样我最终得到 TableColumn<S, T>
并且仍然得到一个干净的编译 ?一旦我知道了这一点,我希望能够解决最后两个编译器问题。
我用 TableView
's selection model rather than the focus model but it seems that table.getSelectionModel().getSelectedCells().get(0)
returns a raw TablePosition
, too. The focus model's use of raw TablePosition
was explained by user Jai in the reply to an earlier question I asked
如果有帮助,这是我正在尝试解决最后两个编译器问题的 MVCE。两者都涉及需要在每个 getFocussedColumn()
和 getGraphic()
方法中获得 <S, T>
类型的 TableColumn
。我留下了我的评论,这样你就可以看到我试过的东西。此外,为了重现问题,MVCE 必须使用我的应用程序使用的自定义复选框单元格。我已经尽可能多地修剪它以尽可能保持它 "M"。
我正在使用 JavaFX8 (JDK1.8.0_181)、NetBeans 8.2 和 Scene Builder 8.3.
我正在使用“-Xlint:unchecked”进行编译。
package test28;
import java.util.function.BiConsumer;
import java.util.function.Function;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.application.Platform;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Test28 extends Application {
static TableView<TestModel> table = new TableView<>();
ToggleGroup tgRadios = new ToggleGroup();
private Parent createContent() {
ObservableList<TestModel> olTestModel = FXCollections.observableArrayList();
olTestModel.add(new TestModel(false));
olTestModel.add(new TestModel(true));
olTestModel.add(new TestModel(false));
table.setItems(olTestModel);
Platform.runLater(() -> table.getSelectionModel().selectFirst());
//Column with a custom cell that renders as a CheckBox
TableColumn<TestModel, Boolean> colCheckbox = createCheckBoxColumn("checkbox", TestModel::checkboxProperty, TestModel::setCheckbox);
table.getSelectionModel().setCellSelectionEnabled(true);
table.setEditable(true);
table.getColumns().add(colCheckbox);
Button btnGetFocussedCol = new Button("get focussed col");
btnGetFocussedCol.setOnAction(event -> {
TableColumn<TestModel, Boolean> col = getFocussedColumn();
System.out.println("col = " + col);
});
Button btnGetGraphic = new Button("get graphic");
btnGetGraphic.setOnAction(event -> {
Node node = getGraphic();
System.out.println("node = " + node);
});
BorderPane content = new BorderPane(table);
HBox hb = new HBox();
hb.setPadding(new Insets(10,10,10,10));
hb.setSpacing(20.0);
hb.getChildren().addAll(btnGetFocussedCol, btnGetGraphic);
content.setTop(hb);
return content;
}
//*************************************************************************************
//First of two remaining compiler issues to resolve
private static <S, T> TableColumn<S, T> getFocussedColumn() {
//getFocusedCell() returns a RAW TablePosition
TablePosition pos = table.getFocusModel().getFocusedCell();
//pos.getTableColumn() should be returning TableColumn<S,T>, however, pos is a RAW type
//so I guess that's why I'm getting an unchecked conversion warning on the following line
//TableColumn<S, T> col = pos.getTableColumn();
//Casting it generates an unchecked cast warning
//TableColumn<S, T> col = (TableColumn<S, T>) pos.getTableColumn();
//Using a RAW TableColumn type fixes the warnings on the TableColumn declaration
//but generates an unchecked conversion warning on the "return col" line
TableColumn col = pos.getTableColumn();
//table.getColumns() returns ObservableList<TableColumn<S,?>>, so I cannot use the following
//TableColumn<S, T> col = table.getColumns().get(pos.getColumn());
//getFocusedCell().getTableColumn() returns TableColumn<S,?>, so I cannot do the following
//return table.getFocusModel().getFocusedCell().getTableColumn();
//unchecked conversion warning generated on this line when TableColumn is raw
//==> HOW CAN I "CONVERT" A RAW TABLECOLUMN TO TABLECOLUMN<S, T>?
return col;
}
//*************************************************************************************
//Second of two remaining compiler issues to resolve
public <S, T> Node getGraphic() {
TablePosition pos = table.getFocusModel().getFocusedCell();
//Declaring TableColumn as a raw type generates an "unchecked call to call(P) as a member of the raw type Callback"
//warning on the TableCell declaration below
TableColumn col = pos.getTableColumn();
//getCellFactory().call() expects CellDataFeatures<S,T> and returns ObservableValue<T>
//unchecked call to call(P) warning generated on this line when TableColumn is raw
//==> HOW CAN I "CONVERT" A RAW TABLECOLUMN TO TABLECOLUMN<S, T>?
TableCell cell = (TableCell) col.getCellFactory().call(col);
Node cellGraphic = cell.getGraphic();
return cellGraphic;
}
//*************************************************************************************
//Create a custom checkbox
public <S> TableColumn<S, Boolean> createCheckBoxColumn(String title,
Function<S, BooleanProperty> methodGetCheckBoxFieldProperty,
BiConsumer<? super S, ? super Boolean> methodSetCheckBoxField) {
TableColumn<S, Boolean> col = new TableColumn<>(title);
col.setCellValueFactory(cellData -> methodGetCheckBoxFieldProperty.apply(cellData.getValue()));
col.setCellFactory(column -> CheckBoxCell.createCheckBoxCell());
col.setOnEditCommit(event -> {
Boolean masterCode = event.getNewValue();
S dataModel = event.getRowValue();
methodSetCheckBoxField.accept(dataModel, masterCode);
});
return col;
}
//*************************************************************************************
//The custom CheckBoxCell class
public static class CheckBoxCell<S, T> extends TableCell<S, T> {
private final CheckBox checkBox = new CheckBox();
public CheckBoxCell() {
setGraphic(checkBox);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
public static <S> CheckBoxCell<S, Boolean> createCheckBoxCell() {
return new CheckBoxCell<S, Boolean>();
}
@Override
protected void updateItem(T item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setGraphic(null);
} else {
setText( ((Boolean) item).toString());
checkBox.setSelected( (Boolean) item);
setGraphic(checkBox);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
}
//*************************************************************************************
public class TestModel {
private BooleanProperty checkbox;
public TestModel() {
this(false);
}
public TestModel(
boolean checkbox
) {
this.checkbox = new SimpleBooleanProperty(checkbox);
}
public boolean getCheckbox() {
return checkbox.get();
}
public void setCheckbox(boolean checkbox) {
this.checkbox.set(checkbox);
}
public BooleanProperty checkboxProperty() {
return checkbox;
}
}
@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);
}
}
感谢用户 Jai 的帮助,答案是从对 tableView.getFocusModel().getFocusedCell();
的调用中获取 TableColumn<S, T>
并获得干净编译的唯一方法是使用 @SuppressWarnings("unchecked")
注释.
这是因为:
TableView
API 被写入 return 来自getFocusedCell()
的原始TablePosition
类型。- 无法将原始类型 "convert" 转换为
<S, T>
(或任何其他)类型。它们是非常不同的东西。
因此,我的问题中 MVCE 中突出显示的编译器问题是这样解决的:
@SuppressWarnings("unchecked")
private static <S, T> TableColumn<S, T> getFocussedColumnx() {
TablePosition<S, T> pos = (TablePosition<S, T>) table.getFocusModel().getFocusedCell();
TableColumn<S, T> col = (TableColumn<S, T>) pos.getTableColumn();
return col;
}
还有这个:
@SuppressWarnings("unchecked")
public <S, T> Node getGraphic() {
TablePosition<S, T> pos = (TablePosition<S, T>) table.getFocusModel().getFocusedCell();
TableColumn<S, T> col = (TableColumn<S, T>) pos.getTableColumn();
TableCell<S, T> cell = (TableCell<S, T>) col.getCellFactory().call(col);
Node cellGraphic = cell.getGraphic();
return cellGraphic;
}
谢谢 Jai 为我指明了正确的方向。