31. oktober 2001 - 11:01Der 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.
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 :)
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.
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.
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.. :-)
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.
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); }
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 ).
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); } }
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)); } } } }
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
Synes godt om
Ny brugerNybegynder
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.