2016-12-16 79 views
4

我試圖製作使用JavaFX的屏幕錄像機。當我看到this這篇文章時,我試着做出了一個真正喜歡的文章,於是我決定用它提供的代碼製作一個JavaFX FXML應用程序。無法在控制檯的主類中使用舞臺

@FXML 
void startOnAction(ActionEvent event) { 
    FXMLDocumentController FXML = new FXMLDocumentController(); 
    FXML.console.setText("######### Starting Screen Recorder #########"); 
    try { 
     Thread.sleep(250); 
    } catch (InterruptedException ex) { 
    } 
    Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); 
    FXML.console.appendText("Your Screen [Width, Height]: " + "[" + screen.getWidth() + "," + screen.getHeight() + "]\nWhen the Recording starts, this window will minimize, to stop them recording, open this window."); 
    try { 
     Thread.sleep(1000); 
    } catch (InterruptedException ex) { 
    } 
    FXML.console.appendText("The recording will start in 5 seconds"); 
    int num = 5; 
    for (int i = 0; i <= 5; i++) { 
     System.out.print(num); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
     } 
     num = num - 1; 
    } 
    FXML.console.appendText("Start!"); 
    File f = new File(store); 
    if (!f.exists()) { 
     f.mkdir(); 
    } 
    startRecord(); 
    Recorder R = new Recorder(); 
    R.stage.setIconified(true); 
    R.stage.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> { 
     focusState(newValue); 
    }); 
} 

這是一個FXMLDocumentController的方法,我想讓我的多行文本控件「控制檯」打印出來,我希望它打印出的文字的變量。

然而,所有的線,我利用的對象,這些FXMLDocumentController FXML = new FXMLDocumentController();Recorder R = new Recorder(); 存在錯誤。

以下是錯誤:127

Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774) 
    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.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.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:380) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416) 
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415) 
    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) 
Caused by: java.lang.reflect.InvocationTargetException 
    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) 
    ... 48 more 
Caused by: java.lang.NullPointerException 
    at recorder.FXMLDocumentController.startOnAction(FXMLDocumentController.java:127) 
    ... 58 more 

Line 127 is `Exception in thread "JavaFX Application Thread" java.lang.RuntimeException: java.lang.reflect.InvocationTargetException 
    at javafx.fxml.FXMLLoader$MethodHandler.invoke(FXMLLoader.java:1774) 
    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.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.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:380) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler$MouseEventNotification.run(GlassViewEventHandler.java:294) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.lambda$handleMouseEvent$354(GlassViewEventHandler.java:416) 
    at com.sun.javafx.tk.quantum.QuantumToolkit.runWithoutRenderLock(QuantumToolkit.java:389) 
    at com.sun.javafx.tk.quantum.GlassViewEventHandler.handleMouseEvent(GlassViewEventHandler.java:415) 
    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) 
Caused by: java.lang.reflect.InvocationTargetException 
    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) 
    ... 48 more 
Caused by: java.lang.NullPointerException 
    at recorder.FXMLDocumentController.startOnAction(FXMLDocumentController.java:127) 
    ... 58 more` 

行是這一行4,在我上面貼的代碼。


下面

的完整代碼...

主要類:

package recorder; 

import javafx.application.Application; 
import static javafx.application.Application.launch; 
import javafx.fxml.FXMLLoader; 
import javafx.scene.Parent; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 

public class Recorder extends Application { 

    public Stage stage; 

    @Override 
    public void start(Stage stage) throws Exception { 
     Parent root = FXMLLoader.load(getClass().getResource("FXMLDocument.fxml")); 

     Scene scene = new Scene(root); 
     stage.setResizable(false); 
     stage.setScene(scene); 
     stage.show(); 
    } 

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

} 

FXML文件:

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

<?import javafx.scene.control.Button?> 
<?import javafx.scene.control.TextArea?> 
<?import javafx.scene.control.TextField?> 
<?import javafx.scene.layout.ColumnConstraints?> 
<?import javafx.scene.layout.GridPane?> 
<?import javafx.scene.layout.RowConstraints?> 

