imagen - javafx imageview set image url
JavaFX: obtenga la imagen de un ImageView y asÃgnelo a otro ImageView (1)
Estoy haciendo una aplicación que el usuario al hacer clic en una imagen (ImageView1) puede ver en otra ImageView2. así que trato de obtener la imagen de ImageView1 en una variable
BufferedImage img= SwingFXUtils.fromFXImage(ImageView1.getImage(), null);
Y luego asigne esa variable a ImageView2
ImageView2.setImage(SwingFXUtils.toFXImage(img, null));
Pero parece, sin embargo, setImage se hace con éxito, pero ImageView2 no muestra nada. ¿alguien puede ayudarme a encontrar una mejor solución?
Aquí está el ejemplo de código: Controller. ImageView1
@FXML
private void HandleMousePressedOnImageOne()
{
BufferedImage img= SwingFXUtils.fromFXImage(ImageOne.getImage(), null);
try
{
ImageSelection imgSelection= ImageSelection.getImageSelectionInstance();
imgSelection.SetBufferedImageOne(img);
FXMLLoader loader= new FXMLLoader();
SplitPane p= loader.load(getClass().getResource("ImageSelection.fxml").openStream());
ImageSelectionController imgSelectionController= (ImageSelectionController)loader.getController();
imgSelectionController.HandleImageOne();
System.out.println("Image One has been Pressed!");
}
catch(Exception e)
{
e.printStackTrace();
}
}
Model.ImageSelection
public class ImageSelection {
private BufferedImage bufferedImageOne;
private static ImageSelection imageSelectionInstace= new ImageSelection();
private ImageSelection(){}
public static ImageSelection getImageSelectionInstance()
{
return imageSelectionInstace;
}
public void SetBufferedImageOne(BufferedImage img)
{
this.bufferedImageOne= img;
}
public BufferedImage getBufferedImageOne()
{
return this.bufferedImageOne;
}
}
Controller2.ImageView2
public void HandleImageOne(){
ImageSelection imgSelection= ImageSelection.getImageSelectionInstance();
BufferedImage img= imgSelection.getBufferedImageOne();
ImageOne.setImage(SwingFXUtils.toFXImage(img, null));
}
Su código no funciona porque está cargando una nueva copia de la interfaz de usuario definida en el archivo ImageSelection.fxml
. No muestra esta nueva copia. Cuando recupera el controlador del cargador que carga esa copia de la interfaz de usuario y llama
imgSelectionController.HandleImageOne();
Cambia la imagen en ImageView
que es parte de esa nueva instancia de la interfaz de usuario. Como esa instancia no se muestra, no verá ningún efecto de esa llamada.
Un mejor enfoque, que también evita que su primer controlador tenga una dependencia del segundo controlador como en su código, es crear un ObjectProperty<Image>
en su modelo y observarlo desde el segundo controlador:
public class ImageSelection {
private final ObjectProperty<Image> image = new SimpleObjectProperty<>();
private static ImageSelection imageSelectionInstance= new ImageSelection();
private ImageSelection(){}
public static ImageSelection getImageSelectionInstance() {
return imageSelectionInstance;
}
public ObjectProperty<Image> imageProperty() {
return image ;
}
public final void setImage(Image image) {
imageProperty().set(image);
}
public final Image getImage()
{
return imageProperty().get();
}
}
y en el segundo controlador, hacer
public class ImageSelectionController {
@FXML
private ImageView imageOne ;
public void initialize() {
ImageSelection.getImageSelectionInstance().imageProperty()
.addListener((obs, oldImage, newImage) -> imageOne.setImage(newImage));
}
// ...
}
Ahora todo lo que el primer controlador necesita hacer es establecer la imagen en el modelo:
@FXML
private void handleMousePressedOnImageOne() {
ImageSelection.getImageSelectionInstance().setImage(imageOne.getImage());
}
Tenga en cuenta que no es necesario convertir desde una imagen JavaFX a una Imagen BufferedImage
y viceversa.
También recomiendo no utilizar un patrón singleton, por varias razones (bien documentadas, solo google "qué pasa con el uso de singletons"). Cree una única instancia y páselo a cada uno de los controladores, o use un marco de inyección de dependencias para administrarlo por usted.