Canvas 在JavaFX8中的滚动窗格中绘制
经过几个小时的搜索,我找不到解决问题的办法 我得到了一个简单的绘图应用程序,其中我有一个矩形来画线。这个矩形应该在滚动窗格中,这样如果它比程序窗口大,用户就可以滚动到不同的位置 以下是我目前的做法:Canvas 在JavaFX8中的滚动窗格中绘制,canvas,javafx,drawing,scrollpane,Canvas,Javafx,Drawing,Scrollpane,经过几个小时的搜索,我找不到解决问题的办法 我得到了一个简单的绘图应用程序,其中我有一个矩形来画线。这个矩形应该在滚动窗格中,这样如果它比程序窗口大,用户就可以滚动到不同的位置 以下是我目前的做法: /** * @param args the command line arguments */ public static void main(String[] args) { Application.launch(args); }
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Application.launch(args);
}
@Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Drawing Board Demo");
final Group root = new Group();
Scene scene = new Scene(root, 600, 800);
// A group to hold all the drawn path elements
line_Group = new Group();
final Rectangle canvas = new Rectangle(scene.getWidth() - 20, scene.getHeight() - 20);
这里的问题是,绘制的路径始终绘制在同一位置,即如果我移动滚动条进一步向下绘制,它不会改变任何内容
我尝试在mouseEvent中使用“.getX()”而不是“.getsceneX()”,但也没有用
我是JavaFX新手,所以请耐心听我说,这是一个简单的应用程序,但有一些事情会根据具体要求而改变,例如,如果用户拖动到滚动窗格之外会发生什么?绘图区域是否固定,或其大小是否至少为可视区域的最小大小?等等 这是我提出的一个示例应用程序。它不会完全符合你的要求,因为我不知道它们到底是什么,但希望它能给你足够的基本信息,让你再次朝着正确的方向前进 按住并拖动鼠标在滚动窗格内显示的窗格上绘制线条。如果将窗格外部拖动到底部或右侧,绘图窗格的最小大小将更新以适应其中的新行内容。鼠标侦听器用于处理绘图操作的开始、设置端点和完成绘图操作
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class LineDrawer extends Application {
public static void main(String[] args) {
launch(args);
}
private Line curLine;
@Override
public void start(Stage stage) throws Exception {
Pane drawingPane = new Pane();
drawingPane.setPrefSize(800, 800);
drawingPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
ScrollPane scrollPane = new ScrollPane(drawingPane);
scrollPane.setPrefSize(300, 300);
scrollPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
scrollPane.setFitToWidth(true);
scrollPane.setFitToHeight(true);
scrollPane.setStyle("-fx-focus-color: transparent;");
drawingPane.setOnMousePressed(event -> {
if (!event.isPrimaryButtonDown()) {
return;
}
curLine = new Line(
event.getX(), event.getY(),
event.getX(), event.getY()
);
drawingPane.getChildren().add(curLine);
});
drawingPane.setOnMouseDragged(event -> {
if (!event.isPrimaryButtonDown()) {
return;
}
if (curLine == null) {
return;
}
curLine.setEndX(event.getX());
curLine.setEndY(event.getY());
double mx = Math.max(curLine.getStartX(), curLine.getEndX());
double my = Math.max(curLine.getStartY(), curLine.getEndY());
if (mx > drawingPane.getMinWidth()) {
drawingPane.setMinWidth(mx);
}
if (my > drawingPane.getMinHeight()) {
drawingPane.setMinHeight(my);
}
});
drawingPane.setOnMouseReleased(event -> curLine = null);
Scene scene = new Scene(scrollPane);
stage.setMinWidth(100);
stage.setMinHeight(100);
stage.setScene(scene);
stage.show();
}
}
这是很多代码。是否可以将其精简一点(仅限于显示问题的代码),以便更容易帮助您?抱歉,我已删除了所有不影响此问题的代码。主要的问题是在“canvas.setonmousedrable”和createScrollPane“我想至少Hanks,这回答了我的问题。我只需要将“Line”替换为“Path”“形状。感谢您的帮助。这是一个很棒的演示,演示了一些通过搜索很难找到的关键概念。@jewelsea为什么要使用
窗格
而不是画布
?在用户拖动时移动鼠标比使用窗格而不是画布更容易实现。我认为如果您尝试创建一个基于画布的解决方案,那么它最终会变得更加复杂。
private ScrollPane createScrollPane(Group layout) {
ScrollPane scroll = new ScrollPane();
scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroll.setMaxHeight(400);
scroll.setContent(layout);
return scroll;
}
}
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.ScrollPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class LineDrawer extends Application {
public static void main(String[] args) {
launch(args);
}
private Line curLine;
@Override
public void start(Stage stage) throws Exception {
Pane drawingPane = new Pane();
drawingPane.setPrefSize(800, 800);
drawingPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
ScrollPane scrollPane = new ScrollPane(drawingPane);
scrollPane.setPrefSize(300, 300);
scrollPane.setMaxSize(Double.MAX_VALUE, Double.MAX_VALUE);
scrollPane.setFitToWidth(true);
scrollPane.setFitToHeight(true);
scrollPane.setStyle("-fx-focus-color: transparent;");
drawingPane.setOnMousePressed(event -> {
if (!event.isPrimaryButtonDown()) {
return;
}
curLine = new Line(
event.getX(), event.getY(),
event.getX(), event.getY()
);
drawingPane.getChildren().add(curLine);
});
drawingPane.setOnMouseDragged(event -> {
if (!event.isPrimaryButtonDown()) {
return;
}
if (curLine == null) {
return;
}
curLine.setEndX(event.getX());
curLine.setEndY(event.getY());
double mx = Math.max(curLine.getStartX(), curLine.getEndX());
double my = Math.max(curLine.getStartY(), curLine.getEndY());
if (mx > drawingPane.getMinWidth()) {
drawingPane.setMinWidth(mx);
}
if (my > drawingPane.getMinHeight()) {
drawingPane.setMinHeight(my);
}
});
drawingPane.setOnMouseReleased(event -> curLine = null);
Scene scene = new Scene(scrollPane);
stage.setMinWidth(100);
stage.setMinHeight(100);
stage.setScene(scene);
stage.show();
}
}