-1

I'm trying use the SwinWorker to update one TextArea with the status of the execution of one button actionPerform method.

I get various samples from internet and nothing work form me. Anybody can help me?

bellow my button method:

private void buttonActionPerformed(java.awt.event.ActionEvent evt) {                                                
        atualizaTextArea("", true);
        button.setEnabled(false);

        SearchDataBase cd = new SearchDataBase();
        textAreaField.setForeground(Color.BLUE);
        try {
            refreshTextArea("......Process Started......\n\n", true);
            cd.search();
            String textt = textAreaField.getText();
            refreshTextArea("Finish\n\n", false);
        } catch (Exception e) {
            button.setEnabled(true);
            StringWriter errors = new StringWriter();
            e.printStackTrace(new PrintWriter(errors));

            textAreaField.setText("Error - Contact the developer");
            textAreaField.setForeground(Color.red);
        }

        if (comboBoxSearchType.getSelectedIndex() == 1) {
            try {
                refreshTextArea("......History search started (too slow!!)......\n\n", false);
                cd.searchHistoryTable(dateChoserPesquisa.getDate().getTime());
                refreshTextArea("Finish\n\n", false);
            } catch (Exception e) {
                button.setEnabled(true);
                StringWriter errors = new StringWriter();
                e.printStackTrace(new PrintWriter(errors));

                textAreaField.setText("Error - Contact the developer");
                textAreaField.setForeground(Color.red);
            }
        }
        refreshTextArea("...............Finish..............", false);
        button.setEnabled(true);
    }

TextAreaAviso is the JtextArea that I'm trying to update.

refreshTextArea(String, boolean) is the method that I have created to update the JTextArea

  private void refreshTextArea(String text, boolean rep) {
        this.texttt = text;
        this.replace = rep;


        // define a SwingWorker to run in background  
        SwingWorker<String, String> worker = new SwingWorker<String, String>() {
            @Override
            public String doInBackground() {
                String t = textAreaField.getText();
                if (replace) {
                    publish(texttt);
                    t = texttt;
                } else {
                    publish(t + texttt);
                    t+= texttt;
                }
                System.out.println(texttt);

                return "";
            }

            @Override
            protected void process(final List<String> chunks) {
                for (String text : chunks) {
                    TextAreaAviso.setText(texttt);
                    System.out.println("HERE!!!!");
                }
            }

        };
        worker.execute();

       // (new AtualizaTextArea(TextAreaAviso, texto, replace)).execute();
    }

In this case I have created all process in the method scope, but I was tried using a separated class, as bellow:

private void refreshTextArea(String text, boolean rep) {
       (new RefreshTextArea(TextAreaAviso, texto, replace)).execute();
 }

class RefreshTextArea extends SwingWorker<Integer, String> {

    private JTextArea textArea;
    private String texto;
    private boolean replace;

    public RefreshTextArea(JTextArea textArea, String texto, boolean replace) {
        this.textArea = textArea;
        this.texttt = texto;
        this.replace = replace;
    }

    @Override
    protected Integer doInBackground() throws Exception {

        int i = 0;
        String t = "";
        if (!replace) {
            t = texttt + textArea.getText();
        } else {
            t = texttt;
        }

        System.out.println(t);
        publish(t);

        return i;
    }

    @Override
    protected void process(final List<String> chunks) {
        for (String text : chunks) {
            textArea.setText(texttt);
        }
    }
}

In both implementations I have tried using with and without execution of revalidate method of textarea. In both implementations I have tried update the textarea value in doBackground method and/or process method.

user1352652
  • 425
  • 1
  • 8
  • 21

1 Answers1

4

Your SwingWorker should not access or update the JTextArea in your implementation of doInBackground(). Instead publish() intermediate results and update the JTextArea only in process(). Moreover, setText() will have the effect of replacing the existing text; you may want append() instead. A complete example is shown here. Note that BackgroundTask has access to the JTextArea in the enclosing scope, but you can also pass it as a parameter to the SwingWorker.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • I improved the readability of the code . You will see que I make all you say ( except the use of append method) . – user1352652 Oct 22 '14 at 11:33
  • 1
    In your first `SwingWorker`, `worker`, the invocation `textAreaField.getText()` incorrectly accesses a GUI component from the background thread. Your second, `RefreshTextArea`, appears correct; it's unclear what's not working. For more specific guidance, please edit your question to include a [complete example](http://stackoverflow.com/help/mcve) that focuses on the effect you want to achieve. – trashgod Oct 22 '14 at 11:46