TGYK Posted December 1, 2014 Share Posted December 1, 2014 Hey guys, first post here, big fan of the show. Long story short, I'm making a frontend GUI for pianobar, and need to run a small shell script and poll a file every half a second or so, and am having difficulty finding easily-understandable documentation on creating the background process thread within the swing framework. If anyone shows interest, I can post some code snippits. Thanks in advance! -TGYK Quote Link to comment Share on other sites More sharing options...
cooper Posted December 1, 2014 Share Posted December 1, 2014 Why would you want this background thread to have anything to do with Swing? Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 1, 2014 Author Share Posted December 1, 2014 From what I've read and understand, you can't use conventional threading while using Swing, because of how the Gui framework works, but that Swing incorporates a way to create a background worker thread to allow at least one other thread in applications. Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 1, 2014 Author Share Posted December 1, 2014 From what I've read and understand, you can't use conventional threading while using Swing, because of how the Gui framework works, but that Swing incorporates a way to create a background worker thread to allow at least one other thread in applications. Been a while since I actually looked at the source, I had put the project down for a while after getting stuck on this. After firing up Eclipse, I believe the thread is something along the lines of doInBackground, if that helps at all Quote Link to comment Share on other sites More sharing options...
cooper Posted December 1, 2014 Share Posted December 1, 2014 https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html I don't see the benefit of using this over just plainly creating a background thread, particularly since there doesn't seem to be a heck of a lot of interaction between the two. Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 2, 2014 Author Share Posted December 2, 2014 https://docs.oracle.com/javase/tutorial/uiswing/concurrency/worker.html I don't see the benefit of using this over just plainly creating a background thread, particularly since there doesn't seem to be a heck of a lot of interaction between the two. Sorry for being a bit incomprehensible in my last few posts, I was on a streak of human uptime, with a dangerously low supply of caffeine. What I didn't notice in my sleepy haze is that yes, I was previously trying to use this swing worker thread, and appeared to be having difficulty making it work. I'm gonna lay down some pseudo-code to see if you might have a suggestion or two. //Set up GUI and various other parts of the program already, but this part doesn't seem to work public class UpdateTime extends SwingWorker<Void, Integer>{ protected Void doInBackground() { while(true){ //I want this to happen always try{ gui.updateTimeLbl(gui.lblTime, pollPath, homePath); //the updateTimeLbl updates the jLabel at gui.lblTime, using the data gotten from a file located in homePath, which is generated by a small shell script located at pollPath //the method polls Pianobar first, and the script outputs the song title and time info to a file, which is used by both updateTimeLbl and updateSongLbl //the method then updates the specified jLabel with the information it got from the file gui.updateSongLbl(gui.lblNowPlaying, homepath); } catch (IOException e1) { e1.printStackTrace(); } catch (InterruptedException e1) { e1.printStackTrace(); } //Using some high-tech debugging skillz (System.out.println("TEST");), I can determine that the execution never reaches this point in code, and I think I had given up before I bothered to figure out why return null; } } } public void doTask(){ UpdateTime time = new UpdateTime(); time.execute(); } So, aside from the flak I'm sure I'm going to catch from using a shell script to poll the program for parameters, and my glorious handling of exceptions, can you see any reason why this shouldn't work? Quote Link to comment Share on other sites More sharing options...
cooper Posted December 2, 2014 Share Posted December 2, 2014 Returning null from a void method is illegal, but that's not the issue here. The issue is that line isn't reached which probably means that your gui.updateTimeLbl method is using a blocking call to do its thing and while you expect it to return immediately, it waits indefinately for some system event. Either that, or this method has itself a loop that's never ending. Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 3, 2014 Author Share Posted December 3, 2014 The updateTimeLbl method is as follows: Public void updateTimeLbl(JLabel l, Sting pollLocation, String home) throws IOException, InterruptedException { String line = null; String time = null; ProcessBuilder poll = new ProcessBuilder(pollLocation); Process p = poll.start(); String timefile = home + "/.config/pianobar/timefile"; BufferedReader br = new BufferedReader(new FileReader(timefile)); while((line = br.readline()) != null) { try { String[] lineAR = line.split("\\s"); time = lineAr[1]; } catch(ArrayIndexOutOfBoundsException ex) { throw ex; } } l.setText(time); frame.repaint(); } The script at pollLocation is a simple bash script which when called, parses the most recent output of the pianobar execution and outputs the time to the timefile Quote Link to comment Share on other sites More sharing options...
cooper Posted December 3, 2014 Share Posted December 3, 2014 I think you'll find that br.readline() can block. Try using the iterator provided by br.lines().iterator() - maybe the hasNext() will return false until a new line is actually available? Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 3, 2014 Author Share Posted December 3, 2014 I think you'll find that br.readline() can block. Try using the iterator provided by br.lines().iterator() - maybe the hasNext() will return false until a new line is actually available? I can try this and get back to you. Am I safe in assuming that the br.lines().iterator() will return one line at a time? Quote Link to comment Share on other sites More sharing options...
cooper Posted December 3, 2014 Share Posted December 3, 2014 You get an iterator for String where each of those is a line, yes. Javadoc is your friend. Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 5, 2014 Author Share Posted December 5, 2014 Alright, I fixed the issue in Java. Now the new issue is that I need to be able to remove ANSI control codes from my input. Namely, from pianobar,I'm getting the sequence ^[[2K, which is basically ESC Erase whole line. I need to be able to do this before passing into Java, because the buffer fills with a long file worth of times, all beginning with ^[[2K, and I can't find a good way to read the last line of the buffer only. Also, the longer the program runs, the bigger the 'timefile' gets, because of these lines not getting parsed correctly. After about 3 hours of scratching my head, I've got nothing.. Sample of the output times from pianobar if captured using tee: ^[[2K# 3:42/3:42 ^[[2K# 3:41/3:42 ^[[2K# 3:40/3:42 ^[[2K# 3:39/3:42 ^[[2K# 3:38/3:42 ^[[2K# 3:37/3:42 ... I want to parse this output using a bash script before passing into Java, because it also contains information like song title, etc I only want the x:xx/x:xx to be output to a file "timefile" to be read by Java. Maybe I'm too tired to figure it out right now, but some help would be greatly appreciated. Quote Link to comment Share on other sites More sharing options...
cooper Posted December 5, 2014 Share Posted December 5, 2014 I'd start by checking if pianobar has an option to omit those control characters... Quote Link to comment Share on other sites More sharing options...
Sebkinne Posted December 5, 2014 Share Posted December 5, 2014 I'd just pipe the output to sed, get rid of the extra characters and whitespace, and write these to a file. If you are reading this file from Java while you are still writing to it, make sure to open the file in read only mode. Best regards, Sebkinne Quote Link to comment Share on other sites More sharing options...
cooper Posted December 5, 2014 Share Posted December 5, 2014 I'd try to get rid of the file altogether. It doesn't seem like anybody's interested. Like, pipe the output of Pianobar though sed to filter out the control chars, on to a bash script that picks up whatever data it needs and further along to the java program that processes the constant yammering of the timestamp. Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 6, 2014 Author Share Posted December 6, 2014 (edited) I'd just pipe the output to sed, get rid of the extra characters and whitespace, and write these to a file. If you are reading this file from Java while you are still writing to it, make sure to open the file in read only mode. Best regards, Sebkinne Sed only recognizes the [2K part, not the ANSI Esc sequence. Tail doesn't realize that there is more than one line in the file. My intention is to move from using files, to just piping the output of pianobar straight into a fifo which Java opens to read, but I'd like to figure out how to get rid of these control characters first. Edit: As far as I can tell, Pianobar does not have any options to disable this feature, as it was designed to be a terminal application, and the control codes handle the 'display' of the application. Edit 2: After mucking around with sed and awk and even trying perl, I'm a bit confused, thinking maybe these programs don't recognize the ANSI escape sequence, whether represented as \e, \033, or \1B. I'm considering doing away with the bash parsing entirely, and recreating it all in code in Java. I'd need a way to strip terminal control codes, then a way to match the last line containing a # character. As this has drifted far away from my original problem of SwingWorker issues, I may delete this thread and make a new one pertaining to my new issues, unless it's alright to go so far off topic here. I'm open to suggestions on how to remove the control codes, and thanks for the help so far! Edited December 6, 2014 by TGYK Quote Link to comment Share on other sites More sharing options...
Jason Cooper Posted December 6, 2014 Share Posted December 6, 2014 Have you tried this to replace all your ^[[2K# entries with newlines (worked when I piped your example through it in bash) sed -e 's/\x1B\[2K#/\n/g' Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 6, 2014 Author Share Posted December 6, 2014 (edited) Have you tried this to replace all your ^[[2K# entries with newlines (worked when I piped your example through it in bash) sed -e 's/\x1B\[2K#/\n/g' Doing this in the terminal on my mac isn't working as would be expected, I'm not sure why, but it acts like sed ignores the escape code. I mucked around with the command and various methods to get it to work, but couldn't get anything to work. Edited December 6, 2014 by TGYK Quote Link to comment Share on other sites More sharing options...
Jason Cooper Posted December 6, 2014 Share Posted December 6, 2014 You're using a Mac, that explains it. The version of sed on macs will be BSD rather than GNU and so doesn't support escape codes. You should be able to insert a literal escape into the string with a bit of fiddling. Try something like: sed -e 's/'$(echo "\x1B")'\[2K#/\n/g' Quote Link to comment Share on other sites More sharing options...
TGYK Posted December 6, 2014 Author Share Posted December 6, 2014 (edited) You're using a Mac, that explains it. The version of sed on macs will be BSD rather than GNU and so doesn't support escape codes. You should be able to insert a literal escape into the string with a bit of fiddling. Try something like: sed -e 's/'$(echo "\x1B")'\[2K#/\n/g' BSD echo doesn't support printing special characters via hex, octal, or escape. I used printf '\033', and confirmed that it does output the escape character, but sed still doesn't recognize it when I use it in the substitution command. Might try awk and see if it works there. EDIT: Figured it out! Thanks for the help guys! Edited December 6, 2014 by TGYK Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.