Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Savet oko JTable i TableModel-a

[es] :: Java :: Savet oko JTable i TableModel-a

[ Pregleda: 2519 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

eXPerience
[ coded ]

Član broj: 14396
Poruke: 88
77.46.200.*

Sajt: [ coded ]


Profil

icon Savet oko JTable i TableModel-a21.08.2007. u 13:03 - pre 202 meseci
Pravim jedan program koji bi, najjednostavnije receno, omogucavao manipulaciju bazom preko JTable, znaci unos, izmena i brisanje podataka. Podaci za tabelu su u vektoru koji se cuva u fajlu. Prva ideja mi je bila da se svaki put pri unosu ili izmeni podataka vektor cuva u fajl, ali to ide sporo jer postoji vise hiljada unosa. Druga ideja mi je da pri startovanju programa pozovem metodu koja ce da ucita vektor iz fajla i koji ce program na dalje da koristi, a da se tek pri izlazu iz programa isti sacuva u fajl. E sad treba mi pomoc, valja li mi ideja i valja li ovako TableModel:

Code:

import java.io.File;
import java.io.FileInputStream;
import java.io.ObjectInputStream;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.table.AbstractTableModel;

public class ModelTabelePlacanja extends AbstractTableModel {
    
    private static final long serialVersionUID = 1L;
    
    public static Vector kolone, podaci;
    
    private static ModelTabelePlacanja instance = null;
    
    public ModelTabelePlacanja() {
        initNazivi();
        initPodaci();
    }
    
    public static ModelTabelePlacanja getInstance() {
        if (instance == null)
            instance = new ModelTabelePlacanja();
        return instance;
    }

    public int getColumnCount() {
        return kolone.size();
    }

    public int getRowCount() {
        return podaci.size();
    }
    
    public String getColumnName(int col) {
        return kolone.elementAt(col).toString();
    }

    public Object getValueAt(int row, int col) {
        Vector red = (Vector)podaci.elementAt(row);
        return red.elementAt(col);
    }
    
    public Class getColumnClass(int c) {
        return getValueAt(0, c).getClass();
    }
    
    public boolean isCellEditable(int row, int col) {
        return false;
    }
    
    public void setValueAt(Object value, int row, int col) {
        Vector red = (Vector)podaci.elementAt(row);
        red.setElementAt(value, col);
        podaci.setElementAt(red, row);
        //System.out.println("\tred ["+row+"], kolona ["+col+"]");
        fireTableCellUpdated(row, col);
    }
    
    public void initNazivi() {
        kolone = new Vector();
        String[] naziviKolona = { "RB", "Firma", "Br. racuna", "DPO", "Valuta", "Iznos", "Placeno" };
        for (int i=0; i<naziviKolona.length; i++)
            kolone.addElement((naziviKolona[i]));
    }
    
    public void initPodaci() {
        File fajl;
        FileInputStream ulazFile;
        ObjectInputStream ulazObject;
        
        try {
            fajl = new File ("baze/placanja.dat");
            ulazFile = new FileInputStream (fajl);
            ulazObject = new ObjectInputStream (ulazFile);
            podaci = (Vector) ulazObject.readObject();
            ulazObject.close();
            ulazFile.close();
        }
        catch (Exception ex) {
            JOptionPane.showMessageDialog(VPGUI.frameMain, "<html>Ne postoji baza placanja ili je ostecena.<br>"+ex.getMessage()+"</html>", "Greska", JOptionPane.ERROR_MESSAGE);
        }
    }
    
    public void sacuvajPodatke() {
        // po izlazu iz programa 'podaci' upisuje u fajl
    }
}

Dame biraju uvek pogresne tipove ... Na srecu ...
 
Odgovor na temu

Dejan Lozanovic
Dejan Lozanovic
Beograd

Član broj: 691
Poruke: 2325
*.adsl.beotel.net.

Jabber: null@elitesecurity.org
Sajt: speedy-order.com


+75 Profil

icon Re: Savet oko JTable i TableModel-a22.08.2007. u 00:35 - pre 202 meseci
Ne valja, iz jednog prostog razloga, ucitavanje moze da traje predugo pa ce sama aplikacija da izgleda kao da stuca, ono sto savetujem jeste da ubacis SwingWorker u celu pricu, i da ucitavas podatke unutar swing workera i kada zavrsis sa ucitavanjem podataka lepo ceo vektor ili neku drugu kolekciju ubacis u model i onda pozoves metod koji ce da refreshuje sve podatke nad samom tabelom, a jos ako hoces da radis malo kozmetike mozes i kroz swing worker da ubacujes red po red u bazu kako ga ucitavas, pogledaj tutorijal na sunovom sajtu oko toga.

I jos jedno drugo pitanje vezano za sam nacin cuvanja podataka, ako radis nesto komerciijalno sto nije iz domena ucenja swinga onda preporucujem da podatke cuvas ipak u nekoj bazi podataka umesto da ih rucno drzis u fajlu, ja znam za 3 baze podataka koje su cele uradjene u javi (Derby,H2Database,HSQLDB) svaka od ove tri dozvoljava da baza podataka bude izvrsavana unutar iste virtuelne masine gde i tvoj java progam, pa sa druge strane oslobodio si se vodjenja racuna oko skladistenja podataka, a sa druge strane SQL upit ti daje mogucnost da elegantnije recimo izvuces neki podskup podataka, tj da lakse napravis neki drugi izvestaj.

A sada ako cemo oko samog modela, recimo zasto ne napravis JavaBean koji ima sva polja koja su vezana za jedan red, i tada parametrizujes kolekciju sa tipa ArrayList<MojBean> ili Vector<MojBean> i onda prilikom poziva elementAt kao rezultat ne dobija Object nego MojBean, drugo za kolone sto ih prebacujes u Vector pa ih onda citas iz vectora. Zar ne mozes lepo da cuvas taj array stringova promeljivu klase pa onda za getColumnCount umesto kolone.size() ti vratis naziviKolona.lenght i isto tako preko indexa vratis ime kolone. radi brze nego Vector.

I na kraju sto su ti kolone i podaci static, tj zasto od modela pokusavas da napravis singleton, i ako vec imas dovoljno jak razlog da ti model bude singleton onda konstruktor definisi da bude private, tako da isforsiras da svi pozivaju samo getInstance
 
Odgovor na temu

Au197/79
Zlatan Kadragić
Minhen

Član broj: 3556
Poruke: 772
*.adsl.beotel.net.

Sajt: aurelije.blogspot.com


+47 Profil

icon Re: Savet oko JTable i TableModel-a22.08.2007. u 07:56 - pre 202 meseci
Sve to možeš automatski da uradiš u javi 6 sa NetBeansom 6 m10 (alfa verzija ali radi posao):
http://www.netbeans.org/kb/60/ide-gui-db-prev.html
A ovoj je to slično samo u flash-u: http://www.netbeans.org/downlo...er/netbeans_6_gui_builder.html

Ja sam ovih dana provaljivao taj Swing Application framework. Uspeo sam da predstavim i relacije 1-m. Tu ti se i Taskovi izgenerišu (potklase SwingWorkera) ma sve automatski.
Bolje džaba ležat nego džaba radit.
 
Odgovor na temu

eXPerience
[ coded ]

Član broj: 14396
Poruke: 88
77.46.200.*

Sajt: [ coded ]


Profil

icon Re: Savet oko JTable i TableModel-a22.08.2007. u 13:09 - pre 202 meseci
Citat:
Dejan Lozanovic: Ne valja, iz jednog prostog razloga, ucitavanje moze da traje predugo pa ce sama aplikacija da izgleda kao da stuca, ono sto savetujem jeste da ubacis SwingWorker u celu pricu, i da ucitavas podatke unutar swing workera i kada zavrsis sa ucitavanjem podataka lepo ceo vektor ili neku drugu kolekciju ubacis u model i onda pozoves metod koji ce da refreshuje sve podatke nad samom tabelom, a jos ako hoces da radis malo kozmetike mozes i kroz swing worker da ubacujes red po red u bazu kako ga ucitavas, pogledaj tutorijal na sunovom sajtu oko toga.


Ok, pogledao sam ovaj novi SwingWorker, odlicno resenje. Pokusacu nesto da iskombinujem. Hvala na predlogu.

Citat:
Dejan Lozanovic: I jos jedno drugo pitanje vezano za sam nacin cuvanja podataka, ako radis nesto komerciijalno sto nije iz domena ucenja swinga onda preporucujem da podatke cuvas ipak u nekoj bazi podataka umesto da ih rucno drzis u fajlu, ja znam za 3 baze podataka koje su cele uradjene u javi (Derby,H2Database,HSQLDB) svaka od ove tri dozvoljava da baza podataka bude izvrsavana unutar iste virtuelne masine gde i tvoj java progam, pa sa druge strane oslobodio si se vodjenja racuna oko skladistenja podataka, a sa druge strane SQL upit ti daje mogucnost da elegantnije recimo izvuces neki podskup podataka, tj da lakse napravis neki drugi izvestaj.


Ukapirah i ja da je bolje da predjem na SQL. Razmisljao sam o mySql mada ove Derby i H2Database baze zvuce jednostavno.

Citat:
Dejan Lozanovic: A sada ako cemo oko samog modela, recimo zasto ne napravis JavaBean koji ima sva polja koja su vezana za jedan red, i tada parametrizujes kolekciju sa tipa ArrayList<MojBean> ili Vector<MojBean> i onda prilikom poziva elementAt kao rezultat ne dobija Object nego MojBean, drugo za kolone sto ih prebacujes u Vector pa ih onda citas iz vectora. Zar ne mozes lepo da cuvas taj array stringova promeljivu klase pa onda za getColumnCount umesto kolone.size() ti vratis naziviKolona.lenght i isto tako preko indexa vratis ime kolone. radi brze nego Vector.


Nikad nisam koristio JavaBeans, ali uglavnom kapiram sta mislis. Ja sam koristio dva vektora, jedan sadrzi nazive kolona a drugi (vektor vektora, tj. vektor koji sadrzi redove za tabelu) sve podatke za tabelu, jer mi je tako bilo lakse, posto modelu samo prosledim ta dva vektora.
Ako si raspolozen, objasni jos malo sta i kako oko JavaBeans-a.

Citat:
Dejan Lozanovic: I na kraju sto su ti kolone i podaci static, tj zasto od modela pokusavas da napravis singleton, i ako vec imas dovoljno jak razlog da ti model bude singleton onda konstruktor definisi da bude private, tako da isforsiras da svi pozivaju samo getInstance


To mi je bila ideja oko inicijalizacije podataka na pocetku, a cuvanja pri zatvaranju programa, pa je zato singleton ... Al' sad ako predjem na sql sve se to menja.

[Ovu poruku je menjao eXPerience dana 22.08.2007. u 17:30 GMT+1]
Dame biraju uvek pogresne tipove ... Na srecu ...
 
Odgovor na temu

eXPerience
[ coded ]

Član broj: 14396
Poruke: 88
77.46.200.*

Sajt: [ coded ]


Profil

icon Re: Savet oko JTable i TableModel-a22.08.2007. u 13:11 - pre 202 meseci
Citat:
Au197/79: Sve to možeš automatski da uradiš u javi 6 sa NetBeansom 6 m10 (alfa verzija ali radi posao):
http://www.netbeans.org/kb/60/ide-gui-db-prev.html
A ovoj je to slično samo u flash-u: http://www.netbeans.org/downlo...er/netbeans_6_gui_builder.html

Ja sam ovih dana provaljivao taj Swing Application framework. Uspeo sam da predstavim i relacije 1-m. Tu ti se i Taskovi izgenerišu (potklase SwingWorkera) ma sve automatski.


Ne volim bas tu automatiku u tolikoj meri, gledajuci ovaj demo kapiram da NetBeans sve sam odradi ...
Dame biraju uvek pogresne tipove ... Na srecu ...
 
Odgovor na temu

Au197/79
Zlatan Kadragić
Minhen

Član broj: 3556
Poruke: 772
*.adsl.beotel.net.

Sajt: aurelije.blogspot.com


+47 Profil

icon Re: Savet oko JTable i TableModel-a22.08.2007. u 17:27 - pre 202 meseci
Sve ono što je prikazano možeš i sam uraditi samo treba skinuti klase. Mada je sve to još u razvoju i dokumentacija je slaba, ali gledajući kod i razumevajući ga sve se skapira i DataBinding, i Swing Application Framework. JPA anotacije i upite sam znao od ranije. Meni entitetske klase nisu bili izgenerisane kako treba jer nije bilo relacija preko referenci u klasama, već je svaka klasa bila kao kopija tabele sama za sebe. Takođe sam mora da dodam nove akcije da prikažem relacije na panelu itd.
Bolje džaba ležat nego džaba radit.
 
Odgovor na temu

eXPerience
[ coded ]

Član broj: 14396
Poruke: 88
77.46.200.*

Sajt: [ coded ]


Profil

icon Re: Savet oko JTable i TableModel-a24.08.2007. u 00:05 - pre 202 meseci
Citat:
Au197/79: Sve ono što je prikazano možeš i sam uraditi samo treba skinuti klase. Mada je sve to još u razvoju i dokumentacija je slaba, ali gledajući kod i razumevajući ga sve se skapira i DataBinding, i Swing Application Framework. JPA anotacije i upite sam znao od ranije. Meni entitetske klase nisu bili izgenerisane kako treba jer nije bilo relacija preko referenci u klasama, već je svaka klasa bila kao kopija tabele sama za sebe. Takođe sam mora da dodam nove akcije da prikažem relacije na panelu itd.

Skinuo sam NetBeans i probao ono kao sa demoa. Interesantno je kako on to sve napravi i fino to radi, iz koda se moze izvuci korisnih stvari, al ipak ostajem pri Eclipse-u i rucnom radu.


Nego, nesto razmisljah ... Ja zapravo imam dve tabele koje su na neki nacin povezane. Jedna je tabela placanja, a druga tabela je tabela uplata i ona je razlicita za svaki unos u tabeli placanja. Tabela uplata ima samo dve kolone - datum i iznos. E sad ako bih ostao pri cuvanju podataka u fajlu, mogu da napravim klasu Placanje i da ona sadrzi sva polja (jednog reda) tabele placanja, znaci par stringova, int, float i boolean, metode getX i setX za sve i jedan vektor Vector<Uplata> koji bi prakticno sadrzao podatke za tabelicu uplata. I sve to lepo u jedan fajl. Pa kad ucitavam izbacim JDialog sa progressbarom dok se tabela uz SwingWorker ne popuni. E sad, ako bi presao na SQL i npr. Derby (Java DB) bazu, kako onda to da resim, tj. gde i kako da cuvam podatke za ove tabele uplata ?
Dame biraju uvek pogresne tipove ... Na srecu ...
 
Odgovor na temu

eXPerience
[ coded ]

Član broj: 14396
Poruke: 88
77.46.184.*

Sajt: [ coded ]


Profil

icon Re: Savet oko JTable i TableModel-a04.09.2007. u 21:22 - pre 201 meseci
Vise od 200 pregleda, a niko nista da prokomentarise ...

No, u medjuvremenu ja isprobavah, kombinovah itd. i napravih nesto. Odustao sam od SQL-a, vec se podaci i dalje pamte u fajlu, ali sada u obliku Vector<Placanja>. Evo kako izgleda TableModel:

Code:

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.util.List;
import java.util.Vector;

import javax.swing.JOptionPane;
import javax.swing.SwingWorker;
import javax.swing.event.TableModelEvent;
import javax.swing.table.AbstractTableModel;

public class VPModelTabelePlacanja extends AbstractTableModel {
    
    private static final long serialVersionUID = 1L;
    
    protected Vector<Placanje> podaci;
    protected Vector<String> naziviKolona;
    
    public VPModelTabelePlacanja() {
        initNaziviKolona();
        initPodaci();
    }

    public int getColumnCount() {
        return naziviKolona == null ? 0 : naziviKolona.size();
    }

    public int getRowCount() {
        return podaci == null ? 0 : podaci.size();
    }
    
    public String getColumnName(int columnIndex) {
        return naziviKolona.elementAt(columnIndex).toString();
    }
    
    public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
    }
    
    public Class<?> getColumnClass(int columnIndex) {
        return getValueAt(0, columnIndex).getClass();
    }

    public Object getValueAt(int rowIndex, int columnIndex) {
        Object result = null;
        if (podaci.size() != 0) {
            Placanje placanje = podaci.elementAt(rowIndex);
            switch (columnIndex) {
                case 0:
                    result = placanje.getRb();
                    break;
                case 1:
                    result = placanje.getFirma();
                    break;
                case 2:
                    result = placanje.getBrracuna();
                    break;
                case 3:
                    result = placanje.getDpo();
                    break;
                case 4:
                    result = placanje.getValuta();
                    break;
                case 5:
                    result = placanje.getIznos();
                    break;
                case 6:
                    result = placanje.getPlaceno();
                    break;
            }
        }
        
        return result;
    }
    
    public void setValueAt(Object value, int rowIndex, int columnIndex) {
        //System.out.println("Setting value at " + rowIndex + "," + columnIndex + " to " + value + " (an instance of " + value.getClass() + ")");
        
        Placanje placanje = podaci.elementAt(rowIndex);
        switch (columnIndex) {
            case 0:
                placanje.setRb((Integer)value);
                break;
            case 1:
                placanje.setFirma((String)value);
                break;
            case 2:
                placanje.setBrracuna((String)value);
                break;
            case 3:
                placanje.setDpo((String)value);
                break;
            case 4:
                placanje.setValuta((String)value);
                break;
            case 5:
                placanje.setIznos((Float)value);
                break;
            case 6:
                placanje.setPlaceno((Boolean)value);
                break;
        }
        podaci.setElementAt(placanje, rowIndex);
        fireTableCellUpdated(rowIndex, columnIndex);
    }
    
    public Vector<Uplata> getUplate (int index) {
        return podaci.elementAt(index).getUplate();
    }
    
    public void setUplate (Vector<Uplata> uplate, int index) {
        podaci.elementAt(index).setUplate(uplate);
    }
    
    public void dodajPlacanje (Placanje placanje) {
        int rowIndex = podaci.size();
        podaci.addElement(placanje);
        fireTableChanged(new TableModelEvent(this, rowIndex, rowIndex, TableModelEvent.ALL_COLUMNS, TableModelEvent.INSERT));
    }
    
    public void izmeniPlacanje (Placanje placanje, int rowIndex) {
        podaci.setElementAt(placanje, rowIndex);
        fireTableRowsUpdated(rowIndex, rowIndex);
    }
    
    public void obrisiPlacanje (int rowIndex) {
        podaci.remove(rowIndex);
        fireTableRowsDeleted(rowIndex, rowIndex);
    }
    
    public void initNaziviKolona() {
        naziviKolona = new Vector<String>();
        String[] nazivi = { "RB", "Firma", "Br. racuna", "DPO", "Valuta", "Iznos", "Placeno" };
        for (int i=0; i<nazivi.length; i++)
            naziviKolona.addElement((nazivi[i]));
    }
    
    public void initPodaci() {
        (new ProcitajFajl()).execute();
    }
    
    private class ProcitajFajl extends SwingWorker<Void, Placanje> {
        protected Void doInBackground() {
            File fajl;
            FileInputStream ulazFile;
            ObjectInputStream ulazObject;
            Vector<Placanje> podaciIzFajla = null;
            try {
                fajl = new File ("baze/placanja.dat");
                ulazFile = new FileInputStream (fajl);
                ulazObject = new ObjectInputStream (ulazFile);
                podaciIzFajla = (Vector<Placanje>) ulazObject.readObject();
                ulazObject.close();
                ulazFile.close();
            }
            catch (Exception ex) {
                JOptionPane.showMessageDialog(VPGUI.frameMain, "<html>Ne postoji baza placanja ili je ostecena.<br>"+ex.getMessage()+"</html>", "Greska", JOptionPane.ERROR_MESSAGE);
            }
            if (podaci == null)
                podaci = new Vector<Placanje>();
            
            for (int i=0; i<podaciIzFajla.size(); i++)
                publish(podaciIzFajla.elementAt(i));
                
            return null;
        }

        protected void process(List<Placanje> delici) {
            for (Placanje placanje : delici)
                dodajPlacanje(placanje);
        }
        
        protected void done() {
            VPPlacanja.getInstance().selectLastRow();
            VPPlacanja.getInstance().setUkupanDug();
        }
    }
    
    public void snimiPodatke() {
        FileOutputStream izlazFile;
        ObjectOutputStream izlazObject;
        File fajl;
        
        try {
            fajl = new File ("baze/placanja.dat");
            izlazFile = new FileOutputStream (fajl);
            izlazObject = new ObjectOutputStream (izlazFile);
            izlazObject.writeObject(podaci);
            izlazObject.close();
            izlazFile.close();
        }
        catch (IOException ioe) {
            JOptionPane.showMessageDialog(VPGUI.frameMain, "<html>Neuspesno snimanje podataka u placanja.dat.<br>"+ioe.getMessage()+"</html>", "Greska", JOptionPane.ERROR_MESSAGE);
        }
    }
}


