2017-05-11 3 views
1

J'ai une classe appelée "AdjustmentBar" qui comprend une imageView, une barre de menu et quelques fonctions d'édition d'image (un fichier FXML et un contrôleur). AdjustmentBar est chargé dans une autre classe appelée "ExaminationDisplayer" (également un fichier FXML et un contrôleur). ExaminationDisplayer charge quelques images d'une base de données MySQL en ligne, et je veux que chacune de ces images soit affichée dans une imageView séparée.Javafx setImage pour ImageView d'un autre contrôleur FXML

J'ai été en mesure de charger le AdjustmentBar dans le ExaminationDisplayer, mais je ne peux pas comprendre comment setImage() de l'imageView qui est inclus dans AdjustmentBar. Je peux afficher une image de la base de données dans une vue d'image que je crée spécifiquement dans ExaminationDisplayer, et je peux afficher une image dans la vue AdjustmentBar si je l'exécute séparément. Je ne peux pas obtenir le AdjustmentBar chargé pour afficher l'image dans ExaminationDisplayer.

Quand je le lance, j'obtiens une erreur NullPointerException pour cette ligne de code: imgView.setImage (image), qui est dans le ExaminationDisplayerController:

public class ExaminationDisplayerController extends AdjustmentBarController { 
    @FXML 
    private void handlebtnFraminghamAction(ActionEvent event) throws IOException {showCardiacConditionEstimator(); } 
    @FXML 
    private AnchorPane anchorPane; 
    @FXML 
    private LineChart<Number, Number> lcChart; 
    @FXML 
    private NumberAxis xAxis; // x-Axis is defined 
    @FXML 
    private NumberAxis yAxis; //y-Axis is defined 

    public void initialize() throws ClassNotFoundException, SQLException, IOException { // Loading methods in ExaminationDisplayerController 
     SPECTLoad(); 
    } 

    public void showCardiacConditionEstimator() throws IOException { // Method for displaying CardiacConditionEstimator 
     Parent parent = FXMLLoader.load(getClass().getResource("/fxml/CardiacConditionEstimator.fxml")); //Reference to the fxml file 
     Stage stage = new Stage(); // creating a new stage 
     Scene scene = new Scene(parent); // creating a new scene for the file to be shown onto 
     stage.setScene(scene); // sets the scene on the stage 
     stage.show(); // Displaying the stage 
     stage.setMaximized(false); // maximizing the stage 
    } 

