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

Nikako ne shvatam Frame

[es] :: Java :: Nikako ne shvatam Frame

[ Pregleda: 2270 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

LightBow
London

Član broj: 4829
Poruke: 158
89.243.150.*



+1 Profil

icon Nikako ne shvatam Frame01.08.2008. u 04:52 - pre 190 meseci
Stvarno mi nije jasno zasto se ovo desava.
Napisao sam program u kojoj glavna klasa nasledjuje JFrame. Evo bitnih delova:
Code:
class Auction extends JFrame implements ActionListener {
U konstruktoru namestam da mi se zatvori prozor i pozivam initAuctionBoard().
U initAuctionBoard() postavljam UI: Kreiram glavni panel na koji postavljam dva panela. Na jednom od ova dva panela postavljam labele za cije title izvlacim artikle iz baze sa trenutnim cenama i dugmad za bidovanje istih (posto je u pitanju online aukcija). Na drugom panelu je par inputa za login mada ovo nije bitno. Zatim glavni panel dodam na frame sa add(pnl);
E sad u actionPerform() sam obradio bidovanje, korisnik unosi cenu za artikal koji je kliknuo i to prosledjujem drugoj klasi koja updateuje bazu.
I to lepo radi i jos samo treba da prikazem novo stanje na ekranu. To sam uradio tako sto sam actionPerform() metod zavrsio sa pozivom initAuctionBoard().
Medjutim na ekranu se nista ne menja, i dalje prikazuje staro stanje.
ovo mi je main method:
Code:
public static void main(String args[]) {
        
        Auction mainFrame = new Auction();
        mainFrame.setSize(700, 700);
        mainFrame.setTitle("Auction");
        mainFrame.setVisible(true);
    }

Prvo sam pomislio da je zbog toga sto je setVisible() smesten u mainu, pa sam ga izmestio u initAuctionBoard, naravno zamenivsi mainFrame sa this. Medjutim iznenadio sam se da kad sam startovao program, pokazao se potpuno prazan frame???
Molio bih nekoga ko zna da objasni sta se desava i kako da postignem da se novonastalo stanje prikaze. Nadam se da sam dovoljno objasnio problem. Ako treba poslacu jos koda.
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
*.adsl-1.sezampro.yu.



+33 Profil

icon Re: Nikako ne shvatam Frame01.08.2008. u 09:46 - pre 190 meseci
Bilo bi dobro kad bi poslao i kod tog konstruktora, teshko je zakljuchiti gde je problem samo iz main metode...

btw Ne znam zashto si metode setSize, setTitle i setVisible stavljao u main-u, one po nekom pravilu idu u konstruktor, al' dobro...
 
Odgovor na temu

LightBow
London

Član broj: 4829
Poruke: 158
89.243.150.*



+1 Profil

icon Re: Nikako ne shvatam Frame01.08.2008. u 13:37 - pre 190 meseci
Nisam znao za to pravilo. Kada sve te tri metode premestim u konstruktor, onda program startuje ok, ali i dalje ne update-uje. Evo konstruktora:
Code:
public Auction() {
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                dispose();
                System.exit(0);
            }
        });
        initAuctionBoard();
        
            
    }
A evo i initAuctionBoard:
Code:
public void initAuctionBoard() {
        
        this.setTitle("Auction");
        pnl = new JPanel();
        pnl.setLayout (new BoxLayout(pnl, BoxLayout.Y_AXIS));
        add(pnl);
        //layout for main panel
        pnlMain = new JPanel();
        auctionList = new ArrayList();
        
        DBconnect db = new DBconnect();
        auctionList = db.getAuctionList();
        itemCount = auctionList.size();
        bidButtons = new BidButton[itemCount];
                    
        pnlMain.setLayout(new GridLayout(itemCount, 4));
        for (int i=0; i<itemCount; i++) {
            Item item = new Item();
            item = (Item)auctionList.get(i);
            String lbl = item.getTitle();
            int bids = item.getBids();
            int id = item.getId();
                                
            float price = item.getCurrentPrice();
            JLabel lblItem = new JLabel(lbl); pnlMain.add(lblItem);
            JLabel lblBids = new JLabel(Integer.toString(bids)); pnlMain.add(lblBids);
            JLabel lblPrice = new JLabel(Float.toString(price)); pnlMain.add(lblPrice);
            bidButtons[i] = new BidButton(); bidButtons[i].setItem(id); pnlMain.add(bidButtons[i]);
            bidButtons[i].addActionListener(this);
            System.out.println(bidButtons[i].getItem());
            
        }
        pnl.add(pnlMain);
                
        this.setSize(700, 700);
        this.setVisible(true);
    }
Znaci sve se postavlja u initAuctionBoard. Ovu metodu zovem ponovo iz actionPerformed() posto korisnik licitira. U Bazi se promeni cena licitiranom artiklu, ali moj frame ne pokazuje tu promenu.
Code:
public void actionPerformed(ActionEvent e) {
        
        BidButton bb = (BidButton)e.getSource();
        int id = bb.getItem();
        Item bidItem = (Item)auctionList.get(id-1);
        placeBid(bidItem);
        
        initAuctionBoard();
        
    }
Meni ovo izgleda OK jer initAuctionBoard ulazi u bazu i uzima nove podatke. Zasto onda na ekranu ostaju stari podaci?
 
Odgovor na temu

LightBow
London

Član broj: 4829
Poruke: 158
89.243.150.*



+1 Profil

icon Re: Nikako ne shvatam Frame01.08.2008. u 15:23 - pre 190 meseci
Evo sta sam otkrio. Sumnjao sam da se novi frame ili panel sa novim podacima zbog nekog razloga ne prikazuje. Medjutim kada za frame title postavim cenu koja je licitirana, title se promeni ali prikazuje staru cenu. Dakle definitivno frame uzima stare podatke iz baze. Zasto, kada sam napravio dobar redosled: iz actionPerformed() pozivam placeBid(), koji uzima novi bid od korisnika i prosledjuje u klasu DBconnect cija metoda se povezuje na bazu i update-uje licitaciju i tek onda pozivam initAuctionBoard() koja kao sto vidite ponovo poziva DBconnect objekat koji uzima podatke iz baze i vraca ih nazad.
Priznajem da u DBconnect klasi nemam nijedan statement koji zatvara konekciju ni rekordset, ali valjda to na bi trebalo da utice na update podataka?
 
Odgovor na temu

LightBow
London

Član broj: 4829
Poruke: 158
78.146.55.*



+1 Profil

icon Re: Nikako ne shvatam Frame03.08.2008. u 06:36 - pre 190 meseci
Citat:
LightBow: Evo sta sam otkrio. Sumnjao sam da se novi frame ili panel sa novim podacima zbog nekog razloga ne prikazuje. Medjutim kada za frame title postavim cenu koja je licitirana, title se promeni ali prikazuje staru cenu. Dakle definitivno frame uzima stare podatke iz baze.

Zapravo, kada nastavim sa bidovanjem, ovaj title se menja ali uvek kasni za jedan klik. Dakle ako cenu artikla koja je 3 bidujem na 4, title ce da pokaze 3, ali kada bidujem opet na recimo 6, title ce da pokaze 4, itd, uvek kasni za jedan klik.
Dalje sam napravio istu bazu u MySql-u, (original je MS Access) i onda je title proradio. Ali glavna lista mi se i dalje ne menja nikako, kao da je zamrznuta.
Help!
 
Odgovor na temu

hyle
Perica Milošević
Belgrade

Član broj: 30030
Poruke: 150
77.247.200.*

Sajt: www.linkedin.com/in/peric..


+4 Profil

icon Re: Nikako ne shvatam Frame04.08.2008. u 09:26 - pre 190 meseci
Glavni problem je što pri svakom pozivu metode initAuctionBoard radiš dodavanje novog panela. Sporan je ovaj deo koda:
Code:

        pnl = new JPanel();
        pnl.setLayout (new BoxLayout(pnl, BoxLayout.Y_AXIS));
        add(pnl);

