Jframe jtable

di il
230 risposte

230 Risposte - Pagina 9

  • Re: Jframe jtable

    Ho editato, comunque sbagliavo, non pensavo di farlo così ahahaha ok, comunque uso 1 e 0 perché dopo nel getValueAt ho una cosa simile nel case
    (l'unica cosa che mi è venuta in mente per convertire i cavalli in kw)
    
    case 15: switch(c)
    			{
    				case 0: return automobile.getCavalli();
    				case 1: return automobile.conversioneCK(automobile.getCavalli());
    				default: return automobile.getCavalli();
    			}
    
    e se ci metto un boolean mi da errore

    ora ti posto gli errori di quel metodo
    
    Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Inva
    lid range
            at javax.swing.DefaultRowSorter.checkAgainstModel(Unknown Source)
            at javax.swing.DefaultRowSorter.rowsInserted(Unknown Source)
            at javax.swing.JTable.notifySorter(Unknown Source)
            at javax.swing.JTable.sortedTableChanged(Unknown Source)
            at javax.swing.JTable.tableChanged(Unknown Source)
            at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)
    
            at javax.swing.table.AbstractTableModel.fireTableRowsInserted(Unknown So
    urce)
            at AutomobileTableModel.changeRowNumber(AutomobileTableModel.java:64)
            at FrameTabella$2.actionPerformed(FrameTabella.java:105)
            at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
            at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
            at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
            at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
            at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Sour
    ce)
            at java.awt.Component.processMouseEvent(Unknown Source)
            at javax.swing.JComponent.processMouseEvent(Unknown Source)
            at java.awt.Component.processEvent(Unknown Source)
            at java.awt.Container.processEvent(Unknown Source)
            at java.awt.Component.dispatchEventImpl(Unknown Source)
            at java.awt.Container.dispatchEventImpl(Unknown Source)
            at java.awt.Component.dispatchEvent(Unknown Source)
            at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
            at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
            at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
            at java.awt.Container.dispatchEventImpl(Unknown Source)
            at java.awt.Window.dispatchEventImpl(Unknown Source)
            at java.awt.Component.dispatchEvent(Unknown Source)
            at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
            at java.awt.EventQueue.access$500(Unknown Source)
            at java.awt.EventQueue$3.run(Unknown Source)
            at java.awt.EventQueue$3.run(Unknown Source)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
    rivilege(Unknown Source)
            at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
    rivilege(Unknown Source)
            at java.awt.EventQueue$4.run(Unknown Source)
            at java.awt.EventQueue$4.run(Unknown Source)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionP
    rivilege(Unknown Source)
            at java.awt.EventQueue.dispatchEvent(Unknown Source)
            at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.run(Unknown Source)
    
    schiacciando a caso ho notato che se prima schiaccio sull'header di una colonna per ordinare e poi inserisco il numero di veicoli da vedere, non succede nulla, e mi da tutta questa bella trafila qua, se invece prima metto i veicoli, prima mi tira fuori tutta sta roba e poi, premendo sull'header per ordinare, dopo un paio di click mi mostra i valori

    EDIT: ho provato a fare il cambio nome colonna come hai detto te, però deve essere dinamico, e quindi non funziona così. voglio dire
    se seleziono "mostra kW" allora dovrà cambiarmi il nome della colonna da cavalli in kw, ma se dopo tolgo la spunta dovrà cambiare di nuovo il nome della colonna
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    Ho editato, comunque sbagliavo, non pensavo di farlo così ahahaha ok, comunque uso 1 e 0 perché dopo nel getValueAt ho una cosa simile nel case
    (l'unica cosa che mi è venuta in mente per convertire i cavalli in kw)
    
    case 15: switch(c)
    			{
    				case 0: return automobile.getCavalli();
    				case 1: return automobile.conversioneCK(automobile.getCavalli());
    				default: return automobile.getCavalli();
    			}
    
    e se ci metto un boolean mi da errore
    Non serve un altro switch. Basta un if, e con un boolean funziona benissimo ...
    
    case 15 : {
       if (mostraKV) ...
       else ...
    }
    
    Ovvio che quando cambia la selezione del checkbox il modello oltre a cambiare il valore del boolean deve fare un qualche tipo di fire, la tabella va notificata del cambiamento.

    KuroKami69 ha scritto:


    Ora ti posto gli errori di quel metodo:
    
    Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Inva
    lid range
            at javax.swing.DefaultRowSorter.checkAgainstModel(Unknown Source)
            at javax.swing.DefaultRowSorter.rowsInserted(Unknown Source)
            ................................................................................
    
    Anche qua è chiaro il messaggio, l'indice è al di fuori del range valido. Dovrebbe essere causato da un inserimento di righe non corretto, ma senza il codice non è facile indovinare l'errore.

    KuroKami69 ha scritto:


    Schiacciando a caso ho notato che se prima schiaccio sull'header di una colonna per ordinare e poi inserisco il numero di veicoli da vedere, non succede nulla, e mi da tutta questa bella trafila qua, se invece prima metto i veicoli, prima mi tira fuori tutta sta roba e poi, premendo sull'header per ordinare, dopo un paio di click mi mostra i valori
    Deve funzionare sempre, appena ottieni un'eccezione sulla console vuol dire che c'è un bug da sistemare.
  • Re: Jframe jtable

    Può essere che si verifica perché la mia tabella viene creata con 0 righe?
    per il firetable, ho provato a usare fireTableDataChanged ma non ha funzionato. quale dovrei usare? fireTableStructureChanged (che ho pensato plausibile perché l'header è parte della struttura della tabella e il cambio di un nome equivale a un cambio strutturale, forse) mi da una marea di eccezioni
    EDIT: confermo, è perché parto con una tabella da 0 righe
    quel metodo si può richiamare solo in nella tabella giusto? quindi se io inizialmente gli passo un arraylist VUOTO, senza aggiungerci elementi, come posso fare? ho idea che non c'è un modo
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    Può essere che si verifica perché la mia tabella viene creata con 0 righe?
    per il firetable, ho provato a usare fireTableDataChanged ma non ha funzionato. quale dovrei usare? fireTableStructureChanged (che ho pensato plausibile perché l'header è parte della struttura della tabella e il cambio di un nome equivale a un cambio strutturale, forse) mi da una marea di eccezioni
    EDIT: confermo, è perché parto con una tabella da 0 righe
    quel metodo si può richiamare solo in nella tabella giusto? quindi se io inizialmente gli passo un arraylist VUOTO, senza aggiungerci elementi, come posso fare? ho idea che non c'è un modo
    Prova a postare il codice che stai usando al momento, detto così non saprei.
    Usando il "vecchio" codice di esempio con il AutomobileTableModel, se la lista è vuota non si ottiene alcun errore con il setAutoCreateRowSorter (), quindi è possibile che tu stia facendo qualcosa di sbagliato, anche se questa è una cosa su cui non ho fatto molta pratica.
  • Re: Jframe jtable

    Non ho detto errori, ho detto eccezioni, perché, quando avvio il programma, essendo la tabella vuota, il setAutoCreateRowSorter () mi rimanda l'eccezione che non ha elementi della tabella su cui lavorare.
    ho risolto questa cosa chiamando il metodo quando premo il bottone "visualizza", e funziona una meraviglia.
    l'altra cosa che non riesco a fare, è sempre quella di avere un cambio dinamico di header name per la colonna "Cavalli" (che dovrebbe diventare KW quando spunto il checkbox). ma quasi quasi provo a sparare anche questo cambio nel codice del checkbox e vediamo se funziona.
    come mi hai fatto vedere te ansharja, me lo cambia solo una volta e basta e a me non va bene
  • Re: Jframe jtable

    Faccio un altro messaggio, perché a volte gli edit non vengono letti.
    l'unico dubbio che mi rimane è se mettere o meno un fire method, e se si quale mmh perché l'header fa parte della tabella in maniera differente rispetto alla lista di automobili.
    EDIT: ok funziona ahahahaha un semplice fireTableStructureChanged() dopo il cambiamento del nome header e apposto
  • Re: Jframe jtable

    Ora le uniche cose che mi restano da fare per finire il lavoro sono
    1) colorare una riga si e una no, o eventualmente, nel caso di auto e moto, far apparire auto moto auto moto, e colorare le moto
    penso si possa fare semplicemente facendo 2 add di fila alla lista anziché 1, ovviamente dopo che il listener dirà che è stata attivata tale funzione
    2) mettere un bel campo di ricerca, perché fa bello e completo il programma
    3) sistemare il layout, perché se lo apro a schermo intero mi mette la tabella nella seconda metà e il panel dei bottoni mi viene ingrandito e occupa la metà superiore della finestra, ma qua credo basti un qualche semplice set sul panel dei bottoni.
    4) spezzare la mia classe automobili e mettere tutti i metodi di assegnazione su una classe componenti, da cui poi richiamerò i metodi sia da auto che da moto e a seconda del nome della classe che li chiama, cambierà anche il file di testo che andranno a leggere e le dimensioni degli array/matrici associati ovviamente
    5) finire gli ultimi metodi che ho lasciato in sospeso, cilindri e cilindrata (mi mancano i range di valori approssimativamente reali)
    6) fare i file di testo con i modelli, tipologie ecc per le moto
    e il progetto si potrà dire concluso.
    il prossimo che farò sarà qualcosa di nettamente più semplice (il gioco della tombola con tabellone e 5, massimo 7 schedine) in cui redigerò anche il chenlog (chanlog?). magari potrei anche pensare a un diagramma delle classi prima, tanto per far felici i prof, ma non son bravissimo sotto quell'aspetto
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    Non ho detto errori, ho detto eccezioni, perché, quando avvio il programma, essendo la tabella vuota, il setAutoCreateRowSorter () mi rimanda l'eccezione che non ha elementi della tabella su cui lavorare.
    Ho risolto questa cosa chiamando il metodo quando premo il bottone "visualizza", e funziona una meraviglia.
    Intendevo dire eccezioni, sono stato impreciso nel termine, comunque era per dire errori in esecuzione.
    E ripeto, non direi che il setAutoCreateRowSorter () debba lanciare per forza un eccezione se la tabella è vuota, a me non succede quindi penso che ci sia "dell'altro".

    Cosa vuol dire che chiami il metodo quando premi il bottone visualizza? Intendi dire il setAutoCreateRowSorter ()? Se sì non ha molto senso, quello va impostato in fase di creazione della tabella, o al massimo una volta se cambi il RowSorter.
    Così tu richiameresti il metodo ad ogni pressione del bottone visualizza, quindi non hai il controllo di quando/quante volte verrà chiamato, il che è inutile se non dannoso.

    KuroKami69 ha scritto:


    L'altra cosa che non riesco a fare, è sempre quella di avere un cambio dinamico di header name per la colonna "Cavalli" (che dovrebbe diventare KW quando spunto il checkbox). Ma quasi quasi provo a sparare anche questo cambio nel codice del checkbox e vediamo se funziona.
    Come mi hai fatto vedere te ansharja, me lo cambia solo una volta e basta e a me non va bene
    No, nel codice del listener sul checkbox no. O almeno, dipende da come vuoi farlo. Se intendi accedere direttamente al tableheader, per cambiare il valore mostrato, evita assolutamente. Lì nel listener tu devi solo dire al modello "ora il checkbox è selezionato/deselezionato, aggiornati di conseguenza", e lo fai ad esempio con:
    
    tableModel.setShowKV (/* true o false in base allo stato nuovo del checkbox*/);
    
    Il table model modifica la propria variabile showKV, che userà nel getColumnName () per ritornare "Cavalli" o "KV" a seconda del valore di showKV (ovviamente solo per il columnIndex corrispondente a quella colonna).
    Fare in questo modo ti permette anche di gestire in modo buono la modifica dei valori della colonna, che gestirai nel getValueAt (), chiedendo alla Automobile i cavalli o i KV in base sempre al valore della variabile.

    Ti devi solo ricordare di richiamare entrambi i metodi fire nel setShowKV (), perché in quel momento deve cambiare sia la visualizzazione dell'header (fireTableStructureChanged ()) sia i dati che mostri nella colonna (fireTableDataChanged ()).
    L'ho provato e funziona correttamente.

    KuroKami69 ha scritto:


    Faccio un altro messaggio, perché a volte gli edit non vengono letti.
    l'unico dubbio che mi rimane è se mettere o meno un fire method, e se si quale mmh perché l'header fa parte della tabella in maniera differente rispetto alla lista di automobili.
    EDIT: ok funziona ahahahaha un semplice fireTableStructureChanged() dopo il cambiamento del nome header e apposto
    Vedi sopra, non so dove/come hai fatto le cose, ma il modo migliore per farlo è appunto gestire il tutto in modo sicuro all'interno del table model.

    KuroKami69 ha scritto:


    Ora le uniche cose che mi restano da fare per finire il lavoro sono
    1) colorare una riga si e una no, o eventualmente, nel caso di auto e moto, far apparire auto moto auto moto, e colorare le moto
    penso si possa fare semplicemente facendo 2 add di fila alla lista anziché 1, ovviamente dopo che il listener dirà che è stata attivata tale funzione
    2) mettere un bel campo di ricerca, perché fa bello e completo il programma
    3) sistemare il layout, perché se lo apro a schermo intero mi mette la tabella nella seconda metà e il panel dei bottoni mi viene ingrandito e occupa la metà superiore della finestra, ma qua credo basti un qualche semplice set sul panel dei bottoni.
    4) spezzare la mia classe automobili e mettere tutti i metodi di assegnazione su una classe componenti, da cui poi richiamerò i metodi sia da auto che da moto e a seconda del nome della classe che li chiama, cambierà anche il file di testo che andranno a leggere e le dimensioni degli array/matrici associati ovviamente
    5) finire gli ultimi metodi che ho lasciato in sospeso, cilindri e cilindrata (mi mancano i range di valori approssimativamente reali)
    6) fare i file di testo con i modelli, tipologie ecc per le moto
    e il progetto si potrà dire concluso.
    il prossimo che farò sarà qualcosa di nettamente più semplice (il gioco della tombola con tabellone e 5, massimo 7 schedine) in cui redigerò anche il chenlog (chanlog?). magari potrei anche pensare a un diagramma delle classi prima, tanto per far felici i prof, ma non son bravissimo sotto quell'aspetto
    1) Il colore di background delle righe lo puoi cambiare facendo l'override di getTableCellRendererComponent ().
    Trovi vari esempi in rete, e hai la possibilità di cambiare tra le altre cose: allineamento, font e colore del testo, margini, bordo e sfondo della riga (e altro ancora) e tutto in base al fatto che la riga/colonna sia selezionata o meno, o in base al numero di riga/colonna, tutto quello che vuoi. Alternare i colori nelle righe è banale, colorare in un modo auto e nell'altro moto è banale, ordinare auto e moto nella lista per mostrarle alternate invece è molto più complesso, e andrebbe pensato bene (pensa se hai rimozioni/aggiunte quanto dovresti lavorare con gli add e i remove per "riallineare" il tutto, a questo punto sarebbe meglio semplicemente riordinare la lista, ma anche qui non è immediato, perché l'ordinamento "standard" è ottenuto con un semplice Collections.sort () e l'implementazione dell'interfaccia Comparable / uso di Comparator, ma i confronti sono fatti a due a due tra gli oggetti in modo indipendente dal resto degli elementi).

    2) Bella cosa sì, ma più avanzata di quello che stai facendo adesso. O ti usi i filtri di cui avevo parlato in precedenza (riguarda il tutorial sulle tabelle e dovresti trovare esempi in cui il testo viene filtrato), o devi implementarlo tu nel table model, cosa non impossibile comunque (secondo me ad esempio è più facile questo rispetto ad alternare moto e auto nella lista).

    3) Per usare bene i layout occorre un po' di tempo, la tabella sicuramente non è facile da gestire, se vuoi farla dimensionata in base al contenuto, sistemare i pannelli nella posizione corretta è più facile.

    4) Onestamente non mi è chiaro quello che vuoi fare. Se intendi solo che crei la lista di auto e moto all'esterno, da file di testo, è perfettamente sensato. Il resto è un po' confuso, soprattutto quando dici "a seconda del nome della classe che li chiama".

    5) - 6) Ok.

    Ma una volta che avrai i file di testo con i dati, vuoi continuare con questa roba di creare una tabella vuota e aggiungere/togliere righe così per sport? Non sarebbe meglio avere un insieme di dati già pronto, che leggi da file, e mostrare come risultato finale una bella tabella già pronta con tutti i dati e la possibilità di filtrare i dati, limitare il numero delle righe, cambiare la visualizzazione di cavalli/KV e tutto il resto ?
  • Re: Jframe jtable

    Bene grazie per la risposta ^_^
    anzitutto partiamo con l'header!
    avevo già provato la tua soluzione di fare un metodo che restituisse cosa mettere nell'header, ma con i firedatatablechanged, o come si scrive, NON mi funzionava. sono ricorso a questa soluzione.
    
    case 15: if (c == false) 
    					{
    						colonne[15] = "Cavalli"; 
    						fireTableStructureChanged(); 
    						return automobile.getCavalli();
    					}
    					else
    					{
    						colonne[15] = "KW"; 
    						fireTableStructureChanged(); 
    						return automobile.conversioneCK(automobile.getCavalli());
    					}
    
    e funziona alla grande. questo codice è dentro al getValueAt().

    poi passiamo al sortrow
    il punto è, io avevo fatto un if. se la dimensione della lista automobili è 0, non fai nulla, se invece la lista ha degli elementi, allora mi attivi la funzione.
    
    if (atb.getRowCount() != 0)
    				{
    					tb.setAutoCreateRowSorter(true);
    				}
    
    il problema è che non funzionava. e te mi dirai che è normale perché non ho considerato qualcosa.
    ok allora la soluzione iniziale era semplicemente
    
    tb.setAutoCreateRowSorter(true);
    
    il problema è che all'inizio la lista essendo vuota, mi genera un'eccezione, ora te la copio
    
    Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range
            at javax.swing.DefaultRowSorter.checkAgainstModel(Unknown Source)
            at javax.swing.DefaultRowSorter.rowsInserted(Unknown Source)
            at javax.swing.JTable.notifySorter(Unknown Source)
            at javax.swing.JTable.sortedTableChanged(Unknown Source)
            at javax.swing.JTable.tableChanged(Unknown Source)
            at javax.swing.table.AbstractTableModel.fireTableChanged(Unknown Source)
            at javax.swing.table.AbstractTableModel.fireTableRowsInserted(Unknown Source)
            at AutomobileTableModel.changeRowNumber(AutomobileTableModel.java:64)
            at FrameTabella$2.actionPerformed(FrameTabella.java:109)
            at javax.swing.AbstractButton.fireActionPerformed(Unknown Source)
            at javax.swing.AbstractButton$Handler.actionPerformed(Unknown Source)
            at javax.swing.DefaultButtonModel.fireActionPerformed(Unknown Source)
            at javax.swing.DefaultButtonModel.setPressed(Unknown Source)
            at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(Unknown Source)
            at java.awt.Component.processMouseEvent(Unknown Source)
            at javax.swing.JComponent.processMouseEvent(Unknown Source)
            at java.awt.Component.processEvent(Unknown Source)
            at java.awt.Container.processEvent(Unknown Source)
            at java.awt.Component.dispatchEventImpl(Unknown Source)
            at java.awt.Container.dispatchEventImpl(Unknown Source)
            at java.awt.Component.dispatchEvent(Unknown Source)
            at java.awt.LightweightDispatcher.retargetMouseEvent(Unknown Source)
            at java.awt.LightweightDispatcher.processMouseEvent(Unknown Source)
            at java.awt.LightweightDispatcher.dispatchEvent(Unknown Source)
            at java.awt.Container.dispatchEventImpl(Unknown Source)
            at java.awt.Window.dispatchEventImpl(Unknown Source)
            at java.awt.Component.dispatchEvent(Unknown Source)
            at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
            at java.awt.EventQueue.access$500(Unknown Source)
            at java.awt.EventQueue$3.run(Unknown Source)
            at java.awt.EventQueue$3.run(Unknown Source)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
            at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
            at java.awt.EventQueue$4.run(Unknown Source)
            at java.awt.EventQueue$4.run(Unknown Source)
            at java.security.AccessController.doPrivileged(Native Method)
            at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(Unknown Source)
            at java.awt.EventQueue.dispatchEvent(Unknown Source)
            at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
            at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
            at java.awt.EventDispatchThread.run(Unknown Source)
    
    visto quello che dice all'inizio, Exception in thread "AWT-EventQueue-0" java.lang.IndexOutOfBoundsException: Invalid range, ho pensato che fosse perché non ha elementi, quell'invalid range mi porta a pensare a questo.

    ho risolto nella maniera forse meno corretta, ma comunque funziona
    
    SpinnerModel jsm = new SpinnerNumberModel(1, 0, 1000, 1);
    		final JSpinner js = new JSpinner(jsm);
    		JButton b = new JButton("Visualizza");
    		b.addActionListener(new ActionListener()
    		{
    			public void actionPerformed(ActionEvent e)
    			{
    				Integer i = (Integer)js.getValue();
    				atb.changeRowNumber(i);
    				if (atb.getRowCount() != 0)
    				{
    					tb.setAutoCreateRowSorter(true);
    				}
    			}
    		});
    
    per il colore, io avevo già questo piccolo metodo, forse inefficiente.
    
    /*public Component prepareRender(TableCellRender r, int data, int colonne)
    	{
    		Component c = super.prepareRender(r, data, colonne)
    		if (data % 2 == 0)
    		c.setBackground(Color.WHITE);
    		else
    		c.setBackground(Color.LIGHT_GRAY);
    		return c;
    	}*/
    
    ma lo avevo usato quando ho provato a fare la prima tabella, ora dovrei adattarlo al nuovo modello. qui abbiamo data che è una matrice contenente tutti i dati della tabella, quindi forse non va bene per la mia attuale tabella

    il punto 4)
    nella mia classe automobili io ho TUTTI i metodi per la creazione random dei valori.
    ora, anche la moto avrà bisogno degli stessi metodi.
    quindi pensavo di toglierli dalla classe automobili, metterli in una classe componenti, e farla estendere da automobili e moto. poi, se automobili richiama il metodo setMarca(), allora dentro avrò un metodo getClassName() (non so se sia davvero questo), che mi va a dire al filereader quale file leggere.
    per esempio
    
    private String marche[] = new String[80];
    private void vettoreMarche()
    	{
                    nomeClasse = getClassName();
    		try
    		{
    			Scanner reader = new Scanner(new FileReader(nomeClasse + ".txt"));
    			for (int i = 0; reader.hasNextLine (); i++)
    			{
    				String line = reader.nextLine();
    				marche[i] = line;
    			}
    		}
    		catch (FileNotFoundException e)
    		{
    		}
    	}
    
    onestamente non ho ancora pensato a come ridimensionare l'array, pensavo semplicemente di fare un bel
    
    if (nomeClasse.equals("Automobili")
    marche[] = new String[80]
    else
    marche[] = new String[ora non so il numero]
    
    dovrebbe essere abbastanza pulito

    bhe no, a quel punto sarebbe un database, e non lo voglio fare perché altrimenti dovrei fare le cose fatte bene, quindi dovrei dare tutti i dati corretti e non mi va proprio. lascio che si arrangi il sistema a buttarmi fuori i valori così mi tolgo un peso
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    
    case 15: if (c == false) 
    					{
    						colonne[15] = "Cavalli"; 
    						fireTableStructureChanged(); 
    						return automobile.getCavalli();
    					}
    					else
    					{
    						colonne[15] = "KW"; 
    						fireTableStructureChanged(); 
    						return automobile.conversioneCK(automobile.getCavalli());
    					}
    
    e funziona alla grande. questo codice è dentro al getValueAt().
    Ma è inappropriato!! Non si invocano i fireXXX dentro getValueAt!!!
    Non hai ancora proprio compreso i table model ....
  • Re: Jframe jtable

    E come ho detto, ho provato la precedente soluzione di ansharja ma non mi ha funzionato. questa è l'unica soluzione che al momento mi funziona, e finchè funziona, PER IL MOMENTO, mi va bene così onestamente.
    come ho già avuto modo di scrivere, magari più avanti, quando sarò più competente, allora prenderò questo esercizio e ci farò una v2 con un codice nettamente migliore
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    Bene grazie per la risposta ^_^
    anzitutto partiamo con l'header!
    avevo già provato la tua soluzione di fare un metodo che restituisse cosa mettere nell'header, ma con i firedatatablechanged, o come si scrive, NON mi funzionava. sono ricorso a questa soluzione.
    
    case 15: if (c == false) 
    					{
    						colonne[15] = "Cavalli"; 
    						fireTableStructureChanged(); 
    						return automobile.getCavalli();
    					}
    					else
    					{
    						colonne[15] = "KW"; 
    						fireTableStructureChanged(); 
    						return automobile.conversioneCK(automobile.getCavalli());
    					}
    
    e funziona alla grande. questo codice è dentro al getValueAt().
    No, questo non va bene. Oltre ai fire, come dice @andbin, non ha alcun senso settare il nome delle colonne all'interno del getValueAt, questo è un metodo che deve solo restituire i valori, e può venire chiamato centinaia o migliaia di volte in base al numero di righe, non deve contenere niente altro.

    Visto che i pezzi di codice coinvolti te li abbiamo già scritti (in particolare @andbin per il TableModel, ma anche come settare la visualizzazione cavalli/KV), ti rimetto in un unico blocco un codice funzionante (basta copiare/incollare, compilare ed eseguire) e dove il tutto è gestito meglio:
    
    import java.awt.BorderLayout;
    import java.awt.FlowLayout;
    import java.awt.event.ActionEvent;
    import java.awt.event.ItemEvent;
    import java.awt.event.ItemListener;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.AbstractAction;
    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingUtilities;
    import javax.swing.border.EmptyBorder;
    import javax.swing.table.AbstractTableModel;
    public class TabellaAutomobiliShortVersion
    {
    	public static void main (String [] args) {
            SwingUtilities.invokeLater (new Runnable () {
                public void run () {
    				createAndShowGUI ();
    			}
            });
        }
    	private static void createAndShowGUI () {
    		JFrame frame = new JFrame ("Tabella Automobili");
    		frame.setContentPane (new MainPanel ());
    		frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    		frame.pack ();
    		frame.setLocationRelativeTo (null);
    		frame.setVisible (true);
    	}
    }
    class MainPanel extends JPanel
    {
        private AutomobileTableModel tableModel;
        private JTable table;
    
        public MainPanel () {
    		super (new BorderLayout (0, 10));
    		// --- List ---
            List <Automobile> automobili = new ArrayList <Automobile> ();
    		// --- Table ---
    		table = new JTable (tableModel = new AutomobileTableModel (automobili));
    		table.setAutoCreateRowSorter (true);
    		// --- CheckBox ---
    		JCheckBox checkBox = new JCheckBox ("Show KV", false);
    		checkBox.addItemListener (new ItemListener () {
    			@Override public void itemStateChanged (ItemEvent e) {
    				tableModel.setShowKV (e.getStateChange () == ItemEvent.SELECTED);
    			}
    		});
    		// --- Options Panel ---
    		JPanel optionsPanel = new JPanel (new FlowLayout (FlowLayout.LEFT, 10, 0));
    		optionsPanel.add (checkBox);
    		// --- Adding Components ----
    		add (new JScrollPane (table), BorderLayout.CENTER);
    		add (optionsPanel, BorderLayout.SOUTH);
    		// --- Border ---
    		setBorder (new EmptyBorder (20, 20, 20, 20));
        }
    }
    class AutomobileTableModel extends AbstractTableModel
    {
        private static final String [] nomiColonne = {"Marca", "Modello", "Anno", "Cavalli"};
        private static final Class <?> [] tipiColonne = {String.class, String.class, Integer.class, Integer.class};
    	
    	private boolean showKV;
        private List <Automobile> automobili;
    
        public AutomobileTableModel (List <Automobile> automobili) {
            this.automobili = automobili;
        }
    	@Override public Class <?> getColumnClass (int columnIndex) {
            return tipiColonne [columnIndex];
        }
    	@Override public int getColumnCount () {
            return nomiColonne.length;
        }
        @Override public String getColumnName (int columnIndex) {
    	if (columnIndex == 3 && showKV) return "KV";
            else return nomiColonne [columnIndex];
        }
        @Override public int getRowCount () {
            return automobili.size ();
        }
        @Override public Object getValueAt (int rowIndex, int columnIndex) {
            Automobile automobile = automobili.get (rowIndex);
    	if (automobile == null) return null;
            switch (columnIndex) {
    			case 0: return automobile.getMarca ();
    			case 1: return automobile.getModello ();
    			case 2: return automobile.getAnno ();
    			case 3: {
    				if (showKV) return automobile.getKV ();
    				else return automobile.getCavalli ();
    			}
    			default: return null;
            }
        }
    	public void setShowKV (boolean showKV) {
    		this.showKV = showKV;
    		fireTableStructureChanged ();
    	}
    }
    class Automobile
    {
        private final int anno;
        private final int cavalli;
        private final String marca;
        private final String modello;
    
        public Automobile (String marca, String modello, int anno, int cavalli) {
            this.marca = marca;
            this.modello = modello;
            this.anno = anno;
    		this.cavalli = cavalli;
        }
    	public int getAnno () {
            return anno;
        }
    	public int getCavalli () {
    		return cavalli;
    	}
    	public int getKV () {
    		// Scrivi qui la conversione ...
    		return cavalli;
    	}
        public String getMarca () {
            return marca;
        }
    	public String getModello () {
            return modello;
        }
    }
    
    E' tutta roba che hai già visto praticamente, a parte il codice per creare il frame che ho scritto un po' diversamente, solo per mia abitudine.

    La parte importante è il getColumnName (), dove setti il nome correttamente in base al fatto di voler mostrare o meno la conversione, il getValueAt (), dove fai praticamente la stessa cosa ma ritornando il valore al posto del nome della colonna, e il setShowKV (), dove imposti se mostrare o meno la conversione e aggiorni l'header.

    Questo funziona, e come vedi anche senza nessun elemento nella lista il setAutoCreateRowSorter () non è causa di eccezioni.

    KuroKami69 ha scritto:



    Poi passiamo al sortrow

    [...]
    Già detto prima, basta richiamarlo in fase di creazione della tabella. Fai qualche prova con il codice sopra, magari trovi prima la causa dell'eccezione, altrimenti posta un esempietto dove riesci a riprodurre il problema con meno codice possibile.

    KuroKami69 ha scritto:


    Per il colore, io avevo già questo piccolo metodo, forse inefficiente.
    
    /*public Component prepareRender(TableCellRender r, int data, int colonne)
    	{
    		Component c = super.prepareRender(r, data, colonne)
    		if (data % 2 == 0) c.setBackground(Color.WHITE);
    		else c.setBackground(Color.LIGHT_GRAY);
    		return c;
    	}*/
    
    ma lo avevo usato quando ho provato a fare la prima tabella, ora dovrei adattarlo al nuovo modello. Qui abbiamo data che è una matrice contenente tutti i dati della tabella, quindi forse non va bene per la mia attuale tabella.
    Hai sbagliato a scrivere o stai usando questo metodo scritto così? Il metodo si chiama prepareRenderer (non prepareRender), idem per TableCellRenderer. Se vuoi modificare il colore devi fare l'ovveride di un metodo chiamato in automatico dalla tabella, non puoi definirti tu un metodo. E gli ultimi due parametri sono semplicemente il numero di riga e di colonna, non puoi passare una matrice di dati.

    Io consiglierei di fare l'override del getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column), hai informazioni maggiori, compreso il valore della cella e il fatto che la cella sia selezionata o abbia il focus. Il modo in cui setti il colore di sfondo è praticamente uguale, compreso il fatto di chiamare il metodo della superclasse.

    KuroKami69 ha scritto:


    il punto 4)
    nella mia classe automobili io ho TUTTI i metodi per la creazione random dei valori.
    ora, anche la moto avrà bisogno degli stessi metodi.
    quindi pensavo di toglierli dalla classe automobili, metterli in una classe componenti, e farla estendere da automobili e moto. poi, se automobili richiama il metodo setMarca(), allora dentro avrò un metodo getClassName() (non so se sia davvero questo), che mi va a dire al filereader quale file leggere.

    [...]

    onestamente non ho ancora pensato a come ridimensionare l'array, pensavo semplicemente di fare un bel
    
    if (nomeClasse.equals("Automobili")
    marche[] = new String[80]
    else
    marche[] = new String[ora non so il numero]
    
    dovrebbe essere abbastanza pulito

    bhe no, a quel punto sarebbe un database, e non lo voglio fare perché altrimenti dovrei fare le cose fatte bene, quindi dovrei dare tutti i dati corretti e non mi va proprio. lascio che si arrangi il sistema a buttarmi fuori i valori così mi tolgo un peso
    Va bene una classe (magari astratta) che sia estesa da Automobile e da Moto. Per il resto non ci siamo. Non ha alcun senso cercare di prendere il nome della classe, stai facendo dei giri assurdi.

    Automobili e Moto creale da una classe esterna, es. CostruttoreVeicoli, e tutte le operazioni di lettura da file le fai in metodi appositamente creati (es. un metodo leggiAutomobili che restituisca una Lista di oggetti Automobile, e un metodo analogo per le moto, o anche un unico metodo che legge un file contenente sia auto sia moto e restituisca una lista di oggetti della superclasse).

    All'interno dei metodi crei un BufferedReader per il file, che a quel punto non viene passato come parametro o con un qualche strano giro, e poi a seconda dei valori letti chiami il costruttore di Auto o Moto con quei valori, o usi dei metodi set (quelli convenzionali) per impostare i valori letti. Nessun bisogno di capire quale classe stia chiamando un metodo.
    Se il metodo restituisce una lista di veicoli di qualsiasi tipo, che aggiunge man mano che legge le righe del file, non hai nessun problema a dover dimensionare un array.
  • Re: Jframe jtable

    Onestamente, a me pare infinitamente più complicato la via da te suggerita. sarà che non son esperto, ma a me pare davvero più complessa.
    proverò a sistemare come consigliato, ma ripeto, se il rowsort lo chiamo alla creazione della tabella, mi da quelle eccezioni. sull'esempio da te messo, che sostanzialmente è un estensione di quello di andbin, tu passi al tablemodel dei dati che riempiono la tabella. io la creo vuota. e quando la crei vuota, questo si domanda, cosa diamine devo ordinare se non c'è nulla? così la vedo io in base a quell'eccezione la.
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    ma ripeto, se il rowsort lo chiamo alla creazione della tabella, mi da quelle eccezioni.
    Il setAutoCreateRowSorter, se sai che ti interessa usarlo, lo usi tipicamente 1 volta sola quando crei la tabella.
    tableModel = new AutomobileTableModel(automobili);
    table = new JTable(tableModel);
    table.setAutoCreateRowSorter(true);
    ....
    Tutto qui. Stop.
  • Re: Jframe jtable

    E usandolo come dici te, mi genera le eccezioni di cui sopra
    generando quelle eccezioni succede che appena inserisco il numero di veicoli da mostrare e premendo il bottone "visualizza", non fa nulla. devo premere sull'header di una colonna un paio di volte per vedere i risultati
Devi accedere o registrarti per scrivere nel forum
230 risposte