4 Replies - 170 Views - Last Post: 19 February 2019 - 01:20 PM Rate Topic: -----

#1 jeffindenver   User is offline

  • D.I.C Head

Reputation: 38
  • View blog
  • Posts: 184
  • Joined: 07-August 15

Problem with Swing concurrency

Posted 13 February 2019 - 07:30 AM

Hello all,

I'm having trouble with Swing concurrency. I have a JTextArea that accepts dropped files and does stuff with them, and I'm trying to print the file names as a sort of progress indicator.

However, the printing is getting queued. All the file names get printed at one time. It bothers me that I have an instruction in the middle of a loop, but it's ignored. Anyone know what's going on?

   private void start() {

        view.getTextArea().setDropTarget(new DropTarget() {
            private static final long serialVersionUID = 1L;

            @Override
            @SuppressWarnings("unchecked")
            public synchronized void drop(DropTargetDropEvent evt) {
                List<File> droppedFiles = Collections.EMPTY_LIST;
                try {
                    evt.acceptDrop(DnDConstants.ACTION_COPY);
                    droppedFiles = (List<File>) 
                    evt.getTransferable().getTransferData(DataFlavor.javaFileListFlavor);
                } catch (UnsupportedFlavorException | IOException ex) {
                    view.printError(ex.getMessage());
                }
                droppedFiles.forEach(f -> processFile(f));
            }
        });
    }

    private void processFile(@NotNull File file) {
        String pathname = file.toString();

        model.setComposer(new ReportComposer(selectReport(pathname)));

        List<String> source = readSourceFile(pathname);

        try {
            model.runReport(source);
        } catch (InvalidFormatException | IOException e) {
            view.printError(e.getMessage());
        }

        countOfFilesProcessed++;
        updateView(pathname);
    }
	
	private void updateView(String pathname) {
        view.printMessage(pathname);
        view.setStatus(countOfFilesProcessed + " files processed.");
    }

    void printMessage(String msg) {
        textArea.append(System.getProperty("line.separator"));
        textArea.append(msg);
    }




I've read through the Java Concurrency and Swing Concurrency tutorials that lead to these solutions, which solved nothing and made no visible difference. I think the first one may have failed.

    void printMessage(String msg) {
        MsgThread mt = new MsgThread(msg);
        mt.run();
    }

    private class MsgThread extends Thread {
        String message;
        MsgThread(String msg) {
            this.message = msg;
        }
        public void run() {
            textArea.append(System.getProperty("line.separator"));
            textArea.append(message);
        }
    }
	
	//**************************************************************
	
	void printMessage(String msg) {

        Runnable appendMessage = () -> {
            textArea.append(System.getProperty("line.separator"));
            textArea.append(msg);
        };

        try {
            SwingUtilities.invokeAndWait(appendMessage);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }

    }
	
	//**************************************************************

	void printMessage(String msg) {

        Runnable appendMessage = () -> {
            textArea.append(System.getProperty("line.separator"));
            textArea.append(msg);
        };

        SwingUtilities.invokeLater(appendMessage);

    }



Is This A Good Question/Topic? 0
  • +

Replies To: Problem with Swing concurrency

#2 g00se   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3617
  • View blog
  • Posts: 16,596
  • Joined: 20-September 08

Re: Problem with Swing concurrency

Posted 13 February 2019 - 08:17 AM

I would personally use SwingWorker. But before we get into that, is it not the case that drop is going to get called once per file?
Was This Post Helpful? 1
  • +
  • -

#3 jeffindenver   User is offline

  • D.I.C Head

Reputation: 38
  • View blog
  • Posts: 184
  • Joined: 07-August 15

Re: Problem with Swing concurrency

Posted 13 February 2019 - 08:28 AM

If you select multiple files then drop, it's one event.

And thanks Goose. I'm looking at the SwingWorker doc, and it looks like they have example showing exactly what I need.
Was This Post Helpful? 0
  • +
  • -

#4 g00se   User is offline

  • D.I.C Lover
  • member icon

Reputation: 3617
  • View blog
  • Posts: 16,596
  • Joined: 20-September 08

Re: Problem with Swing concurrency

Posted 13 February 2019 - 09:18 AM

No problem. You can probably use the drop method
https://examples.jav...g-drop-example/
here as is, with the addition of the following (e.g.) line of code

new FileProcessor(droppedFiles).execute();

Was This Post Helpful? 0
  • +
  • -

#5 jeffindenver   User is offline

  • D.I.C Head

Reputation: 38
  • View blog
  • Posts: 184
  • Joined: 07-August 15

Re: Problem with Swing concurrency

Posted 19 February 2019 - 01:20 PM

Finally had some time to give this a try, and happy to say it works great.


void start(){
    ...
    ...
    new ProcessFileTask(droppedFiles).execute();
}

    private class ProcessFileTask extends SwingWorker<Integer, String> {
        //SwingWorker<T, V>
        // T is return type of doInBackground and get methods
        // v is the type used to carry out intermediate results by publish and process methods
        List<File> fileList;

        ProcessFileTask(List<File> list) {
            fileList = list;
        }

        @Override
        protected Integer doInBackground() {

            int count = 0;

            for (File file : fileList) {
                String filepath = file.toString();

                model.setReport(selectReport(filepath));

                List<String> source = readSourceFile(filepath);

                try {
                    model.runReport(source);
                } catch (InvalidFormatException | IOException e) {
                    view.printError(e.getMessage());
                }
                count++;
                publish(filepath);
            }

            return count;
        }

        @Override
        protected  void process(List<String> chunks) {
            chunks.forEach(v -> updateView(v));
        }
    }



Was This Post Helpful? 0
  • +
  • -

Page 1 of 1