Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment Java pour OS X 2013-004 affecte-t-il (casse) les applications Swing ?

Mise à jour 2013-06-21 :cette réponse contient des solutions de contournement et des alternatives qui peuvent être utiles, mais la réponse de @sidney-markowitz-biomatters contient le correctif de code correct - le LAF doit être défini à partir du fil de l'événement !

Les problèmes récents semblent être liés aux mises à jour brisant l'Aqua Look and Feel (LAF), qui est la valeur par défaut pour les applications Swing sur Mac OS X.

Si vous avez besoin de l'Aqua LAF, il n'y a pas trop d'options. Vous devrez peut-être attendre la prochaine mise à jour Java d'Apple (je suppose qu'ils corrigeront cela en priorité, étant donné qu'il s'agit de leur propre LAF). Vous pouvez également essayer d'utiliser Java Application Bundler (c'est-à-dire regrouper le JRE Oracle et éviter d'utiliser le JRE du système).

Si vous pouvez vous débrouiller avec un LAF différent, votre application devrait fonctionner normalement. C'était le cas pour PaperCut, au moins (la mise à jour 003 a causé des problèmes de focus de fenêtre, la mise à jour 004 a causé du chaos).

Quelques options :

  • Utilisation du LAF multiplateforme spécifique à la version Java à partir du code Java (par exemple, Nimbus ou Metal) :

    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName())
    
  • Définition d'un LAF spécifique à partir du code Java :

    UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel")
    
  • Remplacer le LAF par défaut depuis le terminal :

    java -Dswing.defaultlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel MyApp
    

Dans notre cas, nous appelions explicitement UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) dans notre code et nous voulions une solution de contournement qui n'impliquait pas de changement de code (c'est-à-dire un correctif), nous devions donc remplacer le système par défaut LAF comme suit.

  • Ignorer le système LAF depuis le terminal :

    java -Dswing.systemlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel ...
    
  • Remplacer le système LAF à partir d'un Info.plist fichier (si vous avez fourni une application Mac, fonctionne également pour les autres options de VM) (par exemple, sur My.app/Contents/Info.plist ).

    Vous souhaitez ajouter -Dswing.systemlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel jusqu'à la fin du <string> valeur pour VMOptions <key> . Les options sont séparées par des espaces, tout comme depuis le terminal. Par exemple. si vous avez déjà un useScreenMenuBar choix :

    <key>VMOptions</key>
    <string>-Dcom.apple.macos.useScreenMenuBar=true -Dswing.systemlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel</string>
    


Edit :@trashgod a demandé un exemple reproductible. Je ne sais pas quelle est l'étendue des problèmes avec la mise à jour 004, mais voici une reproduction simple :

Mise à jour 2013-06-21 - dans le mauvais sens, reproduisant l'erreur :

public class AquaLafTest {
    public static void main(String[] args) throws Exception {
        javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
        javax.swing.JOptionPane.showMessageDialog(null, "msg");
    }
}
  1. Exécutez avec Apple JRE fourni avec la mise à jour 004 (par exemple, dans /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home ). Observez que le message n'est pas visible, que l'icône de la boîte de dialogue n'est pas visible et que le bouton n'est pas visiblement cliquable.

  2. Exécutez avec un ancien Apple JRE ou un autre JRE. Observez que la boîte de dialogue s'affiche comme prévu.

Mise à jour 2013-06-21 - dans le bon sens, sur le fil de l'événement, fonctionne correctement :

public class AquaLafTest {
    public static void main(String[] args) throws Exception {
        javax.swing.SwingUtilities.invokeAndWait(new Runnable() {
            public void run() {
                try {
                    javax.swing.UIManager.setLookAndFeel(javax.swing.UIManager.getSystemLookAndFeelClassName());
                    javax.swing.JOptionPane.showMessageDialog(null, "msg");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }
}