问题描述
一个相对的Java新手问题.
A relative Java newbie question.
我正在清理代码,并在以编程方式选择 TableView
.我能够解决警告,但不知道是什么原因引起的.
I'm cleaning up my code and came across two unchecked warnings ("unchecked method invocation" and "unchecked conversion") while programmatically selecting a cell in a TableView
. I was able to resolve the warnings but don't understand what caused them.
这就是我最初对 select()
进行编码的方式:
This was how I initially coded the select()
:
TablePosition<?, ?> previousPos;
//...
table.getSelectionModel().select
(previousPos.getRow(), previousPos.getTableColumn());
我通过将其更改为警告来解决了警告.
and I resolved the warnings by changing it to this.
table.getSelectionModel().select
(previousPos.getRow(), table.getColumns().get(previousPos.getColumn()));
我不了解它们之间的区别,因此我看了一下Java源代码.如果我正确地解释了它,则 TableView.java 中的 select()
方法需要 TableColumn< S,?>
.但是, TablePosition.java 中的 getTableColumn()
返回 TableColumn< S,T>
,而中的 getColumns()
em> TableView.java 返回类型为 TableColumn(S,?)
的 ObservableList
.
I didn't understand the difference so I had a look at the Java source code. If I'm interpreting it correctly, the select()
method in TableView.java expects TableColumn<S, ?>
. However, getTableColumn()
in TablePosition.java returns TableColumn<S,T>
while getColumns()
in TableView.java returns an ObservableList
of type TableColumn(S, ?)
.
我想这就是为什么 table.getColumns().get(...)
编译干净并且 previousPos.getTableColumn()
产生错误的原因.
I guess that's why table.getColumns().get(...)
compiles clean and previousPos.getTableColumn()
generates errors.
但是,从编译器的角度来看, TableColumn< S,?>
和 TableColumn< S,T>
之间有什么区别?为什么它不解析(这是正确的术语?)将 T
转换为?
.
But what is the difference, then, between TableColumn<S, ?>
and TableColumn<S,T>
from the compiler's point of view? Why doesn't it resolve (is that the correct term?) the T
to ?
.
如果有帮助,这里是我正在尝试解决的MVCE,但答案超出了我目前的Java知识. select()
位于 moveToPreviousPos()
中.
If it helps, here is the MVCE I was playing with to try and figure it out, but the answer is beyond my current Java knowledge. The select()
is in moveToPreviousPos()
.
我正在使用JavaFX8(JDK1.8.0_181),NetBeans 8.2和Scene Builder 8.3.
I'm using JavaFX8 (JDK1.8.0_181), NetBeans 8.2 and Scene Builder 8.3.
package test27;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TablePosition;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class Test27 extends Application {
TableView<TestModel> table = new TableView<>();
//Both of these stop the "unchecked conversion" error on line #51 (previousPos = table.getFocusModel().getFocusedCell();)
// TablePosition previousPos;
TablePosition<?, ?> previousPos;
//but using the following generates the "unchecked conversion" error
// TablePosition<TestModel, ?> previousPos;
private Parent createContent() {
ObservableList<TestModel> olTestModel = FXCollections.observableArrayList();
olTestModel.add(new TestModel("A"));
olTestModel.add(new TestModel("B"));
olTestModel.add(new TestModel("C"));
table.setItems(olTestModel);
TableColumn<TestModel, String> colText = new TableColumn<>("text");
colText.setCellValueFactory(cellData -> cellData.getValue().textProperty());
colText.setCellFactory(TextFieldTableCell.forTableColumn());
table.getSelectionModel().setCellSelectionEnabled(true);
table.setEditable(true);
table.getColumns().add(colText);
Button btnGetTablePosition = new Button("get table position");
btnGetTablePosition.setOnAction(event -> {
//TableView.java: getFocusedCell returns TablePosition<S, ?>
previousPos = table.getFocusModel().getFocusedCell(); //Line #51
outputPreviousPos(previousPos);
});
Button btnMoveToPreviousPos = new Button("move to previous pos");
btnMoveToPreviousPos.setOnAction(event -> {
moveToPreviousPos(previousPos);
});
BorderPane content = new BorderPane(table);
HBox hb = new HBox();
hb.getChildren().addAll(btnGetTablePosition, btnMoveToPreviousPos);
content.setTop(hb);
return content;
}
public void outputPreviousPos(TablePosition previousPos){
System.out.println("previousPos = " + previousPos);
}
public void moveToPreviousPos(TablePosition previousPos) {
//select() in TableView.java expects TableColumn<S, ?>
//getTableColumn() in TablePosition.java returns TableColumn<S,T>
//getColumns() in TableView.java returns an ObservableList of type TableColumn(S, ?)
//Is that why the following line generates "unchecked method invocation" and "unchecked conversion" errors
//table.getSelectionModel().select
// (previousPos.getRow(), previousPos.getTableColumn());
//but the following line compiles clean?
table.getSelectionModel().select
(previousPos.getRow(), table.getColumns().get(previousPos.getColumn()));
}
public class TestModel {
private StringProperty text;
public TestModel() {
this("");
}
public TestModel(
String text
) {
this.text = new SimpleStringProperty(text);
}
public String getText() {
return text.get();
}
public void setText(String text) {
this.text.set(text);
}
public StringProperty textProperty() {
return text;
}
}
@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);
}
}
推荐答案
首先,我想说这是 TableView.getFocusModel().getFocusedCell()
(或 focusedCellProperty()
)使用原始的 TablePosition
类型(原始的 TablePosition
只能转换为 TablePositon<?,?>
而不会产生警告).更合适的版本可能是 TablePosition< S,?>
.
First of all, I would say that it was a design flaw that TableView.getFocusModel().getFocusedCell()
(or focusedCellProperty()
) uses the raw TablePosition
type (raw TablePosition
can only be cast to TablePositon<?, ?>
without generating warning). The more suitable version could have been TablePosition<S, ?>
.
由于 TablePosition
表示 TableView
中任何地方的特定单元格,因此对于 TableView.getFocusModel().focusedCellProperty()
:
Since TablePosition
represents a particular cell anywhere in the TableView
, then for TableView.getFocusModel().focusedCellProperty()
:
-
S
的类型对于TableView< S>
是固定的(即类型是已知的). -
T
的类型是指特定TableColumn
的类型,它可以根据聚焦的单元格而变化.您无法在编译时确定类型,因为您不知道将选择哪个TableColumn< S,T>
.
- The type of
S
is fixed forTableView<S>
(i.e. the type is known). - The type of
T
refers to the type of a particularTableColumn
, which can change depending on which cell has been focused. You cannot determine the type at compile time because you have no idea whichTableColumn<S, T>
would be selected.
现在到第二点.
这是因为 TableColumn< S,?>
中的?
是通配符.由于 TableViewFocusModel< S>
不具有 T
类型,并且它不能基于固定列进行操作,因此必须使用?
在这里(请参阅我解释的第一点).
This is because ?
in TableColumn<S, ?>
is a wildcard. Since TableViewFocusModel<S>
does not have the type T
and that it does not operate based on a fixed column, so it has to use ?
here (see the first point that I explained).
另一方面, TableView.getSelectionModel().select()
期望 row
的 int
和 TableColumn<S,?>
列.由于您具有 TablePosition<?,因此?>previousPos
,因此 previousPos
也会返回 TableColumn<?,?>
. TableColumn< S,?
和 TableColumn<?,?>
非常不同-您可以将 TableColumn
与另一个 TableView
,如果允许 TableColumn<?,?>
.
On the other hand, TableView.getSelectionModel().select()
expects an int
for row
and a TableColumn<S, ?>
for column. Since you had TablePosition<?, ?> previousPos
, so previousPos
would return a TableColumn<?, ?>
as well. TableColumn<S, ?
and TableColumn<?, ?>
are very different - you could use the TableColumn
from another TableView
if TableColumn<?, ?>
is allowed.
最后,如果 TableView.getFocusModel().getFocusedCell()
的API是固定的,那么在使用 select()
时就不会有问题.在此之前,您可以手动将其强制转换为 TablePosition< TestModel,?>
,或者像您一样使用 TableView.getColumns().get(index)
Finally, if the API for TableView.getFocusModel().getFocusedCell()
is fixed, then there would not be a problem when you use select()
. Until then, you could manually cast it to TablePosition<TestModel, ?>
with a suppression, or use TableView.getColumns().get(index)
like what you did.
这篇关于当使用TableColumn< S,T& gt;时,为什么编译器会生成未经检查的警告而不是TableColumn< S,<>在JavaFX8 TableView中选择一个单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!