Oracle
 sql >> Database >  >> RDS >> Oracle

In che modo Java per OS X 2013-004 influisce (interrompe) sulle applicazioni Swing?

Aggiornamento 21-06-2013:questa risposta contiene alcune soluzioni e alternative che potrebbero essere utili, ma la risposta di @sidney-markowitz-biomatters contiene la correzione del codice corretta:il LAF deve essere impostato dal thread dell'evento!

I problemi recenti sembrano essere correlati agli aggiornamenti che interrompono l'Aqua Look and Feel (LAF), che è l'impostazione predefinita per le app Swing su Mac OS X.

Se hai bisogno dell'Aqua LAF, non ci sono troppe opzioni. Potrebbe essere necessario attendere il prossimo aggiornamento Java di Apple (suppongo che lo risolveranno con priorità, dato che è il loro LAF). Potresti anche provare a utilizzare Java Application Bundler (ovvero raggruppare Oracle JRE ed evitare di utilizzare JRE del sistema).

Se riesci a cavartela con un LAF diverso, la tua app dovrebbe funzionare normalmente. Almeno per PaperCut (l'aggiornamento 003 ha causato alcuni problemi di messa a fuoco della finestra, l'aggiornamento 004 ha causato confusione).

Alcune opzioni:

  • Utilizzo del codice LAF multipiattaforma specifico per la versione Java dal codice Java (ad es. Nimbus o Metal):

    UIManager.setLookAndFeel(UIManager.getCrossPlatformLookAndFeelClassName())
    
  • Impostazione di un LAF specifico dal codice Java:

    UIManager.setLookAndFeel("javax.swing.plaf.nimbus.NimbusLookAndFeel")
    
  • Sostituzione del LAF predefinito dal terminale:

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

Nel nostro caso stavamo chiamando esplicitamente UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) nel nostro codice e volevamo una soluzione alternativa che non comportasse una modifica del codice (ovvero un hotfix), quindi dovevamo sovrascrivere il sistema predefinito LAF come segue.

  • Esclusione del sistema LAF dal terminale:

    java -Dswing.systemlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel ...
    
  • Sostituzione del sistema LAF da un Info.plist file (se l'hai in bundle come applicazione Mac, funziona anche per le altre opzioni VM) (ad es. su My.app/Contents/Info.plist ).

    Vuoi aggiungere -Dswing.systemlaf=javax.swing.plaf.nimbus.NimbusLookAndFeel fino alla fine del <string> valore per VMOptions <key> . Le opzioni sono separate da spazi, proprio come dal terminale. Per esempio. se hai già un useScreenMenuBar opzione:

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


Modifica:@trashgod ha chiesto un esempio riproducibile. Non sono sicuro di quale sia l'intera portata dei problemi con l'aggiornamento 004, ma ecco una semplice riproduzione:

Aggiornamento 21-06-2013 - nel modo sbagliato, riproducendo l'errore:

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. Esegui con Apple JRE fornito con l'aggiornamento 004 (ad es. su /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home ). Osservare che il messaggio non è visibile, l'icona della finestra di dialogo non è visibile e il pulsante non è visibilmente cliccabile.

  2. Esegui con un JRE Apple meno recente o un altro JRE. Osserva che la finestra di dialogo viene visualizzata come previsto.

Aggiornamento 21-06-2013 - il modo corretto, nel thread dell'evento, funziona correttamente:

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();
                }
            }
        });
    }
}