gpt4 book ai didi

java - 当对象属于某种类型时在桌面 View 上显示图像

转载 作者:太空宇宙 更新时间:2023-11-04 06:17:15 25 4
gpt4 key购买 nike

首先,抱歉我的英语,感谢您的阅读..:-)

我有一个表格 View ,它显示了有关名为 Produto 的类的一些信息。

该表有一列显示带有 produto 名称的图像,但我只需要为某种类型的 Produto 显示此图像。

Produto 类:

public class Produto {

private Integer id;
private String nome;
private Tipo type;


//get set..

}

表格列:

TableColumn<Produto,String> tbcNomeProduto = new TableColumn<Produto,String>();

tbcNomeProduto.setCellValueFactory(new PropertyValueFactory<Produto, String>("nome"));
tbcNomeProduto.setCellFactory(new Callback<TableColumn<Produto,String>,TableCell<Produto,String>>(){
@Override
public TableCell<Produto, String> call(TableColumn<Produto, String> param) {
TableCell<Produto, String> cell = new TableCell<Produto, String>(){



@Override
public void updateItem(String item, boolean empty) {

if(item != null){

HBox box= new HBox();
box.setSpacing(10);
VBox vbox = new VBox();
vbox.getChildren().add(new Label(item));

ImageView imageview = new ImageView();
imageview.setImage(new Image(getClass().getResourceAsStream("16x16.png")));

box.getChildren().addAll(imageview,vbox);

setGraphic(box);
}
}
};

return cell;
}

});

如何访问 updateItem 中的当前 Produto 对象,以获取 Produto 的类型并选择是否在表格上显示图像?

最佳答案

我通常处理此问题的方法是使表列的类型与表的类型相同:

TableColumn<Produto, Produto> tbcNomeProduto = new TableColumn<>();

原因是此列单元格中显示的值取决于两个因素:Produto.nomeProduto.type;换句话说,此列中的单元格是 Produto.nomeProduto.type 的 View 。因此,包含显示单元格所需的所有数据的最小实体(即单元格是 View 的最小实体)是 Produto 实例本身。

所以现在我会这样做

tbcNomeProduto.setCellValueFactory(new Callback<CellDataFeatures<Produto, Produto>, ObservableValue<Produto>>() {
@Override
public ObservableValue<Produto> call(CellDataFeatures<Produto, Produto> data) {
return new ReadOnlyObjectWrapper<>(data.getValue());
}
});
tbcNomeProduto.setCellFactory(new Callback<TableColumn<Produto, Produto>, TableCell<Produto, Produto>>() {
@Override
public TableCell<Produto, Produto> call(TableColumn<Produto, Produto> col) {
return new TableCell<Produto, Produto>() {

private HBox hbox = new HBox();
private ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("16x16.png")));
private Label label = new Label();

// anonymous constructor:
{
setGraphic(hbox);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}

@Override
public void updateItem(Produto item, boolean empty) {
super.updateItem(item, empty);

hbox.getChildren().clear();
if (item != null) {
Tipo type = item.getType();
String nome = item.getNome();
if (/* should show image...*/) {
hbox.getChildren().add(imageView);
}
hbox.getChildren().add(label);
}
}
};
}
});

在您的示例中,您的 Produto 类是一个 POJO,遵循标准 JavaBean 约定,并且不使用可观察的 JavaFX 属性。因此,如果要针对显示的 Produto 实例更改 nome 字段,则表无论如何都没有机会更新,因为 nome 字段不可观察。

如果您要在 Produto 类中包含可观察字段,并且这些值在显示对象时可能会发生变化,那么您需要在表格单元格中做更多的工作。这是因为 nome 字段可能会发生变化,而 Produto 实例不会发生变化;后者意味着不会调用 updateItem(...) 方法。我想包含为可能遇到此问题的其他读者管理此问题的代码,即使它与当前的问题无关。为此使用匿名内部类很快就会变得非常难看,因此我将恢复到 Java 8 代码并在本节中使用 lambda 表达式。

所以假设 Produto 类看起来像

public class Produto {
private final StringProperty nome = new SimpleStringProperty();
public StringProperty nomeProperty() {
return nome ;
}
public final String getNome() {
return nomeProperty().get();
}
public final void setNome(String nome) {
nomeProperty().set(nome);
}

private final ObjectProperty<Tipo> type = new SimpleObjectProperty<>() ;
// get/set and property accessor methods as above....

private final IntegerProperty id = new SimpleIntegerProperty();
// get/set and property accessor methods...
}

如上所述,你有

TableColumn<Produto, Produto> tbcNomeProduto = new TableColumn<>();
tbcNomeProduto.setCellValueFactory(cellData -> new ReadOnlyPropertyWrapper<>(cellData.getValue()));

对于单元工厂,您需要为各个属性创建监听器。当显示的 Produto 发生更改时注册和取消注册这些属性:

tbc.setCellFactory(col -> {
Label label = new Label();
ImageView imageView = new ImageView(new Image(getClass().getResourceAsStream("16x16.png")));
HBox hbox = new HBox();

TableCell<Produto, Produto> cell = new TableCell<>();
// listener for the nome property changing:
ChangeListener<String> nomeListener = (obs, oldNome, newNome) -> label.setText(newNome);
// listener for type property changing:
ChangeListener<Tipo> typeListener = (obs, oldType, newType) -> {
if ( /* should show image */) {
hbox.getChildren().setAll(imageView, label);
} else {
hbox.getChildren().setAll(label);
}
}
cell.itemProperty().addListener((obs, oldProduto, newProduto) -> {
if (oldProduto != null) {
oldProduto.nomeProperty().removeListener(nomeListener);
oldProduto.typeProperty().removeListener(typeListener);
}
if (newProduto == null) {
cell.setGraphic(null);
} else {
label.setText(newProduto.getNome());
Tipo type = newProduto.getType();
if (/* should show graphic */) {
hbox.getChildren().setAll(imageView, label);
} else {
hbox.getChildren().setAll(label);
}
cell.setGraphic(hbox);
newProduto.nomeProperty().addListener(nomeListener);
newProduto.typeProperty().addListener(typeListener);
}
});
cell.setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
return cell ;
});

这很容易概括为在不同条件下显示不同的图像,甚至操作单元格的 CSS 样式等。

关于java - 当对象属于某种类型时在桌面 View 上显示图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27925697/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com