View Full Version : [JAVA] MasterMind: imparando ad usare NetBeans GUI Editor...
riva.dani
25-06-2008, 18:04
Salve a tutti, sto iniziando ad imparare il linguaggio Java. Purtroppo ho delle direttive ben precise, ad esempio devo usare NetBeans e il suo editor di GUI per realizzare una mia versione del famoso gioco Mastermind. Mi sono messo al lavoro da poco, ed il primo problema col quale mi scontro è l'incapacità (mia) di creare array di oggetti grafici (label, ecc...). Volevo chiedervi se è possibile e, se sì, come farlo.
Il problema in pratica sta nel fatto che altrimenti ogni singolo piolo di ogni singola combinazione è un elemento a sè stante, per un totale di 32 oggetti, per ognuno dei quali, al momento, ho previsto le seguenti istruzioni:
private void x8y1MouseEntered(java.awt.event.MouseEvent evt) {
int riga=8;
if(riga==8)
x8y1.setBackground(new java.awt.Color(200, 200, 200));
}
private void x8y1MouseExited(java.awt.event.MouseEvent evt) {
int riga=8;
if(riga==8)
x8y1.setBackground(new java.awt.Color(159, 159, 159));
}
private void x8y1MouseClicked(java.awt.event.MouseEvent evt) {
if(!x8y1.isEnabled())
{
x8y1.setIcon(ColorSelectedG.getIcon());
x8y1.setEnabled(rootPaneCheckingEnabled);
miacomb[0]=c;
x++;
if(x==4)
nebi=ctrl.check(miacomb, codice);
}
}
Mi sembra assurdo dover riscrivere esattamente queste cose per ben 32 volte! :eek:
A questo si aggiungono altri problemi, ad esempio volendo colorare i pioli bianchi e neri relativi ad una soluzione, sarebbe molto comodo usare un ciclo for se si avesse a disposizione un array di oggetti Label.
So di non essere stato chiaro, ma più di così non ci riesco. :p
Confido nel fatto che qualcuno di voi nel corso dei propri studi si sia imbattuto nell'implementazione di Mastermind in Java.
Grazie per l'aiuto. :mano:
banryu79
26-06-2008, 08:32
A questo si aggiungono altri problemi, ad esempio volendo colorare i pioli bianchi e neri relativi ad una soluzione, sarebbe molto comodo usare un ciclo for se si avesse a disposizione un array di oggetti Label.
So di non essere stato chiaro, ma più di così non ci riesco. :p
Confido nel fatto che qualcuno di voi nel corso dei propri studi si sia imbattuto nell'implementazione di Mastermind in Java.
Grazie per l'aiuto. :mano:
Ciao,
non ho mai "avuto a che fare" con MasterMind ma utilizzo anche io NetBeans (in efetti è un tantino sovvradimensionato come ambiente di sviluppo per chi inizia :D) .
Se vuoi crearti un array di Label (JLabel presumo, usi Swing?) allora non devi prenderle una a una dalla palette dei componenti grafici e trascinarle nella tua finestra, perchè così Matisse (l'editor grafico di GUI di NetBeans) crea un'istanza per ogni singola JLabel che ti finisce nel "codice blindato" della tua classe.
Per ovviare al problema devi lasciar perdere l'inserimento delle JLabel da edit grafico e crearti te direttamente nel codice della tua classe una variabile (per esempio) di tipo ArrayList<JLabel>, oppure (se ancora non sei familiare con Collections & Generics) una variabile di tipo JLabel[] (array di JLabel).
Poi nel codice ti devi gestire a mano l'istanziazione delle singole JLabel (che potresti inserire nel costruttore della tua classe, dopo la chiamata al metodo initComponents() aggiunta da Matisse[serve a inizializzare i componenti grafici]).
riva.dani
26-06-2008, 14:50
Grazie mille per la risposta! Però non sono in grado di metterla a punto, avrei bisogno di una mano... :p
Allora se non ho capito male potrei fare qualcosa del genere:
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
JLabel[] array = new JLabel[number]; //questo l'ho trovato su google :p
x8y1.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
x8y1MouseClicked(evt);
}
});
Riga8.add(x8y1, new java.awt.GridBagConstraints());
pack();
}
Ci sono andato tanto lontano? Sicuramente qualcosa di sbagliato c'è, perchè nel copia incolla mi è rimasto qualcosa relativamente al pannello che dovrebbe fare da container per le jlabel. Il mio problema è che "private void initComponents()" esiste già, ed inaccessibile, non posso modificarne il codice. Posso creare una nuova classe contenente le jlabel? Poi matisse come le vede?
In effetti se imparassi a fare questa cosa poi il resto sarebbe in discesa, perchè praticamente ogni componente del campo da gioco diventerebbe parte di un array (riga), o addirittura, se possibile, potrei fare un array di righe, in cui ogni riga è un array di Jlabel (che uso come container per piccole immagini). Quindi grazie a chiunque come banryu79 mi darà una mano! :ave:
PS: Sto cercando guide online per questa cosa, anche in inglese, ma con scarso successo. Anche un piccolo link sarebbe d'aiuto. :)
banryu79
26-06-2008, 16:16
Ehm, come dire, ti avevo già risposto anche su questo:
Poi nel codice ti devi gestire a mano l'istanziazione delle singole JLabel (che potresti inserire nel costruttore della tua classe, dopo la chiamata al metodo initComponents() aggiunta da Matisse[serve a inizializzare i componenti grafici]).
Devi istanziare il tuo array nel costruttore della tua classe, subito dopo la chiamata automatica a initComponents(), non dentro initComponents() ;)
riva.dani
26-06-2008, 16:25
Scusa, forse due righe di codice sarebbero d'aiuto. Non ho idea di come si faccia quello che mi consigli di fare. Per ora ho creato una nuova classe "riga" in un nuovo file per evitare casini, e ci ho scritto questo:
package mastermind;
import javax.swing.JLabel;
public class riga {
JLabel[] elemento = new JLabel[4];
public riga() {
for (int y = 0; y < 4; y++) {
elemento[y] = new JLabel();
}
}
}
Adesso immagino di poter usare elemento[i] come fosse una JLabel qualunque, in modo tale da scrivere il codice una volta sola anzichè 32 volte. Bene! :) Però... Ora, come istanzio l'array? E' possibile vederlo all'interno del GUI editor per piazzare le 4 etichette dove voglio io?
Ecco cosa intendeva banryu! :D
package mastermind;
import javax.swing.JLabel;
public class riga {
public riga(){
initComponents()
JLabel[] elemento = new JLabel[4];
/* Tutto il codice da aggiungere
*va inserito da qui!!!
*/
for (int y = 0; y < 4; y++) {
elemento[y] = new JLabel();
}
}
/*Codice generato da NB*/
public void initComponents(){
........
}
}
}
riva.dani
26-06-2008, 16:54
Grazie 1000!
Ma il mio problema persiste poichè vi è già un
/** Creates new form Interfaccia*/
public Interfaccia() {
initComponents();
}
proprio prima del codice generato da NB e di conseguenza la ripetizione di initComponents() mi dà errore. Comunque inizio a pensare di essere un po' troppo niubbo per queste cose. :wtf: :D
banryu79
26-06-2008, 17:03
Ora, come istanzio l'array?
l'array di JLabel lo hai già istanziato nel codice che hai postato qui sopra.
Perdonami, ma non avendo mai giocato a MasterMind non so se il numero di JLabel che ti occorrono sia fisso e conosciuto a priori o sia dinamico...
E' possibile vederlo all'interno del GUI editor per piazzare le 4 etichette dove voglio io?
Questo no, devi fare tutto da codice.
Ad esempio per settare la posizione puoi usare il metodo .setLocation(x, y) che JLabel eredita da Component .
In pratica devi cominciare a studiarti le basi di AWT e Swing, sul sito della Sun trovi molti tutorial ben strutturati, ovviamente in inglese.
Devi fare tutto da codice propio perchè a te occorre un array di JLabel, cosa che l'editor grafico non ti permette di gestire in modo visuale.
P.S.: initComponents() viene gestito automaticamente da Netbeans, non devi ne scriverci niente dentro (tanto non puoi) ne chiamarlo tu una seconda volta.
Io intendevo che il tuo codice per istanziare l'array e popolarlo con le JLabel lo potresti scrivere dopo la chiamata a initComponets() che di solito viene automaticamente inserita nel costruttore della classe visuale, tutto lì.
riva.dani
26-06-2008, 17:08
Il numero di componenti è fisso, almeno questo è un vantaggio!
Quindi tutto da codice? Ok proverò, e proverò pure ad usare i metodi che mi hai consigliato (tipo .setLocation). Tanto sono libero di scopiazzare dal codice che NB ha generato (proprio quello che non posso modificare). Mi avete sbloccato la mente... Mi stanno venendo un po' di idee nuove, ad esempio creare le JLabel solo quando servono. :)
Quindi per ora grazie mille ad entrambi, se avrò altri problemi scriverò ancora qui! Alla prossima!
Grazie 1000!
Ma il mio problema persiste poichè vi è già un
/** Creates new form Interfaccia*/
public Interfaccia() {
initComponents();
}
proprio prima del codice generato da NB e di conseguenza la ripetizione di initComponents() mi dà errore. Comunque inizio a pensare di essere un po' troppo niubbo per queste cose. :wtf: :D
Avevo capito male.. Comunque va così allora:
/** Creates new form Interfaccia*/
public Interfaccia() {
initComponents();
/* Tutto il codice da aggiungere
*va inserito da qui!!!
*/
JLabel[] elemento = new JLabel[4];
for (int y = 0; y < 4; y++) {
elemento[y] = new JLabel();
}
}
Comunque asclta i consigli di banryu.. :D :D sono preziosi.. Io li sfrutto spesso ultimamente.. ASD ASD :read:
banryu79
26-06-2008, 17:10
Comunque inizio a pensare di essere un po' troppo niubbo per queste cose. :wtf: :D
Non è una questione di essere nubbi o meno, il discorso è che l'editor grafico in NetBeans non è stato inserito con lo scopo di permettere di programmare anche all'utente/programmatore occasionale senza conoscere i dettagli delle librerie AWT/Swing, ma ha lo scopo di permettere al programmatore di GUI una più rapida prototipazione e non lo solleva affatto dalla conoscenza delle librerie Java.
Anzi, spesso gli impone di sapere bene cosa sta andando a fare perchè per interfacce un po' più complesse della norma è neccessario integrare/affiancare il codice prodotto in automatico da Matisse con del codice ad hoc gestito a mano.
riva.dani
26-06-2008, 20:51
Rinnovo i miei ringraziamenti, ma ancora non ci sono... :(
Vi ho detto che sono niubbo, perchè sono completamente a digiuno di Java. Però con un po' di buona volontà ho scritto questo:
package mastermind;
import java.awt.event.*;
import javax.swing.JLabel;
public class riga {
JLabel[] elemento = new JLabel[4];
public riga() {
for (int y = 0; y < 4; y++) {
elemento[y] = new JLabel();
elemento[y].addMouseListener(new Ascoltatore());
elemento[y].setIcon(new javax.swing.ImageIcon((getClass().getResource("/immagini/nero.jpg"))));
elemento[y].setLocation(50, 50); //50 e 50 sono valori messi lì a casaccio :p
}
}
public class Ascoltatore implements MouseListener
{
public void mouseClicked(MouseEvent e, int k) {
elemento[k].setBackground(new java.awt.Color(50, 50, 50));
}
public void mousePressed(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseReleased(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseEntered(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseExited(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseClicked(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
}
Mi sembra di essere ad un buon punto: posso fare eseguire azioni ai miei oggetti che compongono l'array, ad esempio. Però non riesco a fare apparire il tutto insieme al resto dell'interfaccia che già appare di suo, perchè l'ho costruita col GUI editor. In più se mi sposto dal file "riga" al file "interfaccia" e provo a richiamare un oggetto di tipo riga, me lo fa fare, ma poi se invoco un metodo dell'oggetto appena creato fa casini di questo tipo:
...
riga row=new riga();
row[0]. //la parte dopo il punto sparisce automaGicamente
@Override
public void setBackground(Color c) {
super.setBackground(c);
}
...
Attendo fiducioso un'ulteriore spintarella. :cincin:
banryu79
27-06-2008, 08:52
Però non riesco a fare apparire il tutto insieme al resto dell'interfaccia che già appare di suo...
Questo perchè con il codice che hai postato tu hai creato il tuo array di JLabel, ma non le hai aggiunte ad un Container.
Detta in parole povere, in AWT ogni "oggetto grafico" è un Component.
Alcuni Component sono anche Container, cioè possono contenere al loro interno altri Component.
Nel tuo caso per esempio, le JLabel sono dei Component che tu hai creato; ora devi "inserirle" in un Container.
Tipicamente i componenti di un JFrame (suppongo tu stia usando un JFrame come top level container) vengono inseriti nel ContentPane che ha all'interno (diciamo l'area client della finestra, anche se non è proprio una definizione esatta).
Ogni Container espone un metodo pubblico del tipo .add(Component...) che permette di inserire il Component passato in ingresso nel Container.
Quindi nel tuo caso sarà il JFrame il tuo container (posto che non ci hai prima aggiunto dentro un JPanel).
La faccenda qui te l'ho sintetizzata tantissimo, ti ripeto e invito a spendere 3-4 orette sul sito della Sun a consultare il Javadocs del package java.awt e javax.swing mentre studi il tutorial su Awt i Component.
Se vuoi tutorial specifici per componenti li trovi sempre in quel sito.
P.S.: per il posizionamento delle JLabel ti ho detto una castroneria: non usare setLocation() (che tipicamente di usa per posizionare finestre), quando avrai aggiunto col metodo .add() le JLabel nel container il LayoutManager associato a quel container provvederà lui a posizionare i componenti al suo interno.
Quindi è necessario che tu conosca almeno un po' i LayoutManager...
Qui (http://java.sun.com/docs/books/tutorial/uiswing/components/index.html) del materiale su come si usare i componenti di Swing.
Qua (http://java.sun.com/docs/books/tutorial/index.html)la pagina dei Java tutorials
riva.dani
29-06-2008, 09:57
Avevo già visitato i due link, comunque grazie!
Forse mi ero espresso male, quello che non riuscivo a fare era: tasto destro su un JPanel creato col GUI editor, "Customize code", ed aggiungere come post-adding code due righe del tipo:
for (int y = 0; y < 4; y++)
Pannello1.add(elemento[y]);
Come vedi tutto si è risolto per il meglio, anche (anzi, soprattutto) grazie a te. A buon rendere! :mano:
PS: Mi stavo chiedendo, già che ci sono, se si può creare un unico mouseListener per l'array, al quale passare anche l'indice dell'array. In questo modo potrei definire una sola volta le azioni da compiere. Ad esempio, qualcosa del genere:
for (y = 0; y < 4; y++)
{Riga.add(row[y]);
row[y].addMouseListener(new Ascoltatore());
}
...
public class Ascoltatore implements MouseListener
{
public void mouseClicked(MouseEvent e) {
row[y].setBackground(250, 250, 250);
}
}
Ma temo sia impossibile. :(
wizard1993
29-06-2008, 11:27
se ho capito bene; te vorresti screare un solo ascoltatore di eventi che faccia lo stesso lavoro a tutti?
potresti passare come parametro alla classe Ascoltatore il numero della colonna, con un codice tipo questo
for(int i=0;i<4;i++){
Ascoltatore a=new Ascoltatore(i);
row[y].addMouseListener(a);
}
//...
class Ascoltatore implemets MouseListener{
private int row=0;
public Ascoltatore(int y){
this.row=y;
}
//TODO: il tuo codice
}
riva.dani
29-06-2008, 12:21
se ho capito bene; te vorresti screare un solo ascoltatore di eventi che faccia lo stesso lavoro a tutti?
potresti passare come parametro alla classe Ascoltatore il numero della colonna, con un codice tipo questo
for(int i=0;i<4;i++){
Ascoltatore a=new Ascoltatore(i);
row[y].addMouseListener(a);
}
//...
class Ascoltatore implemets MouseListener{
private int row=0;
public Ascoltatore(int y){
this.row=y;
}
//TODO: il tuo codice
}
In realtà:
...
class Ascoltatore implemets MouseListener{
public int row=0;
public Ascoltatore(int y){
this.row=y;
}
Così funziona!!!!!! Miticissimo, grazie mille!!!!!!!! :ave:
wizard1993
29-06-2008, 13:23
Così funziona!!!!!! Miticissimo, grazie mille!!!!!!!! :ave:
non se dici a me; comunque grazie per avermi fatto notare l'errore
vBulletin® v3.6.4, Copyright ©2000-2025, Jelsoft Enterprises Ltd.