Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1235 connectés 

  FORUM HardWare.fr
  Programmation
  Java

  [RESOLU] SplashScreen qui clignote

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[RESOLU] SplashScreen qui clignote

n°1924223
Yop69
Posté le 15-09-2009 à 14:05:53  profilanswer
 

Bonjour all !
 
Voila j'avance tout doucement (mais surement) sur mon projet. Mais la je bloque.  
Je ne trouve pas pourquoi mon splashscreen clignote :
 

Code :
  1. public class HelloWorld extends JFrame {
  2. private static final long serialVersionUID = 1L;
  3. public JTextField txt;
  4. public static void main(String[] args) {
  5.  try{ new Splash();} catch(IllegalStateException e) { System.out.println(e.toString());}
  6.  HelloWorld f = new HelloWorld("Mon application" );
  7.  f.setVisible(true);
  8. }
  9. }
  10. public class Splash implements ActionListener {
  11.     static void renderSplashFrame(Graphics2D g, int frame) {
  12.      String str = new String("." );
  13.      for(int i=0; i<frame; i++) str += ".";
  14.    
  15.      g.setPaintMode();
  16.      g.drawString("Loading "+ str, 130, 150);
  17.      g.fillRect(130,270,100,20);
  18.     }
  19.    
  20.     public Splash() {
  21.      final SplashScreen splash = SplashScreen.getSplashScreen();
  22.         if (splash == null) throw new IllegalStateException("HelloWorld >> no overlay image available" );
  23.        
  24.         Graphics2D g = (Graphics2D)splash.createGraphics();
  25.         Dimension size = splash.getSize();
  26.         g.setComposite(AlphaComposite.Clear);
  27.         g.setColor(Color.BLACK);
  28.         g.fillRect(0, 0, size.width, size.height);
  29.    
  30.         for(int i=0; i<5; i++) {
  31.          renderSplashFrame(g,i);
  32.             try { Thread.sleep(1000); } catch(InterruptedException e) { }
  33.             splash.update();
  34.         }
  35.         splash.close();
  36.     }
  37.     public void actionPerformed(ActionEvent e) {
  38.      System.out.println(e.toString());
  39.      System.exit(0);
  40.     }
  41. }


 
Pouvez vous m'aider ?  [:cerveau du chaos]


Message édité par Yop69 le 18-09-2009 à 16:05:24
mood
Publicité
Posté le 15-09-2009 à 14:05:53  profilanswer
 

n°1924369
cbeyls
Hail to the King, Baby
Posté le 15-09-2009 à 23:45:17  profilanswer
 

Moi j'appellerais
 
g.setPaintMode();
 
une seule fois juste après
 
g.setColor(Color.BLACK);
 
ensuite je ferais
 
splash.update();
 
AVANT le
 
Thread.sleep(1000);

n°1924413
Yop69
Posté le 16-09-2009 à 08:58:49  profilanswer
 

La cette fois ci, il y a un clignement avec une image totalement noire.
A savoir que mon gif est un gif animé est celui la :
 
http://java.sun.com/developer/technicalArticles/J2SE/Desktop/javase6/splashscreen/splashtest_350W.gif
 
Au début on voit apparaitre le gif correctement et puis, un coup il y a un rectangle de la taille de l'image qui est noire, un coup l'image d'origine est totalement noire.
Moi j'aimerais que le rectangle noir fasse place à l'image avec le contour transparent bien sur et aussi que l'image ne soit pas noir (normal)
 
J'ai essayé avec une image jpg basique (pas de transparence) et sans tes corrections et je n'ai pas de clignotements. J'ai la nette impression que cela vient du gif et de sa transparence  :sweat:


Message édité par Yop69 le 16-09-2009 à 09:13:19
n°1924606
cbeyls
Hail to the King, Baby
Posté le 16-09-2009 à 18:47:36  profilanswer
 

Je ne suis pas expert en dessin 2D et je ne sais pas ce que tu essayes d'afficher exactement mais
 
g.fillRect()
 
