[JAVA] Snel een afbeelding weergeven

Pagina: 1
Acties:
  • 103 views sinds 30-01-2008
  • Reageer

  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
Ik heb als leek mijn eerste echte applicatie gemaakt welke als achtergrond een GIF afbeelding gebruikt. Nu duurt het ongeveer 10 á 20 seconden na het starten van het programma voordat het plaatje tevoorschijn komt.

Ik heb al andere dingen geprobeerd. Bijvoorbeeld ipv. drawImage() het plaatje in een JLabel zetten maar dat wou ook niet werken. ;(
Ik heb ook al de GoT-seach en die van de java API gebruikt en daar kon ik uit opmaken dat ik waarschijnlijk een Buffered of double BufferedImage moet gebruiken. Ik kan alleen nergen opmaken hoe ik dat precies zou moeten gebruiken.

Als ik het plaatje van te voren kan inladen bij een splashscreen of iets dergelijks zou dat niet erg zijn. Een interface die 20 na het starten nog verandert is gewoon geen gezicht.

Ik ben erg benieuwd! *D

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Double buffered drawing gebruik je automatisch als je Swing gebruikt.

Gebruik je AWT, dan moet je alle tekenafbeeldingen doen op een tweede Graphics object en deze in eenkeer met drawImage op het scherm knallen.

Wat je ook kan doen is een tracker op je image hangen, die je waarschuwt waarneer de image volledig ingeladen is. Ik gebruikte daar altijd MediaTracker voor, maar ik geloof dat er ondertussen een betere is :+

Als je dan de waarschuwing krijgt dat de image volledig geladen is, dan kun je het splashscreen over laten gaan naar de GUI

  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
Dat van die tracker klink erg leuk.
Enig id wat de naam van die betere is? :P
Ander ga ik wel op zoek naar die MediaTracker.
Kan zo'n ding ook aangeven wanneer hij op de helft of op 10% met laden is. In dat geval kan ik een mooi JProgressBarretje in de splash dumpen :)

- edit -

woei!
Goudentip..
Ik heb hier op GoT even naar mediatracker gezocht en vond een prachtig voorbeeld. Zo ver ik kan zien werkt het nu perfect.
Tnx!

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
En anders je eigen image observer maken...

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
Observer was toch om 2 classes met elkaar te laten communiceren? :?
Correct me if I'm wrong.

  • Infinitive
  • Registratie: Maart 2001
  • Laatst online: 10-08 15:15
Op woensdag 29 mei 2002 22:17 schreef Maxonic het volgende:
Observer was toch om 2 classes met elkaar te laten communiceren? :?
Correct me if I'm wrong.
Zo zou je het kunnen zeggen :)
De image update methode van een ImageObserver wordt aangeroepen als er iets met het plaatje verandert (bijvoorbeeld omdat er weer een aantal pixels beschikbaar zijn). Of beter gezegt: als er eerst iets met het plaatje moet gebeuren voordat de opgegeven actie (zoals het drawen van de afbeelding of het opvragen van de breedte) gedaan kan worden. Dit gebeurt asynchroom (in een aparte thread) zodat je via een image observer kan weten wanneer dat dan daadwerkelijk gebeurt is.

Elke component is bijvoorbeeld een ImageObserver, en zodra er bijvoorbeeld meer pixels beschikbaar zijn roept de component's imageUpdate de repaint methode aan, zodat je een afbeelding stapsgewijs geladen kan zien worden.

Over het algemeen is een image observer schrijven misschien wat overkill (bovendien krijg je meteen een thread-gehannis over je heen, dus je moet wel redelijke kennis van java hebben om zoiets te gebruiken), dus als je het met een media-tracker af kan. Use the tracker :)

putStr $ map (x -> chr $ round $ 21/2 * x^3 - 92 * x^2 + 503/2 * x - 105) [1..4]


  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