    public void SPECTLoad() throws SQLException, ClassNotFoundException { 
     DBConnection dbConn = new DBConnection(); 
     Connection conn = dbConn.connect(); 
     PreparedStatement pstmt = null; 

     try { 

      for (int numberOfExaminations = 0; numberOfExaminations < 3; numberOfExaminations++) { 

       String[] ID = {"1111", "1112", "1113"}; 
       List<String> chosenExaminations = Arrays.asList(ID); 
       String SQL = "SELECT `IMAGE` FROM `SPECT` WHERE `ID` = ?;"; 
       pstmt = conn.prepareStatement(SQL); 

       pstmt.setString(1, chosenExaminations.get(numberOfExaminations)); 

       ResultSet rs = pstmt.executeQuery(); 

       while (rs.next()) { 
        InputStream is = rs.getBinaryStream("IMAGE"); 
        OutputStream os = new FileOutputStream(new File("SPECT_IMAGE.jpg")); 

        byte[] content = new byte[1024]; 
        int size = 0; 
        while ((size = is.read(content)) != -1) { // Når inputstream er real passer den et -1 værdi og så stoppes loopet 
         os.write(content, 0, size); 
        } 
        os.close(); 
        is.close(); 

        Image image = new Image(new File("SPECT_IMAGE.jpg").toURI().toString(), 200, 200, true, true); 

        anchorPane.getChildren().add(FXMLLoader.load(getClass().getResource("/fxml/AdjustmentBar.fxml"))); 
        imgView.setImage(image); 
       } 
      } 

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

Voici le code pour AdjustmentBarController:

public class AdjustmentBarController { 

    @FXML 
    private AnchorPane AnchorPane; 
    @FXML 
    private ScrollPane ScrollPane; 
    @FXML 
    public ImageView imgView; 
    @FXML 
    private Slider contrastAdjuster; 
    @FXML 
    private ToggleButton btnMeasure; 
    @FXML 
    private Pane imgContainer; 
    @FXML 
    private Label txtLabel; 

    @FXML 
    private void btnZoomInAction(ActionEvent event) {...} 

    @FXML 
    private void btnZoomOutAction(ActionEvent event) {...} 

    @FXML 
    private void btnRotateRightAction(ActionEvent event) {...} 

    @FXML 
    private void btnRotateLeftAction(ActionEvent event) {...} 

    /** 
    * Initializes the controller class. 
    * 
    * @param url 
    * @param rb 
    */ 
    public void initialize(URL url, ResourceBundle rb 
    ) { 
     contrastAdjuster.valueProperty().addListener((observable, oldValue, newValue) -> { 
      double value = contrastAdjuster.getValue(); 
      ColorAdjust colorAdjust = new ColorAdjust(); 
      colorAdjust.setContrast(value); 
      imgView.setEffect(colorAdjust); 
     }); 
    } 
} 

Je ne sais pas si le fichier FXML pour AdjustmentBar est pertinente, mais voilà:

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

<?import javafx.geometry.Insets?> 
<?import javafx.scene.control.Button?> 
<?import javafx.scene.control.Label?> 
<?import javafx.scene.control.ScrollPane?> 
<?import javafx.scene.control.Slider?> 
<?import javafx.scene.control.ToggleButton?> 
<?import javafx.scene.image.Image?> 
<?import javafx.scene.image.ImageView?> 
<?import javafx.scene.layout.AnchorPane?> 
<?import javafx.scene.layout.BorderPane?> 
<?import javafx.scene.layout.HBox?> 
<?import javafx.scene.layout.Pane?> 

<AnchorPane id="AnchorPane" prefHeight="435.0" prefWidth="435.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="Multimodality.controller.AdjustmentBarController"> 
    <children> 
     <BorderPane prefHeight="435.0" prefWidth="435.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0"> 
     <center> 
      <ScrollPane fx:id="ScrollPane" pannable="true" prefHeight="435.0" prefWidth="435.0" BorderPane.alignment="CENTER"> 
       <content> 
        <Pane fx:id="imgContainer"> 
        <children> 
          <ImageView fx:id="imgView" fitHeight="400.0" fitWidth="400.0" nodeOrientation="INHERIT" pickOnBounds="true" preserveRatio="true" /> 
         <Label fx:id="txtLabel" alignment="TOP_LEFT" layoutX="336.0" layoutY="-1.0" prefHeight="134.0" prefWidth="75.0" wrapText="true" /> 
        </children> 
        </Pane> 
       </content> 
      </ScrollPane> 
     </center> 
     <bottom> 
      <HBox alignment="CENTER" prefHeight="35.0" prefWidth="435.0" spacing="8.0" BorderPane.alignment="CENTER"> 
       <children> 
         <Button fx:id="btnZoomOut" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#btnZoomOutAction" prefHeight="25.0" prefWidth="25.0"> 
          <graphic> 
           <ImageView fitHeight="20.0" fitWidth="20.0" preserveRatio="true"> 
            <image> 
             <Image url="/img/icon_zoomout.png" /> 
            </image> 
           </ImageView> 
          </graphic> 
         </Button> 
         <Button fx:id="btnZoom100" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#btnZoom100Action" prefHeight="25.0" prefWidth="25.0"> 
          <graphic> 
           <ImageView fitHeight="20.0" fitWidth="20.0" preserveRatio="true"> 
            <image> 
             <Image url="/img/icon_fit.png" /> 
            </image> 
           </ImageView> 
          </graphic> 
         </Button> 
         <Button fx:id="btnZoomIn" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#btnZoomInAction" prefHeight="25.0" prefWidth="25.0"> 
          <graphic> 
           <ImageView fitHeight="20.0" fitWidth="20.0" preserveRatio="true"> 
            <image> 
             <Image url="/img/icon_zoomin.png" /> 
            </image> 
           </ImageView> 
          </graphic> 
         </Button> 
         <Button fx:id="btnRotateRight" contentDisplay="CENTER" graphicTextGap="0.0" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#btnRotateRightAction" prefHeight="25.0" prefWidth="25.0"> 
          <graphic> 
           <ImageView fitHeight="20.0" fitWidth="20.0" preserveRatio="true"> 
            <image> 
             <Image url="/img/shape_rotate_clockwise.png" /> 
            </image> 
           </ImageView> 
          </graphic> 
         </Button>  
         <Button fx:id="btnRotateLeft" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#btnRotateLeftAction" prefHeight="25.0" prefWidth="25.0"> 
          <graphic> 
           <ImageView fitHeight="20.0" fitWidth="20.0" preserveRatio="true"> 
            <image> 
             <Image url="/img/shape_rotate_anticlockwise.png" /> 
            </image> 
           </ImageView> 
          </graphic> 
         </Button> 
        <ToggleButton fx:id="btnMeasure" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#btnMeasureAction" prefHeight="25.0" prefWidth="25.0"> 
        <graphic> 
         <ImageView fitHeight="20.0" fitWidth="20.0" preserveRatio="true"> 
          <image> 
           <Image url="/img/ruler.png" /> 
          </image> 
         </ImageView> 
        </graphic> 
        </ToggleButton> 
        <ImageView fitHeight="20.0" fitWidth="20.0" preserveRatio="true"> 
        <image> 
         <Image url="/img/contrast.png" /> 
        </image> 
        <HBox.margin> 
         <Insets left="8.0" right="-2.0" /> 
        </HBox.margin> 
        </ImageView> 
         <Slider fx:id="contrastAdjuster" blockIncrement="0.1" majorTickUnit="0.5" max="1.0" min="-1.0" minorTickCount="4" prefHeight="24.0" prefWidth="128.0" showTickMarks="true" /> 
       </children> 
       <BorderPane.margin> 
        <Insets /> 
       </BorderPane.margin> 
      </HBox> 
     </bottom> 
     </BorderPane> 
    </children> 
</AnchorPane> 

Enfin mais surtout, voici le NullPointerException je reçois si je lance le code:

java.lang.NullPointerException 
    at Multimodality.controller.ExaminationDisplayerController.SPECTLoad(ExaminationDisplayerController.java:224) 
    at Multimodality.controller.ExaminationDisplayerController.initialize(ExaminationDisplayerController.java:86) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) 
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2566) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:2441) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3214) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3175) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3148) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3124) 
    at javafx.fxml.FXMLLoader.loadImpl(FXMLLoader.java:3104) 
    at javafx.fxml.FXMLLoader.load(FXMLLoader.java:3097) 
    at Multimodality.controller.ExaminationOverviewController.showExaminationDisplayer(ExaminationOverviewController.java:352) 
    at Multimodality.controller.ExaminationOverviewController.btnChooseExaminationsAction(ExaminationOverviewController.java:341) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.reflect.misc.Trampoline.invoke(MethodUtil.java:71) 
    at sun.reflect.GeneratedMethodAccessor1.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at sun.reflect.misc.MethodUtil.invoke(MethodUtil.java:275) 
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1769) 
    at javafx.fxml.FXMLLoader$ControllerMethodEventHandler.handle(FXMLLoader.java:1657) 
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:86) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:49) 
    at javafx.event.Event.fireEvent(Event.java:198) 
    at javafx.scene.Node.fireEvent(Node.java:8413) 
    at javafx.scene.control.Button.fire(Button.java:185) 
    at com.sun.javafx.scene.control.behavior.ButtonBehavior.mouseReleased(ButtonBehavior.java:182) 
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:96) 
    at com.sun.javafx.scene.control.skin.BehaviorSkinBase$1.handle(BehaviorSkinBase.java:89) 
    at com.sun.javafx.event.CompositeEventHandler$NormalEventHandlerRecord.handleBubblingEvent(CompositeEventHandler.java:218) 
    at com.sun.javafx.event.CompositeEventHandler.dispatchBubblingEvent(CompositeEventHandler.java:80) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:238) 
    at com.sun.javafx.event.EventHandlerManager.dispatchBubblingEvent(EventHandlerManager.java:191) 
    at com.sun.javafx.event.CompositeEventDispatcher.dispatchBubblingEvent(CompositeEventDispatcher.java:59) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:58) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.BasicEventDispatcher.dispatchEvent(BasicEventDispatcher.java:56) 
    at com.sun.javafx.event.EventDispatchChainImpl.dispatchEvent(EventDispatchChainImpl.java:114) 
    at com.sun.javafx.event.EventUtil.fireEventImpl(EventUtil.java:74) 
    at com.sun.javafx.event.EventUtil.fireEvent(EventUtil.java:54) 
    at javafx.event.Event.fireEvent(Event.java:198) 
    at javafx.scene.Scene$MouseHandler.process(Scene.java:3757) 
    at javafx.scene.Scene$MouseHandler.access$1500(Scene.java:3485) 
    at javafx.scene.Scene.impl_processMouseEvent(Scene.java:1762) 
    at javafx.scene.Scene$ScenePeerListener.mouseEvent(Scene.java:2494) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:381) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:295) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:417) 
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:416) 
    at com.sun.glass.ui.View.handleMouseEvent(View.java:555) 
    at com.sun.glass.ui.View.notifyMouse(View.java:937) 
    at com.sun.glass.ui.win.WinApplication._runLoop(Native Method) 
    at com.sun.glass.ui.win.WinApplication.lambda$null$148(WinApplication.java:191) 
    at java.lang.Thread.run(Thread.java:745) 

