Jump to content

Java Swing help


TGYK
 Share

Recommended Posts

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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 by TGYK
Link to comment
Share on other sites

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 by TGYK
Link to comment
Share on other sites

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'
Link to comment
Share on other sites

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 by TGYK
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...