ça sert à afficher un rectangle (noir, vu que c'est la couleur choisie par setColor juste avant) donc c'est normal. Enlève cette instruction si tu ne veux pas de rectangle noir.

n°1924615
Yop69
Posté le 16-09-2009 à 19:14:24  profilanswer
 

Le g.setColor(Color.BLACK); set à faire afficher le Loading .... sinon on ne verrait pas la font (blanc sur blanc)
 
En commentant g.fillRect(130,270,100,20); maintenant l'application commence par faire afficher un cadre blanc autour de mon gif (donc ca fait un cadre diront nous normal mais qui dépasse du petit bonhomme qui fait coucou), puis ce cadre devient transparent puis le cadre blanc revient etc...  :sweat:  
Alors que je le repète avec un jpg normal (carré sans transparence, forcément c'est un jpg) ca marche bien
 
(merci de m'aider  :jap: ca fait plaisir !)

n°1924683
cbeyls
Hail to the King, Baby
Posté le 17-09-2009 à 01:13:46  profilanswer
 

Voici le meilleur code auquel je suis arrivé.
 
HelloWorld.java
 

Code :
  1. import javax.swing.JFrame;
  2.  
  3. public class HelloWorld extends JFrame {
  4.     private static final long serialVersionUID = 1L;
  5.  
  6.     public static void main(String[] args) {
  7.         new Thread(new Splash()).start();
  8.  
  9.         // A supprimer: permet d'admirer le SplashScreen pendant un minimum de temps
  10.         try {
  11.             Thread.sleep(6000);
  12.         } catch (InterruptedException e) {
  13.             // TODO Auto-generated catch block
  14.             e.printStackTrace();
  15.         }
  16.  
  17.         HelloWorld f = new HelloWorld();
  18.         f.setVisible(true);
  19.     }
  20. }


 
Splash.java
 

Code :
  1. import java.awt.AlphaComposite;
  2. import java.awt.Color;
  3. import java.awt.Dimension;
  4. import java.awt.Graphics2D;
  5. import java.awt.SplashScreen;
  6.  
  7. public class Splash implements Runnable {
  8.  
  9.     @Override
  10.     public void run() {
  11.         SplashScreen splash = SplashScreen.getSplashScreen();
  12.         // Quitte si aucun SplashScreen n'a été spécifié
  13.         if (splash == null) {
  14.             return;
  15.         }
  16.  
  17.         try {
  18.             Graphics2D g = (Graphics2D)splash.createGraphics();
  19.             Dimension size = splash.getSize();
  20.             StringBuilder str = new StringBuilder("Loading " );
  21.             while (true) {
  22.                 // Efface la zone de dessin
  23.                 g.setComposite(AlphaComposite.Clear);
  24.                 g.fillRect(0, 0, size.width, size.height);
  25.                 // Ecrit le texte en noir
  26.                 g.setColor(Color.BLACK);
  27.                 g.setPaintMode();
  28.                 str.append('.');
  29.                 g.drawString(str.toString(), 130, 150);
  30.                 splash.update();
  31.                 Thread.sleep(1000);
  32.             }
  33.         } catch (IllegalStateException e) {
  34.             // Le SplashScreen a été fermé suite à l'affichage de la première Frame
  35.         } catch (InterruptedException e) {
  36.             // Le Thread a été interrompu
  37.         }
  38.     }
  39. }


 
Si l'image clignote c'est un problème de l'image elle-même (un GIF animé). Je conseille plutôt l'usage d'un PNG transparent non animé.
 
Pour info, j'exécute l'animation du SplashScreen dans un Thread séparé afin de ne pas bloquer le Thread d'exécution principal. Le SplashScreen est fermé automatiquement par le système dès que la première JFrame est affichée. Pour pouvoir admirer le SplashScreen, j'ai volontairement bloqué le Thread principal pendant 6 secondes, mais cet appel devra être retiré dans la version finale de l'application, le but étant évidemment que le SplashScreen occupe l'utilisateur pendant que le reste de l'appli se charge le plus vite possible et non de retarder volontairement le chargement afin que l'utilisateur voie le SplashScreen.


Message édité par cbeyls le 17-09-2009 à 01:20:01
n°1924740
Yop69
Posté le 17-09-2009 à 10:33:50  profilanswer
 

Tu travailles tard dis moi  :)  
 
Bon cela fait pareil avec ton code (qui est super propre au passage !  :ouch: )
Donc je te le pique  :o  
Je vais suivre ton conseil, mettre un png transparent.
C'est dommage j'aurais bien mis ce gif qui fait bouger le petit bonhomme Java, je trouve cela class (euh non classe !)
 
En tout cas ca me fait apprendre l'histoire des threads, que je comprend mieux et j'ai la place maintenant de mettre les instructions de l'appli pendant l'execution du splashscreen c'est super !
 
Merci à toi ! j'adore de plus en plus le Java  :love:  
 
(je vais aussi essayer de voir pourquoi ce gif pose problème avec un logiciel de gif animé...)


Message édité par Yop69 le 17-09-2009 à 10:34:02
n°1924754
cbeyls
Hail to the King, Baby
Posté le 17-09-2009 à 11:02:24  profilanswer
 

Si tu enlèves tout le code et que tu laisses juste le SplashScreen normal sans texte ça fait la même chose. Donc le problème vient de l'image.
 
J'avais jamais utilisé le SplashScreen donc j'avais un envie de coder un peu pour voir comment ça fonctionne, et oui je m'y suis mis tard :)

n°1924757
Yop69
Posté le 17-09-2009 à 11:13:49  profilanswer
 

Donc j'ai regardé dans Gimp, et j'ai enregistré le gif en enlevant l'option "loop forever" en pensant que le clignotement venait de la.
Bah non, le clignotement se fait juste à la fin de ma dernière ou avant dernière frame et je ne vois pas du tout pourquoi  :??:  
Donc je vais investiguer un peu plus (ça prend du temps dediou !)
 
La prochaine étape est de passer mon appli dans le systray quand je la minimize :) (je fais les truc les plus important comme tu peux le voir lol)


Message édité par Yop69 le 17-09-2009 à 11:56:53
n°1924786
Yop69
Posté le 17-09-2009 à 12:34:06  profilanswer
 

Bon j'ai passé le problème de mon image GIF, faut savoir parfois s'avouer vaincu :(
Donc j'entame le fait de mettre mon api dans le systray voici le code que j'ai :

Code :
  1. Runnable runner = new Runnable() {
  2.   public void run() {
  3.    if (SystemTray.isSupported()) {
  4.        SystemTray tray = SystemTray.getSystemTray();
  5.        Image image = Toolkit.getDefaultToolkit().getImage("icon.gif" );
  6.     TrayIcon trayIcon = new TrayIcon(image, "The Tip Text", null);
  7.     try { tray.add(trayIcon); }
  8.     catch (AWTException e) { System.err.println("Can't add to tray" ); }
  9.    }
  10.   }
  11.  };
  12.     EventQueue.invokeLater(runner);


 
La commande invokeLater me fout en l'air X apparement !!  :D. Mon écran devient tout zarbi avec plein de couleurs partout des carrés de couleurs qui se forment et je ne peux plus rien cliquer ! je suis obligé de killer X  :??:
 
Edit : une petite question ? tu travailles sous quelle plate forme et avec quel IDE ? (moi je suis sur Ubuntu Jaunty avec Eclipse) mais j'ai installé netbeans pour voir ce que cela donne


Message édité par Yop69 le 17-09-2009 à 12:49:26
mood
Publicité
Posté le 17-09-2009 à 12:34:06  profilanswer
 

n°1924884
cbeyls
Hail to the King, Baby
Posté le 17-09-2009 à 17:10:34  profilanswer
 

Pourquoi dois-tu appeler invokeLater?
 
Je travaille sous Windows et Ubuntu avec le dernier Eclipse et le JDK de Sun.


Message édité par cbeyls le 17-09-2009 à 17:12:53
n°1924931
Yop69
Posté le 17-09-2009 à 21:22:38  profilanswer
 

j'invoque invokeLater car c'est le code que j'ai pompé et j'avoue que je ne sais pas à quoi ça sert  :D  
 
Ah ok moi aussi j'ai windows mais je ne developpe que sous Ubuntu. (j'utilise très peu windows en fait)

n°1924959
cbeyls
Hail to the King, Baby
Posté le 17-09-2009 à 23:28:26  profilanswer
 

invokeLater() ou pas, ça devrait fonctionner. À moins que ton icône soit encore un foutu GIF animé ;) Tu aimes tant les GIFs? Moi je te conseille plutôt une image PNG avec une taille de 24x24 ou 32x32 pixels.
 
