JAR Bundler using OSXAdapter causing application to lag or terminate

前端 未结 3 984
温柔的废话
温柔的废话 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:07

    Here's a variation of @kleopatra's example in which a continuously running Controller accepts new entries in doWork(), while a SwingWorker processes the pending entries asynchronously in its background thread. ArrayBlockingQueue handles the synchronization.

    import java.awt.EventQueue;
    import java.util.List;
    import java.util.Random;
    import java.util.concurrent.ArrayBlockingQueue;
    import java.util.concurrent.BlockingQueue;
    import javax.swing.JFrame;
    import javax.swing.JScrollPane;
    import javax.swing.JTable;
    import javax.swing.SwingWorker;
    import javax.swing.table.DefaultTableModel;
    
    public class GUI {
    
        private static final Random rnd = new Random();
        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.
         */
        private static class Controller extends SwingWorker {
    
            private static final int MAX = 5;
            private GUI gui;
            private BlockingQueue pending =
                new ArrayBlockingQueue(MAX);
    
            public Controller() {
                EventQueue.invokeLater(new Runnable() {
    
                    @Override
                    public void run() {
                        gui = new GUI();
                    }
                });
            }
    
            private void doWork(String newLine) {
                try {
                    pending.put(newLine);
                } catch (InterruptedException e) {
                    e.printStackTrace(System.err);
                }
            }
    
            @Override
            protected Void doInBackground() throws Exception {
                while (true) {
                    // may block if nothing pending
                    publish(pending.take());
                    try {
                        Thread.sleep(rnd.nextInt(500)); // simulate latency
                    } catch (InterruptedException e) {
                        e.printStackTrace(System.err);
                    }
                }
            }
    
            @Override
            protected void process(List chunks) {
                for (String object : chunks) {
                    gui.addRow(object);
                }
            }
        }
    
        /** 
         * Exercise the Controller.
         */
        private static class Adapter implements Runnable {
    
            private Controller controller;
    
            private Adapter(Controller controller) {
                this.controller = controller;
            }
    
            @Override
            public void run() {
                controller.execute();
                int i = 0;
                while (true) {
                    // may block if Controller busy
                    controller.doWork("Line " + (++i));
                    try {
                        Thread.sleep(rnd.nextInt(500)); // simulate latency
                    } catch (InterruptedException e) {
                        e.printStackTrace(System.err);
                    }
                }
            }
        }
    
        public static void main(String[] args) {
            System.out.println("Initializing controller");
            // Could run on inital thread via
            // new Adapter(new Controller()).run();
            // but we'll start a new one
            new Thread(new Adapter(new Controller())).start();
        }
    }
    

提交回复
热议问题