JavaFX ImageView不在BorderLayout中显示Image

时间:2014-12-01 15:38:56

标签: java multithreading image javafx

我是一个包含View的BorderLayout。在左侧和右侧有两个ImageView。我通过另一个线程的ObejctProperty设置图像。 TypedImage只是javaFXs Image的一个容器。

@Override
public void changed(ObservableValue<? extends TypedImage> observable,
        TypedImage oldValue, 
        TypedImage newValue) {
    switch (newValue.getTyp()) {
    case TYPE1:
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                imageView1.setImage(newValue.getImage());
            }
        });
    case TYPE2:
        Platform.runLater(new Runnable() {
            @Override
            public void run() {
                imageView2.setImage(newValue.getImage());
            }
        });
        break;
    default:
        break;
    }
}

更改的方法是正常调用两次,因为Listener正在侦听两个ObjectProperties。当第一次调用方法时,匹配的ImageView(取决于类型)会更新,并在UI中显示图像。当第二个属性第二次调用方法时,第二个ImageView。从第一点开始,最后更新的ImageView在UI中显示图像,第一个更新的ImageView不可见或为空。有人可以帮助我理解和解决这个问题吗?

Java的Implementaion

public class MainApp extends Application {
  private ObjectProperty<TypedImage> image1 = new SimpleObjectProperty<TypedImage>();
  private ObjectProperty<TypedImage> image2 = new SimpleObjectProperty<TypedImage>();

  public vois start(){
    [..]
    image1.addListener(mainView.getController());
    image2.addListener(mainView.getController());
    {
      Image1Drawer drawer = new Image1Drawer();
      drawer.setParent(this);
      Thread t = new Thread(drawer);
      t.start();
    }
    {
      Image2Drawer drawer = new Image2Drawer();
      drawer.setParent(this);
      Thread t = new Thread(drawer);
      t.start();
    }
    [..]
  }

  public void notifyDrawerFinish(AbstractDrawer source, TypedImage img){
    if(source instanceof Image1Drawer){ image1.setValue(img); }
    if(source instanceof Image2Drawer){ image2.setValue(img); }
  }
}

/**
  * extended by Image1Drawer and Image2Drawer, run-methode draws stuff on image
  */
public abstract class AbstractDrawer implements Runable {
  private MainApp parent;
  private void fireFinish(TypedImage img){
    mainApp.notifyDrawerFinish(this,img);
  }
  public void setParent(MainApp parent){ 
    this.parent = parent; 
  }
}

public class MianViewController implements Initializable, ChangeListener {
  @FXML
  private ImageView imageView1;
  @FXML
  private ImageView imageView2;

  [..]
  public void changed(ObservableValue<? extends TypedImage> observable,
        TypedImage oldValue, 
        TypedImage newValue) {
    /* see above */
  }
  [..]
}

FXML

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity"
    minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0"
    prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="org.nemo.view.MainViewController">>
    <left>
        <ImageView fx:id="imageView1" fitHeight="600.0" fitWidth="50.0"
            pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
    </left>
    <right>
        <ImageView fx:id="imageView2" fitHeight="600.0" fitWidth="50.0"
            pickOnBounds="true" preserveRatio="true" BorderPane.alignment="CENTER" />
    </right>
</BorderPane>

1 个答案:

答案 0 :(得分:0)

尝试将控制器的路径放在FXML文件中。我想你错过了:

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity"
minHeight="-Infinity" minWidth="-Infinity" prefHeight="600.0"
prefWidth="800.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="YOUR_PACKAGE_NAME.MianViewController">