Sinon quand tu utilises le JDK de Sun, le résultat est le même sous Ubuntu ou Windows. J'utilise indifféremment les 2 OS. Avant je développais sur un Mac aussi, toujours avec Eclipse.

n°1924963
Yop69
Posté le 18-09-2009 à 00:23:28  profilanswer
 

Oui tu as raison, je ne sais pas pourquoi j'utilise constamment les GIF  :wahoo:  
Je vais utiliser les PNG dorénavant.  
Par contre, je t'assure invokeLater me fout la zone à moins que ce soit l'exécution du script qui m'a causé un problème (mais je ne vois pas le rapport avec ma carte graphique qui me faisait n'importe quoi )
Enfin bref.
 
Je comprends bien qu'avec la même JVM sous différents OS ca marche tout pareil :)

n°1924964
cbeyls
Hail to the King, Baby
Posté le 18-09-2009 à 00:29:55  profilanswer
 

invokeLater() permet d'exécuter un Runnable dans le thread de gestion des événements de Swing. Ca sert avant tout à permettre à des threads auxilliaires de notifier le GUI à la fin de leur travail, puisque seul le thread de gestion des événements de Swing peut modifier le GUI. Si tu as au moins une fenêtre Swing ouverte ça devrait fonctionner je suppose.
 
Edit: en fait je pensais à SwingUtilities.invokeLater() mais je vois que tu utilises EventQueue.invokeLater(). Je crois que c'est l'équivalent pour AWT mais je n'en suis pas sûr et franchement je ne l'ai jamais utilisé. C'est peut-être pour ça que ça déconne d'ailleurs.


Message édité par cbeyls le 18-09-2009 à 00:37:03
n°1924973
Yop69
Posté le 18-09-2009 à 08:33:37  profilanswer
 

ok, je n'arrive pas trop à conceptualiser et voir la différence entre thread et runnable.
Hum  [:transparency] en executant mon script sans invokeLater, j'ai mon X qui a encore fait n'importe quoi. Obligé de killer X ! bizarre cette affaire :??:
 
Edit : j'ai enlevé les effets 3D du bureau et la ça marche impec... (avant j'ai eu 5 freezes d'affilés !  :sweat: )


Message édité par Yop69 le 18-09-2009 à 12:33:00
n°1925177
cbeyls
Hail to the King, Baby
Posté le 18-09-2009 à 22:39:15  profilanswer
 

Runnable c'est juste une interface avec une méthode run() qui peut être exécutée par un Thread. Un Thread implémente Runnable aussi.
L'intérêt principal d'implémenter Runnable et puis de passer la classe à un Thread au lieu d'étendre Thread lui-même c'est qu'une classe peut à la fois implémenter Runnable et étendre une autre classe que Thread. Puisqu'en java il n'y a pas d'héritage multiple: on ne peut étendre qu'une seule classe.
 
Je n'ai pas testé le system tray mais je te crois sur parole. Tu utilises bien la JVM Sun? Ou bien OpenJDK ou autres?


Message édité par cbeyls le 18-09-2009 à 22:42:17
n°1925181
Yop69
Posté le 18-09-2009 à 22:47:34  profilanswer
 

A chaque fois j'attends ta réponse avec impatience  :D  
 
ok merci pour runnable c'est pratique en effet. (faut maintenant que je maitrise tout ce qui est notion d'interface car je vois à peu près mais c'est encore flou)
Pour le systray je suis dessus, ma GUI a direct une icone dans le systray alors que moi je voudrais pouvoir la mettre que quand je clique sur fermer. (et ne pas l'avoir dans la barre des taches)
 
Depuis que j'ai désactiver les effets 3D d'Ubuntu, je n'ai plus de problemes donc je pense que ya un bug quelque part par contre pour le trouver (je me suis rendu compte que les effets 3D n'etaient pas du tout indispensable  :D ) J'utilise la JVM de Sun

