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,
    Im not sure, if I have chosen the right topic for my problem, nontheless I hope that I have.

    Id 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, Id 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 hasnt 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,316
    Blog Entries
    1
    Rep Power
    26

    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 Im 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,
    Im so sorry, I didnt 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
  •