Taj deo prebaci u konstruktor i time ćeš obezbediti da ti JPanel pod nazivom pnl uvek bude aktivan. E sada moraš obezbediti da ti se svaki put ponovo kreira pnlMain. Najbolje bi bilo da uradiš nešto ovako:
Code:

        JPanel newMainPanel = new JPanel();
        newMainPanel.setLayout(new GridLayout(itemCount, 4));

        // ovde dovlačiš podatke i pupunjavaš newMainPanel umesto pnlMain
        // ...
        // ...

        // ovo je bitno, izbacuješ stari glavni panel     
        if (pnlMain != null)
                pnl.remove(pnlMain);

        // dodaješ novi glavni panel
        pnlMain = newMainPanel;
        pnl.add(pnlMain);

Za ove stvari koje ti sada radiš obično se koristi JTable, onda ne moraš da žongliraš sa panelima već lepo prepustiš njemu ceo posao oko toga.

Drugo, konekciju za rad sa bazom obavezno moraš da zatvaraš u finally bloku. To nije opcija ili nešto što čini kod lepim, bez toga je kod neispravan.
Treće, dugačke operacije sa bazom se ne rade u actionPerformed i sličnim swing event-ima. User interface smrzne dok se ne obavi operacija sa bazom i stvara loš utisak o aplikaciji, pogledaj SwingWorker da bi znao kako to da izbegneš.
Četvrto, vidim da nepotrebno kreiraš objekte:
Code:

        auctionList = new ArrayList();
        auctionList = db.getAuctionList();
        // ...
            Item item = new Item();
            item = (Item)auctionList.get(i);

Zbog čega si prvo napravio novi ArrayList, pa odmah zatim pozvao metodu koja kreira listu. Isti slučaj važi i za kreiranje Item-a, odmah nakon toga uzimaš Item iz liste. Kreiranje tih objekata je totalno nepotrebno.

Nadam se da sam ti barem malo pomogao, pozdrav
 
Odgovor na temu

LightBow
London

Član broj: 4829
Poruke: 158
78.149.148.*



+1 Profil

icon Re: Nikako ne shvatam Frame04.08.2008. u 17:04 - pre 190 meseci
Pomogao si mi puno :). Hvala
Konacno sam uspeo da refreshujem podatke. Ali problem je sad sto se novi podaci dodaju ispod starih, iako sam u istom if bloku stavio ove tri linije kao sto si i predlozio. Evo kako sada izgleda app.
Extends JFrame, JPaneli pnl (kao drzac), pnlMain (inicijalno prikazuje podatke iz baze), ova dva su deklarisana globalno, i newMainPanel.
Iz main() samo pozivam konstruktor koji glasi ovako:
Code:
public Auction() {
        addWindowListener(new WindowAdapter() {
            public void windowClosing(WindowEvent e) {
                dispose();
                System.exit(0);
            }
        });
        pnl = new JPanel();
        pnl.setLayout (new BoxLayout(pnl, BoxLayout.Y_AXIS));
        add(pnl);
        initAuctionBoard();
        
            
    }
E u initAuctionBoard
Code:
public void initAuctionBoard() {
        
        
        pnlMain = new JPanel();
        init liste, DB conn etc...
        
        if (bidovano== true) {//ovo znaci da je bid izvrsen
            JPanel newMainPanel = new JPanel();
            newMainPanel.setLayout(new GridLayout(itemCount, 4));
            
            for (int i=0; i<itemCount; i++) {
                //izvlacim data iz liste: inicijalizujem Labele i stampam podatke
                lblBids = new JLabel(Integer.toString(bids)); newMainPanel.add(lblBids);
                                          ...etc...
            }
            if (pnlMain != null) {
                pnl.remove(pnlMain);
                pnlMain = newMainPanel;
                pnl.add(pnlMain);
            }
        }
        else {//ovo je pocetan prikaz (pre bidovanja)
            pnlMain.setLayout(new GridLayout(itemCount, 4));
            for (int i=0; i<itemCount; i++) {
                //popunjavam sve isto samo na pnlMain;
            }
            pnl.add(pnlMain);
        }
                
        
        this.setSize(700, 700);
        this.setVisible(true);
    }

Cini mi se da si na ovo mislio, samo nije mi jasno zasto dodaje panele, izgleda da pnl.remove(pnlMain);
ne radi? Da li fali jos koja linija?
 