n°1925190
cbeyls
Hail to the King, Baby
Posté le 19-09-2009 à 02:14:41  profilanswer
 

Si tu veux t'initier au Java, fais les choses dans l'ordre: commence par apprendre les bases du langage et l'orienté-objet, les classes, les constructeurs, l'héritage, la surcharge et redéfinition de méthodes, les interfaces, etc. en faisant des petits programmes en ligne de commande.
 
Ensuite une fois que tu maîtrises tout ça, tu peux passer à plus compliqué avec la notion de thread.
 
Et enfin, faire des interfaces graphiques Swing qui utilisent tous ces concepts à la fois. Et les Applets c'est tout aussi compliqué.

n°1925191
Yop69
Posté le 19-09-2009 à 02:31:02  profilanswer
 

Bah disons que je connais un peu la notion d'heritage, de classe, constructeur, surcharge etc.
Ya juste la notion d'interface en terme concret (je pense savoir a quoi ca sert mais c'est abstrait) c'est pour cela que je me lance.
 
J'ai fait du c++ quand j'etais étudiant et du php5 dans mon taf donc je touche à la notion de poo même si je ne suis pas expert loin de la. :)
 

n°1925245
cbeyls
Hail to the King, Baby
Posté le 19-09-2009 à 14:50:28  profilanswer
 

Une interface c'est un "contrat", ce sont des spécifications publiques d'une classe (avec des signatures de méthodes et éventuellement des constantes, mais pas d'implémentation). Ca permet à du code d'utiliser indifféremment n'importe quelle classe qui implémente cette interface, peu importe l'implémentation qui se trouve derrière. Pourquoi? Tout simplement pour rendre le code réutilisable au maximum. Dans ton code, tu a intérêt à utiliser les interfaces autant que possible.
 
Par exemple, tu programmes une classe qui a besoin de stocker des éléments dans une liste. Si tu utilises l'interface List, ton code est indépendant de l'implémentation de la liste. Supposons qu'au départ tu avais assigné une ArrayList et tu te rends compte que tu fais de nombreuses suppressions d'éléments sur la liste qui est de grande taille et que ceci pénalise les performances quand on utilise ArrayList (=un tableau) puisque tous les éléments suivants dans le tableau doivent être décalés d'une position vers la gauche à chaque suppression. Tu devrais juste changer la classe instanciée et remplacer ArrayList par LinkedList, sans devoir changer quoi que ce soit d'autre dans ton code, et voilà le tour est joué.
 
Les classes abstraites sont à mi-chemin entre une interface et une classe "concrète": une partie des méthodes sont implémentées pour faire le gros du travail, l'autre pas (et doivent être implémentées par les classes qui l'étendent).
 
Une classe peut étendre une seule autre classe (éventuellement abstraite) mais peut implémenter plusieurs interfaces.
 
Seules les classes "concrètes", dont toutes les méthodes sont implémentées, peuvent être instanciées.
 

n°1925247
Yop69
Posté le 19-09-2009 à 15:29:19  profilanswer
 

Merci à toi, ça commence à rentrer. Je me suis renseigné sur le Web et effectivement je commence à cerner la différence entre les 2.
L'un qui sert à factoriser du code et l'autre à définir un standard pour les classes qui l'implémenteront.
 
Merci  :jap:

mood
Publicité
Posté le   profilanswer
 


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  Java

  [RESOLU] SplashScreen qui clignote

 

Sujets relatifs
[Matlab] (Résolu) Décalage de fréquences avec DCT[Résolu] Informations d'une photo
[Résolu] erreur stray \320 \240Résolu : Récupérer le nom d'un tableau dynamique sous Excel2007
[Résolu] warning friend declaration[RESOLU] Lors de l'éxecution un coup ca marche, un coup ca marche pas
[RESOLU]J2ME et la génération de timestamp...[Résolu]pb compilation operator ++
[RESOLU]Limiter le nombre de résultats d'un fichier xml[Résolu] problème de CSS sur un menu
Plus de sujets relatifs à : [RESOLU] SplashScreen qui clignote


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR