您创建了一个 Java 应用程序,该应用程序每秒向 JTable 添加一个新行,持续 10 秒。它由三个类组成:
程序启动后调用的主类
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),您必须使用 Apple Jar Bundler 将 JAR 文件捆绑到应用程序中。您已成功完成此操作,您的应用程序打开,数到十,每秒写出。
默认情况下,双击 .jarbundler 问题,然后关联该文件对于您的应用程序,不会将我双击的文件作为参数传递给应用程序。显然,这只是 OS X 上的 Java 工作。
由于您需要能够查看双击的文件,因此您使用 OSXAdapter,这是 Apple 为此目的而制作的 Java 库。您已经通过更改 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 秒内将完全空白,之后将添加 10 行。
看起来您正在阻塞事件调度线程 (EDT)。 SwingWorker 会是一个更好的选择,但这个示例实现了 Runnable。
顺便说一句,这个示例展示了一种自动滚动 JTable 的方法。单击拇指可暂停滚动;释放以恢复。
附录:您的应用程序在启动时滞后 10 秒。由于这是控制器休眠的确切时间,因此它肯定在 EDT 上休眠。 sscce 将具有决定性作用。相反,在另一个线程上完成工作并在 EDT 上更新模型。 SwingWorker 有一个 process() 方法可以自动执行此操作,或者您可以使用 invokeLater() ,如下所示。在您的应用程序正确同步之前,让 Apple 事件正常工作的希望很小。
附录:您可以在控制器中调用 isDispatchThread() 进行检查。引用的项目包括一个带有 Mac 应用程序的 .dmg 和一个 ant 文件,该文件通过目标 dist2 原位构建捆绑包。
附录:另请参阅此处显示的替代方法。
以上是使用 OSXAdapter 处理 .jarbundlerproblem 文件关联时,为什么我的 Java 应用程序会滞后或终止?的详细内容。更多信息请关注PHP中文网其他相关文章!