我正在尝试构建一个JavaFX应用html" target="_blank">程序,其中我有一个名为“Start”的按钮和一个ImageView。使用JavaFX-12的机器人类,我正在尝试在单击按钮时截取笔记本电脑屏幕的屏幕截图,并在ImageView中的运行时逐一显示图像。我的问题是JavaFX窗口没有响应,程序崩溃(可能)。甚至让线程进入睡眠状态似乎也不起作用。我假设它不起作用,因为我没有设置任何fps规则,但我怎么能这样做呢?目前,我正在创建可写图像,将它们转换为带有数字的单独图像,保存它们,然后再次重复使用它们。我的目标是在图像视图中创建同一台笔记本电脑的屏幕共享。我知道这很难。我是JavaFx机器人类的新手(不是他awt一个)。感谢任何帮助。
注意:这些图片在目录中正确排列。
package sample;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.fxml.FXMLLoader;
import javafx.geometry.Rectangle2D;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.VBox;
import javafx.scene.robot.Robot;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
public class Main extends Application {
@Override
public void start(Stage primaryStage) throws Exception{
Parent root = FXMLLoader.load(getClass().getResource("sample.fxml"));
primaryStage.setTitle("Hello World");
ImageView iv = new ImageView();
iv.setFitWidth(100);
iv.setFitHeight(100);
Button b = new Button("Start");
VBox v = new VBox(10);
v.getChildren().addAll(b,iv);
b.setOnAction(event -> {
Robot r = new Robot();
WritableImage wi = new WritableImage(300,300);
WritableImage i;
Rectangle2D rect = Screen.getPrimary().getVisualBounds();
while(true){
i = r.getScreenCapture(wi,rect);
try {
ImageIO.write(SwingFXUtils.fromFXImage(i,null),"png",new File("F:/Pic/pic" + x + ".png"));
iv.setImage(new Image(new FileInputStream("F:/Pic/pic" + x + ".png")));
//Thread.sleep(500);
//iv.setImage(null);
} catch (Exception e) {
System.out.println(e);
}
}
});
primaryStage.setScene(new Scene(v, 500, 500));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
与大多数UI框架一样,JavaFX是单线程的。决不能阻止(例如睡眠
)或垄断(例如while(true)
)JavaFX应用程序线程。该线程负责与UI相关的所有事情,如果它不能自由地完成其工作,则UI将变得无响应。请注意,在FX线程执行任何操作返回之前,渲染过程都不会发生,因此在循环中设置ImageView
的图像在循环终止后的一段时间内不会产生可见效果。
此外,全速while
循环将尝试以CPU执行所述循环的速度获取屏幕捕获。这可能比用户界面刷新的速度快得多,因此是对资源的浪费。屏幕捕获的速率不应超过帧速率。
如果需要在FX线程上循环和/或受到(JavaFX)帧速率的限制,那么使用JavaFX。动画
API。在你的例子中,AnimationTimer
似乎很合适。下面是一个持续截屏主屏幕的示例:
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.image.ImageView;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.StackPane;
import javafx.scene.robot.Robot;
import javafx.stage.Screen;
import javafx.stage.Stage;
public class App extends Application {
@Override
public void start(Stage primaryStage) {
ImageView view = new ImageView();
view.setFitWidth(720);
view.setFitHeight(480);
// Keep a reference to the AnimationTimer instance if
// you want to be able to start and stop it at will
new AnimationTimer() {
final Robot robot = new Robot();
final Rectangle2D bounds = Screen.getPrimary().getBounds();
@Override
public void handle(long now) {
WritableImage oldImage = (WritableImage) view.getImage();
WritableImage newImage = robot.getScreenCapture(oldImage, bounds);
if (oldImage != newImage) {
view.setImage(newImage);
}
}
}.start();
primaryStage.setScene(new Scene(new StackPane(view)));
primaryStage.show();
}
}
注意:
AnimationTimer#hand(long)
方法。JavaFX尝试以每秒60帧为目标。如果这太快(上面在我的计算机上有些滞后),那么您可以使用该方法的参数,即当前帧的时间戳(以纳秒为单位)来限制屏幕捕获的速率。您还可以考虑使用Timeline
或PauseTransition
而不是AnimationTimer
。有关更多信息,请参阅JavaFX定期后台任务。我的示例不包括将每个图像保存到文件中。您似乎已经理解了如何做到这一点,因此应该能够轻松地修改代码。不过,将I/O移动到后台线程可能是个好主意。不幸的是,这可能需要为每次捕获使用不同的WritableImage
实例,以避免FX线程在后台线程读取图像时对图像进行变异。它可能还需要一些调整或删除图像;我不确定I/O能否跟上屏幕截图的涌入(即标准的生产者-消费者问题)。
顺便说一句,你的问题解释了你试图分享整个屏幕。如果是这种情况,则继续使用Robot
。但是,如果您只需要共享来自JavaFX应用程序本身的内容,那么可以考虑使用节点#快照(SnapshotParameters,WritableImage)
或场景#快照(WritableImage)
(假设您不能只发送模型数据而不是图像)。
问题内容: 我想在屏幕上居中放置一个舞台。 这是我尝试过的: 调用centerOnScreen()后,舞台过高。它似乎无法正常工作。我需要自己计算x和y pos吗?或者如何正确使用此功能? 问题答案: 的默认实现如下: 哪里 总是将舞台设置为比中心高一点。 要将舞台定位在精确的中心,可以使用您设置的 自定义X和Y值 。
我正在尝试以编程方式添加ImageView,但不要在不同的屏幕上制作相同的大小。我尝试了许多比例代码,但没有任何好的结果。 屏幕:屏幕图像 这是我的代码:
我正在尝试制作一款包含来自存储或网络的无限图像的应用程序。但问题是,recyclerview的滚动速度非常慢 我如何在我的应用程序中创建图像列表,如gallery、whats应用程序、instagram等 我想让我的应用程序运行得非常平稳 请帮帮我! 适配器代码 :
我的有问题,当我在手机上启动应用程序时,它会显示约0.5秒的白色屏幕。扩展了,在中,我声明为启动器,肖像模式为。 代码: XML:
请检查升级最新版本; 若依旧无法看到请尝试退出会议后重新加入,并向我们反馈问题详情
我是JavaFX新手,在做我的项目时,我尝试切换屏幕。我正在考虑相应的AnchorPane可见性设置为真或假,当从另一个控制器访问AnchorPane时,我遇到了问题。我试图使AnchorPane成为静态的,但它给出了NullPointerException。 这是我的密码。 控制器类 SignUpController类 我试图像这样解决问题,但它关闭了窗口并打开了一个新窗口。