基本的に、データベースからimageViewに画像をロードするメソッドと、画像を変更する2番目のメソッドがあります。例外を取得せずに両方のメソッドを正常に実行していますが、changeImage()メソッドのsetImageの後に、何を更新する必要があり、どのように更新する必要がありますか(シーン、ステージ)全然可能です。 javafxのswingにrepaint()のようなメソッドがないことを知っているので、これにどのようにアプローチしますか?
public class MainMenuController implements Initializable {
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
private AnchorPane stck1;
@FXML
private AnchorPane openSecondWindow(ActionEvent event) throws Exception {
GUIController ctrl = new GUIController();
Stage stage = new Stage();
setStck1((AnchorPane) FXMLLoader.load(InteractiveFictionGame2.class.getResource("GUI.fxml")));
ImageView img_1 = new ImageView(ctrl.loadImg().getImage());
img_1.setPreserveRatio(true);
img_1.setSmooth(true);
img_1.setCache(true);
getStck1().getChildren().add(img_1);
Scene scene = new Scene(getStck1());
stage.setTitle("Interactive Fiction Game");
stage.setScene(scene);
stage.setFullScreen(true);
// stage.sizeToScene();
stage.show();
return getStck1();
}
public class GUIController implements Initializable {
@FXML
private TabPane tb1;
/**
* Initializes the controller class.
*
* @param url
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
// TODO
}
@FXML
private ImageView img_1;
public ImageView loadImg() {
try {
con = DriverManager.getConnection(Host, unm, pswrd);
stmnt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
rs = stmnt.executeQuery(SQL);
rs.next();
fis = rs.getBinaryStream(4);
imgt = javax.imageio.ImageIO.read(fis);
Image newImg = SwingFXUtils.toFXImage(imgt, null);
img_1 = new ImageView();
img_1.setImage(newImg);
rs.close();
stmnt.close();
con.close();
} catch (Exception e) {
System.out.println("Not working");
}
return img_1;
}
public void changeImage() {
..
fis = rs.getBinaryStream(1);
imgt = javax.imageio.ImageIO.read(fis);
Image newImg = SwingFXUtils.toFXImage(imgt, null);
img_1.setImage(newImg);
...
} catch (Exception e) {
System.out.println("Not working");
}
return img_1;
}
あなたの問題
@FXML
を使用して挿入するメンバーノードがコントローラーにある場合は、new
コンストラクターを使用して新しいオブジェクトインスタンスを作成し、その新しいオブジェクトを既存の参照に割り当てないでください。代わりに、作成したFXMLでオブジェクトを使用してください。
あなたが持っている:
@FXML
private ImageView img_1;
それはいいです。次に、loadImgには、次のものがあります。
img_1 = new ImageView();
img_1.setImage(newImg);
それは悪いです。 FXMLドキュメントをロードしたときにFXMLLoaderが作成したImageViewがすでにあります。次に、FXMLローダーは、img_1
アノテーションを使用したため、そのImageViewを@FXML
参照に割り当てました。
修正方法
したがって、必要なのは、新しいImageViewの作成を停止し、次のように記述することだけです。
img_1.setImage(newImg);
これで完了です。
なぜ機能するのか
ImageViewのImageプロパティは、監視可能なプロパティです。 JavaFXシステムは、変更がないかImageプロパティを監視し、変更された場合は、ImageViewの画面に表示されている画像を自動的に更新します。再描画呼び出しを実行する必要はありません(どのような場合でも呼び出すような再描画ルーチンはありません)。
背景資料
JavaFXシーングラフアーキテクチャをよりよく理解したい場合は、Oracleチュートリアルをお読みください。
いくつかのヒント
免責事項
ここで指摘されている問題の他に、提供していないコードに他のエラーがあり、アプリケーションを希望どおりに動作させることができない場合があります。
Java私はここで卒業します:
JavaFX用語プロジェクトでは、setOnActionイベント(ボタンをクリック)時にimageViewオブジェクトを更新する必要がありました。これにより、プログラムユーザーは一連の画像をクリックすることができました。
以下はうまくいきました:
最初にImageインスタンスとImageViewインスタンスを作成します。
Image imageObject = new Image();
ImageView imageViewObject = new ImageView();
次に、コード内でボタンイベントを実行すると、(次の)画像が次のように割り当てられて更新されます。
btn.setOnAction(e -> {
imageIndex++;
imageFilename = imageNamesArray.get(imageIndex);
imageObject = new Image(imageFilename);
imageViewObject.setImage(imageObject);
}
注:私のプロジェクトのファイル名は、ArrayList()の文字列要素として保存されたjpgファイル(名前)です。ボタンをクリックすると、配列インデックスが次のjpgファイル名(およびパスまたはURL)にインクリメントされ、新しい画像が表示されます。したがって、前述の回答のように、ImageViewObjectを1つだけ作成しますが、毎回新しい画像を画像オブジェクト「imageObject」に再割り当てします。