Salut,
J'ai actuellement 2 problèmes (enfin plutôt un problème et une interrogation), je les mets sur le même post car à mon avis ils ne sont pas si différents que ça.
Le premier...
Je voudrais pouvoir changer de look and feel dont la librairie (contenant les classes du look and feel) n'est pas connue à la compilation / création du jar de l'application, mais n'est pas connue non plus au démarrage du programme. On ne la connait que dynamiquement.
Un programme simple illustrant ceci pourrait être un simple filechooser, et un textfield pour choisir le nom de la classe du look and feel, on choisirait la librairie dans le filechooser, on indiquerait le nom de la classe principale du lookandfeel (le lookandfeelclassname), et on appuierait sur un bouton, et hop, le look and feel se charge...
Sauf qu'en pratique, je n'ai pas réussi à le faire.
En effet, j'ai testé 2 choses, dont voici le code (sans la gestion des exceptions) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // crée mon ClassLoader pour la librairie ClassLoader specificClassLoader = createClassLoader(); // instancie le look and feel LookAndFeel look = (LookAndFeel)Class.forName(lookAndFeelName,true,specificClassLoader).newInstance(); // applique le look and feel UIManager.setLookAndFeel(look);Dans les 2 cas le look and feel est bien chargé, je n'ai pas de ClassNotFoundException.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 // crée mon ClassLoader pour la librairie ClassLoader specificClassLoader = createClassLoader(); // affecte ce ClassLoader au contexte du thread Thread.setContextClassLoader(specificClassLoader); // applique le look and feel UIManager.setLookAndFeel(lookAndFeelName);
Le problème, c'est que dès que mon interface graphique se lance, j'ai le droit à une java.lang.Error (pour chaque composant). Voici celui du JTextArea :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 UIDefaults.getUI() failed: no ComponentUI class for: javax.swing.JTextArea[,0,0,0x0,invalid,alignmentX=0.0,alignmentY=0.0,border=,flags=0,maximumSize=,minimumSize=,preferredSize=,caretColor=,disabledTextColor=,editable=true,margin=,selectedTextColor=,selectionColor=,colums=0,columWidth=0,rows=0,rowHeight=0,word=false,wrap=false] java.lang.Error at javax.swing.UIDefaults.getUIError(UIDefaults.java:706) at javax.swing.MultiUIDefaults.getUIError(MultiUIDefaults.java:117) at javax.swing.UIDefaults.getUI(UIDefaults.java:736) at javax.swing.UIManager.getUI(UIManager.java:1012) at javax.swing.text.JTextComponent.updateUI(JTextComponent.java:332) at javax.swing.text.JTextComponent.<init>(JTextComponent.java:306) at javax.swing.JTextArea.<init>(JTextArea.java:187) at javax.swing.JTextArea.<init>(JTextArea.java:123) ...
Voici ma deuxième interrogation. On peut charger une classe dynamiquement avec
Donc comme ça on peut obtenir un objet qui a accès aux librairies définies dans le ClassLoader, très bien.
Code : Sélectionner tout - Visualiser dans une fenêtre à part Class.forName(nomDeLaClass, initializeFlag, classLoader)
Maintenant, si on veut faire encore plus dynamique, supposons une classe comme ceci:
On veut charger cette classe par Class.forName, sauf qu'on ne connait pas encore les librairies dont elle a besoin pour exécuter exec(), puisque c'est la classe qui va nous les donner.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11 class Dynamic { String[] getLibs() { return new String[] { "fichier1.jar", "fichier2.jar" }; } void exec() { //code utilisant les librairies définies dans getLibs() } }
Y'a-t-il une autre solution que de charger la classe une première fois pour récupérer les librairies, et de la recharger une seconde fois avec les librairies dans le ClassLoader?
Merci d'avance de vos réponses
®om
Partager