gpt4 book ai didi

java - JAR Bundler 使用 OSXAdapter 导致应用程序滞后或终止

转载 作者:搜寻专家 更新时间:2023-11-01 01:18:34 25 4
gpt4 key购买 nike

我创建了一个简单的 Java 应用程序,它在连续 10 秒内每秒向 JTable 添加一个新行。它由三个类组成。

程序启动后调用的主类

public class JarBundlerProblem {
public static void main(String[] args)
{
System.err.println("Initializing controller");
new Controller();
}
}

创建 GUI 并通过 doWork() 更改它的 Controller

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 文件到 APP 使用 Apple Jar Bundler .我已成功完成此操作,我的应用程序打开,数到十,每秒写一次。

现在,对于这个问题

默认情况下,双击 .jarbundlerproblem,并将文件与我的应用程序相关联,不会将我双击的文件作为参数传递给应用程序。显然,这只是 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();
}
}

但是在这个(小的)修改之后,我的应用程序开始出现问题。有时,它打不开,尽管我可以在控制台中看到它刚刚启动(Initializing controller 是这样写的),但经过几次尝试后,它最终会启动,但窗口将是前 10 秒完全空白,之后将添加 10 行。

帮助

现在,我一直在努力解决这个问题,似乎没有很多关于 OSXAdapter 和 Jar Bundler 的文档。我究竟做错了什么?或者我不应该首先使用 OSXAdapter 或 Jar Bundler?

最佳答案

您好像屏蔽了 event dispatch thread (美东时间)。 SwingWorker 会是一个更好的选择,但这个例子实现了 Runnable .

附录:你可能会看看这个 projectMVC 为例建筑学。它还展示了如何在不使用 JAR Bundler 的情况下构建 Mac OS 应用程序包。有关 MVC 的更多信息,请参见 here .

顺便说一句,这个例子展示了一种自动滚动 JTable 的方法。 .单击拇指暂停滚动;释放恢复。

附录:您的应用程序在启动时滞后 10 秒。因为这是 Controller 的确切时间 sleep ,它肯定在 EDT 上 sleep 。一个sscce将是决定性的。相反,在另一个线程上执行工作并在 EDT 上更新模型。 SwingWorker有一个 process()自动执行此操作的方法,或者您可以使用 invokeLater()如下所示。在您的应用程序正确同步之前,让 Apple 事件发挥作用的希望很小。

附录:您可以调用 isDispatchThread() Controller去检查。引用的项目包括 .dmg使用 Mac 应用程序和 ant通过目标 dist2 构建包的文件就地 .

附录:另请参阅显示的替代方法 here .

enter image description here

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

/** @seehttps://stackoverflow.com/questions/7519244 */
public class TableAddTest extends JPanel implements Runnable {

private static final int N_ROWS = 8;
private static String[] header = {"ID", "String", "Number", "Boolean"};
private DefaultTableModel dtm = new DefaultTableModel(null, header) {

@Override
public Class<?> getColumnClass(int col) {
return getValueAt(0, col).getClass();
}
};
private JTable table = new JTable(dtm);
private JScrollPane scrollPane = new JScrollPane(table);
private JScrollBar vScroll = scrollPane.getVerticalScrollBar();
private JProgressBar jpb = new JProgressBar();
private int row;
private boolean isAutoScroll;

public TableAddTest() {
this.setLayout(new BorderLayout());
jpb.setIndeterminate(true);
this.add(jpb, BorderLayout.NORTH);
Dimension d = new Dimension(320, N_ROWS * table.getRowHeight());
table.setPreferredScrollableViewportSize(d);
for (int i = 0; i < N_ROWS; i++) {
addRow();
}
scrollPane.setVerticalScrollBarPolicy(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
vScroll.addAdjustmentListener(new AdjustmentListener() {

@Override
public void adjustmentValueChanged(AdjustmentEvent e) {
isAutoScroll = !e.getValueIsAdjusting();
}
});
this.add(scrollPane, BorderLayout.CENTER);
JPanel panel = new JPanel();
panel.add(new JButton(new AbstractAction("Add Row") {

@Override
public void actionPerformed(ActionEvent e) {
addRow();
}
}));
this.add(panel, BorderLayout.SOUTH);
}

private void addRow() {
char c = (char) ('A' + row++ % 26);
dtm.addRow(new Object[]{
Character.valueOf(c),
String.valueOf(c) + String.valueOf(row),
Integer.valueOf(row),
Boolean.valueOf(row % 2 == 0)
});
}

private void scrollToLast() {
if (isAutoScroll) {
int last = table.getModel().getRowCount() - 1;
Rectangle r = table.getCellRect(last, 0, true);
table.scrollRectToVisible(r);
}
}

@Override
public void run() {
while (true) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
addRow();
}
});
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
scrollToLast();
}
});
try {
Thread.sleep(1000); // simulate latency
} catch (InterruptedException ex) {
System.err.println(ex);
}
}
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
TableAddTest nlt = new TableAddTest();
f.add(nlt);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
new Thread(nlt).start();
}
});
}
}

关于java - JAR Bundler 使用 OSXAdapter 导致应用程序滞后或终止,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7519244/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com