我目前正在尝试用JavaFX编程BlackJack,我使用ImageViews来显示卡。我有一个播放器模型,该模型具有String和我的Card类中的卡片的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)返回存储在方括号(0)中数字索引处的字符串。
我希望有人可以提供帮助吗?这是我第一次使用MVVM,并使用JavaFX编写更复杂的程序。谢谢。
不确定我是否会帮上大忙,但我只用一张这样的图片做了类似的事情:
Bindings.bindBidirectional(imageView.imageProperty(),manager.getCurrentImage());
具有经理的形象
public final ObjectProperty<Image> currentImage = new SimpleObjectProperty<>();
因此,在您的情况下,我想为每张卡直接放置一个Object元素会更容易然后去
playerCardOne.imageProperty().bind(vm.getPlayerCard(0).getImage())
回答您的问题,您需要先使cards
易于观察:
ObservableMap<String, Card> cards = FXCollections.observableMap(new LinkedHashMap<>());
然后您可以创建一个Binding
,它总是像这样返回地图中的第一项:
ObjectBinding<Image> firstImageBinding = Bindings.createObjectBinding(() -> {
Iterator<Map.Entry<String, Card>> iterator = cards.entrySet().iterator();
if (iterator.hasNext()) {
new Image("/cards/" + iterator.next().getKey() + ".png");
}
return null;
}, cards);
最后,您可以将其绑定到Image
属性:
playerCardOne.imageProperty().bind(firstImageBinding);
尽管这可能会如您所愿,但我相信您可以做得更好。
首先,我不知道您如何实现Card
类,但是每当需要固定的一组常量时,都应使用枚举:
西装类:
enum Suit {
CLUB, DIAMOND, HEART, SPADE
}
等级:
enum Rank {
ACE, DEUCE, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE, TEN, JACK, QUEEN, KING
}
卡类:
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);
}
}
现在,您无需使用Image
即可获得Card
的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