2017-04-22 6 views
0

Ich erstelle ein Blackjack-Spiel und muss die JFrame jedes Mal aktualisieren, wenn der Benutzer auf eine Schaltfläche klickt. Der Rahmen ist jedoch nicht aktualisiert! Ich habe stundenlang versucht, das vergeblich zu beheben.Reloading GUI in JFrame Probleme

Wie lade ich alle Elemente im Rahmen basierend auf dem Stapel von ImageIcon Objekten, die ich zum Laden von Bildern verwende, ordnungsgemäß neu?

Hier ist mein Code:

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Stack; 

public class Blackjack extends JFrame implements ActionListener { 
    public void drawGUI(boolean firstTime) { 
     getContentPane().removeAll(); 

     setLayout(new GridLayout(3, 9, 1, 1)); 
     updateValues(); 

     add(new JLabel(DEALER_TEXT, SwingConstants.CENTER)); 
     add(new JLabel("Value: " + computerValue, SwingConstants.CENTER)); 
     for(int i = 0; i < computerCards.size(); i++) 
      add(new JLabel(computerCards.get(i).getImagePath())); 

     leaveSpacing(false); 

     add(new JLabel(USER_TEXT, SwingConstants.CENTER)); 
     add(new JLabel("Value: " + userValue, SwingConstants.CENTER)); 
     for(int i = 0; i < userCards.size(); i++) 
      add(new JLabel(userCards.get(i).getImagePath())); 

     leaveSpacing(true); 

     if(firstTime) { 
      hitButton.addActionListener(this); 
      standButton.addActionListener(this); 
     } 

     leaveSpacing(3); 
     add(hitButton); 
     add(standButton); 
     leaveSpacing(1); 
    } 
} 
+1

TL; DR; Bevor Sie verrückt werden, warum schreiben Sie nicht [mcve], um es Ihnen leichter zu machen, das Problem zu lokalisieren und Hilfe zu bekommen? – c0der

+0

@ c0der Danke für Ihre Antwort. Das Problem besteht darin, zu aktualisieren. In der Methode actionPerformed (ActionEvent evt) wird drawGUI (boolean firstTime) aufgerufen, um den gesamten JFrame neu zu zeichnen; aber es entfernt nicht alle Elemente und aktualisiert sie. Es hält nur die Elemente gleich. –

+1

Ich verstehe das. Ich nehme an, dass das Problem mit viel kürzerem Code demonstriert werden kann. [mcve] bedeutet auch kompilierbar – c0der

Antwort

2

Sie benötigen revalidate(); und repaint(); am Ende Ihres drawGUI(); Methode aufzurufen. Dies sollte den Trick machen.

Dies wird vor auf SO jedoch beantwortet finden Sie unter: Java Swing revalidate and repaint

+0

Sie haben mich unzählige Stunden gerettet. Vielen Dank! –

+0

Wie muss dies am Ende der Methode geschehen? Warum nicht vorher? –

+0

Eigentlich müssen Sie 'revalidate', nachdem Sie ein' removeAll' gemacht haben, um Swing zu benachrichtigen, ein Panel ist "dreckig", und Sie müssen 'repaint' aufrufen, nachdem Sie eine Komponente neu eingelesen haben, damit der Layout-Manager das Layout neu berechnet nochmal. Es muss also nicht wirklich am Ende sein. – skubski

2

Wie wäre dies eine (Arbeits-) mcve:

import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.ImageIcon; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.SwingConstants; 

public class BalckJack extends JFrame implements ActionListener { 

    private JButton hitButton = new JButton("Hit"); 
    private int computerValue; 

    public static void main(String[] args) { 

     BalckJack frame = new BalckJack(); 
     frame.setTitle("Cards"); 
     frame.setSize(800, 320); 
     frame.setLocationRelativeTo(null); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
    } 

    public BalckJack() { 

     computerValue = 0; 

     for(int i = 0; i < 27; i++) { 
      add(new JLabel(new ImageIcon(""))); 
     } 

     drawGUI(true); 
    } 

    public void drawGUI(boolean firstTime) { 

     getContentPane().removeAll(); 

     setLayout(new GridLayout(1, 2, 1, 1)); 

     add(new JLabel("Value: " + computerValue++, SwingConstants.CENTER)); 

     if(firstTime) { 
      hitButton.addActionListener(this); 
     } 

     add(hitButton); 
     revalidate(); //(!!!!) 
    } 

    @Override 
    public void actionPerformed(ActionEvent evt) { 

     drawGUI(false); 
    } 
}