Odgovor na temu

hyle
Perica Milošević
Belgrade

Član broj: 30030
Poruke: 150
77.247.200.*

Sajt: www.linkedin.com/in/peric..


+4 Profil

icon Re: Nikako ne shvatam Frame05.08.2008. u 07:49 - pre 190 meseci
Odakle ti to da sam stavio sve tri naredbe u if bloku :)

Jedina komponenta koja se nalazi u panelu pnl je panel pnlMain tako da možeš raditi i removeAll prilikom uklanjanja starog panela.
Evo primera u kome se eliminiše newMainPanel:
Code:

public void initAuctionBoard() {
        
        pnlMain = new JPanel();
        pnlMain.setLayout(new GridLayout(itemCount, 4));
        init liste, DB conn etc...
        
        for (int i=0; i<itemCount; i++) {
            //izvlacim data iz liste: inicijalizujem Labele i stampam podatke
            lblBids = new JLabel(Integer.toString(bids)); pnlMain.add(lblBids);
                                      ...etc...
        }

        pnl.removeAll();
        pnl.add(pnlMain);
                
        // ovde dve linije prebaci u konstruktor,
        this.setSize(700, 700);
        this.setVisible(true);
    }


Promenljiva bidovano je totalno nepotrebna. Onaj deo u kome radiš početnu inicijalizaciju mora ići u konstruktor, sve ovo iz else bloka:
Code:

        else {//ovo je pocetan prikaz (pre bidovanja)
            pnlMain.setLayout(new GridLayout(itemCount, 4));
            for (int i=0; i<itemCount; i++) {
                //popunjavam sve isto samo na pnlMain;
            }
            pnl.add(pnlMain);
        }

 
Odgovor na temu

LightBow
London

Član broj: 4829
Poruke: 158
78.149.157.*



+1 Profil

icon Re: Nikako ne shvatam Frame06.08.2008. u 09:45 - pre 190 meseci
Evo, konacno sam uspeo, mada ni sam ne znam kako i zasto.
Prvo, kada this.setSize(700, 700); i this.setVisible(true); stavim u konstruktor, startuje mi prazan frejm, pa sam ove dve linije vratio nazad u main().
Dalje sam pazljivo iscitao hyle-ova uputstva i ispravio kod prema njima, ali posle dobrog starta, nakon bidovanja bi ostali stari podaci. Medjutim, primetio sam da, posto sam napravio da popup window uzima podatke nakon klika na bid dugme, kada taj window zatvorim (unesem bid i pritisnem OK) deo panela koji je bio iza se izbrise.
Zatim sam uzo frejm za title bar misom i povuko na dole skroz, i kada ga vratim ponovo na pocetni polozaj, on prazan! Sve izbrisano!
Sta je ovo? -rekoh sebi- Zar je moguce da je sve to laz?
E onda sam slucajno dohvatio frejm za ivicu i gle cuda: paneli se pojavise i to update-ovani!
Onda sam proguglao i nasao ovo:
panel.setVisible(true); i validate(); dodati nakon kreiranja panela, jer to forsira repaint.
I to je proradilo.
Eto.
Hvala svima na pomoci
 
Odgovor na temu

Nikola Poša
Backend (PHP) developer
Beograd

Član broj: 173839
Poruke: 1616
*.adsl-1.sezampro.yu.



+33 Profil

icon Re: Nikako ne shvatam Frame06.08.2008. u 10:02 - pre 190 meseci
Citat:
LightBow:Prvo, kada this.setSize(700, 700); i this.setVisible(true); stavim u konstruktor, startuje mi prazan frejm, pa sam ove dve linije vratio nazad u main().

Kad ih stavljash direktno u konstuktor, ne treba da pishesh sa this, a kad ih stavljash u neku metodu koju pozivash u konstruktoru, treba da ih pozivash preko oblika npr. imeKlase.this.setVisible(true).
 
Odgovor na temu

[es] :: Java :: Nikako ne shvatam Frame

[ Pregleda: 2270 | Odgovora: 9 ] > FB > Twit

Postavi temu Odgovori

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