3

I have made a small swing application for my personal use. This app connects to internet, retrieves a text file, displays its contents in a jTextArea and saves the text file locally (in my hardisk). So far so good.

Now I want to receive this text file on a fixed regular interval (say after every 30 seconds). I can do this via for/while loops (and thread.sleep methods), but I know this is not the right way as it does not allow me pause/resume the receiving. I have tried solving my problem using ‘threads’ and ‘callable’ but not able to succeed. (I do not have much knowledge of these)

Can you please guide me how to collect string value from a thread? Am I doing the right thing using Callable/Future? (please see my code). I should be able to pause / resume the text collection.

(During pause and resume my software I will some manual text editing and saving it to the disk. But I can handle that.)

Below is my code which I tried.

public class AmybactUI extends javax.swing.JFrame {

    public AmybactUI() {
        initComponents();
    }
    private void initComponents()  { .... }

    public static void main(String args[]) throws Exception {

    //    (Look and feel setting code here)

        java.awt.EventQueue.invokeLater(new Runnable() {

            public void run() {
                new AmybactUI().setVisible(true);
            }
        });

        ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();
        List<Future<String>> results = executor.invokeAll(Arrays.asList(new GetScore()), 30, TimeUnit.SECONDS);
        for (Future<String> result : results) {
            if (!result.isCancelled()) {
                   jTextAreaOnlineScore.append(result.get()+"\n");
                   jTextAreaOnlineScore.setCaretPosition(jTextAreaOnlineScore.getDocument().getLength());
                } else {
                    System.out.println("Task timed out.");
                }
                executor.shutdown();
            }            
    }

    // Variables declaration - do not modify                     
    private javax.swing.ButtonGroup buttonGroup1;
    private javax.swing.JButton jButtonSaveSMS;
    private javax.swing.JLabel jLabelTitle;
    private javax.swing.JMenuBar jMenuBar;
    private javax.swing.JMenu jMenuFile;
    private javax.swing.JMenu jMenuHelp;
    private javax.swing.JMenuItem jMenuItemAbout;
    private javax.swing.JMenuItem jMenuItemExit;
    private javax.swing.JMenuItem jMenuItemOptions;
    private javax.swing.JMenu jMenuTools;
    private javax.swing.JPanel jPanel;
    private static javax.swing.JRadioButton jRadioButtonOffline;
    public static javax.swing.JRadioButton jRadioButtonOnline;
    private javax.swing.JScrollPane jScrollPane;
    public static javax.swing.JTextArea jTextAreaOnlineScore;
    private javax.swing.JTextField jTextFieldCustomSMS;
    // End of variables declaration                   
}

class GetScore implements Callable<String> {
    public String call() throws Exception {        
        Calendar cal = Calendar.getInstance();
        SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
        String nextLine;
        String myString = "";
        String myTryString;
        URL url;
        URLConnection urlConn;
        InputStreamReader inStream;
        BufferedReader buff;
        FileWriter fustream;
        BufferedWriter bfout;  
        try {
//         (some code here which connects to internet and gets my text)
            } else {
              break;
            }
         }
            bfout.write(myString);
            bfout.close();           
        } catch(MalformedURLException e) {
            System.out.println("Please check the URL:" + e.toString());
        } catch(IOException  e1) {
            System.out.println("Can't read from the Internet: " + e1.toString());
        }
        Thread.sleep(4000);
        return (""+sdf.format(cal.getTime())+myString);
    }
}
kleopatra
  • 51,061
  • 28
  • 99
  • 211
mzeeshan
  • 33
  • 4

1 Answers1

2

Actually, you don't need to use Futures in order to get results. Do the following:

  • make GetScore as Runnable
  • pass TextArea to the constructor of GetScore
  • when GetScore.run method will be executed, wither use textArea.setText method, or use SwingUtilities.invokeLater

like:

 SwingUtilities.invokeLater(new Runnable() {
     public void run() {
        textArea.setText(text);
     }
 );
kleopatra
  • 51,061
  • 28
  • 99
  • 211
jdevelop
  • 12,176
  • 10
  • 56
  • 112
  • jdevelop: Ok. I will make code as you suggessted and will get back later. Thanks – mzeeshan Sep 24 '12 at 06:09
  • I got this new code in my main class working: public static void main(String args[]) { javax.swing.SwingUtilities.invokeLater(new Runnable() { public void run() { new NewJFrame().setVisible(true); jTextArea1.append(myMethod()); } private String myMethod() { return "Some text\n"; } }); } But how to make continous loop of jTextArea1.append? At fixed intervals? And as I said earlier, how to pause and resume this loop? Please help. – mzeeshan Sep 24 '12 at 17:04
  • Done. I got it all working now. Thanks. The key was SwingUtilities.invokeLater. If anyone likes I can post the complete correct code. – mzeeshan Sep 25 '12 at 14:03