KuroKami69 ha scritto:
Ma vedi, il fatto che nonostante programmare sia interessante, a me non piace. [...]
Non sono indicato a dare consigli di nessun genere su questo tipo di lavoro, sto appena iniziando a fare uno stage, ma se dici che non ti piace poi così tanto forse non ne vale tanto la pena no? Magari java non è il linguaggio che fa per te, e troverai altro di molto appassionante, ma non è che programmare videogiochi sia facile eh ... Ma devi avere innanzitutto molta passione e stimoli dal mio punto di vista.
KuroKami69 ha scritto:
Però anche se te mi dici "leggi al documentazione", ok io la leggo, ma poi succede che, magari non capisco una cosa, vado a vedermi come funziona, e la ne trovo un'altra che non capisco, e via a cascata.
Capisco, può essere frustrante. Ma hai bisogno di qualche indicazione, e quello è il punto di partenza, lascia stare le cose troppo complicate ma prova sempre a controllare cosa fa un metodo che invochi, quando non lo sai già o non è ovvio. Se poi questo implica una catena infernale pazienza, puoi chiedere qui o cercare sui libri quando ne avrai.
KuroKami69 ha scritto:
Mettere entrambe le soluzioni mi farebbe solo uscire scemo da tutto questo, al mio stato attuale, quindi mi dedicherò a quella proposta da te del filter.
Se ho capito bene, qua si tratta solo di scegliere quanto visualizzare in base a 2 semplici scelte dell'utente.
A me verrebbe quindi da dire che devo passare il valore dello spinner a getRowCount, e leggendo la descrizione del metodo, sarei anche portato a pensare che sto facendo giusto. Poi però mi viene in mente: "aspetta, ma qua abbiamo menzionato anche i filtri, che dovrebbe permettermi di visualizzare solo n righe" quindi che diamine faccio?
La logica è quella. JTable chiede al proprio model quante righe deve mostrare, quindi tu devi solo "convincere" getRowCount () del TableModel a ritornare quello che vuoi tu. "Passare" un valore a getRowCount () lo fai mantenendo una variabile nel TableModel, che andrai a modificare dall'esterno con un metodo set. Attenzione che se il valore è maggiore del numero di automobili presenti nella lista, non dovresti aggiungere automobili in questo caso, ma ti basta un controllo, prova a farlo!
I filtri li ho menzionati per darti una panoramica, potresti averne bisogno in futuro, in questo caso è più complicato, lascia perdere, non stai filtrando per testo, vuoi solo limitare il numero di risultati.
KuroKami69 ha scritto:
poi leggendo quello che hai scritto sul rimuovere, mi viene da pensare che se tolgo dalla mia lista i costruttori delle automobili, allora diminuisco il numero di righe della tabella, mentre aggiungendo costruttori alla lista, allora visualizzo più righe, io così la penso. Aggiungo/tolto elementi alla lista -> il getValueAt si allinea con tutto e mi mostra i risultati, dopo avergli comunicato i cambiamenti.
Questa è la linea di pensiero che ho, probabilmente è ancora sbagliata [...]
No, non è sbagliato, il concetto è giusto. I costruttori però non c'entrano nulla, tu alla lista aggiungi/rimuovi direttamente gli oggetti Automobile, i costruttori sono metodi, anche se particolari.
Quindi potresti avere un metodo addAutomobile (Automobile auto) nel TableModel, e un anche un metodo removeAutomobile.
Perché addAutomobile prende in ingresso un parametro di tipo Automobile e non intero? E' quello che dicevo prima, il TableModel non saprebbe che farsene di un intero, lui ha una lista di automobili, quindi l'operazione che deve fare è solo un add sulla lista e una notifica ai listener.
Al massimo puoi permettere di specificare anche la posizione di inserimento nella tabella, ad esempio invece che aggiungere la nuova auto come ultima, la inserisci come prima.
Ma se passi solo un intero al metodo add (), dai un compito al TableModel che lui non dovrebbe avere, ad esempio inventarsi con che parametri deve costruire la nuova auto, non è lì che lo devi fare.
Se non vuoi ancora inserire valori per l'auto creata ok, allora quando vuoi inserire un'automobile non richiami subito il addAutomobile (Automobile auto) del table model, ma prima ne costruisci una (con i valori che vuoi) che poi passi al table model.
Cosa riceverà invece il removeAutomobile ? Il remove di ArrayList puoi chiamarlo sia con l'oggetto da rimuovere, sia con l'indice dell'oggetto da rimuovere. Sarebbe difficile passare il riferimento dell'auto da rimuovere, è molto più semplice passare l'indice della lista, che corrisponderà alla riga da eliminare. Potresti ad esempio cliccare su una riga, e aggiungere un pulsante che quando premuto richiama il removeAutomobile del table model passando come parametro l'indice della riga cliccata (che lo prendi con una singola istruzione da JTable).
Per quanto riguarda la guida, è passato molto tempo da quando l'ho letta e forse è anche cambiata, prendila così com'è, come un'infarinatura del linguaggio, io ne ho lette molte da lì prima di iniziare un nuovo linguaggio di programmazione, puoi trovare cose utili, ma non aspettarti che sia "completa".
KuroKami69 ha scritto:
Ricevo un valore dallo spinner e in base a questo valore aggiungo/tolgo elementi dalla mia lista (il filtro ho deciso che è meglio se evito per il momento). Quindi i passaggi sono:
il valore viene immesso -> il listener lo becca -> dentro al listener richiamo il metodo di aggiunta/rimozione righe a cui passo il valore dello spinner -> il metodo, a seconda di che valore io passo farò un add oppure un remove -> i listener appropriati, fire...deleted e fire...insert comunicheranno i cambiamenti di stato.
Secondo questo ragionamento, dove mi pare di aver seguito tutto quello che mi avete detto, anche se forse con i termini non ci ho preso molto, ho scritto questo:
[...]
Il codice dentro all'actionPerformed del pulsante va bene per cancellare una riga, magari cambia il nome del pulsante da "Visualizza" a "Rimuovi".
Ora però stai prendendo il valore dello spinner per dire quale riga rimuovere, puoi anche farlo, ma per il resto dei compiti dovresti allora usare altri componenti. Consiglio sempre un pulsante del tipo "Rimuovi riga selezionata" che cancelli la riga selezionata della tabella.
Il metodo per aggiungere/rimuovere non è prefabbricato nell'AbstractTableModel, quindi sì lo devi gestire tu. Il setRow (), alla luce di quanto ho detto all'inizio del messaggio, invece, non va molto bene, vedi sopra quello che ho scritto.
Tutti i controlli li fai nella classe con l'interfaccia grafica, se vuoi scegliere in base a un valore se vadano aggiunte o rimosse righe. Poi in base a quello che vuoi richiami nel table model una o più volte addAutomobile o removeAutomobile.
Non fare "indovinare" al table model quello che deve fare.
Se vuoi scrivere anche un metodo removeRange nel table model, che cancella più di una riga alla volta, o un addAutomobili che prende più di una automobile alla volta da aggiungere alla lista ok.
Ma non usare appunto un setRow nel table model (tra l'altro ricordati cosa si diceva sui metodi set, il nome setRow (int rowIndex) per chiunque vorrebbe dire che tu modifica la riga all'indice passato, non che fai altro), usa il/gli add/remove.
KuroKami69 ha scritto:
[...]
Mi tira giù migliaia di errori in esecuzione
Exception in thread "AWT-EventQueue-0" java.lang.NoSuchMethodError: AutomobileTa
bleModel.setRow(I)V
at FrameTabella$2.actionPerformed(FrameTabella.java:96)
at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
......................................................................................
tutta sta roba qua cosa vuol dire mmh? ho letto in giro e alcuni di questi escono perché non ci sono elementi nella lista/array ma gli altri?
No questo errore vuol dire semplicemente che il file .class AutomobileTableModel non ha all'interno la dichiarazione del metodo setRow (che come detto va cambiato).
Questo probabilmente perché hai ricompilato solo gli altri file, il file AutomobileTableModel invece non è stato ricompilato (quindi è stato trovato un file .class, precedente e il compilatore ha deciso di non ricompilare, non saprei dirti esattamente quando questo accada) ed è alla versione "vecchia".
KuroKami69 ha scritto:
Perché quando compilo, prima mi viene il seguente errore:
1) .\FrameTabella.java:95: error: cannot find symbol
Integer i = (Integer)js.getValue().getNumber();
^
symbol: method getNumber()
location: class Object
2) .\AutomobileTableModel.java:48: error: cannot find symbol
automobili.removeRange(automobili.size(), rowIndex);
^
symbol: method removeRange(int,int)
location: variable automobili of type List<Automobili>
3) .\AutomobileTableModel.java:54: error: cannot find symbol
fireTableRowsInsert(automobili.size(), rowIndex);
^
symbol: method fireTableRowsInsert(int,int)
location: class AutomobileTableModel
3 errors
e dopo quando risalvo il file non mi da più l'errore? [...]
1) Perché stai usando un getNumber? Il getValue con il cast a Integer è corretto. Tra l'altro ora il getNumber () lo stai richiamando su un Object, come vedi dal messaggio di errore, non su un Integer, se volessi applicarlo direttamente sul valore ottenuto dal cast dovresti usare le parentesi:
((Integer) js.getValue()).getNumber();
Questo richiama getNumber () su un reference di tipo Integer (ovviamente il cast può dare errore, il compilatore si sta "fidando" che troverà un Integer), ma comunque sarebbe un errore, perché Integer non ha un metodo getNumber.
2) Leggi sempre bene il messaggio, sotto dice:
variable automobili of type List<Automobili>
removeRange è definito in ArrayList, ma non in List, e automobili è dichiarato come List. Questo perché @andbin voleva scrivere un codice più generalizzato, poi anche se tu effettivamente crei un arraylist il compilatore non può saperlo, perché è lecito trovare qualcos'altro.
Quindi puoi pure dichiarare la lista come ArrayList in questo caso.
3) Il metodo si chiama
fireTableRowsInserted.
E' importante capire bene i messaggi d'errore, una delle prime cose a cui ti devi abituare. Non so perché se modifichi il file non ti dia più errore, mi pare molto strano, quegli sono effettivamente tre errori e il sorgente non può essere compilato.