我有一个代码可以在JavaFX 2.0中的XYChart上徒手绘制 我做调整大小图表时遇到问题。 当我调整大小时,我已经翻译了写意画的问题
当我调整大小时,新绘制最初会出现超出规模,但经过一些“图表移动”后,它会自行修复。
我该如何改进?
我的代码是:
package testjavafxapplication;
import javafx.application.Application;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Bounds;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.chart.LineChart;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.transform.Scale;
import javafx.scene.transform.Transform;
import javafx.scene.transform.Translate;
public class FreehandResize extends Application {
private CategoryAxis xAxis = new CategoryAxis();
private NumberAxis yAxis = new NumberAxis(0.53000, 0.53910, 0.0001);
private LineChart<String, Number> lineChart = new LineChart<String, Number> (xAxis, yAxis);
private Path path;
private double initialWidth;
private double initialheight;
private Translate translate = new Translate(0, 0);
private Scale scale = new Scale(1, 1);
private ChangeListener<Number> changeListener = new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
Bounds y_axisBounds = yAxis.getBoundsInLocal();
double xOffset = y_axisBounds.getMaxX();
translate.setX(xOffset);
Bounds chartBounds = lineChart.getBoundsInLocal();
scale.setX((chartBounds.getWidth() - xOffset) / initialWidth);
scale.setY((chartBounds.getHeight() - xAxis.getBoundsInLocal().getHeight()) / initialheight);
}
};
private EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent mouseEvent) {
double targetX = (mouseEvent.getX() - translate.getX()) / scale.getX();
double targetY = mouseEvent.getY() / scale.getY();
if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) {
path.getElements().add(new MoveTo(targetX, targetY));
} else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED) {
path.getElements().add(new LineTo(targetX, targetY));
}
}
};
@Override
public void start(Stage stage) {
stage.setTitle("Resize line plot");
yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
@Override
public String toString(Number object) {
return String.format("%6.4f", object);
}
});
lineChart.setCreateSymbols(false);
lineChart.setAlternativeRowFillVisible(false);
XYChart.Series series1 = new XYChart.Series();
series1.getData().add(new XYChart.Data("Jan", 0.53185));
series1.getData().add(new XYChart.Data("Feb", 0.532235));
series1.getData().add(new XYChart.Data("Mar", 0.53234));
series1.getData().add(new XYChart.Data("Apr", 0.538765));
series1.getData().add(new XYChart.Data("May", 0.53442));
series1.getData().add(new XYChart.Data("Jun", 0.534658));
series1.getData().add(new XYChart.Data("Jul", 0.53023));
series1.getData().add(new XYChart.Data("Aug", 0.53001));
series1.getData().add(new XYChart.Data("Sep", 0.53589));
series1.getData().add(new XYChart.Data("Oct", 0.53476));
series1.getData().add(new XYChart.Data("Nov", 0.530123));
series1.getData().add(new XYChart.Data("Dec", 0.53035));
lineChart.getData().addAll(series1);
BorderPane pane = new BorderPane();
pane.setCenter(lineChart);
Scene scene = new Scene(pane, 800, 600);
stage.setScene(scene);
path = new Path();
path.setStrokeWidth(2);
path.setStroke(Color.CHOCOLATE);
ObservableList<Transform> transforms = path.getTransforms();
transforms.add(0, translate);
transforms.add(1, scale);
scene.setOnMouseClicked(mouseHandler);
scene.setOnMouseDragged(mouseHandler);
scene.setOnMouseEntered(mouseHandler);
scene.setOnMouseExited(mouseHandler);
scene.setOnMouseMoved(mouseHandler);
scene.setOnMousePressed(mouseHandler);
scene.setOnMouseReleased(mouseHandler);
pane.getChildren().add(path);
scene.widthProperty().addListener(changeListener);
scene.heightProperty().addListener(changeListener);
stage.show();
Bounds axisBounds = yAxis.getBoundsInLocal();
double xOffset = axisBounds.getMaxX();
translate.setX(xOffset);
Bounds chartBounds = lineChart.getBoundsInLocal();
initialWidth = chartBounds.getWidth() - xOffset;
initialheight = chartBounds.getHeight() - xAxis.getBoundsInLocal().getHeight();
}
public static void main(String[] args) {
launch(args);
}
}
答案 0 :(得分:1)
看来你的坐标是基于错误的锚点。您需要找到一个包含图形本身的节点,并且只能使用此节点的坐标,而不是轴或场景。
我甚至建议将所有鼠标事件添加到该节点而不是场景,以避免过多的坐标转换。
另一个建议是使用ScenicView工具调查您的应用程序,看看哪些节点有什么坐标并验证您的数学。