如何将imageview绑定到数组索引mvvm javafx

问题描述 投票:0回答:2

我目前正在尝试用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编写更复杂的程序。谢谢。

java javafx mvvm imageview bind
2个回答
0
投票

不确定我是否会帮上大忙,但我只用一张这样的图片做了类似的事情:

Bindings.bindBidirectional(imageView.imageProperty(),manager.getCurrentImage());

具有经理的形象

public final ObjectProperty<Image> currentImage = new SimpleObjectProperty<>();

因此,在您的情况下,我想为每张卡直接放置一个Object元素会更容易然后去

playerCardOne.imageProperty().bind(vm.getPlayerCard(0).getImage())

0
投票

回答您的问题,您需要先使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即可获得CardMap<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
© www.soinside.com 2019 - 2024. All rights reserved.