Partage
  • Partager sur Facebook
  • Partager sur Twitter

[Java] Jar file, JEditorPane, getResource, Image de Fond

15 janvier 2007 à 20:20:02

Bonjour, je me présente rapidement :
Julien, 3ème année de License Informatique, embarqué là-dedans grâce au site du zero !


Cette année, en POO, nous devons rendre un projet.
Celui-ci est pour demain.

Vous allez me dire
Encore un qui s'y prend au dernier moment !

Mais je vous répondrais que cela fait deux mois que je travaille dessus et j'y ai passé beaucoup beaucoup d'heures... Je dirais presque une centaine et je n'exagère rien. Ce qui m'a pris le plus de temps : apprendre à créer une interface graphique avec swing d'autant plus que le professeur n'a pas jugé bon de nous faire un cours là-dessus.

J'ai rencontré donc des tas de problèmes et je n'ai jamais demandé d'aide ici car je préférais y réfléchir seul mais là, il ne me reste plus du tout de temps et il me reste encore quelques problèmes inrésolus.

No 1
Comment créer un éxécutable jar

Alors là, je peux vous dire que j'ai fait tous les sites que j'ai trouvé sous google, les plus complet du monde, de developpez.com à comment ça marche en passant par la javadoc en anglais et je n'arrive toujours pas à le faire. J'ai même fait monté un prof de java du département info et il n'a pas su m'aider.