<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="639.0" prefWidth="578.0" xmlns="http://javafx.com/javafx/8.0.60" xmlns:fx="http://javafx.com/fxml/1" fx:controller="recorder.FXMLDocumentController"> 
    <columnConstraints> 
     <ColumnConstraints hgrow="SOMETIMES" minWidth="578.0" prefWidth="578.0" /> 
    </columnConstraints> 
    <rowConstraints> 
     <RowConstraints maxHeight="1.7976931348623157E308" minHeight="10.0" prefHeight="95.0" vgrow="SOMETIMES" /> 
     <RowConstraints maxHeight="245.0" minHeight="9.0" prefHeight="12.0" vgrow="SOMETIMES" /> 
     <RowConstraints maxHeight="481.0" minHeight="10.0" prefHeight="478.0" vgrow="SOMETIMES" /> 
    </rowConstraints> 
    <children> 
     <Button fx:id="start" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" mnemonicParsing="false" onAction="#startOnAction" prefHeight="220.0" prefWidth="578.0" text="Start Recording" /> 
     <TextArea fx:id="console" editable="false" prefHeight="200.0" prefWidth="200.0" promptText="Console" wrapText="true" GridPane.rowIndex="2" /> 
     <TextField fx:id="input" prefHeight="105.0" prefWidth="578.0" promptText="File Name" GridPane.rowIndex="1" /> 
    </children> 
</GridPane> 

FXMLDocumentController(其中的代碼剪斷來自):

package recorder; 

import java.awt.Dimension; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.Toolkit; 
import java.awt.image.BufferedImage; 
import java.io.File; 
import java.io.FileNotFoundException; 
import java.io.FileOutputStream; 
import java.io.OutputStream; 
import java.net.MalformedURLException; 
import java.net.URL; 
import java.util.ResourceBundle; 
import java.util.Vector; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javafx.beans.value.ObservableValue; 
import javafx.event.ActionEvent; 
import javafx.fxml.FXML; 
import javafx.fxml.Initializable; 
import javafx.scene.control.Button; 
import javafx.scene.control.TextArea; 
import javafx.scene.control.TextField; 
import javax.imageio.ImageIO; 
import javax.media.MediaLocator; 
import javax.swing.JOptionPane; 

public class FXMLDocumentController implements Initializable { 

    File file; 
    /** 
    * Screen Width. 
    */ 
    public static int screenWidth = (int) Toolkit.getDefaultToolkit() 
      .getScreenSize().getWidth(); 

    /** 
    * Screen Height. 
    */ 
    public static int screenHeight = (int) Toolkit.getDefaultToolkit() 
      .getScreenSize().getHeight(); 

    /** 
    * Interval between which the image needs to be captured. 
    */ 
    public static int captureInterval = 50; 

    /** 
    * Temporary folder to store the screenshot. 
    */ 
    public static String store = "tmp"; 

    /** 
    * Status of the recorder. 
    */ 
    public static boolean record = false; 

    @FXML 
    private Button start; 

    @FXML 
    private TextArea console; 

    @FXML 
    private TextField input; 

