Impossible de supprimer le composant de DPanel

Zahidul Islam:

Je refondus mon code pour produire un Minimal, Exemple Reproductibles.

Question - Je ne suis pas en mesure de retirer la carte du panneau (je l'ai commenté dans le code où le problème se produit, voir la classe « ClearCardEventListener »).

code complet ci-dessous.

Avant d' exécuter le programme, vous aurez besoin d' une seule image qui doit être ajouté le téléchargement et aux ressources dossier = https://ibb.co/MNccGS0

  1. Exécutez le programme
  2. Cliquez sur le bouton « Ajouter carte » (cela va ajouter le 2 coeurs icône d'image sur le panneau)
  3. Cliquez sur le bouton « Effacer carte » (ce qui est le problème, où je suis incapable de retirer la carte du panneau)

    package debug.debug;
    
    import java.awt.Insets;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Collections;
    import java.util.List;
    
    import javax.swing.ImageIcon;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    
    public class App extends JFrame {
        public static void main(String[] args) {
            App app = new App();
    
            Insets insets = app.getInsets();
            app.setSize(300 + insets.left + insets.right,
                300 + insets.top + insets.bottom);
        }
    
        JPanel panel;
        JButton clearCardButton;
        JButton addCardButton;
    
        List<Card> playerCards = new ArrayList<Card> ();
    
        Deck deck = new Deck();
    
        public App() {
            setTitle("BlackJack Game");
            setVisible(true);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setLocationRelativeTo(null);
            panel = new JPanel();
            add(panel);
            panel.setLayout(null);
            addCardButton = new JButton("Add card");
            clearCardButton = new JButton("Clear card");
    
            panel.add(addCardButton);
            panel.add(clearCardButton);
    
            addCardButton.addActionListener(new AddCardEventListener(this, this.deck));
            clearCardButton.addActionListener(new ClearCardEventListener(this, this.deck));
    
            addCardButton.setBounds(150, 50, addCardButton.getPreferredSize().width, addCardButton.getPreferredSize().height);
            clearCardButton.setBounds(150, 100, clearCardButton.getPreferredSize().width, clearCardButton.getPreferredSize().height);
    
        }
    
        public JPanel getPanel() {
            return panel;
        }
    
        public void addPlayerCard(Card card) {
            playerCards.add(card);
        }
    
        public List<Card> getPlayerCards() {
            return playerCards;
        }
    
        public List<JLabel> getPlayerCardLabels() {
    
            List<JLabel> playerCardLabels = new ArrayList<JLabel> ();
    
            for (int i = 0; i<this.getPlayerCards().size(); i++) {
                playerCardLabels.add(this.getPlayerCards().get(i).getCardLabel());
    
            }
    
            return playerCardLabels;
        }
    
    }
    
    class AddCardEventListener implements ActionListener {
    
        private App app;
        private Deck deck;
    
        AddCardEventListener(App app, Deck deck) {
            this.app = app;
            this.deck = deck;
        }
    
        public void actionPerformed(ActionEvent arg0) {
    
            // Player gets a card
            app.addPlayerCard(deck.getCard());
    
            // Display that player's card
            app.getPanel()
                .add(app.getPlayerCards().get(0).getCardLabel()).setBounds(0, 0, 72, 96);
    
        }
    
    }
    
    class ClearCardEventListener implements ActionListener {
    
        private App app;
        private Deck deck;
    
        ClearCardEventListener(App app, Deck deck) {
            this.app = app;
            this.deck = deck;
        }
    
        public void actionPerformed(ActionEvent arg0) {
    
            System.out.println("DEBUG: " + app.getPlayerCards().get(0).getCardLabel());
    
            /***
             * 
             * NOT ABLE TO REMOVE CARD, WHY ???
             * 
             */
    
            app.getPlayerCards().get(0).getCardLabel().setIcon(null);
            app.getPlayerCards().get(0).getCardLabel().revalidate();
            app.getPlayerCards().get(0).getCardLabel().repaint();
    
            app.getPanel().remove(app.getPlayerCards().get(0).getCardLabel());
    
        }
    
    }
    
    class Card {
    
        private String suit;
        private String rank;
        private int value;
    
        public void setSuit(String suit) {
            this.suit = suit;
        }
        public void setRank(String rank) {
            this.rank = rank;
        }
        public void setValue(int value) {
            this.value = value;
        }
        public String getSuit() {
            return suit;
        }
        public String getRank() {
            return rank;
        }
        public int getValue() {
            return value;
        }
    
        // Hardcoded for debugging, so every card image is a 2 of hearts
        public JLabel getCardLabel() {
            return new JLabel(new ImageIcon(getClass()
                .getResource("/cards/2h.png")));
        }
    }
    
    class Deck {
    
        private final String RANKS[] = {
            "Ace",
            "Deuce",
            "Three",
            "Four",
            "Five",
            "Six",
            "Seven",
            "Eight",
            "Nine",
            "Ten",
            "Jack",
            "Queen",
            "King"
        };
        private final String SUITS[] = {
            "Spades",
            "Hearts",
            "Diamonds",
            "Clubs"
        };
    
        private Card[] deck;
        static private int cardPosition = 0;
    
        public Deck() {
            deck(); // Create the deck
            shuffle(); // shuffle the deck
        }
    
        public Card[] deck() {
            deck = new Card[52];
    
            for (int x = 0; x<deck.length; x++) {
                String rankTemp = RANKS[x % 13];
                String suitTemp = SUITS[x / 13];
                deck[x] = new Card();
                deck[x].setRank(rankTemp);
                deck[x].setSuit(suitTemp);
                deck[x].setValue((x % 13) + 1);
                if (deck[x].getValue() > 10)
                    deck[x].setValue(10);
                else if (deck[x].getValue() == 1)
                    deck[x].setValue(11);
            }
    
            return deck;
        }
    
        public void shuffle() {
            Collections.shuffle(Arrays.asList(deck()));
        }
    
        public Card[] getDeck() {
            return deck;
        }
    
        public Card getCard() {
            return deck[cardPosition++];
        }
    
    }
    
programmes alimentaires:

Problème n ° 1

Chaque fois que vous appelez Card#getCardLabelcela crée une nouvelle JLabelinstance ...

class Card {

    // Hardcoded for debugging, so every card image is a 2 of hearts
    public JLabel getCardLabel() {
        return new JLabel(new ImageIcon(getClass()
            .getResource("/cards/2h.png")));
    }
}

Cela signifie que lorsque vous faites ...

app.getPanel().add(app.getPlayerCards().get(0).getCardLabel()).setBounds(0, 0, 72, 96);

et...

System.out.println("DEBUG: " + app.getPlayerCards().get(0).getCardLabel());

et...

app.getPlayerCards().get(0).getCardLabel().setIcon(null);
app.getPlayerCards().get(0).getCardLabel().revalidate();
app.getPlayerCards().get(0).getCardLabel().repaint();

app.getPanel().remove(app.getPlayerCards().get(0).getCardLabel());

chaque appel est en fait de créer une nouvelle instance d'un JLabel, de sorte que celui sur l'écran n'a rien à voir avec celui que vous essayez de modifier.

Ainsi, au lieu, votre Card#getCardLabeldevrait créer UNE JLabelFOIS seulement, cela est également connu comme « le chargement paresseux » ...

class Card {

    private JLabel label;

    //...

    // Hardcoded for debugging, so every card image is a 2 of hearts
    public JLabel getCardLabel() {
        if (label == null) {
            // Simple image for demonstration purposes
            BufferedImage img = new BufferedImage(100, 150, BufferedImage.TYPE_INT_RGB);
            Graphics2D g2d = img.createGraphics();
            g2d.setColor(Color.WHITE);
            g2d.fillRect(0, 0, 100, 150);
            g2d.setColor(Color.RED);
            g2d.drawLine(0, 0, 100, 150);
            g2d.drawLine(100, 0, 0, 150);
            g2d.dispose();

            label = new JLabel(new ImageIcon(img));
        }

        return label;
    }
}

Problème n ° 2

Swing est paresseux (ok, il est « optimisé »), ce qui signifie que l'ajout ou la suppression de composants, en soi, ne déclenche pas une mise en page ou de la peinture passe. Ceci est fait pour que vous puissiez apporter des modifications massives à l'interface utilisateur et ne pas l'avoir essayer de mettre à jour chaque changement, ce qui serait très lent.

Cela signifie que lorsque vous ajoutez ou supprimez un composant, vous devez appeler également repaintpour déclencher une nouvelle passe de la peinture (je recommande aussi revalidate, mais vous n'êtes pas à l' aide des gestionnaires de mise en page, donc il ne va rien faire pour vous)

app.getPanel().remove(app.getPlayerCards().get(0).getCardLabel());
app.getPanel().repaint();

Je suppose que tu aimes

Origine http://43.154.161.224:23101/article/api/json?id=339073&siteId=1
conseillé
Classement