动态更改线程中imageview的图像

时间:2014-08-17 00:59:20

标签: multithreading image dynamic javafx-2

应用

我试图在我的JavaFX应用程序中创建幻灯片放映。为此,我创建了一个线程并处理该线程内的图像更改。我在线程中使用Thread.sleep(int)来暂停图像之间的转换。

实施

我在Scene Builder中创建了应用程序,因此它在FXML中。 imageview以图像开始,我给了imageview一个id。以下是imageview所在的FXML的一部分:

<Tab>
  <content>
    <AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="376.0" prefWidth="981.0">
           <children>
              <ImageView fx:id="myImage" fitHeight="197.0" fitWidth="294.0" layoutX="20.0" layoutY="151.0" pickOnBounds="true" preserveRatio="true">
                 <image>
                    <Image url="@../Pictures/NevadaDesert.jpg" />
                 </image>
                 <effect>
                    <Glow />
                 </effect>
              </ImageView>

我在我的Java代码中获取了imageview:

@FXML
private ImageView myImage;

然后我处理加载FXML后调用的新runnable线程内的所有图像更改:

@Override
public void start(Stage stage) throws Exception {

    Parent root = FXMLLoader.load(getClass().getResource("MyResume.fxml"));

    Scene scene = new Scene(root);

    stage.setScene(scene);
    stage.show();

    (new Thread(new PictureRunnable())).start();

}

PictureRunnable的run方法如下所示:

public void run() {

        try {


        File file1 = new File("C:/Users/Kyle/Documents/NetBeansProjects/MyResume/src/Pictures/activities.jpg");
        File file2 = new File("C:/Users/Kyle/Documents/NetBeansProjects/MyResume/src/Pictures/foodService2.png");
        File file3 = new File("C:/Users/Kyle/Documents/NetBeansProjects/MyResume/src/Pictures/NevadaDesert.jpg");

        Image a = new Image(file1.toURI().toURL().toExternalForm());
        Image b = new Image(file2.toURI().toURL().toExternalForm());
        Image c = new Image(file3.toURI().toURL().toExternalForm());

        for(int i=0; true; i++) {

    //Pause for 5 seconds
        try {
                Thread.sleep(5000);
    } catch (InterruptedException e) {
                e.printStackTrace();
    }

            if( i%2 == 0 )
                myImage.setImage(a);
            else if( i%3 == 0 )
                myImage.setImage(b);
            else
                myImage.setImage(c);
        }

        }
        catch(MalformedURLException e) {
            e.printStackTrace();
        }
    }

问题:

我在设置图片myImage.setImage(abc)的行上得到NullPointerException。

  • 我的代码中是否存在我如何更改图片的问题?

  • 或者问题是线程,也许我无法打开新线程并对舞台进行更改?

2 个答案:

答案 0 :(得分:0)

如果你想在imageView上设置一个图像,它必须在javafx线程上:使用你的线程或其他机制中的Platform.runLater()。

我刚注意到我的简单幻灯片帖子在其历史记录中有一些点击 - 抱歉它有一些错误,java8的最终版本改变了它在动画中处理空指针的方式。我修复了这些错误并更新了帖子。

(我注意到了)

答案 1 :(得分:0)

仅使用Java

package sample;

import java.util.ArrayList;
import java.util.List;
import javafx.application.*;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.stage.*;
import javafx.scene.*;
import javafx.scene.Cursor;
import java.lang.String;
import javafx.scene.layout.*;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.geometry.*;
import javafx.scene.paint.ImagePattern;
import javafx.scene.effect.DropShadow;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import com.jfoenix.controls.JFXButton;



public class Main extends Application {

    public static void main(String[] args) {
        launch(args);
    }

    private List<String> list = new ArrayList<String>();
    int j = 0;
    JFXButton lbutton, rButton;
    ImageView imageView;

    @Override
    public void start(Stage primaryStage) {

        // images in src folder.
        try {
            list.add("/image/1.jpg");
            list.add("/image/2.jpg");
            list.add("/image/3.jpg");
            list.add("/image/4.jpg");
            list.add("/image/5.jpg");
            list.add("/image/6.jpg");
            list.add("/image/7.jpg");
            list.add("/image/8.jpg");

            GridPane root = new GridPane();
            root.setAlignment(Pos.CENTER);

            lbutton = new JFXButton("<");
            rButton = new JFXButton(">");

            Image images[] = new Image[list.size()];
            for (int i = 0; i < list.size(); i++) {
                images[i] = new Image(list.get(i));
            }

            imageView = new ImageView(images[j]);
            imageView.setCursor(Cursor.CLOSED_HAND);

            rButton.setOnAction(e -> {
                System.out.print("hello");
                j++;
                if (j > list.size()-1)
                {
                    j = list.size()-1;
                    imageView.setImage(images[j]);
                }
                else
                {
                    imageView.setImage(images[j]);
                }
            });

            lbutton.setOnAction(e -> {
                System.out.print("hello");
                j--;
                if (j < 0)
                {
                    j = 0;
                    imageView.setImage(images[j]);
                }
                else
                {
                    imageView.setImage(images[j]);
                }
            });

            imageView.setFitHeight(350);



          //main controls
          AnchorPane pane = new AnchorPane(imageView, rButton, lbutton);
          AnchorPane.setTopAnchor(lbutton, 300.0);
          AnchorPane.setLeftAnchor(lbutton, 210.0);
          AnchorPane.setTopAnchor(rButton, 300.0);
          AnchorPane.setRightAnchor(rButton, 210.0);

          // Set the stage
          Scene scene = new Scene(pane, 600, 600);
          imageView.fitWidthProperty().bind(scene.widthProperty());
          primaryStage.setScene(scene);
          primaryStage.setResizable(false);
          primaryStage.setTitle("Sample");
          primaryStage.show();

    } catch (Exception e) {
        e.printStackTrace();
    }
  }
}