    public static void startRecord() { 
     Thread recordThread = new Thread() { 
      @Override 
      public void run() { 
       Robot rt; 
       int cnt = 0; 
       try { 
        rt = new Robot(); 
        while (cnt == 0 || record) { 
         BufferedImage img = rt.createScreenCapture(new Rectangle(screenWidth, screenHeight)); 
         ImageIO.write(img, "jpeg", new File("./" + store + "/" 
           + System.currentTimeMillis() + ".jpeg")); 
         if (cnt == 0) { 
          record = true; 
          cnt = 1; 
         } 
         Thread.sleep(captureInterval); 
        } 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }; 
     recordThread.start(); 
    } 

    /** 
    * @throws MalformedURLException 
    * 
    */ 
    public static void makeVideo(String movFile) throws MalformedURLException { 
     FXMLDocumentController FXML = new FXMLDocumentController(); 
     FXML.console.appendText("Processing Video... please wait"); 
     JpegImagesToMovie imageToMovie = new JpegImagesToMovie(); 
     Vector<String> imgLst = new Vector<String>(); 
     File f = new File(store); 
     File[] fileLst = f.listFiles(); 
     for (int i = 0; i < fileLst.length; i++) { 
      imgLst.add(fileLst[i].getAbsolutePath()); 
     } 
     // Generate the output media locators. 
     MediaLocator oml; 
     if ((oml = imageToMovie.createMediaLocator(movFile)) == null) { 
      FXML.console.appendText("Error in processing"); 
      System.exit(0); 
     } 
     imageToMovie.doIt(screenWidth, screenHeight, (1000/captureInterval), imgLst, oml); 

    } 

    @FXML 
    void setOnAction(ActionEvent event) { 
     String path = JOptionPane.showInputDialog("Type in the File Path", "C:/Users/" + System.getProperty("user.name") + "/Desktop"); 
     file = new File(path); 
    } 

    @FXML 
    void startOnAction(ActionEvent event) { 
     FXMLDocumentController FXML = new FXMLDocumentController(); 
     FXML.console.setText("######### Starting Screen Recorder #########"); 
     try { 
      Thread.sleep(250); 
     } catch (InterruptedException ex) { 
     } 
     Dimension screen = Toolkit.getDefaultToolkit().getScreenSize(); 
     FXML.console.appendText("Your Screen [Width, Height]: " + "[" + screen.getWidth() + "," + screen.getHeight() + "]\nWhen the Recording starts, this window will minimize, to stop them recording, open this window."); 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException ex) { 
     } 
     FXML.console.appendText("The recording will start in 5 seconds"); 
     int num = 5; 
     for (int i = 0; i <= 5; i++) { 
      System.out.print(num); 
      try { 
       Thread.sleep(1000); 
      } catch (InterruptedException ex) { 
      } 
      num = num - 1; 
     } 
     FXML.console.appendText("Start!"); 
     File f = new File(store); 
     if (!f.exists()) { 
      f.mkdir(); 
     } 
     startRecord(); 
     Recorder R = new Recorder(); 
     R.stage.setIconified(true); 
     R.stage.focusedProperty().addListener((ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) -> { 
      focusState(newValue); 
     }); 
    } 

    ; 

    private void focusState(boolean value) { 
     if (value) { 
      System.out.println("Focus Gained"); 
      record = false; 
      try { 
       makeVideo(input.getText() + ".mov"); 
      } catch (MalformedURLException ex) { 
      } 
     } else { 
     } 
    } 

    @Override 
    public void initialize(URL url, ResourceBundle rb) { 

    } 

} 

我希望我能正確遵循你的指導方針和內容。

回答

1

您剛剛創建了一個FXMLDocumentController的實例,該實例與任何已加載FXMLLoader的fxml沒有關係。

然而它的FXMLLoader在於用於注入的字段值是負責並且當FXML文件被加載它僅注入的字段與FXMLLoader使用的控制器類的實例(即,任一個由FXMLLoader本身基於所述fx:controller創建屬性或使用setController提供的屬性;在這兩種情況下,都可以在調用load之後直接使用FXMLLoader.getController來檢索實例)。

永遠不會修改的字段仍然包含默認值null,這會導致NPE例如在這裏:

FXMLDocumentController FXML = new FXMLDocumentController(); 
FXML.console.setText("######### Starting Screen Recorder #########"); 

this.console.setText("######### Starting Screen Recorder #########"); 

可能會成功,但請注意,您與Thread.sleep幾秒鐘,這將使得應用程序凍結這個時候阻止在你的代碼的應用程序線程...


要檢索Window後,現場已被添加到它,你可以使用一個Node場景,而不是內部:

Stage stage = (Stage) this.console.getScene().getWindow(); 
stage.setIconified(true); 
stage.focusedProperty()... 
+0

我會試試,謝謝 – Gamer818

+0

這部分怎麼樣?記錄器R =新的記錄器();R.stage.setIconified(true); ()();}};}};}};}}}; – Gamer818

+0

'this'將不起作用,因爲它來自不同的類 – Gamer818