J'ai donc une arborescence de ce type :
Projet (Dossier racine contenant le projet) contient les dossiers "src" et "ressources";
"src" contient les dossiers "Modele" et "VueControleur" qui sont aussi des packages :
Je les compile usuellement via les commandes javac Modele/*.java et javac VueControleur/*.java
Chacun des fichier comporte la ligne de code : package Modele; ou package VueControleur;

"ressources" contient deux dossiers "html" et "images"
"images" contient des images au format png, jpg
"html" contient des pages html.

J'ai ajouté un dossier META-INF dans Projet, dans lequel j'ai mis me famaux fichier MANIFEST.MF. En voici son contenu
Manifest-Version: 1.0
Created-By: 1.5.0_05 (Sun Microsystems Inc.)
Main-Class: src/VueControleur/Main

J'ai également essayé avec un Main-Class genre ./src...... , /src....., //src....,
Ma classe Main se trouve bien dans le package VueControleur.

J'ai bien retiré les .java et laissé les .class,
j'ai éxécuter plusieurs commandes genre
jar cvfm ShisenSho.jar Projet/META-INF/MANIFEST.MF -C Projet/ .

ou encore avec la commande java cvf et compagnie ou encore en bougeant le MANIFEST, en le modifiant, en l'ajoutant seul dabord...

No 2
J'ai lu quelquepart et le problème est arrivé aux autres, alors je l'anticipe que mes url d'images qui étaient jusqu'alors du type new ImageIcon("../ressources/images/image.png"); ne fonctionneraient pas dans un jar file.


Et là pareil, j'ai lu tous les trucs possibles et inimaginables : sur le getClass().getResource("url"); que je dois mettre à la place de mon url. Ceci ne fonctionne pas chez moi et renvoie une url nulle provoquant une exception NullPointerException
Pareil, une professeur m'a dit d'essayer de mettre des doubles slashs, inversés ou pas dans les chemins et que ça fonctionnerait ou alors, on m'a dit de mettre getClass().getRessource("mon url") mais de changer l'url que j'avais mise : ../ressources/images/image.png en ressources/images/image.png ou avec un ./ ou un / ou autre chose. J'ai tout essayé.
J'ai même rajouté une ligne au MANIFEST Classpath ./ mais rien n'y fait, il me provoque des exceptions alors faut-il que je change tout cela seuleument au moment de faire mon jar file ou les getClass() devraient aussi fonctionner avec ma traditionnelle compilation des .java et éxécution "javac VueControleur.Main"?

No 3
Je dois réaliser une aide au format HTML, Le visionneur que j'ai réalisé demande une url et me lance des exceptions en tout sens avec ou sans getClass.


Sans commentaire, je crois que cela découle du problème précédent.

No 4
Mon visionneur html fonctionne mal même avec une url type google.fr



package VueControleur;

import java.net.*;
import javax.swing.*;
import java.io.*;
import javax.swing.event.HyperlinkEvent;
import javax.swing.event.HyperlinkListener;


public class Miniweb extends JFrame implements HyperlinkListener{

        private JEditorPane htmlComp;
        protected URL adresse;


        public Miniweb(String adresse){
                super();
                this.adresse=getClass().getResource(adresse);;
                setSize(1000, 740);
                setLocationRelativeTo(null);
                setDefaultCloseOperation(EXIT_ON_CLOSE);
                try {
                        htmlComp=new JEditorPane();
                        htmlComp.setEditable(false);
                        htmlComp.setPage(this.adresse);
                }
                catch (IOException erreur){
                        JOptionPane.showMessageDialog(this,"Page Introuvable ou URL invalide","IOException",JOptionPane.ERROR_MESSAGE);
                }
               
                add(htmlComp);
               
                htmlComp.addHyperlinkListener(this);
                setVisible(true);
               
        }

        public void hyperlinkUpdate(HyperlinkEvent e) {
                if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED){
                        try{
                                htmlComp.setPage(e.getURL());
                        }
                        catch (IOException erreur){
                                e.printStackTrace();
                        }
                }
        }

}


Ce code a été un peu pompé sur le net, je l'ai remodifié, nous nous sommes mis à plusieurs. Je l'appelle de cette manière à partir d'une autre classe : Miniweb m = new Miniweb("../ressources/html/index.html");
Outre le problème de l'url qui ne marche pas, quand je la remplace par google, cela me plante mon programme.
En regardant les erreurs je me rend compte que c'est parce que je n'ai rien mis dans IOException. Je met alors un message d'erreur qui me donne des erreurs sur le protocole ou d'autres choses fantaisistes. Bref, il ne fonctionne pas. La fenêtre s'ouvre mais rien ne s'affiche et clou du spectacle : je ferme la fenêtre, le jeu se ferme avec !
Alors je me lance dans l'écriture de Thread mais rien n'y fait, la fenêtre ferme l'autre. Je me doute bien que cela est du au setDefaultCloseOperation(EXIT_ON_CLOSE); mais comment fermer juste la fenêtre du navigateur sans fermer celle du programme principale !

No 5
J'ai peiné à trouver comment afficher une image de fond mais j'ai finalement réussi en redéfinissant paintComponent mais mon fond ne s'affiche pas aussitôt que le JPanel sur lequel il est dessiné, est créé.


J'ai fait une sous-classe fond héritant de JPanel et je récris sa méthode paintComponent :
        class Fond extends JPanel {
                protected Image fond;
                //Constructeur
                public Fond(Image fond){
                        super();
                        this.fond=fond;

                }
                //Redéfinition de paintComponent
                public void paintComponent(Graphics g) {
                        super.paintComponent(g);
                        g.drawImage(fond, 0, 0, null);
                }
        }


Bon ensuite j'instancie un objet de cette classe dans ma fenêtre principale et j'ajoute le fond au contentPane de la fenêtre puis je remplis l'objet de boutons et donc le résultat : le fond ne s'affiche pas directement, il faut attendre que les boutons changent pour voir apparaître le fond.
Alors là j'ai essayé tous les repaint possible et compagnie, mais rien n'y fait. NB : j'ai aussi quelques boutons dont le setVisible est à false qui sont sur le même panneau et ceux-ci devraient donc laisser voir le fond ce qu'il fond mais pas dès le début. Est-ce un problème de superposition ? Quand je redimensionne la fenêtre, il me redessine le fond ! De quoi cela vient-il ?

No 6
Je voudrais afficher une image assez grande comme un fond mais juste pour la voir, pas de boutons dessus.

En faisant comme pour le précédent, le fait qu'il n'y a pas de boutons fait que la taille de panel se réduit automatiquement à 0 (je pense) et les setSize n'y font rien (je peux eventuellement réssayé le setMinimumSize que je ne me souviens plus si je l'ai essayé). Ou alors j'ai pensé faire un bouton géant avec une image icone mais ça il digère pas, elle doit être trop grande. Sinon je pensais à un canvas ou je ne sais trop quoi mais celui-ci devra aller là ou va mon panel Fond dont je parlais avant. Et lorsqu'on clique sur nouvelle partie, l'image dégage et laisse place au panel Fond (le jeu avec son fond). Je ne sais pas si je suis trop clair.

Voilà tout.
Mon problème le plus grave est celuidu jarfile.
Merci d'avance de l'aide que vous m'apporterez. Evitez juste de m'envoyer des url et que je me démerde après, j'ai déjà regardé toutes les urls possibles, si je vous écris là, c'est parce que mon problème est un peu personnalisé et que je n'arrive à adapter aucune solution.
Enfin, je nutilise aucun IDE (ni eclipse, ni autre) j'ai bien essayé eclipse mais eclipse me pose des problèmes supplémentaires à la compilation que je n'ai pas le temps de résoudre. Je compile donc via la console.
Je suis sous linux à la fac, sous windows à la maison.

Le logiciel doit être portable car le prof l'éxécute chez lui et on ne sait pas ce qu'il a comme système.
Pour le navigateur web, d'autres solutions me plairaaient aussi mais ouvrir le navigateur web avec un runtime et compagnie ,'est pas portable et il ne faut pas que le prof ait à installer un quelconque module pour que cela fonctionne comme je l'ai vu sur certains sites.

Merci à tous les zéros !



  • Partager sur Facebook
  • Partager sur Twitter
15 janvier 2007 à 21:20:05

le jEditorPane est pas optimisé pour le html , donc si tu a des problemes avec au niveau du visuel dedans , c'est normal
  • Partager sur Facebook
  • Partager sur Twitter
16 janvier 2007 à 8:40:57

Pour le manifest, je te conseillerais peut-être de séparer les sources et les binaires.
Tu as le dossier . de base. Dedans il y a ton fichier src avec le code source.
Tu crées un dossier bin.
Puis quand tu compiles, tu fais javac -d bin src/* par exemple.
Il va alors créer les fichiers javas dans bin (et en suivant les packets).
Après, pour lancer ton prog, tu fais java -classpath bin pack.classavecmain et ca devrait marcher.
Tu crées ton fichier manifest pour que le main class soit pack.classavecmain et ca pourrait marcher. Je dis "pourrait" car j'ai déjà eu des problèmes ^^
Sinon, poste ton manifest (s'il n'est pas trop tard :x )
  • Partager sur Facebook
  • Partager sur Twitter
31 janvier 2007 à 22:04:59

J'ai donc rendu le projet le lendemain même et je réalise aujourd'hui que je n'ai fas conclut le sujet ne serait-ce que pour ceux qui rencontrent le même problème et tombent par hasard dessus en faisant une recherche.

Alors tout dabord, mes sources étaient bien séparés de .class. Merci mais ce n'était pas ça.

Je n'ai pas encore résolu les problèmes 5 et 6.
En revanche mon problème de jar est réglé et par résolution en cascade, tout a été résolu.
Mon erreur résidait dans la déclération du package : il faut déclarer le package de cette manière :
package src.Modele (par exemple) où src est un dossier à la racine du projet. Ce que je n'avais pas fait. (j'avais mis simplement package Modele).
La compilation et l'éxécution fonctionnait mais au niveau du jar, il ne trouvait pas de class main.
En changeant ça, plus aucune image ne fonctionnait. Il faut alors pour régler le problème numéro 2 vers ceci :
getClass().getResource("url en chaine de caractère par rapport à la racine du projet") Tout ce ci renvoie un objet de type URL directement injectable dans un ImageIcon ou autre. Cela ne fonctionnait pas avant car il faut que l'url soit relative à la racine du projet et mon package ne connaissait pas la racine. Et en mettant une url relative au package lui-même, cela ne fonctionnait que sans getClass.
Cela a aussi résolu mon problème 3 et 4 avec le miniweb qui n'arrivait pas à charger l'url tout simplement parce que je n'arrivais pas à avoir un objet URL correct.

Je vais donc mettre le sujet en résolu même si deux points restent non résolus.

Et puis j'ai passé le TP qui allait avec le projet, j'ai eu 20, alors je dis merci à mateo car c'est grâce à lui que je me suis engagé dans des études en informatique et cela marche très bien pour moi. J'adore la programmation et vive les zéros ;)
  • Partager sur Facebook
  • Partager sur Twitter