如何解决JavaFX 在图表上拖动细线
我在图表上画了一条水平线。将鼠标悬停在其上时,光标会更改为 CursorType.S_RESIZE。这表示用户可以开始拖动。由于线很细,您必须非常准确地放置光标。为了获得更好的用户体验,我想在线上方和下方添加边距,以便更轻松地进入可拖动区域。
有没有办法使线条“更粗”,以便在接近时 setOnMouseMoved() 事件已经触发?
import javafx.application.Application;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.chart.Axis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class DragLine extends Application {
public void start(Stage stage) {
ChartWithLine chartWithLine = new ChartWithLine(new NumberAxis(),new NumberAxis());
stage.setScene(new Scene(chartWithLine,500,400));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
class ChartWithLine<X,Y> extends LineChart {
public ChartWithLine(Axis axis,Axis axis2) {
super(axis,axis2);
line = new Line();
line.setOnMouseMoved(event -> line.setCursor(Cursor.S_RESIZE));
getPlotChildren().add(line);
}
private Line line;
public void layoutPlotChildren() {
super.layoutPlotChildren();
double yPos = getYAxis().getDisplayPosition(55);
line.setStartX(0);
line.setEndX(getBoundsInLocal().getWidth());
line.setStartY(yPos);
line.setEndY(yPos);
}
}
解决方法
这是我的工作。我正在绘制细线的同一位置绘制第二条更粗的线。粗线设置为透明,因此不可见。拖动功能设置为较粗的线。拖动时,两条线都绘制到拖动位置。 解决了鼠标难以抓取细线的问题。但我不喜欢它有两个原因。首先,我实际上根本不需要第二行。其次,如果您将鼠标悬停在可见细线所在的粗线的中间,鼠标将变回不可拖动光标。我现在也必须为细线实现可拖动性以避免这种情况。但这实在是太过分了。
再说一次,有没有什么方法可以将线条设置得更粗而不让它看起来更粗?
import javafx.application.Application;
import javafx.scene.Cursor;
import javafx.scene.Scene;
import javafx.scene.chart.Axis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.input.MouseEvent;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
public class DragLine extends Application {
public void start(Stage stage) {
ChartWithLine chartWithLine = new ChartWithLine(new NumberAxis(),new NumberAxis());
stage.setScene(new Scene(chartWithLine,500,400));
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
//ChartWithLine
class ChartWithLine<X,Y> extends LineChart {
public ChartWithLine(Axis axis,Axis axis2) {
super(axis,axis2);
draggableLine = new DraggableLine(this);
getPlotChildren().addAll(draggableLine.lineToShow,draggableLine.lineToDrag);
}
private DraggableLine draggableLine;
public void layoutPlotChildren() {
super.layoutPlotChildren();
updateLinePlot();
}
//updateLinePlot called when line was dragged
public void updateLinePlot() {
//mouse position after drag
double yPos = draggableLine.mousePosY;
System.out.println("Line dragged to: " + getYAxis().getValueForDisplay(yPos));
//plot lines accordingly to new mouse position
Line line = draggableLine.lineToDrag;
line.setStartX(0);
line.setEndX(getBoundsInLocal().getWidth());
line.setStartY(yPos);
line.setEndY(yPos);
line = draggableLine.lineToShow;
line.setStartX(0);
line.setEndX(getBoundsInLocal().getWidth());
line.setStartY(yPos);
line.setEndY(yPos);
}
}
//DraggableLine
class DraggableLine {
public DraggableLine(ChartWithLine chart) {
this.chart = chart;
//lineToShow is thin line plotted visible on chart
lineToShow = new Line();
//lineToDrag is plotted at same position on chart as thin visible line.
lineToDrag = new Line();
//set transparent to make it not visible
lineToDrag.setStyle("-fx-stroke: transparent;");
//set line to drag stroke width very broad so it is easy to grab
lineToDrag.setStrokeWidth(20.0);
lineToDrag.setOnMouseMoved(this::mouseOver);
lineToDrag.setOnMouseDragged(event -> onMouseDragged(event.getY()));
lineToDrag.setOnMousePressed(this::onMousePressed);
lineToDrag.setOnMouseReleased(event -> onMouseReleased());
}
private ChartWithLine chart;
public Line lineToShow;
public Line lineToDrag;
boolean isDragging = false;
public double mousePosY = 55;
//change cursor
protected void mouseOver(MouseEvent event) {
if (isDragZone(event)) {
lineToDrag.setCursor(Cursor.S_RESIZE);
} else {
lineToDrag.setCursor(Cursor.DEFAULT);
}
}
//mouse pressed over draggable zone
void onMousePressed(MouseEvent event) {
if (isDragZone(event))
isDragging = true;
}
//mouse released
void onMouseReleased() {
isDragging = false;
}
//change values when mouse is dragging
void onMouseDragged(double y) {
if (!isDragging) return;
mousePosY = y;
chart.updateLinePlot();
}
//check if mouse is in draggable zone
protected boolean isDragZone(MouseEvent event) {
return event.getY() > (lineToDrag.getStartY()) || event.getY() < (lineToDrag.getStartY());
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。