我正在使用 JavaFX 制作屏幕录像机,屏幕录像机中的一个强制性实用程序是让用户定义要记录多少区域。
我设法制作了一个未装饰的、半透明的Stage,它可以被拖动来定义区域,并添加了一个close按钮让用户确认该区域是要记录下来的。
现在,如何让用户通过拖动舞台的边缘来调整舞台的大小?
中南合作:
package draggable;
import javafx.application.Application;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Pos;
import javafx.geometry.Rectangle2D;
import javafx.scene.Scene;
import javafx.scene.SceneBuilder;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBuilder;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.StackPaneBuilder;
import javafx.scene.paint.Color;
import javafx.stage.Screen;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
public class DraggableStage extends Application{
Button close;
StackPane holder;
Rectangle2D maxBounds;
Scene theScene;
double pressedX;
double pressedY;
double draggedX;
double draggedY;
@Override
public void start(Stage stage) throws Exception {
final Stage theStage = stage;
// determine how big the screen is
maxBounds = Screen.getPrimary().getVisualBounds();
//create the close button
close = ButtonBuilder
.create()
.text("Close")
.build();
//create the StackPane holder for the button
holder = StackPaneBuilder
.create()
.alignment(Pos.CENTER)
.children(close)
.build();
// you cannot resize the screen beyond the max resolution of the screen
holder.setMaxSize(maxBounds.getWidth(), maxBounds.getHeight());
//you cannot resize under half the width and height of the screen
holder.setMinSize(maxBounds.getWidth() / 2,maxBounds.getHeight() / 2);
//the scene where it all happens
theScene = SceneBuilder
.create()
.root(holder)
.width(maxBounds.getWidth() / 2)
.height(maxBounds.getHeight() / 2)
.build();
// add the button listeners
close.setOnAction(new EventHandler<ActionEvent>(){
@Override
public void handle(ActionEvent event) {
theStage.close();
}
});
// add the drag and press listener for the StackPane
holder.setOnMousePressed(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent e) {
pressedX = e.getX();
pressedY = e.getY();
}
});
holder.setOnMouseDragged(new EventHandler<MouseEvent>(){
@Override
public void handle(MouseEvent e) {
draggedX = e.getX();
draggedY = e.getY();
double differenceX = draggedX - pressedX;
double differenceY = draggedY - pressedY;
theStage.setX(theStage.getX() + differenceX);
theStage.setY(theStage.getY() + differenceY);
}
});
//the mandatory mumbo jumbo
theScene.setFill(Color.rgb(128, 128, 128, 0.5));
stage.initStyle(StageStyle.TRANSPARENT);
stage.setScene(theScene);
stage.sizeToScene();
stage.show();
}
public static void main(String[] args) {
Application.launch("draggable.DraggableStage");
}
}
图片:
最佳答案
我创建了一个 ResizeHelper 类,它可以在这种情况下为您提供帮助,用法:
ResizeHelper.addResizeListener(yourStage);
辅助类:
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.event.EventType;
import javafx.scene.Cursor;
import javafx.scene.Node;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.input.MouseEvent;
import javafx.stage.Stage;
//created by Alexander Berg
public class ResizeHelper {
public static void addResizeListener(Stage stage) {
ResizeListener resizeListener = new ResizeListener(stage);
stage.getScene().addEventHandler(MouseEvent.MOUSE_MOVED, resizeListener);
stage.getScene().addEventHandler(MouseEvent.MOUSE_PRESSED, resizeListener);
stage.getScene().addEventHandler(MouseEvent.MOUSE_DRAGGED, resizeListener);
stage.getScene().addEventHandler(MouseEvent.MOUSE_EXITED, resizeListener);
stage.getScene().addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, resizeListener);
ObservableList<Node> children = stage.getScene().getRoot().getChildrenUnmodifiable();
for (Node child : children) {
addListenerDeeply(child, resizeListener);
}
}
public static void addListenerDeeply(Node node, EventHandler<MouseEvent> listener) {
node.addEventHandler(MouseEvent.MOUSE_MOVED, listener);
node.addEventHandler(MouseEvent.MOUSE_PRESSED, listener);
node.addEventHandler(MouseEvent.MOUSE_DRAGGED, listener);
node.addEventHandler(MouseEvent.MOUSE_EXITED, listener);
node.addEventHandler(MouseEvent.MOUSE_EXITED_TARGET, listener);
if (node instanceof Parent) {
Parent parent = (Parent) node;
ObservableList<Node> children = parent.getChildrenUnmodifiable();
for (Node child : children) {
addListenerDeeply(child, listener);
}
}
}
static class ResizeListener implements EventHandler<MouseEvent> {
private Stage stage;
private Cursor cursorEvent = Cursor.DEFAULT;
private int border = 4;
private double startX = 0;
private double startY = 0;
public ResizeListener(Stage stage) {
this.stage = stage;
}
@Override
public void handle(MouseEvent mouseEvent) {
EventType<? extends MouseEvent> mouseEventType = mouseEvent.getEventType();
Scene scene = stage.getScene();
double mouseEventX = mouseEvent.getSceneX(),
mouseEventY = mouseEvent.getSceneY(),
sceneWidth = scene.getWidth(),
sceneHeight = scene.getHeight();
if (MouseEvent.MOUSE_MOVED.equals(mouseEventType) == true) {
if (mouseEventX < border && mouseEventY < border) {
cursorEvent = Cursor.NW_RESIZE;
} else if (mouseEventX < border && mouseEventY > sceneHeight - border) {
cursorEvent = Cursor.SW_RESIZE;
} else if (mouseEventX > sceneWidth - border && mouseEventY < border) {
cursorEvent = Cursor.NE_RESIZE;
} else if (mouseEventX > sceneWidth - border && mouseEventY > sceneHeight - border) {
cursorEvent = Cursor.SE_RESIZE;
} else if (mouseEventX < border) {
cursorEvent = Cursor.W_RESIZE;
} else if (mouseEventX > sceneWidth - border) {
cursorEvent = Cursor.E_RESIZE;
} else if (mouseEventY < border) {
cursorEvent = Cursor.N_RESIZE;
} else if (mouseEventY > sceneHeight - border) {
cursorEvent = Cursor.S_RESIZE;
} else {
cursorEvent = Cursor.DEFAULT;
}
scene.setCursor(cursorEvent);
} else if(MouseEvent.MOUSE_EXITED.equals(mouseEventType) || MouseEvent.MOUSE_EXITED_TARGET.equals(mouseEventType)){
scene.setCursor(Cursor.DEFAULT);
} else if (MouseEvent.MOUSE_PRESSED.equals(mouseEventType) == true) {
startX = stage.getWidth() - mouseEventX;
startY = stage.getHeight() - mouseEventY;
} else if (MouseEvent.MOUSE_DRAGGED.equals(mouseEventType) == true) {
if (Cursor.DEFAULT.equals(cursorEvent) == false) {
if (Cursor.W_RESIZE.equals(cursorEvent) == false && Cursor.E_RESIZE.equals(cursorEvent) == false) {
double minHeight = stage.getMinHeight() > (border*2) ? stage.getMinHeight() : (border*2);
if (Cursor.NW_RESIZE.equals(cursorEvent) == true || Cursor.N_RESIZE.equals(cursorEvent) == true || Cursor.NE_RESIZE.equals(cursorEvent) == true) {
if (stage.getHeight() > minHeight || mouseEventY < 0) {
stage.setHeight(stage.getY() - mouseEvent.getScreenY() + stage.getHeight());
stage.setY(mouseEvent.getScreenY());
}
} else {
if (stage.getHeight() > minHeight || mouseEventY + startY - stage.getHeight() > 0) {
stage.setHeight(mouseEventY + startY);
}
}
}
if (Cursor.N_RESIZE.equals(cursorEvent) == false && Cursor.S_RESIZE.equals(cursorEvent) == false) {
double minWidth = stage.getMinWidth() > (border*2) ? stage.getMinWidth() : (border*2);
if (Cursor.NW_RESIZE.equals(cursorEvent) == true || Cursor.W_RESIZE.equals(cursorEvent) == true || Cursor.SW_RESIZE.equals(cursorEvent) == true) {
if (stage.getWidth() > minWidth || mouseEventX < 0) {
stage.setWidth(stage.getX() - mouseEvent.getScreenX() + stage.getWidth());
stage.setX(mouseEvent.getScreenX());
}
} else {
if (stage.getWidth() > minWidth || mouseEventX + startX - stage.getWidth() > 0) {
stage.setWidth(mouseEventX + startX);
}
}
}
}
}
}
}
}
关于java - 允许用户调整未装饰舞台的大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19455059/
我的目标是转换表单输入,例如“100兆字节”或“1GB”,并将其转换为我可以存储在数据库中的文件大小(以千字节为单位)。目前,我有这个:defquota_convert@regex=/([0-9]+)(.*)s/@sizes=%w{kilobytemegabytegigabyte}m=self.quota.match(@regex)if@sizes.include?m[2]eval("self.quota=#{m[1]}.#{m[2]}")endend这有效,但前提是输入是倍数(“gigabytes”,而不是“gigabyte”)并且由于使用了eval看起来疯狂不安全。所以,功能正常,
我将应用程序升级到Rails4,一切正常。我可以登录并转到我的编辑页面。也更新了观点。使用标准View时,用户会更新。但是当我添加例如字段:name时,它不会在表单中更新。使用devise3.1.1和gem'protected_attributes'我需要在设备或数据库上运行某种更新命令吗?我也搜索过这个地方,找到了许多不同的解决方案,但没有一个会更新我的用户字段。我没有添加任何自定义字段。 最佳答案 如果您想允许额外的参数,您可以在ApplicationController中使用beforefilter,因为Rails4将参数
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
我正在处理旧代码的一部分。beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)endRubocop错误如下:Avoidstubbingusing'allow_any_instance_of'我读到了RuboCop::RSpec:AnyInstance我试着像下面那样改变它。由此beforedoallow_any_instance_of(SportRateManager).toreceive(:create).and_return(true)end对此:let(:sport_
我正在尝试使用boilerpipe来自JRuby。我看过guide从JRuby调用Java,并成功地将它与另一个Java包一起使用,但无法弄清楚为什么同样的东西不能用于boilerpipe。我正在尝试基本上从JRuby中执行与此Java等效的操作:URLurl=newURL("http://www.example.com/some-location/index.html");Stringtext=ArticleExtractor.INSTANCE.getText(url);在JRuby中试过这个:require'java'url=java.net.URL.new("http://www
我意识到这可能是一个非常基本的问题,但我现在已经花了几天时间回过头来解决这个问题,但出于某种原因,Google就是没有帮助我。(我认为部分问题在于我是一个初学者,我不知道该问什么......)我也看过O'Reilly的RubyCookbook和RailsAPI,但我仍然停留在这个问题上.我找到了一些关于多态关系的信息,但它似乎不是我需要的(尽管如果我错了请告诉我)。我正在尝试调整MichaelHartl'stutorial创建一个包含用户、文章和评论的博客应用程序(不使用脚手架)。我希望评论既属于用户又属于文章。我的主要问题是:我不知道如何将当前文章的ID放入评论Controller。
我在新的Debian6VirtualBoxVM上安装RVM时遇到问题。我已经安装了所有需要的包并使用下载了安装脚本(curl-shttps://rvm.beginrescueend.com/install/rvm)>rvm,但以单个用户身份运行时bashrvm我收到以下错误消息:ERROR:Unabletocheckoutbranch.安装在这里停止,并且(据我所知)没有安装RVM的任何文件。如果我以root身份运行脚本(对于多用户安装),我会收到另一条消息:Successfullycheckedoutbranch''安装程序继续并指示成功,但未添加.rvm目录,甚至在修改我的.bas
我只想对我一直在思考的这个问题有其他意见,例如我有classuser_controller和classuserclassUserattr_accessor:name,:usernameendclassUserController//dosomethingaboutanythingaboutusersend问题是我的User类中是否应该有逻辑user=User.newuser.do_something(user1)oritshouldbeuser_controller=UserController.newuser_controller.do_something(user1,user2)我
什么是ruby的rack或python的Java的wsgi?还有一个路由库。 最佳答案 来自Python标准PEP333:Bycontrast,althoughJavahasjustasmanywebapplicationframeworksavailable,Java's"servlet"APImakesitpossibleforapplicationswrittenwithanyJavawebapplicationframeworktoruninanywebserverthatsupportstheservletAPI.ht
这篇文章是继上一篇文章“Observability:从零开始创建Java微服务并监控它(一)”的续篇。在上一篇文章中,我们讲述了如何创建一个Javaweb应用,并使用Filebeat来收集应用所生成的日志。在今天的文章中,我来详述如何收集应用的指标,使用APM来监控应用并监督web服务的在线情况。源码可以在地址 https://github.com/liu-xiao-guo/java_observability 进行下载。摄入指标指标被视为可以随时更改的时间点值。当前请求的数量可以改变任何毫秒。你可能有1000个请求的峰值,然后一切都回到一个请求。这也意味着这些指标可能不准确,你还想提取最小/