29/04/10 10:13
Yuppie
Ciao a tutti
nel mio gioco in memory sto cercando di creare una tabella con dentro la classifica dei migliori dieci giocatori e che compaia al termine della partita se si vince, ma purtroppo mi compare solo una jframe con il contenuto vuoto e non capisco la motivazione. Metto il file zip e posto le parti di codice.
Main
Carta
Mazzo
Classifica
Record
View
Contatore
GUI_classifica
Nell'oggetto classifica segna un paio di errori ma non dovrebbero influire nel problema che ho io.
nel mio gioco in memory sto cercando di creare una tabella con dentro la classifica dei migliori dieci giocatori e che compaia al termine della partita se si vince, ma purtroppo mi compare solo una jframe con il contenuto vuoto e non capisco la motivazione. Metto il file zip e posto le parti di codice.
Main
package memory; /** * @author Nicolò */ /** * In questo semplice main, viene creato un mazzo con le sue carte e viene passato a un oggetto della classe View * che si prendere cura di farlo visualizzare. */ public class Main { public static void main(final String[] args) { Mazzo mazzo = new Mazzo(); @SuppressWarnings("unused") View v = new View(mazzo); } }
Carta
package memory; /** * @author Nicolò */ import java.awt.Image; import java.awt.Toolkit; /** * Nella classe Carta vengono create funzioni che tendono a memorizzare lo stato della carta, ossia se è presente * (COPERTA o VISIBILE) o se è stata rimossa dal tavolo, e a dirci la sue proprietà, tipo l'immagine */ public class Carta { /** * Queste costanti ci informano dello stato della carta: * - VISIBILE: la carte è visibile con la sua immagine; * - COPERTA: è visibile il retro della carta; * - RIMOSSA: la carta è stata rimossa dal gioco. */ static final int VISIBILE = 1; static final int COPERTA = 0; static final int RIMOSSA = -1; /** * - stato: ci indica se la carta è stata è presente (coperta o girata) o se è stata rimossa dal gioco; * - tipo: indica il seme della carta; * - immagine: variabile di tipo Image contenente l'immagine del seme della carta; * - retro: variabile di tipo image che contiene il retro della carta (uguale per tutte le carte). */ private int stato; private int tipo; private Image immagine; private Image retro; /** * Costruttore della classe. Quando un oggetto di tipo Carta viene inizializzato richiede il seme (o tipo) della carta. * Quindi imposta il tipo, poi carica l'immagine del rispettivo simbolo e infine imposta lo stato su COPERTA, * poichè tutte le carte a inizio gioco mostrano il retro. * @param simbolo */ public Carta(int simbolo){ tipo = simbolo; caricaImmagine(simbolo); stato = Carta.COPERTA; } /** * Funzione che ritorna un immagine a seconda dello stato: * - l'immagine se lo stato è VISIBILE; * - il retro se lo stato è COPERTA; * - fa return null se lo stato è RIMOSSA. * @return */ public Image Immagine(){ if (stato == Carta.VISIBILE) return immagine; else if(stato == Carta.COPERTA) return retro; else return null; } /** * Funzione utilizzata per girare la carta, quindi può modificare lo stato da COPRTA a VISIBILE e viciversa, * ma non può impostarlo su RIMOSSA. */ public void volta(){ if (stato == Carta.VISIBILE) stato = Carta.COPERTA; else if(stato == Carta.COPERTA) stato = Carta.VISIBILE; } /** * Funzione che imposta lo stato della carta su RIMOSSA. In sostanza la funzione lo scopo di questa funzione è quella di rimuovere dal gioco la carta. */ public void rimuovi(){ stato = Carta.RIMOSSA; } /** *Funzione similie alla funzione rimuovi: in sostanza il compito di questa funzione è quella di riassegnare lo stato * COPERTA alla carta facendola tornare quindi visibile in gioco. */ public void riassegna(){ stato = Carta.COPERTA; } /** * Funzione che ha il compito di caricare le immagini per poi passarle al mediatracker nell classe Mazzo * e quindi renderle visibili. Alla funzione viene passato una variabile di tipo int che rappresenta il seme * della carta e quindi indica alla funzione quale immagine caricare. * @param n */ public void caricaImmagine(int n){ Toolkit kit = Toolkit.getDefaultToolkit(); immagine = kit.getImage("carta"+n+".jpg"); retro = kit.getImage("carta_retro.jpg"); } /** *Funzione il cui semplice compito è quello di fare un return simbolo della carta in esame. * @return */ public int simbolo() { return tipo; } /** * Funzione booleana che effettua un comparazione tra la carta che si sta valutando e un altra passata come parametro. * Ritorna true se le carte sono uguali, false in caso contrario. * * @param compara * @return */ public boolean Uguale(Carta compara) { if (compara.simbolo() == tipo) return true; else return false; } /** * Funzione booleana che controlla se la carta analizzata è stata rimossa o è ancora in gioco. * Ritorna true se le carta è stata rimossa, false in caso contrario. * @return */ public boolean Rimossa() { if (stato == Carta.RIMOSSA) return true; else return false; } /** * Funzione booleana che controlla se la carta analizzata è visibile oppure se è coperta o rimossa. * Ritorna true se le carta è visibile, false in caso contrario. * @return */ public boolean Visibile(){ if(stato == Carta.VISIBILE) return true; else return false; } }
Mazzo
package memory; /** * @author Nicolò * Nella classe Mazzo vengono creati 16 oggetti di tipo Carta, i quali vengono istanziati con i relativi semi e le relative proprietà. * In questa classe vengono poi mescolate le carte. */ public class Mazzo { private Carta carte[]; /** * Costruttore della classe Mazzo. Qui viene istanziato un vettore di 16 carte che cosituiscono a tutti gli effetti un mazzo. * In seguito le carte vengono mescolate con l'apposita funzione mescola(). */ public Mazzo(){ carte = new Carta[16]; mescola(); } /** * Funzione che viene richiamata nel costruttore per mescolare la carte del mazzo. A ogni indice da 1 a 16 viene assegnato un sign booleano che viene messo a false * per tutti gli indici. In seguito usando un math.random() si sceglie a caso uno dei 16 indici e se il suo sign è a false * allora alll'elemento carta corrispondente a quel numero non è stata ancora dato un seme. Se invece sign è true il ciclo Do..While ripete l'operazione * fino a trovare un indice libero. */ public void mescola(){ boolean sign[] = new boolean[16]; int indice; for(int i = 0; i < 16; i++) sign[i] = false; for(int i = 0; i < 2; i++) for(int s = 0; s < 8; s++){ do{ indice = (int)(Math.random()*16); if (indice == 16) indice = 15; } while(sign[indice]); carte[indice] = new Carta(s); sign[indice] = true; } } /** * Semplice funzione che fa il return della carta con le sue relative caratteristiche. Alla funzione viene passato il numero della carta che si intende vedere. * @param i * @return */ public Carta Carta(int i){ return carte[i]; } }
Classifica
package memory; import java.io.BufferedInputStream; import java.io.BufferedOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.ObjectInputStream; import java.io.ObjectOutputStream; import java.io.Serializable; import java.util.Vector; /** * Classe che astrae la lista di records. * <p> * La lista è implementata tramite il metodo dei riferimenti. * * @author Nicolò Torreggiani */ public class Classifica implements Serializable{ /** * */ private static final long serialVersionUID = 1L; private static final int MAX_RECORDS = 10; // La radice della lista. private Record radice; // Numero di elementi in lista private int numero; private Vector listeners; /** * Funzione statica che consente di ricavare da una stringa i dati di un record. * * @param stringa La stringa da cui ricavare i dati del record. * @return Un oggetto Record corrispondente ai dati della stringa, il cui puntatore al record successivo è nullo. * @throws IllegalArgumentException Questa eccezione viene lanciata se non è possibile ricavare tutti i dati dalla stringa. */ public static Record analizzaRecord(String stringa) throws IllegalArgumentException { String nome; int mosse; // Divide la stringa String parti[] = stringa.split(","); // Controlla l'esistenza effettiva delle stringhe try { if (parti[0] == null || parti[1] == null) throw new IllegalArgumentException(); } catch (ArrayIndexOutOfBoundsException e) { throw new IllegalArgumentException(); } // Ricava il nome nome = parti[0]; // Prova a ricavare i numeri try { mosse = Integer.parseInt(parti[1]); } catch (NumberFormatException e) { throw new IllegalArgumentException(); } return new Record(nome, mosse, null); } /** * Costruttore della lista. Imposta le variabili e la radice. */ public Classifica() { numero = 0; radice = new Record(null, 0, null); listeners = new Vector(); } /** * Aggiunge un record alla lista in modo ordinato. L'ordine è decrescente. * * @param record Il record da aggiungere. */ public void Aggiungi(Record record) { Record puntatore = radice; // Scorriamo la lista in cerca del posto giusto while (puntatore.successivo != null) { if (record.Compara(puntatore.successivo) <= 0) break; puntatore = puntatore.successivo; } // Inseriamo il record nel posto giusto record.successivo = puntatore.successivo; puntatore.successivo = record; // Aumentiamo il numero di records numero++; // Controlliamo che non si sia superato il limite if (numero > Classifica.MAX_RECORDS) { RimuoviUltimo(); } } /** * Versione alternativa dell'aggiunta di un record. I parametri sono direttamente i dati del record. * * @param nome Nome del giocatore che ha effettuato il record. * @param punteggio Punteggio del record. * @param altezza Altezza del record. */ //public void Aggiungi(String nome, int punteggio, int altezza) { // Aggiungi(new Record(nome, punteggio, altezza, null)); //} public int Numero() { return numero; } /** * Consente di ottenere il record indice-esimo. * * @param indice L'indice del record che si vuole ottenere. * @return Il record indice-esimo. * @throws ArrayIndexOutOfBoundsException Se l'indice è scorretto viene lanciata una ArrayIndexOutOfBoundsException. */ public Record Record(int indice) throws ArrayIndexOutOfBoundsException { Record puntatore = radice; // Controlliamo che l'indice sia corretto if (indice < 0 || indice >= numero) throw new ArrayIndexOutOfBoundsException(); // Scorriamo fino al record desiderato for (int i = 0; i <= indice; i++) puntatore = puntatore.successivo; return puntatore; } // Rimuove l'ultimo record, se si è superato il limite private void RimuoviUltimo() { Record puntatore = radice; // Se non ci sono elementi si esce if (radice.successivo == null) return; // Scorre fino al penultimo while (puntatore.successivo.successivo != null) puntatore = puntatore.successivo; // Tronca il collegamento con l'ultimo puntatore.successivo = null; // Diminuisce il numero numero--; } //Salva la rubrica nell'aposito file public void save(){ //Per evitare che qualche listener sia un oggetto di una //classe non serializabile, svuotima la lista dei listener //prima di salvare e poi la ripristiniamo Vector tempListeners = listeners; listeners = new Vector(); try{ ObjectOutputStream out = new ObjectOutputStream( new BufferedOutputStream( new FileOutputStream(file))); out.writeObject(this); out.close(); } catch (Exception e){ System.out.print("An Exception has been raised while saving the file " + file); System.out.println(e); } listeners = tempListeners; } public void carica(){ Classifica migliori; Object o = null; try{ ObjectInputStream in = new ObjectInputStream( new BufferedInputStream( new FileInputStream(file))); o = in.readObject(); } catch (Exception e){ System.out.print("An exception has been raised while reading the file " + file + "\n" + e); } if((o != null) && (o instanceof Classifica)) migliori = (Classifica)o; } }
Record
package memory; import java.io.Serializable; /** * Un elemento della lista dei records. * <p> * Questa classe è utilizzata soltanto dalla ListaRecords. Contiene allo stesso tempo i dati del record e un puntatore al record successivo. * <p> * La classe implementa l'interfaccia Serializable. Infatti i records sono salvati come oggetti nel file dei records. * * @author Nicolò Torreggiani */ public class Record implements Serializable { /** * */ private static final long serialVersionUID = 1L; /** * Nome del giocatore che ha effettuato il record. */ public String nome; /** * Numero di mosse fatte dal giocatore */ public int mosse; /** * Puntatore al record successivo. Viene impostato dalla lista quindi è transient. */ transient public Record successivo; /** * Costruttore del record. * * @param n Nome del giocatore che ha effettuato il record. * @param m numero di mosse * @param s Puntatore al record successivo. */ public Record(String n, int m, Record s) { nome = n; mosse = m; successivo = s; } // // Confronta due records. // @param record Il record da confrontare con questo. // @return 0 se sono uguali, >0 se questo record ha usato più mosse per vincere di quello di confronto, <0 altrimenti. // Poi compare le i nomi dei due record: 0 sono uguali, se < 0 la prima stringa precede la seconda, se > 0 al contrario public int Compara(Record record) { int risultato; // Prima il numero di mosse risultato = this.mosse - record.mosse; // Poi il nome if (risultato == 0) risultato = this.nome.compareTo(record.nome); return risultato; } }
View
package memory; import java.awt.Graphics; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import javax.swing.JFrame; import javax.swing.JPanel; import java.awt.MediaTracker; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JDialog; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JOptionPane; /** * @author Nicolò * La classe View estende JPanel e implementa il MouseListener. L'oggetto di tipo View che verrà creato riceverà * come parametro un oggetto di tipo mazzo, poichè si dovrà occupare di visualizzarlo correttamente e dovrà occuparsi * di rendere visibili tutte le azioni e le modifiche che verranno fatte su di esso tramite il MousePressed. */ public class View extends JPanel implements MouseListener{ /** * */ private static final long serialVersionUID = 1L; private final Mazzo mazzo; private JFrame frame; private MediaTracker segugio; private int preselezionata; private Contatore contatore; private int soluzione; private int difficoltà; private String posizione; private int mosse; private Classifica classifica; private GUI_classifica fenetre; /** * Costruttore della classe View, riceve come variabile un oggetto di tipo Mazzo (ovviamente con le carte al suo interno già mescolate). * In seguito viene inizializzato il MediaTracker che si dovrà occupare di rendere visualizzabili le carti nel pannello, due variabili contatore * e soluzione, utilizzate rispettivamente per contare il numero di mosse utilizzate per terminare il gioco * e per vedere se il giocatore ha indovinato tutte le coppie. * @param m */ public View (Mazzo m){ mazzo = m; segugio = new MediaTracker(this); preselezionata = -1; contatore = new Contatore(0); soluzione = 0; classifica = new Classifica(); // Viene creato il frame e due JOpitonPane per chiedere al giocatore la difficoltà a cui vuole giocare // e per avveritrlo delle mosse a sua disposizione. frame = new JFrame("Memory 1.0 - Nicolò Torreggiani "); frame.setBounds(450, 200, 400, 420); frame.setResizable(false); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.addMouseListener(this); frame.getContentPane().add(this); frame.setVisible(true); Object[] options = {"Facile", "Media", "Difficile"}; int n = JOptionPane.showOptionDialog(frame, "Scegli la difficoltà:", "Difficoltà", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,options, options[1]); switch(n){ case 0: difficoltà = 56; break; case 1: difficoltà = 36; break; case 2: difficoltà = 24; break; default: System.exit(0); } JOptionPane.showMessageDialog(frame,"Ha inizio una nuova partita!!\nRicorda: hai un massimo di " + difficoltà + " mosse per poter scoprire tutte le coppie!!\nBuon divertimento!!","Nuova partita",JOptionPane.PLAIN_MESSAGE); Segui(); this.repaint(); } /** * Funzione che si occupa di prendere tutte le immagini e disegnarle. * @param g */ @Override public void paint(Graphics g) { int i = 0; g.clearRect(0,0, 400, 400); for (int x = 0; x < 4; x++){ for(int y = 0; y < 4; y++){ g.drawImage(mazzo.Carta(i).Immagine(), x*100 + 13, y*100, this); i++; } } } @Override /** * Creata poichè si ricorre a dei componenti SWING. */ public void paintComponent(Graphics g){ paint(g); } /** * Funzione il cui scopo e quello di prendere le carte disegnate passarle al Media Tracker che poi si occupera della visulizzazione. * Prima viene passato il retro di tutte le carte, poi vengono volte a vengono passate le immagini dei vari semi. Infine tornano a essere volatate poichè */ public void Segui(){ int id = 0; for(int i = 0; i < 16; i++){ segugio.addImage(mazzo.Carta(i).Immagine(), id); mazzo.Carta(i).volta(); id++; segugio.addImage(mazzo.Carta(i).Immagine(), id); mazzo.Carta(i).volta(); id++; } try{ segugio.waitForAll(); } catch(Exception e){} } public void reset(){ mazzo.mescola(); for(int i = 0; i < 16; i++){ if(mazzo.Carta(i).Rimossa()) mazzo.Carta(i).riassegna(); } contatore.setVal(0); soluzione = 0; Object[] options = {"Facile", "Media", "Difficile"}; int n = JOptionPane.showOptionDialog(frame, "Scegli la difficoltà:", "Difficoltà", JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null,options, options[1]); switch(n){ case 0: difficoltà = 56; break; case 1: difficoltà = 36; break; case 2: difficoltà = 24; break; default: System.exit(0); } JOptionPane.showMessageDialog(frame,"Ha inizio una nuova partita!!\nRicorda: hai un massimo di " + difficoltà + " mosse per poter scoprire tutte le coppie!!\nBuon divertimento!!","Nuova partita",JOptionPane.PLAIN_MESSAGE); this.repaint(); } public void mouseClicked(MouseEvent e) { int indice; int x, y; x = e.getX() / 100; y = (e.getY()-25) / 100; indice = 4 * x + y; // Controllo che non sia stata rimossa if(!mazzo.Carta(indice).Rimossa()) { // Controllo che sia la prima carta selezionata if(preselezionata == -1) { preselezionata = indice; mazzo.Carta(indice).volta(); contatore.inc(); } else{ // Controllo che non sia la stessa carta if(preselezionata == indice){ System.out.println("E' la stessa carta"); //preselezionata = -1; //mazzo.Carta(indice).volta(); //contatore.inc(); } else { mazzo.Carta(indice).volta(); this.paint(this.getGraphics()); try { Thread.sleep(2000); } catch (InterruptedException ex) { } // Controllo che le due carte siano dello stesso tipo if(mazzo.Carta(preselezionata).Uguale(mazzo.Carta(indice))){ System.out.println("Uguali"); mazzo.Carta(preselezionata).rimuovi(); mazzo.Carta(indice).rimuovi(); preselezionata = -1; contatore.inc(); soluzione++; } else{ System.out.println("Diverse"); mazzo.Carta(preselezionata).volta(); mazzo.Carta(indice).volta(); preselezionata = -1; contatore.inc(); } } } } this.repaint(); if((contatore.getVal()) > difficoltà){ JOptionPane.showMessageDialog(frame,"Hai perso!", "Fine Partita", JOptionPane.WARNING_MESSAGE); JOptionPane option = new JOptionPane ("Giocare una nuova partita?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION); JDialog dialog = option.createDialog(frame,"Nuova partita"); dialog.pack(); dialog.setVisible(true); int n = ((Integer)option.getValue()).intValue(); switch(n){ case 0: reset();break; case 1: System.exit(0); } } if(soluzione == 8){ JOptionPane.showMessageDialog(frame,"Hai vinto in " + contatore.getVal() + " mosse!!", "Complimenti!!", JOptionPane.INFORMATION_MESSAGE); posizione = JOptionPane.showInputDialog("Nome:"); mosse = contatore.getVal(); classifica.Aggiungi(new Record(posizione, mosse, null)); fenetre = new GUI_classifica(classifica); fenetre.Mostra(); try { Thread.sleep(10000); } catch (InterruptedException ex) { } fenetre.Nascondi(); System.out.println(posizione + "" + mosse); JOptionPane option = new JOptionPane ("Giocare una nuova partita?", JOptionPane.QUESTION_MESSAGE, JOptionPane.YES_NO_OPTION); JDialog dialog = option.createDialog(frame,"Nuova partita"); dialog.pack(); dialog.setVisible(true); int n = ((Integer)option.getValue()).intValue(); switch(n){ case 0: reset();break; case 1: System.exit(0); } } } public void mousePressed(MouseEvent e) {} public void mouseReleased(MouseEvent e) {} public void mouseEntered(MouseEvent e) {} public void mouseExited(MouseEvent e) {} }
Contatore
package memory; /** * Classe che crea un oggetto in grado di essere incrementato, decrementato, settato a un valore diverso durante il suo utilizzo * e che è in grado di fare un return del suo valore. */ public class Contatore { private int valore; public Contatore(){ valore = 0; } public Contatore(int valore){ this.valore = valore; } public void setVal(int valore){ this.valore = valore; } public void inc(){ valore++; } public int getVal(){ return valore; } }
GUI_classifica
/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package memory; // Oggetti grafici swing import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JFrame; import javax.swing.SwingConstants; // Oggetti awt import java.awt.Color; import java.awt.Font; import java.awt.GridLayout; /** * Grafica per visualizzare i records. * <p> * La classe estende l'oggetto grafico JPanel per comodità (nessun metodo è sovrascritto). * * @author Massimiliano Zanoli * @version 0.1 */ public class GUI_classifica extends JPanel { private static final long serialVersionUID = 1L; // Elementi grafici private JFrame finestra; private JLabel records[][]; private JLabel intestazione; private JLabel autore; private JLabel mosse; // Dati private String font; private int larghezza; private int altezza; private int numero; // Colori dei font private Color titolo; private Color dati; private Color nome; private Color sfondo; /** * Il costruttore necessita di un'istanza della classe Struttura come riferimento, da cui ricavare i dati. * * @param riferimento La Struttura di riferimento. */ public GUI_classifica(Classifica classifica) { // Ottengo i dati font = "Comic Sans MS"; numero = classifica.Numero(); larghezza = 300; altezza = 300; // Creo i colori titolo = new Color(0, 255, 0); dati = new Color(0, 128, 0); nome = new Color(64, 255, 192); sfondo = Color.WHITE; System.out.println("sono al gruppo 1"); // Creo la finestra finestra = new JFrame("Classifica"); finestra.setBounds(0, 0, larghezza, altezza); finestra.setResizable(false); finestra.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); finestra.getContentPane().add(this); System.out.println("sono al gruppo 2"); // Creo il titolo intestazione = new JLabel("Classifica"); intestazione.setForeground(titolo); intestazione.setFont(new Font(font, Font.BOLD, 20)); intestazione.setHorizontalAlignment(SwingConstants.CENTER); System.out.println("sono al gruppo 3"); autore = new JLabel("Giocatore:"); autore.setForeground(dati); autore.setFont(new Font(font, Font.BOLD, 16)); autore.setHorizontalAlignment(SwingConstants.CENTER); System.out.println("sono al gruppo 4"); mosse = new JLabel("Mosse:"); mosse.setForeground(dati); mosse.setFont(new Font(font, Font.BOLD, 16)); mosse.setHorizontalAlignment(SwingConstants.CENTER); System.out.println("sono al gruppo 5"); // Creo le etichette con i records records = new JLabel[numero][2]; for (int i = 0; i < numero; i++) { records[i][0] = new JLabel(classifica.Record(i).nome); records[i][1] = new JLabel("" + classifica.Record(i).mosse); System.out.println(records[i][0].getText()); System.out.println(records[i][1].getText()); for (int c = 0; c < 2; c++) { records[i][c].setForeground(nome); records[i][c].setFont(new Font(font, Font.PLAIN, 16)); records[i][c].setHorizontalAlignment(SwingConstants.CENTER); } } System.out.println("sono al gruppo 6"); // Messa a punto del pannello this.setBackground(Color.WHITE); this.setLayout(new GridLayout(numero + 2, 2)); this.add(new JLabel()); this.add(intestazione); this.add(new JLabel()); this.add(autore); this.add(mosse); for (int r = 0; r < numero; r++) { for (int c = 0; c < 2; c++) { this.add(records[r][c]); } } System.out.println("sono al gruppo 7"); } /** * Visualizza la finestra dei records. */ public void Mostra() { finestra.setVisible(true); } /** * Nasconde la finestra dei records. */ public void Nascondi() { finestra.setVisible(false); } }
Nell'oggetto classifica segna un paio di errori ma non dovrebbero influire nel problema che ho io.
aaa