Maison >Java >javaDidacticiel >Pourquoi mon application Java est-elle en retard ou s'arrête-t-elle lors de l'utilisation d'OSXAdapter pour gérer les associations de fichiers .jarbundlerproblem ?
Vous avez créé une application Java qui ajoute une nouvelle ligne à une JTable chaque seconde pendant 10 secondes consécutives. Il se compose de trois classes :
La classe principale qui est appelée une fois le programme démarré
public class JarBundlerProblem { public static void main(String[] args) { System.err.println("Initializing controller"); new Controller(); } }
Un contrôleur qui crée l'interface graphique et le modifie via doWork()
public class Controller { public Controller() { doWork(null); } public static void doWork(String s) { GUI gui = new GUI(); for (int i=0; i<10; i++) { gui.addRow("Line " + (i+1)); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } }
Et enfin, le GUI
import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; public class GUI { private JFrame frame = new JFrame(); private DefaultTableModel model = new DefaultTableModel(); private JTable table = new JTable(model); private JScrollPane pane = new JScrollPane(table); public GUI() { model.addColumn("Name"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(pane); frame.pack(); frame.setVisible(true); } public void addRow(String name) { model.addRow(new Object[]{name}); } }
Puisque vous développez pour OS X et que vous devez pouvoir associer votre application à un certain type de fichier (disons .jarbundlerproblem), vous devez regroupez votre fichier JAR dans une application à l’aide d’Apple Jar Bundler. Vous avez fait cela avec succès, votre application s'ouvre, compte jusqu'à dix, écrit chaque seconde.
Par défaut, double-cliquez sur un problème .jarbundler et associez le fichier avec votre application, ne transmettra pas le fichier sur lequel j'ai double-cliqué comme argument à l'application. Apparemment, c'est juste Java sur OS X qui fonctionne.
Puisque vous devez pouvoir voir sur quel fichier vous avez double-cliqué, vous utilisez OSXAdapter qui est une bibliothèque Java créée par Apple à cet effet. Ceci, vous l'avez implémenté en modifiant le constructeur de votre classe Controller et en ajoutant une autre méthode registerForMacOSXEvents():
public Controller() { registerForMacOSXEvents(); //doWork(null); } public void registerForMacOSXEvents() { try { OSXAdapter.setFileHandler(this, getClass().getDeclaredMethod("doWork", new Class[] { String.class })); } catch (Exception e) { System.err.println("Error while loading the OSXAdapter:"); e.printStackTrace(); } }
Mais après cette (mineure) modification, votre application commence à agir. Parfois, il ne s'ouvre pas, même si vous pouvez voir dans la console qu'il vient de démarrer (l'initialisation du contrôleur est écrite), mais après quelques tentatives, il finira par démarrer, mais les fenêtres seront complètement vides pendant les 10 premières secondes. , et après cela, les 10 lignes seront ajoutées.
Il semble que vous bloquez le fil de répartition d'événements (EDT). SwingWorker serait un meilleur choix, mais cet exemple implémente Runnable.
En passant, cet exemple montre une approche du défilement automatique d'une JTable. Cliquez sur le pouce pour suspendre le défilement ; release pour reprendre.
Addendum : Votre application est en retard de 10 secondes au démarrage. Comme c'est l'heure exacte pendant laquelle le contrôleur dort, il dort sûrement sur l'EDT. Un sscce serait déterminant. Au lieu de cela, effectuez le travail sur un autre thread et mettez à jour le modèle sur l'EDT. SwingWorker a une méthode process() qui le fait automatiquement, ou vous pouvez utiliser EnsureLater() comme indiqué ci-dessous. Tant que votre application n'est pas correctement synchronisée, il y a peu d'espoir de faire fonctionner les événements Apple.
Addendum : Vous pouvez appeler isDispatchThread() dans le contrôleur pour vérifier. Le projet cité comprend un .dmg avec une application Mac et un fichier fourmi qui construit le bundle in situ via target dist2.
Addendum : Voir aussi les approches alternatives présentées ici.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!