Wait() & Sleep() Not Working As Thought

牧云@^-^@ 提交于 2019-12-31 05:26:15

问题


Using JavaFX 8.0 and JRE 1.8.0 u45 in IntelliJ, I created a basic pixel editor app. I have two windows(stages). One is a 32x128 matrix of Circle Objects placed in a Grid Pane and the other, a Tools widow; I have one Controller.java. Using the mouse, the Tools window provides tools to draw lines, rectangles, etc. and a menu for Setup, Files and Playlists. The Files menu presents the user with Open, SaveAs and Delete. To view a saved pixel art file, the user clicks Open and via the JFileChooser, the selected file is opened and each Circle’s assigned color is displayed using the following method:

public static void openFile( String pathName) throws IOException {

    path = Paths.get(pathName);
    pixelByteArray = Files.readAllBytes(path);

    int cnt = 0;
    for (int r = 0; r < row; r++) {
        for (int c = 0; c < col; c++) {

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

            Color color = Color.valueOf(hexRGB);

            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));

} // openFile

The Circle’s color is updated with for loops using setFill(color).

Next I created a class to test a basic slide show. I would use JFileChooser to select multiple files, put them in an ArrayList<file> and use the openFile(pathname) in a for loop to display each, pausing 5 secs between each openFile(pathname) as shown below:

public class PlayPlaylist {

public static void playPlaylist() throws IOException, InterruptedException {

    FileChooser fileChooser = new FileChooser();
    fileChooser.setInitialDirectory(new File("C:\\ProgramData\\L1 Art Files\\"));
    fileChooser.setTitle("Play One or More Pixel Art Files");
    java.util.List<File> selectedFiles = fileChooser.showOpenMultipleDialog(null);

   for (File selectedFile : selectedFiles) {
       openFile(selectedFile.getPath());
       sleep(5000);
   }
} //Method playPlaylist()

I first used wait(5000) but couldn’t compile because I have a static method, which I need. The wait() method won’t run in a static method. I then tried sleep(5000) which compiles but to my confusion only the last file in the ArrayList<file> will be displayed. All the pixel art files will display the setTitle() correctly and pause for about 5 secs but the Circle’s will not change to the assigned color except for the last file, after the 5 secs have passed. The for loop, setFill(color) process in openFile() seems to be paused even though the setTitle() is executed correctly, which is after the setFill(color) process?

I’m new to Java and JavaFX and have never created any threads directly in this program or any other but researching possible problems implies the problem may be related to threads.

Is there a classic fix to this problem? Thanks for any help

After studying the references and suggested solutions below, I am unable to fix the problem. I tried two code changes. The first was to the for loop code above:

for (File selectedFile : selectedFiles) {
       Platform.runLater(() -> {
           try {
               openFile(selectedFile.getPath());
               try {
                   sleep(5000);
               } catch (InterruptedException e) {
                   e.printStackTrace();
               }
           } catch (IOException e) {
               e.printStackTrace();
           }
       });

The second change was to the openFile(pathname) above:

final int finalR = r;
final int finalC = c;
Platform.runLater(() -> pixelArray[finalR][finalC].setFill(color));

I get the same results as described above with only the last file being displayed. If I simply select one file in the Arraylist<File> it will display, i.e.:

if (selectedFiles != null) {
        File playFile = selectedFiles.get(0);
        openFile(playFile.getPath());
        System.out.println("\n File 1 = " + playFile.getPath());
 }

Now if I add Sleep(5000):

if (selectedFiles != null) {
        File playFile = selectedFiles.get(0);
        openFile(playFile.getPath());
        System.out.println("\n File 1 = " + playFile.getPath());
        sleep(5000);
    }

It will display the pixel art file after 5 secs. What I don't understand is why it appears to "skip" over the pixelArray[r][c].setFill(color)); which sets all the Circle's to the saved colors but does execute the following and last statement in the openFile(pathname) which is setTitle(...)? It's like sleep(5000) blocks the pixelArray[r][c].setFill(color));but nothing else?

Why can I openFile(pathname) for just one file with proper results but not two or more in sequence?

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.

***This question was answered elegantly by jewelsea at:

How to avoid Thread.sleep() in a for loop from interrupting the UI Thread?***


回答1:


You have two problems here, your understanding of wait(), and a GUI multithreading issue.

About the GUI multithreading... You will find more informations here about Platform.runLater(...):

Platform.runLater and Task in JavaFX

Now about Wait... It will pause your Thread until a Notify event is received through its monitor. To be able to call notify() you need to synchronize on the same object (the monitor).

synchronized (someObject) {
    someObject.wait();
}

/* different thread / object */
synchronized (someObject) {
    someObject.notify();
}

If you want to use Wait, you will need another Thread (a Timer?), to wakeup/notify you. Sleep should work fine in your case, as long as you use Platform.runlater(...)



来源:https://stackoverflow.com/questions/34003813/wait-sleep-not-working-as-thought

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!