BUILD SUCCESSFUL 

Total time: 52.909 secs 

J'espère que certains d'entre vous peut me aider! Merci d'avance :-)

+0

Deux déclarations me confondez - « AdjustmentBar est chargé dans une autre classe appelée "ExaminationDisplayer" et "J'ai été en mesure de charger le AdjustmentBar dans le ExaminationDisplayer"? Aussi, je peux voir que votre ExaminationDisplaye rController étend AdjustmentBarController mais cela ne semble pas correct. Pouvez-vous nous éclairer sur ce que vous essayez d'accomplir ici? – ItachiUchiha

+0

@ItachiUchiha Salut! Oui, ExaminationDisplayer charge les images à partir d'une base de données et doit les afficher dans une imageView.Cependant, je ne veux pas que ce soit juste un ImageView normal, plutôt ce devrait être celui que j'ai conçu dans AdjustmentBar - parce que celui-ci a également une barre d'outils qui me permet le zoom/rotation/ajuster le contraste pour chaque ImageView . Je n'ai pas pu appeler imgView (qui est le fixID de ImageView of AdjustmentBar) à moins d'avoir ajouté la commande "extend" - mais peut-être que ce n'est pas correct du tout. J'espère que cela a du sens! J'ai également ajouté l'erreur que je reçois à la poste. :-) – Heidi

