2009-12-05 3 views
0

J'ai un objet JFrame et je dois prendre en charge deux JVM 1.5 sous Mac OS X et 1.6 sous Windows. Sur Windows, j'ai besoin d'utiliser la fonction setIconImages pour définir plusieurs icônes de taille pour l'application mais cette fonction n'est pas disponible sur 1.5. Est-il possible d'appeler cette fonction dans JFrame avec réflexion?Appel d'une fonction basée sur la version JVM

Application extends JFrame{ 
. 
. 
. 
    void init(){ 
    //check version 
    //call setIconImages 
    } 

} 
+2

un 'si' sur la propriété système 'java.version' suffirait-il? – miku

+0

Pourquoi ne pas utiliser 1.6 sur MacOS? Je veux dire, il semble que vous visez la dernière victoire, pourquoi pas mac? – KitsuneYMG

+0

il n'y a pas de standard pour le nommage/numérotation des versions, donc si c'est très problématique – TofuBeer

Répondre

2

je ferais quelque chose comme ce qui suit (ne » compilez, mais devrait vous aider à démarrer):

créer une classe appelée FrameUtils et lui donner la méthode suivante:

public static void setIconImages(final java.awt.Window window, 
           final List<? extends Image> icons) 
{ 
    try 
    { 
     Method setIconImagesMethod; 

     setIconImagesMethod = // use reflection to get the setIconImages method. 
     setIconImagesMethod.invoke(window, icons); 
    } 
    catch(final NoSuchMethodException ex) 
    { 
     // fall back to the single image method 
     window.setIconImage(icons.get(0)); 
    } 
} 

This link shows you how to get the method and call it via reflection.

+0

// utilise la réflexion pour obtenir la méthode setIconImages. c'est en fait ce que je demande désolé si je ne pouvais pas préciser comment puis-je obtenir un objet méthode pour une méthode dans l'objet que je suis. –

0

Il ressemble à javax.swing.JFrame en Java 1.5 a une fonction setIconImage(). Pourquoi avez-vous besoin de définir plusieurs images?

+0

Windows 7 utilise plusieurs icônes d'application. si j'utilise setIconImage() ils sont redimensionnés pour différentes tailles, désordre les icônes. –

1

Puisque vous devez compiler séparément les deux versions de jdk, la meilleure solution serait probablement d'avoir une interface pour les choses qui ne fonctionnent pas sur le vieux jdk et qui ont deux implémentations. Ensuite, chargez l'implémentation dont vous avez besoin au démarrage.

+0

+1 - cette approche est meilleure que la réflexion car elle isole naturellement la différence entre les versions JDK. Il est également plus efficace (et moins sujet aux erreurs) que l'utilisation de la réflexion dans la plupart des cas. –

0

oui, la réflexion est la voie à suivre dans ce but.

J'ai vu cette astuce sur certaines bibliothèques où la "rétrocompatibilité" est nécessaire. le binaire doit fonctionner sur une machine virtuelle plus ancienne, de sorte que les API plus récentes doivent être accessibles par réflexion.

+0

hmm ... Je pense que j'ai dit des choses stupides. Dans votre cas, appelez simplement la méthode normalement et compilez la sous 1.6. lorsqu'il est déployé à 1.5, il fonctionne bien jusqu'à ce que la méthode soit invoquée; juste attraper et ignorer NoSuchMethodException – irreputable

+1

dernière fois que j'ai couru une classe 1.6 compilé sur 1.5, il n'a pas fonctionné. Vous devez le compiler en utilisant les classes -target et 1.5 bootstrap. –

0

Si vous pouvez compiler avec Java 1.6, un moyen simple de le faire en attrapant NoSuchMethodError. Voici un exemple de mon code qui obtient les limites de l'écran représentant la barre des tâches, mais retombe à l'ensemble des limites si la version Java est trop tôt:

try { 
    sb=wnd.getGraphicsConfiguration().getBounds(); 
    } 
catch(NoSuchMethodError thr) { 
    Dimension ss; 
    ss=wnd.getToolkit().getScreenSize(); 
    sb=new Rectangle(0,0,ss.width,ss.height); 
    } 

Si vous devez utiliser la réflexion (car J6 a changé la version de classe et vous devez compiler à J5) alors vous avez juste besoin d'extraire la méthode J6 avec la réflexion, et attraper MethodNotFoundException pour exécuter l'appel de secours.

Questions connexes