Jframe jtable

di il
230 risposte

230 Risposte - Pagina 2

  • Re: Jframe jtable

    Premesso che implementare il tuo modello è sicuramente utile e magari in molti casi praticamente l'unica scelta, se non hai grandi esigenze a mio parere per ora potresti anche "appoggiarti" al DefaultTableModel, ti permette di impostare cose essenziali come il fatto di avere le celle editabili o meno, e può essere costruito anche a partire da una matrice di dati, che però dovresti popolare tu, copiandoci i dati da dove li stai attualmente memorizzando (a meno che non sia già una matrice bidimensionale ovviamente).

    Altrimenti puoi anche sfruttare il metodo addRow (Object [] data), con cui sostanzialmente a partire dal tuo oggetto, es. una macchina, inserisci man mano i campi in un vettore che poi passi al modello per aggiungere una riga. Ci sarebbe anche il metodo addColumn, che è comodo ad esempio quando hai una lista che puoi "convertire" al volo in array e passare al metodo.

    Qui trovi i metodi e i costruttori di DefaultTableModel, la documentazione è molto importante da leggere (compresi i tutorial del tipo "How to use tables" che hai già linkato se non sbaglio), soprattutto se vuoi partire in quarta, quindi fai uno sforzo con l'inglese

    Comunque il tipo di modello è solo l'inizio: per fare tutto quello che scrivi nel primo messaggio hai bisogno di inserire la tabella dentro a uno JScrollPane per renderla "scrollabile", ma poi ci saranno più problemi, ad esempio:

    - Di default non è lo scrollpane che si adatta alla dimensione della tabella ma viceversa, quindi le colonne occupano tutte la stessa larghezza e se sono tante vedrai le celle che troncano il testo con "...". Se la tabella ha poche righe poi, lo scrollpane sarà più alto e potresti avere un fastidioso buco in mezzo. Una soluzione è fare l'override in JTable del metodo getPreferredScrollableViewportSize(), dove ritorni le dimensioni "corrette", per fare in modo che sia lo scrollpane ad adattarsi alla tabella.
    - Altra cosa è data dal fatto che le colonne della tabella non sono dimensionate in base alla cella più larga, ma appunto occupano tutte la stessa misura e si resizano automaticamente. Se vuoi che le celle si adattino al contenuto tipicamente devi settare l'auto resize su off (vedi la documentazione di JTable, così prendi un po' la mano ) e poi settare manualmente la preferred size delle TableColumn calcolando la dimensione richiesta invocando per ogni colonna il prepareRenderer, ciclando su ogni riga fino a trovare la dimensione maggiore (trovi su internet codici già pronti all'occorrenza).

    Questo solo per confermare che le tabelle possono essere parecchio rognose. Nel tutorial che hai linkato ti dice anche come abilitare l'ordinamento automatico, senza dover esplicitamente create un RowSorter (che gestisce anche il filtraggio delle colonne all'interno, quindi implementandone uno avresti la possibilità di filtrare la tabella per righe mostrando solo le auto o le moto o tutte e due, un'altra possibilità è invece avere due modelli separati per auto e moto e usare un JRadioButton o JComboBox per scambiare i modelli della tabella).

    Buona lettura!

    Ps: Per me non è affatto chiaro perché credi che una Hashtable sia comoda da usare, magari fai un po' chiarezza sul come pensi di creare le auto, io ero rimasto al file da cui leggi le marche, hai un altro file contenente delle auto di esempio o fai tutto al volo (magari con quei frammenti di codice che avevi postato in altre parti per settare le variabili casualmente)?
  • Re: Jframe jtable

    Bhe non credo sia comoda, solo che mi è stato detto che l'unico modo per poter istanziare diversi oggetti automaticamente, con un for o un while per esempio, e quindi questo ho fatto. Se ce ne sono altri allora sono tutto orecchie tra l'altro installando reimage mi si è impestato il pc quindi ora dovrò perdere un sacco di tempo per sistemare tutto :/
    Comunque ho letto quello che hai scritto, ma le mie necessitá sno davvero poche. Alcuni tuoi punti esulano totalmente, ma prendo nota casomai dovessero servirmi in futuro, grazie domanda ignorante, cos'è l'override?
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    solo che mi è stato detto che l'unico modo per poter istanziare diversi oggetti automaticamente, con un for o un while per esempio
    Sì ma non c'entra niente direttamente una hashtable!

    KuroKami69 ha scritto:


    domanda ignorante, cos'è l'override?
    È uno dei concetti più importanti della programmazione Java (e in generale della OOP) .... prendi quel libro indicato prima. Senza certi concetti non si va molto avanti ...
  • Re: Jframe jtable

    andbin ha scritto:


    KuroKami69 ha scritto:


    solo che mi è stato detto che l'unico modo per poter istanziare diversi oggetti automaticamente, con un for o un while per esempio
    Sì ma non c'entra niente direttamente una hashtable!

    KuroKami69 ha scritto:


    domanda ignorante, cos'è l'override?
    È uno dei concetti più importanti della programmazione Java (e in generale della OOP) .... prendi quel libro indicato prima. Senza certi concetti non si va molto avanti ...
    la domanda rimane invariata mi consigliate di aspettare quello che esce a fine febbraio con la versione 9, e intanto arrangiarmi con quello che ho, visto che i concetti son sempre gli stessi indipendentemente dalla versione, credo, oppure prendo la 8 e per la 9 aspetto un annetto o più?
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    mi consigliate di aspettare quello che esce a fine febbraio con la versione 9
    No, prendi pure quello indicato prima. Le novità di Java 9 non dovrebbero nemmeno interessarti più di tanto, almeno ora. Già Java 8 ha introdotto una svagonata di nuovi concetti e su questi prima che ci arrivi dovrà passare un bel po' di tempo (mesi ...).

    KuroKami69 ha scritto:


    visto che i concetti son sempre gli stessi indipendentemente dalla versione
    I concetti di base sì, sono sempre gli stessi, anche in Java 8/9. E sono questi che devi apprendere. Poi tutte le novità di Java 7/8/9 vengono dopo e solo dopo aver ottenuto solide basi sul resto (almeno su tutto quanto fino a Java 5).
  • Re: Jframe jtable

    D'accordo, allora vedo di ordinare subito quel libro, grazie
  • Re: Jframe jtable

    Comunque per ora ho trovato un paio di video su youtube che mi han fatto capire che a livello di codice non è poi così difficile, che era la cosa che mi spaventava maggiormente.
    mi han anche dato un'idea carina per fare una cosa fatta bene, nei limiti della casualità con cui ho fatto questo miniprogettino
    ci metterò qualche giorno a sviluppare il codice, ma poi spero che abbiate voglia di darci un occhio, aiutarmi se qualcosa non mi torna, e darmi altri consigli ancora
    ovviamente, ho intenzione di studiare anche i concetti teorici, ma intanto permettetemi di finire questo miniprogetto, nell'attesa del libro
    onestamente non mi è chiaro come fare una tabella e un frame che si adattano al contenuto, voglio dire, avere delle colonne che si adattano al loro contenuto senza doverci settare un valore, ma per il momento vediamo di creare una tabella standard
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    ho trovato un paio di video su youtube che mi han fatto capire che a livello di codice non è poi così difficile
    Non ho nulla contro i video su youtube .... ma per studiare "sul serio" servono dei bei libri ....

    KuroKami69 ha scritto:


    onestamente non mi è chiaro come fare una tabella e un frame che si adattano al contenuto, voglio dire, avere delle colonne che si adattano al loro contenuto senza doverci settare un valore
    JTable purtroppo non ha la capacità di adattare la larghezza di una colonna al contenuto. Ci sono vari approcci per dimensionare le colonne in modo che venga fuori qualcosa di "ragionevole". Ma JTable non "sa" calcolare la massima larghezza misurando l'occupazione in pixel di tutti i dati nella colonna.
    Se vuoi puoi farlo tu ma serve un "po'" di codice.
  • Re: Jframe jtable

    Al momento non son in grado di sviluppare un codice simile, quindi la mia tabella rimarrà con le colonne di default^^''
    ahahahah
    ok allora posso capire se sto andando bene?
    sto impostando la classe Tabella.
    mi serve una tabella di 25 colonne e tante righe quante auto l'utente vuole vedere, quindi nella tabella o jframe che sia (penso jframe) ci sarà un campo dati con un bottoncino
    mi son fatto un array con i vari header.
    a questo punto mi son fatto la mia hashtable per generare n auto, a seconda di quante ne vuole vedere l'utente
    poi mi son fatto un array di oggetti, non so onestamente se ho fatto bene, (Object metodi[] = new Object[25] da usare per popolare la matrice dei dati della tabella, con 2 for. nel primo for passo le colonne, nel secondo le righe. in ogni colonna richiamo il metodo adatto.
    non so se questa soluzione è accettabile ma è il meglio che son riuscito a pensare finora
  • Re: Jframe jtable

    Bene vi posto il codice, sicuramente migliorabile, potreste dirmi se secondo voi è quantomeno accettabile per favore?
    manca ancora la tendina/radiobutton per scegliere se vedere auto, moto, entrambe, ma credo che il concetto sia lo stesso del button. fino ad ora comunque funziona tutto
    
    JFrame jf = new JFrame("Lista Veicoli");
    		JLabel jl = new JLabel("Inserisci il numero di veicoli da visualizzare");
    		JButton b = new JButton("Visualizza");
    		JTextField jt = new JTextField(5);
    		b.addActionListener(new ActionListener()
    		{
    			public void actionPerformed(ActionEvent e)
    			{
    				int i = Integer.parseInt(jt.getText());
    				//JOptionPane.showMessageDialog(null, "hai digitato " + i, "allert", JOptionPane.INFORMATION_MESSAGE);
    			}
    		});
    		JPanel p = new JPanel();
    		
    		//Tabella t = new Taella();
    		jf.setSize(1600, 500);
    		jf.setVisible(true);
    		jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		jf.add(p);
    		p.add(jl);
    		p.add(jt);
    		p.add(b);
                    //jf.add(t);
    		
    
  • Re: Jframe jtable

    Accettabile più o meno in realtà, anche se è poca roba, e il difficile viene dopo, c'è comunque qualcosa da sistemare. Non va bene aggiungere al frame componenti dopo averlo reso visibile, in alcuni casi non vedrai proprio il contenuto o lo vedrai solo quando il frame sarà "forzato" a ridisegnarsi, ad esempio perché stai ridimensionando la finestra.

    L'istruzione setVisible (true); è l'ultima da richiamare sul frame, e sarebbe meglio evitare di impostare la dimensione programmaticamente con setSize ();, ma piuttosto richiamare sul frame il metodo pack () per lasciare che si dimensioni correttamente in base al layout manager utilizzato dal content pane:
    
    // crei quello che devi
    jf.add (p); // questo di default aggiunge p in BorderLayout.CENTER del content pane
    // jf.setContentPane (p); // in alternativa setti direttamente il content pane
    jf.pack ();
    // jf.setLocationRelativeTo (null); // se vuoi puoi centrare il frame sullo schermo, o rispetto a un altro componente (es. un frame "genitore" se stessi facendo una finestra modale, ma questa è un'altra storia ...)
    jf.setVisible (true);
    
    Altra cosa da considerare: il textfield non è formattato per contenere numeri (lo puoi fare con altri tipi di componenti o settando un filtro, ma quest'ultimo è più complicato), quindi per ora sarebbe meglio usare un try-catch per evitare eccezioni NumberFormatException se il parseInt fallisce a causa di testo non convertibile in numero.

    Se vuoi poi il JButton può essere costruito direttamente passando al costruttore una classe che implementa Action (che implementa a sua volta ActionListener), ad esempio AbstractAction, questo ti evita di dover salvarti il reference al bottone se non ne hai bisogno in altre parti del codice solo per aggiungere l'ActionListener, es:
    
    p.add (new JButton (new AbstractAction ("Visualizza") {
    	public void actionPerformed (ActionEvent e) {
    		// ... fai quello che devi qui
    	}
    });
    
    Ma è solo per comodità, non è affatto sbagliato.
  • Re: Jframe jtable

    In realtà ho bisogno dell'input del textfield per poter capire quante auto visualizzare, quindi mi salvo l'input e lo dirigo poi nella tabella dove lavoro con la classe automobili.
    detto questo ho cambiato linea d'azione.
    da quando ho capito per fare le cose molto semplicemente, mi basterebbe, anzitutto per la creazione dinamica di oggetti, creare una arraylist, in cui ogni volta chiamo il costruttore di automobili. devo ancora capire poi come usare i metodi, ma presumo sarà qualcosa tipo, per esempio
    arrayListAuto[0].getModello();
    tra l'altro ho saputo che è possibile bindare un dato elemento a una data colonna di una tabella, e quindi stavo appunto pensando di utilizzare questa tecnica per evitare così di fare un doppio for annidato.
    come linea d'azione dovrebbe essere più soddisfacente che usare le hashmap giusto?
    detto questo, ti ringrazio per avermi dato dei consigli sul codice postato sopra, non ho capito però il metodo pack(). basta che lo richiamo al posto dei valori di altezza e larghezza del frame?
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    tra l'altro ho saputo che è possibile bindare un dato elemento a una data colonna di una tabella
    Quel JTableBinding è di una libreria esterna. E' appunto un altra cosa e va scaricata e referenziata appositamente.
    Ma non c'entra direttamente con i concetti e le capacità di "base" di JTable.
    Visti i dubbi, lascia perdere librerie esterne.
  • Re: Jframe jtable

    KuroKami69 ha scritto:


    In realtà ho bisogno dell'input del textfield per poter capire quante auto visualizzare, quindi mi salvo l'input e lo dirigo poi nella tabella dove lavoro con la classe automobili.
    Non sto mettendo in dubbio questo, ma se jt è un JTextField il codice:
    
    int i = Integer.parseInt (jt.getText());
    
    Non è sicuro, nessuno ti assicura che jt contenga un testo interpretabile come numero. Se non è così, il programma lancia un'eccezione, che dovresti quindi catturare tu inserendo il parseInt in un blocco try-catch, anche se in questo caso l'applicazione non verrebbe interrotta non va bene esporsi a questi errori. Se sostituisci un JTextField con un componente che può contenere solo numeri, es. JSpinner con uno SpinnerNumberModel, non hai questo problema (e JSpinner è anche più comodo per aumentare/diminuire il numero di righe, dai un'occhiata al tutorial How to use Spinners per farti un'idea), ma se per ora vuoi continuare col textfield (che è più semplice per ora) cattura l'eccezione.

    KuroKami69 ha scritto:


    detto questo ho cambiato linea d'azione.
    da quando ho capito per fare le cose molto semplicemente, mi basterebbe, anzitutto per la creazione dinamica di oggetti, creare una arraylist, in cui ogni volta chiamo il costruttore di automobili. devo ancora capire poi come usare i metodi, ma presumo sarà qualcosa tipo, per esempio
    arrayListAuto[0].getModello();
    tra l'altro ho saputo che è possibile bindare un dato elemento a una data colonna di una tabella, e quindi stavo appunto pensando di utilizzare questa tecnica per evitare così di fare un doppio for annidato.
    come linea d'azione dovrebbe essere più soddisfacente che usare le hashmap giusto?
    Se non hai bisogno di accedere agli elementi per chiave o altre cose particolari una lista è decisamente più comoda, ed è assolutamente possibile usare un ciclo per aggiungere elementi in una lista, che siano creati al volo o letti da qualche parte. Quindi ok per la lista.
    In realtà non credo che tu abbia bisogno di importare soluzioni esterne per la creazione della tabella, non credo che usare un doppio for o passare per gli altri costruttori dei modelli sia un grande problema ...

    KuroKami69 ha scritto:


    non ho capito però il metodo pack(). basta che lo richiamo al posto dei valori di altezza e larghezza del frame?
    Esatto, non sei tu a dover controllare la dimensione del frame, lascia che questo lavoro lo facciano i layout manager.
  • Re: Jframe jtable

    @andbin capisco. ma parlando con il mio prof di sistemi, mi ha detto che dovrebbe esserci un metodo di jtable per fare il bind.
    leggendo un attimino di sfuggita la spiegazione della classe e il codice che propone, mi sembra anche una cosa abbastanza semplice, alla fine mi basta bindare a ogni colonna il metodo inerente e dovrei essere apposto no?
    anyway per il momento mi dedico a capire gli arraylist prima di fare altri passi.

    @Ansharja ho letto male, scusami, sono un attimo stanco e qualche errorino di lettura e interpretazione, dovuto anche magari al fatto che ero concentrato sul binding, mi ha portato a fraintendere.
    per il pack, lo inserisco subito, grazie per la dritta
    EDIT: il pack però funziona solo qualora nel mio frame io abbia già una tabella però, o mi sbaglio?
    EDIT2: ok il pack va messo come istruzione a se stante non dentro la definizione della size del frame xD
    per quanto riguarda l'arraylist. come detto a me basta semplicemente poter abbinare a una colonna il metodo adatto. che poi farlo con 2 for o bindando il metodo alla colonna stessa non mi cambia nulla a livello esistenziale, magari i for son meno problematici da gestire
    mi darò un'occhiata agli spinner, sembrano abbastanza interessanti e utili al mio attuale piccolo progettino quindi magari implementerò
    EDIT3: stavo provando un po' a giochicciare con lo spinner, ma non posso usare un bottone con un listener associato, devo usare un listener associato al cambiamento dello spinner giusto?
    onestamente non ho ben capito il setvisible(true)
    sostanzialmente mi conviene prima chiamare ogni singolo elemento del frame e poi rendere tutto visibile?
Devi accedere o registrarti per scrivere nel forum
230 risposte