Avatar billede ppstyle Nybegynder
31. oktober 2001 - 11:01 Der er 18 kommentarer og
1 løsning

GUI og giffer igen igen :)

Jeg har tidligere været på banen med et lignende spørgmål. Problemet var dog ikke helt løst alligevel.

1) Hvorfor når \"GUI\" ikke altid at painte et image ???
Nogle gange bliver mit gif paintet så jeg kan se
det andre gange ikke. Måske når giffen ikke at blive indlæst ?

200 points !

2) Man kan sikre paintningen af giffen ved at sætte paint kaldet ind i en for løkke der kører 100 gange. Lidt mystsisk men er der nogen der har et bud på hvorfor, så er der 100 mere at hente :)


3) De gange min gif er synlig, kan jeg få den til at forsvinde igen ved at minimere vinduet eller evt. trække et andet vindue hen over det. Når giffen er væk er der kun en hvid skærm tilbage :(
Jeg kan næste regne ud det er noget med repaint ?
Gerne en forklaring med noget kode eksempel

100 points !

Det skal bemærkes jeg er afhængig af at kunne painte et billede i et x,y koordinat, hvorfor jeg ikke bare bruger panels eller labels som jeg kan sætte.


Min program kode start :


________________________________________________

import java.awt.*;
import javax.swing.*;

public class MyImage extends JComponent {

public Image image = null;


public MyImage(){
    super();
    }



public void paintComponent(Graphics g) {

    g.drawImage(image, 50, 50, this);

    }
}

__________________________________________________

import java.awt.*;
import javax.swing.*;

public class Test{   


public static void main(String [] args){


    JFrame theFrame = new JFrame(\"Simulator\");
   
    theFrame.setSize(new Dimension(800, 600));
   
    theFrame.setVisible(true);

    Container contentPane = theFrame.getContentPane();

    contentPane = theFrame.getContentPane();

    contentPane.setLayout(new FlowLayout());
   
        contentPane.setBackground(Color.white);


    MyImage mi = new MyImage();

    mi.image = (Image) Toolkit.getDefaultToolkit().getImage(\"TGreen.gif\");

    contentPane.add(mi);   

    mi.paintComponent(contentPane.getGraphics());   
    }
}

______________________________________________________

program kode slut.


mvh. Daniel

Avatar billede disky Nybegynder
31. oktober 2001 - 11:06 #1
hmm, det er noget med du skal køre en opdatering hvis der ændres noget i GUI\'en.

FLytning, et vindue henover osv.
Avatar billede ppstyle Nybegynder
31. oktober 2001 - 11:13 #2
Det har jeg også forsøgt, nemlig med windowListeners. Altså fx. hvis vinduet blev deiconifiseret så har jeg sat den til at starte funktionen : paintComponent, men det hjælper ikke :(

Disky -> du var ellers en af dem jeg havde sat min lid til :)
Avatar billede disky Nybegynder
31. oktober 2001 - 11:16 #3
Jeg kan godt kigge på det lidt senere, men GUI er ikke min stærke side indenfor java
Avatar billede ppstyle Nybegynder
31. oktober 2001 - 11:20 #4
Ok,det var heller ikke for at presse :) Men man er jo efterhånden vant til at svarene kommer flyvende fra din hånd he he...

Når men jeg venter tålmodigt.Hvad gør du eller i inden for java ?
Avatar billede disky Nybegynder
31. oktober 2001 - 11:22 #5
Det forsøger jeg også altid på, men gui roder jeg meget sjældent med.

Jeg laver næsten udelukkende baggrunds applikationer, JSP løsninger og jeg skal faktisk igang med J2ME ting idag :))
Avatar billede kresten Nybegynder
31. oktober 2001 - 11:24 #6
Til #1:

Brug MediaTracker objectet til at finde ud af om din gif fil er loadet færdig. Noget i stil med...

MediaTracker tracker;
tracker = new MediaTracker(this);
tracker.addImage(mi, 0);

try {
  tracker.waitForAll(); // Vent til de er loadet
} catch (InterruptedException e) {}


.. og nede i din paint metode eller paintComponent skriver du noget i stil med..

if (!tracker.checkAll()) {
    g.clearRect(0, 0, d.width, d.height);
    g.drawString(\"Loader billeder...\", 0, d.height/2);
}

Mht. #3 så tror jeg nok det er noget med at at repaint kalder paint og den sørger for at update. Må indrømme det er noget siden jeg har kigget på det. Men det korte af det lange er, at nogle gange bliver paint og andre gange repaint - alt efter om man f.eks. dækker dele af billedet eller maximerer.
Avatar billede logical Nybegynder
31. oktober 2001 - 12:05 #7
Det jeg bla lige kan se er, at du sætter din frame visible, og så adder du efterfølgende komponenter til dit panel.

Skærmen bliver kun opdateret så sjældent som muligt (Eller kunne man jo ikke lave noget andet :-)
Når du har kaldt setVisible(true), vil indholdet af din content pane blive tegnet. Derefter sker der ingen gentegning før du enten resizer vinduet eller overlapper vinduet. Ikke engang hvis du flytter vinduet.
Hvis du i perioden mellem en gentegning, f.eks. mellem første gang og første resize adder en component i din content pane, bliver den ikke tegnet med før næste gang, MEDMINDRE at du f.eks. kalder validate() på din container.
Hvis du imellem to gentegninger ændrer på en eksisterende komponent skal du kalde invalidate() på din komponent og validate() på din container.

Derudover har du ingen angivelser af size i din component. Dvs. du ikke ved hvor meget plads du har til din komponent, hvor meget af den der vises etc.
Hvis din komponent kun får størrelsen 50,50 af en layoutmanager vil din paintComponent(g) metode tegne dit image uden for din komponents synlige område, og derfor bliver det ikke tegnet ind på din frame.

Der er ikke nogen problemer med repaint i swing, fordi en JComponent aldrig clearer sin baggrund (Men mindre den vil specifikt).

Som du nok kan se, kræver det sin mælk at designe en JComponent.
Er det fordi du skal lave noget animation (rumskibe, whatever) og ikke ved hvordan det kan gøres? Så spørg om det istedet. Så skal jeg vise dig det.
Avatar billede logical Nybegynder
31. oktober 2001 - 12:08 #8
kresten>> Du har nogle rester fra AWT i baghovedet. Det er blevet ændret lidt i forbindelse med Swing. update kalder paint direkte, som så (bla) kalder paintcomponent som kalder sin UI delegate etc.. :-)
Avatar billede kresten Nybegynder
31. oktober 2001 - 12:10 #9
oh! Ja, men lærer jo hver dag :-)
Avatar billede ppstyle Nybegynder
31. oktober 2001 - 12:58 #10
Altså for at skære helt ind til benet, drejer det sig bare om jeg skal kunne vise et mindre antal iconer i en frame. Det kunne fx. være et array af iconer. Det vigtige er som sagt, at de vises/tegnes, men det er ikke en animation. Udelukkende et statisk billede. Der ud over skal man selvfølgelig kunne minimere og flytte billedet uden at iconerne forsvinder.
Avatar billede ppstyle Nybegynder
31. oktober 2001 - 12:59 #11
ok, Kresten jeg leger lige lidt med mediatracker, og vender tilbage
Avatar billede logical Nybegynder
31. oktober 2001 - 13:02 #12
MediaTracker sørger bare for at loade dit image op.

Hvis du nu brugte new ImageIcon(\"TGreen.gif\").getImage() ville du nå det samme i Swing.
Avatar billede ppstyle Nybegynder
31. oktober 2001 - 13:02 #13
Logical -> Dit bud ser også meget rigtigt ud, det prøver jeg også lige af, så skal jeg nok vende tilbage.

mvh. Daniel
Avatar billede logical Nybegynder
31. oktober 2001 - 13:07 #14
Prøv at køre det her eksempel:

public static void main(String [] args){
    JFrame f = new JFrame(\"Simulator\");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JPanel p = new JPanel();
    for (int i = 0 ; i < 25 ; i++) {
        p.add(new JLabel(new ImageIcon(\"TGreen.gif\")));
    }
    f.setContentPane(p);
    f.setSize(800,600);
    f.setVisible(true);
}

Og fortæl mig, hvad mere du skal bruge
Avatar billede ppstyle Nybegynder
31. oktober 2001 - 13:30 #15
Logical -> Tak for hjælpen - det er faktisk lidt ala det jeg har brug for, men som jeg skrev i mit spørgsmål har jeg brug for at kunne sætte billedet ind præcist i det x,y koordinat jeg vælger, hvorfor jeg bevidst har undgået panels og labels.

Men kan du vise mig en måde det kan gøres på har du faktisk løst alle mine problemer ( næsten ).
Avatar billede logical Nybegynder
31. oktober 2001 - 13:49 #16
    class FixedPanel extends JPanel {
        public FixedPanel(int width, int height) {
            this(new Dimension(width, height));
        }
       
        public FixedPanel(Dimension size) {
            super();
            setLayout(null);
            setSize(size);
        }
        public Dimension getPreferredSize() {
            return getSize();
        }
        public Dimension getMinimumSize() {
            return getSize();
        }
        public Dimension getMaximumSize() {
            return getSize();
        }
        public void add(Component c) {
            c.setSize(c.getPreferredSize());
            super.add(c);
        }
       
        public void addAtLocation(Component c, int x, int y) {
            c.setLocation(x,y);
            add(c);
        }
    }

public class Test{   


public static void main(String [] args){
    JFrame f = new JFrame(\"Simulator\");
    f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    FixedPanel p = new FixedPanel(800,600);
    for (int i = 0 ; i < 25 ; i++) {
        JLabel l = new JLabel(new ImageIcon(\"TGreen.gif\"));
        p.addAtLocation(l, 10*i, 20*i);
    }
    f.setContentPane(p);
    f.pack();
    f.setVisible(true);
}
}
Avatar billede logical Nybegynder
31. oktober 2001 - 13:52 #17
Ups, ret linie
public void add(Component c)

i FixedPanel til

public Component add(Component c)
Avatar billede logical Nybegynder
31. oktober 2001 - 21:39 #18
Så er vi oppe igen. Jeg legede lige lidt videre (forfinede tingene lidt), og opdagede også, at du ville kunne flytte komponenterne, så prøv det her:
import java.awt.*;
import javax.swing.*;

class FixedPanel extends JPanel {
    public FixedPanel(int width, int height) {
        super();
        super.setLayout(null);
        super.setSize(width, height);
    }
    // Must be null methods..
    public void setLayout(LayoutManager lm) {}
    public void setSize(Dimension d) {}
    public void setSize(int x, int y) {}
   
   
    public Dimension getPreferredSize() {return getSize();}
    public Dimension getMinimumSize()  {return getSize();}
    public Dimension getMaximumSize()  {return getSize();}
   
    public Component add(Component c) {
        c.setSize(c.getPreferredSize());
        super.add(c);
        return c;
    }
   
    public void moveComponentTo(Component c, int x, int y) {
        Rectangle r = c.getBounds();
        c.setLocation(x,y);
        RepaintManager.currentManager(this).addDirtyRegion(this,r.x, r.y, r.width, r.height);
    }
   
    public void addAtLocation(Component c, int x, int y) {
        c.setLocation(x,y);
        add(c);
        revalidate();
    }
}

public class Test{
   
   
    public static void main(String [] args){
        JFrame f = new JFrame(\"Simulator\");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        FixedPanel p = new FixedPanel(800,600);
        JLabel[] labels = new JLabel[25];
        for (int i = 0 ; i < labels.length ; i++) {
            labels[i] = new JLabel(new ImageIcon(\"TGreen.gif\"));
            p.addAtLocation(labels[i], 0, 20*i);
        }
        f.setContentPane(p);
        f.pack();
        f.setVisible(true);
        while(true) {
            for (int i = 0 ; i < labels.length ; i++) {
                try { Thread.sleep(200); } catch (InterruptedException e) {}
                p.moveComponentTo(labels[i], (int)(Math.random()*750),(int)(Math.random()*550));
            }
        }
    }
}
Avatar billede ppstyle Nybegynder
31. oktober 2001 - 23:38 #19
Logical -> jeg overgiver mig. Du har leveret svaret på alle min tre spørgsmål med konkret kode.

Det kunne ikke gøres bedre.

Mange tak for hjælpen - hilsen Daniel
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester