0

Over the last two weeks I have studied 10 different ways to avoid problems with sleep(). The concept of running a block of code on the UI Thread that cannot be interrupted seems the most practical. So I have proceeded to create a FutureTask<Void> object that contains the code not to be interrupted before completed. The code in for loops, pixelArray[r][c].setFill(color) sets the new colors for Circle Objects in a Grid Array that's 32x64. This has always failed to display the colors when just sleep(5000) is invoked between the pixel art files, FileChooser selects and assigns to List<File> selectedFiles. Unfortunately the following code will not compile because runLater in the linePlatform.runLater(diplayFileTask); can't be resolved in the following code:

public class PlayPlaylist{

public static List<File> selectedFiles;

public static void play() throws ExecutionException {

    FileChooser fileChooser = new FileChooser();
    fileChooser.setInitialDirectory(new File("C:\\ProgramData\\L1 Art Files\\"));
    fileChooser.setTitle("Play One or More Pixel Art Files");
    List<File> selectedFiles = fileChooser.showOpenMultipleDialog(null);
    for (File selectedFile : selectedFiles) {
        try {
            displayFile(selectedFile.getPath());
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public static void displayFile( String pathName) throws IOException, InterruptedException, ExecutionException {

    FutureTask<Void> displayFileTask = new FutureTask<>(new Runnable() {
        @Override
        public void run() {

            path = Paths.get(pathName);
            try {
                pixelByteArray = Files.readAllBytes(path);
            } catch (IOException e) {
                e.printStackTrace();
            }


            int cnt = 0;
            for (int r = 0; r < row; r++) {
                for (int c = 0; c < col; c++) {
                    //int i = r * col + c;
                    //System.out.println("\nr = " + r + "  c = " + c);

                    String hexRGB = String.format("#%02X%02X%02X",
                            pixelByteArray[cnt++],                  //red
                            pixelByteArray[cnt++],                  //green
                            pixelByteArray[cnt++]);                 //blue

                    Color color = Color.valueOf(hexRGB);
                    //System.out.println("\ncolor is " + color);

                    pixelArray[r][c].setFill(color);
                }
            }
            String fileName = path.getFileName().toString();
            window.setTitle(MessageFormat.format("Pixel Array {0} x {1}    File:  {2}", Integer.toString(row), Integer.toString(col), fileName));
        }
    }, null); // displayFile
    Platform.runLater(displayFileTask);
    displayFileTask.get();
    sleep(5000);
}

I've followed the example(s) closely in Stack Overflow and fail to see the problem(s).

I have more details on past attempts posted on Stack Overflow at: Wait() & Sleep() Not Working As Thought.

I also have the two UI windows posted on the web at: Virtual Art. I think the pixel art shown in the Pixel Array window clarifies the goal of creating a user-defined slide show.

Can anyone correct my errors? Do you think my sleep(5000) is in the best location?

Answering James_D's questions. This is my best solution to your answer at my first post, Wait() & Sleep() Not Working As Thought. I was actually following your logic and code posted at, java thread immediately update UI.

I save and display pixel art files that are 32x64. You can see an example posted on the Virtual Art website. I thought it would be straight forward to create a slide show under Playlist, click Play. I would use the same class and OpenFile(pathname) method in a for loop to display each file selected and placed in the ArrayList<> but pause by putting Thread.sleep(5000) in the loop.

As you pointed out, this doesn't work, as I best understand, because the Thread.sleep(5000) interrupts the UI Thread causing a "skip" over of just the display code of all the files looped through. But last pixel art file will appear after 5 secs.

I thought your answer in the post referenced above applied: You create a block of code using FutureTask<Void> and Platform.runLater<task> that can't be interrupted until completed. I thought the FutureTask<Void> runs on the UI Thread and would finish displaying the pixel art file before Thread.sleep(5000) could interrupt.

At 68 and retired, I'm new to JavaFX and trying to develop this RGB LED product that can be programmed with a basic pixel editor. Learning JavaFX is a real challenge for me, thanks for your time and patience.

Community
  • 1
  • 1
sgroen
  • 29
  • 1
  • 8
  • _concept of running a block of code on the UI Thread that cannot be interrupted seems the most practical_ no, no, no, on the contrary: you _must not_ ever think of anything in the UI as uninteruptable! The result would be a sluggish/unresponsive UI that would annoy your users. That's why you do all the time-consuming processing plus sleeping in the background. BTW: for highest probability to get concrete help it's best to provide a SSCCE that demonstrates the exact problem. – kleopatra Dec 08 '15 at 09:38
  • Can you explain what the overall aim is here? (Is it a slideshow? Why not use a `Timeline`, or at least a `ScheduledService`?) I don't actually understand what you are trying to do with the threading: I assume `play()` is called as the result of a user event, so it is on the FX Application Thread, and consequently so is `displayFile`. But then why are you using `Platform.runLater(...)` if you are already on the FX Application Thread? And this also means your `Thread.sleep(...)` is on the FX Application Thread, which you must not do. Or have I misinterpreted the context? – James_D Dec 08 '15 at 16:27
  • FWIW I pasted the code into a context in which it would work (i.e. defined a bunch of `static` variables of the appropriate type), and the `Platform.runLater(...)` compiled just fine. I assume `sleep(5000);` is `Thread.sleep(5000);`. But executing `Platform.runLater(displayFileTask);` and then `displayFileTask.get();` from the FX Application Thread would surely result in deadlock. – James_D Dec 08 '15 at 16:36
  • James_D: Thanks for your help. I will answer your Q's above where I have more room to be clearer. – sgroen Dec 08 '15 at 16:51
  • @kleopatra: What does SSCCE stand for? – sgroen Dec 08 '15 at 18:11
  • @James_D Yes, I'm using Thread.sleep(5000). What does FWIW I stand for? I posted detailed answers to your under Edit; I hope there clear enough. Thanks again. – sgroen Dec 08 '15 at 18:21
  • "FWIW" = "For what it's worth" – James_D Dec 08 '15 at 18:24
  • @sgroen Usually a "cannot be resolved" error has to do with library imports. Have you correctly imported to class? Can you create a simple example that I could run if I had the javafx dependency? – John Vint Dec 08 '15 at 20:41
  • [Short, Self Contained, Correct Example: SSCCE](http://sscce.org), and the StackOverflow equivalent: [Minimal, Complete and Verifiable Example MCVE](http://stackoverflow.com/help/mcve). – jewelsea Dec 08 '15 at 23:56
  • @jewelsea: I have a new post using pseudo code which should clarify the question and solution. I have admired your many well constructed answers and would really appreciate your answer as I'm desperate. (see [link](http://stackoverflow.com/questions/34190772/how-avoid-thread-sleep-in-a-for-loop-from-interrupting-the-ui-thread) How to avoid Thread.sleep() in a for loop from interrupting the UI Thread – sgroen Dec 09 '15 at 23:26

0 Answers0