当前位置: 首页 > 面试题库 >

Java使用OSXAdapter的JAR Bundler导致应用程序滞后或终止

杜彦君
2023-03-14
问题内容

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

程序启动后被调用的主类

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

And finally, the 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的文件中。我已成功完成此操作,我的应用程序打开,计数到十,每秒写一次。

Now, for the problem

默认情况下,双击a .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行。

Help

现在,我为此付出了很多努力,似乎关于OSXAdapter和Jar Bundler的文档都很少。我究竟做错了什么?还是我不应该首先使用OSXAdapter或Jar Bundler?


问题答案:

完成此操作后,我不完全相信SwingWorker是一个更简单(又称更好)的解决方案-仍然需要其他线程同步(在工作线程和传入文件/名称的“外部”线程之间)。无论如何(利用学习的机会,并避免错误:),以下是基本思想的概念证明示例:

  • 将Controller实现为SwingWorker,它将来自外线程的输入汇集到EDT中
  • 通过doWork(..)方法使其接受输入(来自适配器,fi),该方法将输入排队以便发布
  • 实现doInBackground以成功发布输入

开放式问题

  • 同步对本地列表的访问(不是并发专家,但是很确定需要这样做)
  • 可靠地检测到外线程的结束(这里在输入队列为空时停止)
    欢迎反馈:-)
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 });
    }

    /**
     * Controller is a SwingWorker.
     */
    public static class Controller extends SwingWorker<Void, String> {
        private GUI gui;

        private List<String> pending;

        public Controller() {
            gui = new GUI();
        }

        public void doWork(String newLine) {
            if (pending == null) {
                pending = new ArrayList<String>();
                pending.add(newLine);
                execute();
            } else {
                pending.add(newLine);
            }
        }

        @Override
        protected Void doInBackground() throws Exception {
            while (pending.size() > 0) {
                publish(pending.remove(0));
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            return null;
        }

        /**
         * @inherited <p>
         */
        @Override
        protected void process(List<String> chunks) {
            for (String object : chunks) {
                gui.addRow(object);
            }
        }

    }

    /** 
     * Simulating the adapter.
     * 
     *  Obviously, the real-thingy wouldn't have a reference 
     *  to the controller, but message the doWork refectively 
     */
    public static class Adapter implements Runnable {

        Controller controller;

        public Adapter(Controller controller) {
            this.controller = controller;
        }

        @Override
        public void run() {
            for (int i=0; i<10; i++)
            {
                controller.doWork("Line "+(i+1));
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

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

    @SuppressWarnings("unused")
    private static final Logger LOG = Logger.getLogger(GUI.class.getName());
}


 类似资料:
  • 我在java应用程序中使用log4j2。就日志功能而言,一切都很好,但是在启动应用程序时,它似乎会导致非常明显的延迟。 我已经把代码剥离到基本的 如果不包括log4j2,那么当我运行应用程序时,控制台中就会出现“TEST”,包括构建路径中的log4j2代码和文件夹,这会导致测试出现时间延迟40-50秒。 log4j2.xml中设置为跟踪的标志 谢谢你的帮助,亚历克西斯

  • 这里是Android开发者新手。我在MainActivity中使用recyclerview,应用程序不断崩溃。 任何帮助都将受到赞赏! 编辑:对不起,我是新来的。我已经附加了Logcat。和其他xml文件。谢谢 这是我的代码: 列出你的布局。xml: activity_main.xml: } ProductAdapter。java类: } Logcat: 致命异常:主进程:e.wolverine2

  • 我很难让Autowired注释在我的spring boot应用程序中工作。 我也无法在包之外运行main方法。有什么建议吗? UserService类 UserRepository类

  • 问题内容: 我正在开发一个Android 3.1应用程序,该应用程序使用USB主机模式通过USB上的MIDI与我的键盘(Korg M3)进行通信。这是在装有Android 4.0.3的Xoom上运行的。我可以通过USB接收MIDI消息而没有任何问题,但是将音符数据发送回键盘的效果是好坏参半,延迟半秒钟后便会频繁崩溃。 这是我在点击操作栏上的按钮发送注释时不断遇到的错误: E / dalvikvm(

  • 问题内容: 我已经在我的应用中实现了GCM通知。我现在尝试在用户注销时注销该应用程序。我正在使用以下代码。执行此代码时,它将导致应用程序崩溃,并显示以下logcat: 这是代码: 问题答案: 将支持库更新为25.0.0后,我遇到了同样的问题。对我来说,更新下面的库之后,在应用程序gradle文件中,问题消失了。