经过几个小时的搜索,我无法找到解决问题的方法。
我有一个简单的绘图应用程序,我有一个矩形来绘制线条。这个矩形应该在Scrollpane中,所以如果它是'大于程序窗口,用户只需滚动到不同的位置。
这是我目前的做法:
/**
* @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);
...
// Build the canvas
canvas.setCursor(Cursor.CROSSHAIR);
canvas.setFill(Color.LIGHTGRAY);
canvas.setOnMousePressed(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
path = new Path();
path.setMouseTransparent(true);
path.setStrokeWidth(sampleLine.getStrokeWidth());
path.setStroke(sampleLine.getStroke());
line_Group.getChildren().add(path);
path.getElements().add(new MoveTo(me.getSceneX(), me.getSceneY()));
}
});
canvas.setOnMouseDragged(new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent me) {
// keep lines within rectangle
if (canvas.getBoundsInLocal().contains(me.getX(), me.getY())) {
path.getElements().add(new LineTo(me.getSceneX(), me.getSceneY()));
}
}
});
// Build the VBox container for the toolBox, sampleline, and canvas
final Group board = new Group();
board.getChildren().addAll(canvas, line_Group);
ScrollPane scroll = createScrollPane(board);
VBox vb = new VBox(20);
vb.setPrefWidth(scene.getWidth() - 20);
vb.setLayoutY(20);
vb.setLayoutX(10);
vb.getChildren().addAll(toolBox, stackpane, scroll);
root.getChildren().addAll(vb);
primaryStage.setScene(scene);
primaryStage.show();
}
...
private ScrollPane createScrollPane(Group layout) {
ScrollPane scroll = new ScrollPane();
scroll.setHbarPolicy(ScrollPane.ScrollBarPolicy.NEVER);
scroll.setMaxHeight(400);
scroll.setContent(layout);
return scroll;
}
}
这里的问题是,绘制的路径总是在相同的位置绘制,即如果我移动滚动条进一步向下绘制,它不会改变任何东西。
我尝试过使用&#34; .getX()&#34;而不是&#34; .getsceneX()&#34;在mouseEvent中,但这并没有帮助。
我是JavaFX的新手所以请耐心等待我
答案 0 :(得分:2)
这是一个简单的应用程序,但有些事情会根据具体要求而改变,例如:如果用户拖动滚动窗格外会发生什么?绘图区域是固定的还是大小至少是可视区域的最小尺寸?等等。
这是我想出的一个示例应用程序。它完全不符合您的要求,因为我不确切地知道它们是什么,但希望它能为您提供足够的基本信息,让您再次朝着正确的方向前进。
按住并拖动鼠标在滚动窗格内显示的窗格上绘制线条。如果在窗格外部向下或向右拖动,则将更新绘图窗格的最小尺寸以适合其中的新行内容。鼠标侦听器onMousePressed
,onMouseDragged
,onMouseReleased
用于处理绘图操作的开始,设置端点并完成绘图操作。
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();
}
}