+0

@ItachiUchiha C'est, j'ai un fichier FXML appelé ExaminationDisplayer qui charge/ouvre/affiche un autre fichier FXML appelé AdjustmentBar. Le nombre d'AdjustmentBar-ImageViews à charger dépend du nombre de photos que je veux afficher à la fois. Ce pourrait être seulement un, mais habituellement ce sera trois ou quatre. – Heidi

Répondre

2

Chaque fois que vous avez une exigence et que vous devez faire vos contrôles public, c'est une odeur de code. N'exposez jamais vos nœuds d'interface utilisateur.

La meilleure façon d'y parvenir serait d'ajouter une méthode dans le AdjustmentBarController pour accepter une image. Cette méthode définirait alors cette image dans ImageView définie dans le contrôleur.

public class AdjustmentBarController { 

    ... 

    @FXML 
    private ImageView imgView; 
    ... 
    public void setImage(Image image) { 
     imgView.setImage(image); 
    } 
} 

Maintenant, une fois cela fait. N'étendez pas le ExaminationDisplayerController de AdjustmentBarController.

Pour chaque image que vous chargez dans ExaminationDisplayerController, chargez le fichier FXML pour AdjustmentBar, récupérez le contrôleur à partir du FXMLLoader et définissez l'image dans le contrôleur.

// Do not extend from AdjustmentBarController 
public class ExaminationDisplayerController { 

    ... 

    public void SPECTLoad() throws SQLException, ClassNotFoundException { 
     DBConnection dbConn = new DBConnection(); 
     ... 
     Image image = new Image(new File("SPECT_IMAGE.jpg").toURI().toString(), 200, 200, true, true); 
     FXMLLoader loader = new FXMLLoader(getClass().getResource("/fxml/AdjustmentBar.fxml")); 
     AnchorPane anchorPaneFromAdjustmentBar = loader.load(); 
     anchorPane.getChildren().add(anchorPaneFromAdjustmentBar); 
     // Get the controller from the FXMLLoader 
     AdjustmentBarController controller = (AdjustmentBarController) loader.getController(); 
     // Set the image 
     controller.setImage(image); 
     ... 
    } 
} 

Pour plus d'informations, rendez-vous par:

+0

Merci, ça aide beaucoup! J'ai essayé de charger un fichier image existant de mon projet avec votre code et cela fonctionne parfaitement. Mais malheureusement, je ne peux toujours pas afficher le fichier SPECT_IMAGE.jpg. Je pense que ça doit être à cause d'autre chose, alors je vais faire un peu de recherche pour savoir ce qui ne va pas. Merci encore! – Heidi

+1

N'hésitez pas à poser d'autres questions dans les commentaires ci-dessous une fois que vous avez terminé votre recherche. – ItachiUchiha

+1

L'image @Heidi comporte [erreur] (https://docs.oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html#errorProperty) et [exception] (https: // docs. oracle.com/javase/8/javafx/api/javafx/scene/image/Image.html#exceptionProperty), essayez d'ajouter des écouteurs ou de les interroger pour voir s'il y a eu une erreur de chargement d'image. – jewelsea