如何将 imageview 绑定到数组索引 mvvm javafx
how to bind imageview to array index mvvm javafx
我目前正尝试在 JavaFX 中编写 BlackJack 程序,我使用 ImageViews 来显示卡片。我有一个播放器模型,它有一个由我的 Card class.
中的字符串和卡片组成的 LinkedHashMap
LinkedHashMap<String, Card> cards = new LinkedHashMap<>();
字符串总是看起来像 "ACE-CLUB" 或 "SIX-HEART",因为我导入的图像也是这样命名的 ("ACE-CLUB.png")。
现在,我不知道应该如何将 ImageView playerCardOne 绑定到 LinkedHashMap 的第一个位置。我考虑过制作一个只存储 LinkedHashMap 的字符串的数组,但我仍然不知道如何绑定 ImageView。我认为它可能看起来像这样,但它不起作用:
playerCardOne.imageProperty().bind(new Image("/cards/" + vm.getPlayerCard(0) + ".png"));
方法 getPlayerCard(0) returns 存储在括号中数字索引处的字符串 (0)。
希望有人能帮忙?这是我第一次使用 MVVM 并使用 JavaFX 制作更复杂的程序。谢谢。
不确定我会有多大帮助,但我只用一张这样的图片做了类似的事情:
Bindings.bindBidirectional(imageView.imageProperty(),manager.getCurrentImage());
经理形象
public final ObjectProperty<Image> currentImage = new SimpleObjectProperty<>();
所以在你的情况下,我想直接为每张卡片放置一个对象元素会更容易
然后选择
playerCardOne.imageProperty().bind(vm.getPlayerCard(0).getImage())
回答你的问题,你需要先让cards
可观察:
ObservableMap<String, Card> cards = FXCollections.observableMap(new LinkedHashMap<>());
然后您可以创建一个 Binding
,它总是 returns 您地图中的第一个项目,如下所示:
ObjectBinding<Image> firstImageBinding = Bindings.createObjectBinding(() -> {
Iterator<Map.Entry<String, Card>> iterator = cards.entrySet().iterator();
if (iterator.hasNext()) {
return new Image("/cards/" + iterator.next().getKey() + ".png");
}
return null;
}, cards);
最后,你可以把它绑定到一个Image
属性:
playerCardOne.imageProperty().bind(firstImageBinding);
虽然这可能会如您所愿,但我相信您可以做得更好。
首先,我不知道你是如何实现的 Card
class,但任何时候你需要一组固定的常量,你应该使用枚举:
花色 class:
enum Suit {
CLUB, DIAMOND, HEART, SPADE
}
排名class:
enum Rank {
ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING
}
卡片class:
public class Card {
private final Suit suit;
private final Rank rank;
public Card(Suit suit, Rank rank) {
this.suit = suit;
this.rank = rank;
}
public Suit getSuit() {
return suit;
}
public Rank getRank() {
return rank;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Card card = (Card) o;
return suit == card.suit &&
rank == card.rank;
}
@Override
public int hashCode() {
return Objects.hash(suit, rank);
}
@Override
public String toString() {
return String.format("%s %s", suit, rank);
}
}
现在,您可以用 Card
获得 Image
而无需使用 Map<String, Card>
:
public Image getImageForCard(Card card) {
String url = String.format("/cards/%s-%s.png", card.getRank(), card.getSuit());
return new Image(url);
}
如果你一直对List<Card>
中第一张卡片的图片感兴趣,你可以这样获取:
ObservableList<Card> cards = FXCollections.observableArrayList();
ImageView playerCardOne = new ImageView();
ObjectBinding<Image> firstImageBinding = Bindings.createObjectBinding(() ->
cards.isEmpty() ? null : getImageForCard(cards.get(0)), cards);
playerCardOne.imageProperty().bind(firstImageBinding);
cards.add(new Card(Suit.CLUB, Rank.ACE));
// playerCardOne's image is now /cards/ACE-CLUB.png
cards.add(0, new Card(Suit.HEART, Rank.SIX));
// playerCardOne's image is now /cards/SIX-HEART.png
我目前正尝试在 JavaFX 中编写 BlackJack 程序,我使用 ImageViews 来显示卡片。我有一个播放器模型,它有一个由我的 Card class.
中的字符串和卡片组成的 LinkedHashMapLinkedHashMap<String, Card> cards = new LinkedHashMap<>();
字符串总是看起来像 "ACE-CLUB" 或 "SIX-HEART",因为我导入的图像也是这样命名的 ("ACE-CLUB.png")。
现在,我不知道应该如何将 ImageView playerCardOne 绑定到 LinkedHashMap 的第一个位置。我考虑过制作一个只存储 LinkedHashMap 的字符串的数组,但我仍然不知道如何绑定 ImageView。我认为它可能看起来像这样,但它不起作用:
playerCardOne.imageProperty().bind(new Image("/cards/" + vm.getPlayerCard(0) + ".png"));
方法 getPlayerCard(0) returns 存储在括号中数字索引处的字符串 (0)。
希望有人能帮忙?这是我第一次使用 MVVM 并使用 JavaFX 制作更复杂的程序。谢谢。
不确定我会有多大帮助,但我只用一张这样的图片做了类似的事情:
Bindings.bindBidirectional(imageView.imageProperty(),manager.getCurrentImage());
经理形象
public final ObjectProperty<Image> currentImage = new SimpleObjectProperty<>();
所以在你的情况下,我想直接为每张卡片放置一个对象元素会更容易 然后选择
playerCardOne.imageProperty().bind(vm.getPlayerCard(0).getImage())
回答你的问题,你需要先让cards
可观察:
ObservableMap<String, Card> cards = FXCollections.observableMap(new LinkedHashMap<>());
然后您可以创建一个 Binding
,它总是 returns 您地图中的第一个项目,如下所示:
ObjectBinding<Image> firstImageBinding = Bindings.createObjectBinding(() -> {
Iterator<Map.Entry<String, Card>> iterator = cards.entrySet().iterator();
if (iterator.hasNext()) {
return new Image("/cards/" + iterator.next().getKey() + ".png");
}
return null;
}, cards);
最后,你可以把它绑定到一个Image
属性:
playerCardOne.imageProperty().bind(firstImageBinding);
虽然这可能会如您所愿,但我相信您可以做得更好。
首先,我不知道你是如何实现的 Card
class,但任何时候你需要一组固定的常量,你应该使用枚举:
花色 class:
enum Suit {
CLUB, DIAMOND, HEART, SPADE
}
排名class:
enum Rank {
ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING
}
卡片class:
public class Card {
private final Suit suit;
private final Rank rank;
public Card(Suit suit, Rank rank) {
this.suit = suit;
this.rank = rank;
}
public Suit getSuit() {
return suit;
}
public Rank getRank() {
return rank;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Card card = (Card) o;
return suit == card.suit &&
rank == card.rank;
}
@Override
public int hashCode() {
return Objects.hash(suit, rank);
}
@Override
public String toString() {
return String.format("%s %s", suit, rank);
}
}
现在,您可以用 Card
获得 Image
而无需使用 Map<String, Card>
:
public Image getImageForCard(Card card) {
String url = String.format("/cards/%s-%s.png", card.getRank(), card.getSuit());
return new Image(url);
}
如果你一直对List<Card>
中第一张卡片的图片感兴趣,你可以这样获取:
ObservableList<Card> cards = FXCollections.observableArrayList();
ImageView playerCardOne = new ImageView();
ObjectBinding<Image> firstImageBinding = Bindings.createObjectBinding(() ->
cards.isEmpty() ? null : getImageForCard(cards.get(0)), cards);
playerCardOne.imageProperty().bind(firstImageBinding);
cards.add(new Card(Suit.CLUB, Rank.ACE));
// playerCardOne's image is now /cards/ACE-CLUB.png
cards.add(0, new Card(Suit.HEART, Rank.SIX));
// playerCardOne's image is now /cards/SIX-HEART.png