JAR Bundler using OSXAdapter causing application to lag or terminate

前端 未结 3 960
温柔的废话
温柔的废话 2020-11-22 14:36

I\'ve created a simple Java application that each second for for 10 seconds consecutive seconds adds a new row to a JTable. It consists of three classes.

3条回答
  •  执笔经年
    2020-11-22 15:03

    After doing it, I'm not fully convinced a SwingWorker is a simpler (aka: better) solution - still requires additional thread synching (between the worker thread and the "outer" thread which passes in the file/names). Anyway (taking the opportunity to learn, and be it by errors :), below is a crude proof of concept example for the basic idea:

    • implement the Controller as SwingWorker, which funnels the input from the outer thread into the EDT
    • make it accept input (from the adapter, f.i.) via a method doWork(..) which queues the input for publishing
    • implement doInBackground to succesively publish the input

    open issues

    • synch the access to the local list (not an expert in concurrency, but pretty sure that needs to be done)
    • reliably detecting the end of the outer thread (here simply stops when the input queue is empty)

    Feedback welcome :-)

    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 {
            private GUI gui;
    
            private List pending;
    
            public Controller() {
                gui = new GUI();
            }
    
            public void doWork(String newLine) {
                if (pending == null) {
                    pending = new ArrayList();
                    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 

    */ @Override protected void process(List 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()); }

提交回复
热议问题