Results 1 to 4 of 4

Thread: SwingWorker

  1. #1
    3.14.TR is offline Member
    Join Date
    Mar 2011
    Posts
    6
    Rep Power
    0

    Unhappy SwingWorker

    Hi,
    I´m not sure, if I have chosen the right topic for my problem, nontheless I hope that I have.

    I´d like to create a simple progressBar app, involving simple delayed counter and progressbar-dialog.

    My vision is simple: with 500ms delay counting untill 10 is being displayed to the console.
    Meanwhile, the indeterminete progressbar is being displayed.
    After counting is done, I´d like to return the integer of value 987 (this is very important for me, in order to develop app later)

    According to some tutorials I tried to code this app, but unfortunatelly unsuccessfully.

    Here is my code:
    Java Code:
    public class Task{
      public static void main(String[] args) {
        final JProgressBar progressBar = new JProgressBar(0, 10);
    
        final CounterTask task = new CounterTask();
    
        JButton startButton = new JButton("Start");
        startButton.addActionListener(new ActionListener() {
          public void actionPerformed(ActionEvent e) {
            System.out.println("start");
            task.execute();
            
            Integer res=new Integer(5);
            try{
              System.out.println("try");
              while(!task.isDone()){
                System.out.println("while");
                res=task.get(50, TimeUnit.MILLISECONDS);
                System.out.println("res: "+res);
                System.out.println("afterRes");
              } 
              res=task.get(50, TimeUnit.MILLISECONDS);
                System.out.println("res: "+res);
                
              System.out.println("/while"); 
            }
            catch (Exception ex){}
          }
          
        });
    
    
    
        JPanel buttonPanel = new JPanel();
        buttonPanel.add(startButton);
    
    
        JPanel cp = new JPanel();
        LayoutManager layout = new BoxLayout(cp, BoxLayout.Y_AXIS);
        cp.setLayout(layout);
        cp.add(buttonPanel);
        cp.add(progressBar);
    
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(cp);
        frame.pack();
        frame.setVisible(true);
      }
    }
    
    class CounterTask extends SwingWorker<Integer, Integer> {
      
      protected JDialog dialog;
      
      @Override
      protected Integer doInBackground() throws Exception {
        int i = 0;
        int count = 10;
        
        dialog=new JDialog();
        JProgressBar progressBar=new JProgressBar();
        progressBar.setIndeterminate(true);
        dialog.add(progressBar);
        dialog.pack();
        dialog.setVisible(true);
        
         
        while (!isCancelled() && i < count) {
          i++;
          Thread.sleep(500);
          System.out.println(i);
        }
        publish(new Integer(987));
        return new Integer(987);
      }   
    
      @Override
      protected void done() {
        dialog.setVisible(false);  
        System.out.println("Done !");
      }
    }
    The counting is ok as same as progressbar, however the return value hasn´t been written.

    Please, could anybody help me find out, where my problem is, or furthermore could anybody provide me with working solution?

    Thank you very much

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,252
    Blog Entries
    1
    Rep Power
    24

    Default

    One problem with your code is this:

    Java Code:
                        while (!task.isDone()) {
                            System.out.println("while");
                            res = task.get(50, TimeUnit.MILLISECONDS);
                            System.out.println("res: " + res);
                            System.out.println("afterRes");
                        }
    As this could freeze the event dispatch thread, the main Swing thread, and nullify all the benefits of using a SwingWorker. But there is a better way since SwingWorkers have built in support for a PropertyChangeListener, and you might want to use that to your advantage. With this, you could even use a determinate progress bar rather than an indeterminate progress bar. For example,

    Java Code:
    import java.awt.Dialog.ModalityType;
    import java.awt.Window;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.util.List;
    
    import javax.swing.*;
    import javax.swing.SwingWorker.StateValue;
    
    @SuppressWarnings("serial")
    public class Task3 extends JPanel {
        private static final int FINAL_VALUE = 987;
        private JTextArea textArea = new JTextArea(10, 20);
        private JButton startBtn = new JButton("Start");
        
        public Task3() {
            JPanel startBtnPanel = new JPanel();
            startBtnPanel.add(startBtn);
            startBtn.addActionListener(new ActionListener() {
                
                public void actionPerformed(ActionEvent e) {
                    startBtnActionPerformed();
                }
            });
            
            textArea.setEditable(false);
            textArea.setFocusable(false);
            setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
            add(new JScrollPane(textArea, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, 
                    JScrollPane.HORIZONTAL_SCROLLBAR_NEVER));
            add(startBtnPanel);
        }
        
        private void startBtnActionPerformed() {
            startBtn.setEnabled(false);
            Window win = SwingUtilities.getWindowAncestor(this);
            final JDialog dialog = new JDialog(win, "Progress", ModalityType.APPLICATION_MODAL);
            final JProgressBar progressBar = new JProgressBar();
            JPanel progressPanel = new JPanel();
            progressPanel.add(progressBar);
            progressPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            dialog.getContentPane().add(progressPanel);
            dialog.pack();
            dialog.setLocationRelativeTo(null);
            final CounterTask3 counterTask3 = new CounterTask3(this, FINAL_VALUE);
            counterTask3.addPropertyChangeListener(new PropertyChangeListener() {
                
                public void propertyChange(PropertyChangeEvent evt) {
                    if (evt.getPropertyName().equals("state")) {
                        if (counterTask3.getState().equals(StateValue.DONE)) {
                            dialog.setVisible(false);
                            startBtn.setEnabled(true);
                            // could call counterTask3.get() here to get the final value
                        }
                    } 
                    else if (evt.getPropertyName().equals("progress")) {
                        int progress = counterTask3.getProgress();
                        progressBar.setValue(progress);
                    }
                }
            });
            counterTask3.execute();
            dialog.setVisible(true);
        }
    
        public void appendToTextArea(String text) {
            textArea.append(text);
        }
        
        public static void main(String[] args) {
            
            
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    createGui();
                }
            });
        }
    
        private static void createGui() {
            Task3 task3 = new Task3();
            JFrame frame = new JFrame("App");
            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            frame.getContentPane().add(task3);
            frame.pack();
            frame.setLocationRelativeTo(null);
            frame.setVisible(true);
        }
    }
    
    class CounterTask3 extends SwingWorker<Integer, Integer> {
        private static final int MAX_COUNTER = 10;
        private static final long SLEEP_TIME = 500;
        private Task3 task3;
        private int finalValue;
    
        public CounterTask3(Task3 task3, int finalValue) {
            this.task3 = task3;
            this.finalValue = finalValue;
        }
    
        @Override
        protected Integer doInBackground() throws Exception {
            int counter = 0; 
            while (counter < MAX_COUNTER && !isCancelled()) {
                counter++;
                Thread.sleep(SLEEP_TIME);
                publish(counter);
                setProgress((counter * 100)/MAX_COUNTER); // if use determinate PB 
            }
            return finalValue;
        }
        
        @Override
        protected void process(List<Integer> chunks) {
            for (Integer intChunk : chunks) {
                task3.appendToTextArea("int value: " + intChunk + "\n");
            }
        }
        
        @Override
        protected void done() {
            task3.appendToTextArea("Final value: " + finalValue + "\n");
        }
        
    }
    There are several ways to skin this cat and my suggestion is not the only way, and may not even be the best way.

  3. #3
    3.14.TR is offline Member
    Join Date
    Mar 2011
    Posts
    6
    Rep Power
    0

    Default

    hi,
    thank you very much for help.
    The property-change listener works good, the determinate progressBar is not nessesary, anyway thanks a lot.

    Nontheless, I probably have expresed in a strange way (sorry for my english) - I want to get the Integer (987) from worker into the rest of my other code, i.e. write returned int from propertyChangeListener insteand of from done() method.

    I asked you to explain me the example with only integer, but in future I´m going to let it return more complicated classes, e.g. ResultSet etc.

    Thank you very much for your helpful responses.

  4. #4
    3.14.TR is offline Member
    Join Date
    Mar 2011
    Posts
    6
    Rep Power
    0

    Default

    oh man,
    I´m so sorry, I didn´t see your coment. It works fine. Thanks for help

Similar Threads

  1. Using SwingWorker
    By viking90 in forum New To Java
    Replies: 1
    Last Post: 04-24-2010, 09:17 AM
  2. Swingworker or new thread
    By cotarelo in forum Threads and Synchronization
    Replies: 3
    Last Post: 03-24-2010, 06:59 PM
  3. SwingWorker question
    By cotarelo in forum Threads and Synchronization
    Replies: 16
    Last Post: 03-23-2010, 11:29 AM
  4. SwingWorker Opinions
    By frejon26 in forum AWT / Swing
    Replies: 3
    Last Post: 04-13-2009, 08:41 PM
  5. swingworker
    By musiigedeo in forum AWT / Swing
    Replies: 1
    Last Post: 07-26-2007, 12:59 PM

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •