連続 10 秒間、毎秒 JTable に新しい行を追加する Java アプリケーションを作成しました。これは 3 つのクラスで構成されます:
プログラムが開始されると呼び出されるメイン クラス
public class JarBundlerProblem { public static void main(String[] args) { System.err.println("Initializing controller"); new Controller(); } }
GUI を作成するコントローラーそしてそれを変える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(); } } } }
そして最後に、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}); } }
OS X 用に開発しているので、次のものが必要です。アプリケーションを特定のファイル タイプ (たとえば、.jarbundlerproblem) に関連付けることができるようにするには、JAR をバンドルする必要があります。 Apple Jar Bundler を使用してファイルを APP に追加します。これは正常に完了しました。アプリケーションが開き、10 までカウントし、毎秒書き出します。
デフォルトでは、.jarbundlerproblem をダブルクリックし、ファイルを関連付けます。あなたのアプリケーションでは、ダブルクリックしたファイルを引数としてアプリケーションに渡しません。どうやら、これは OS X 上で Java が動作するだけのようです。
どのファイルがダブルクリックされたのかを確認できるようにする必要があるため、その目的のために Apple によって作成された Java ライブラリである OSXAdapter を使用しています。これは、Controller クラスのコンストラクターを変更して実装し、別のメソッド 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(); } }
を追加しましたが、この (マイナーな) 変更の後、アプリケーションは動作し始めます。場合によっては、コンソールで起動したことが確認できても(コントローラーの初期化が書かれている)開かないことがありますが、数回試行すると最終的には起動しますが、最初の 10 秒間はウィンドウが完全に空白になります。
イベント ディスパッチ スレッド (EDT) をブロックしているようです。 SwingWorker の方が良い選択ですが、この例では Runnable を実装しています。
余談ですが、この例は JTable を自動スクロールする 1 つのアプローチを示しています。スクロールを一時停止するには、親指をクリックします。
追記: アプリケーションの起動に 10 秒の遅れが生じます。これはコントローラーがスリープする正確な時間であるため、コントローラーは EDT 上で確実にスリープしています。 sscce はポジティブになります。代わりに、別のスレッドで作業を実行し、EDT でモデルを更新します。 SwingWorker には、これを自動的に行う process() メソッドがあります。または、以下に示すように invokeLater() を使用することもできます。アプリケーションが正しく同期されるまで、Apple イベントが機能する見込みはほとんどありません。
追記: コントローラーで isDispatchThread() を呼び出して確認できます。引用されたプロジェクトには、Mac アプリケーションを含む .dmg と、ターゲット dist2 経由でバンドルをその場で構築する Ant ファイルが含まれています。
補足: ここに示されている代替アプローチも参照してください。
以上がOSXAdapter を使用して .jarbundlerproblem ファイルの関連付けを処理すると、Java アプリケーションが遅延したり終了したりするのはなぜですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。