Ja, misschien is dat toch handiger.. Zit nl. toch nog met een probleempje. Ik zal het even uittekenen. mom...
code:
1
2
3
4
5
6
7
Main -|- new splash (extends JWindow)
    |
 [3 seconden wachten]
    |
 [splash.dispose() en main.setvisible(true)]
    |
    |- new interface (extends JPanel)

Misschien een beetje vaag, dus ik geef ff uitleg. :)
Ik heb een mainclasse die een JFrame aan maakt. Deze JFrame wordt nog niet weergegeven.
Eerst maakt de classe namelijk een instantie van splash-screen aan. Deze laat ie 3 seconden staan en dan hide hij splash-screen en showed hij de main-frame.

Naast het showen van de mainframe maakt hij een instantie van Interface aan welke dus het plaatje tekent.

De splashscreen is nu dus nutteloos.
Hoe kan ik het voor elkaar krijgen dat het plaatje dat in de interface weergegeven moet worden al in de splashscreen (of tijdens het weergeven daarvan) geladen wordt?

  • Jelmer
  • Registratie: Maart 2000
  • Laatst online: 18:06
Probeer eens gebruik te maken van de advanced imaging io, die werkt voor mijzelf aanzienlijk beter dan de standaard awt dingen.

  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
Heeft iemand anders een pratisch voorbeeltje van een observer?

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 29-08 19:47

Bosmonster

*zucht*

En hoe groot is die GIF? :)

  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
800 x 600 en iets van 160KB

  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
Misschien toch handig als ik mijn probleem wat onderbouw. Het zit dus zo... Ik ben een totale n00b wat betreft OOP. Ik zit nu dus met het volgende probleem.

Ik heb 2 classes:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Interface extends JFrame {

  Interface(){

    speelveld = new Speelveld();

  }

  public void main(String parameter[]){

    frame = new Interface();

  }

  public void setStatusbar(String tekst, int timeout){

    // doe iets

  }

}


code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
class Speelveld extends JPanel {

  Speelveld(){

    // doe iets

  }

  public void PaintComponent(Graphics g){

    String bestandsnaam = "achtergrond1.gif"; 
    Image afbeelding = Toolkit.getDefaultToolkit().getImage("images/" + bestandsnaam);
    MediaTracker tracker = new MediaTracker(this);
    tracker.addImage(afbeelding, 0);
      
     try {
       
        tracker.waitForID(0);
        // Laat de statusbar op een een of andere manier weten dat het laden gelukt is

      } catch (InterruptedException e) { 

        // Laat de statusbar op een een of andere manier weten dat het laden mislukt is

      }

    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    g2d.drawImage(afbeelding, 0, 0, this);
    }
}

Dit is niet het probleem waar ik mee kamp waar het soort probleem waarmee ik mee kamp. In meerdere situaties wil ik graag gewoon onderling tussen 2 classes kunnen communiceren. Hoe kan ik dat doen?

Ik hoop dat de kennis der mede-tweaker mij kan helpen... :)

  • Glimi
  • Registratie: Augustus 2000
  • Niet online

Glimi

Designer Drugs

(overleden)
Op donderdag 30 mei 2002 17:36 schreef Maxonic het volgende:
Misschien toch handig als ik mijn probleem wat onderbouw. Het zit dus zo... Ik ben een totale n00b wat betreft OOP. Ik zit nu dus met het volgende probleem.
Java en problemen! :) FF kijken hoor :)
Ik heb 2 classes:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Interface extends JFrame {

  Interface(){

    speelveld = new Speelveld();

  }

  public void main(String parameter[]){

    frame = new Interface();

  }

  public void setStatusbar(String tekst, int timeout){

    // doe iets

  }

}
Ik ga even in de Alarmnummer-mode tips geven hoor:
1)Noem je klasse NIET Interface. Een interface is een reserved keyword in Java. De reden dat het nu goed gaat, is omdat het keyword met een kleine i is, en jouw klasse met een grote I. Echter voor een mens is het erg moeilijk te overzien dat jouw classe Interface geen interface is maar een classe

Wat is dan een interface? Een interface is een defnitie aan welke eisen een class zou moeten voldoen, maar de implementatie laat je aan de class zelf over. Echter je hebt dus wel methodes gespecificeerd, maar deze hebben geen inhoud. Meer info (en duidelijker :+ ) kun je [url=http://java.sun.com/docs/books/tutorial/java/interpack/interfaces.html]hier[url] vinden.

2) Dit is een class die de main gaat bevatten? Deze classe geef je meestal geen andere methodes, maar alleen een aanroep naar een klasse die een JFrame extend. In jouw geval maakt de main een instantie van z'n eigen klasse aan. Deze methode wordt wel gebruikt, maar eigenlijk alleen bij Factory's, als ik het goed heb. Ik zou je dan ook willen adviseren de main uit deze class te halen (of het JFrame/GUI gedeelte uit deze class)

3) Geef je methodes altijd een accessmodifier (public/private ed.). Nu geef je je constructor de 'friendly' modifier, wat betekend dat alleen classes binnen de package hem kunnen accessen. Dat is meestal geen goede keuze

Let er wel op dat je niet teveel public gaat maken. Hou de methodes die andere classes kunnen aanspreken zo sober mogelijk qua aantal. Des te meer er zijn, des te meer gekloot er kan worden met je object, des te meer er fout kan gaan. Wees dus streng voor jezelf!
Dit is niet het probleem waar ik mee kamp waar het soort probleem waarmee ik mee kamp. In meerdere situaties wil ik graag gewoon onderling tussen 2 classes kunnen communiceren. Hoe kan ik dat doen?

Ik hoop dat de kennis der mede-tweaker mij kan helpen... :)
3 opties. Stel class 1 wil met class 2 communicieren.

1) Je kan een wrapperclass maken. Deze class kan objecten van zowel class 1 als 2 bevatten en de communicatie tussen deze twee regelen door de methodes die ze aanbieden.

2) Class 1 bevat een verwijzing naar een object van class 2. Deze verwijzing kan dan via de constructor van class 1 meegegeven worden. Hierdoor kan class 1 naar hartelust de methodes van class 2 aanspreken met zijn klassevariabeles als parameters.

3) Class 2 kan een innerclass zijn van class 1.

Methode 1 gebruik ik soms als 1 en 2 weinig met elkaar te maken hebben. Stel class 1 is een Mens en class 2 is een Stoeptegel. Een mens kan eens communicatie hebben met de stoeptegel (hey! ik sta op je! :+ ) maar het is niet echt een onderdeel van de class mens.

Mehode 2 gebruik ik veel vaker. Je geeft gewoon via de constructor of settermethode gewoon aan de mens klasse.

Methode 3 is echt een beetje cryptisch. De innerclass (een klasse binnen een klasse) kan wel bij final variabelen van de outerclass (de class waar de innerclass in zit) maar niet andersom. Verder ziet het er vaak ook nogal cryptisch uit binnen een class. Echter voor het definieren van actionListners ed. is het echt superhandig!

Ik wens je veel plezier!

  • D2k
  • Registratie: Januari 2001
  • Laatst online: 31-08 10:19

D2k

glimi +1 informatief +2 behulpzaam ;)

Doet iets met Cloud (MS/IBM)


  • Maxonic
  • Registratie: September 2000
  • Laatst online: 28-08 09:43
Puntje 1, 3: Dit was slechts een snel voorbeeld hoor. :) In mijn echte source heb ik overal accessmodifiers staan en ik heb ook geen klasse Interface (iig niet meer sinds de eerste posts :P)
Die main zal ik er idd nog wel even uithalen.

Ik was op het moment van je bericht al een beetje aan het goochelen met innerclasses. Dit beviel me wel moet ik zeggen, alleen wordt je code zo lang. Of zou je het op een een of andere manier nog wel in apparte bestanden kunnen houden?

Het meegeven van parameters is idd leuk, maar volgens mij nog steeds 1 richting verkeer.

De andere methode kende ik nog niet maar ik zal er zeker eens naar kijken.


Bedankt voor je tips!
Pagina: 1