Podaci se ucitavaju pomocu SwingWorker-a i jedan po jedan red se dodaju u tabelu. Pri izlazu iz programa poziva se metoda snimiPodatke() takodje iz SwingWorker klase.

A evo i kako izgleda klasa Placanja:

Code:

import java.io.Serializable;
import java.util.Vector;

public class Placanje implements Serializable {
    
    private static final long serialVersionUID = 1L;
    
    private Integer rb;
    private String firma;
    private String brracuna;
    private String dpo;
    private String valuta;
    private Float iznos;
    private Boolean placeno;
    private Vector<Uplata> uplate;
    
    public Placanje (Integer rb, String firma, String brracuna, String dpo, String valuta, Float iznos, Boolean placeno) {
        this.rb = rb;
        this.firma = firma;
        this.brracuna = brracuna;
        this.dpo = dpo;
        this.valuta = valuta;
        this.iznos = iznos;
        this.placeno = placeno;
        uplate = new Vector<Uplata>();
    }
    
    public Integer getRb() {
        return rb;
    }
    
    public String getFirma() {
        return firma;
    }
    
    ...
    
    public void setDpo (String dpo) {
        this.dpo = dpo;
    }
    
    public void setValuta (String valuta) {
        this.valuta = valuta;
    }
    
    public String toString() {
        return "RB: "+rb+"\nFirma: "+firma+"\nBroj racuna: "+brracuna+"\nDPO: "+dpo+"\nValuta: "+valuta+"\nIznos: "+iznos+"\nPlaceno: "+ (placeno == true ? "Da" : "Ne");
    }
}


Nego, postoji li resenje za "Type safety: Unchecked cast from Object to Vector<Placanje>" ?

Code:

Vector<Placanje> podaciIzFajla = null;
podaciIzFajla = (Vector<Placanje>) ulazObject.readObject();

Dame biraju uvek pogresne tipove ... Na srecu ...
 
Odgovor na temu

[es] :: Java :: Savet oko JTable i TableModel-a

[ Pregleda: 2519 | Odgovora: 7 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.