1

このコードは、XY LineChart をプロットし、(コードは Bhupendra に感謝します) マウスの左クリックでチャートに線を描画します。マウスをホバーすると、選択された線が赤に変わり、削除または移動できます。

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.chart.CategoryAxis;
import javafx.scene.chart.LineChart;
import javafx.scene.chart.NumberAxis;
import javafx.scene.chart.XYChart;
import javafx.scene.control.Label;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.stage.Stage;

public class LinesEdit extends Application {

Path path;

public static void main(String[] args) {
    launch(args);
}

@Override
public void start(Stage stage) {

    final CategoryAxis xAxis = new CategoryAxis();
    final NumberAxis yAxis = new NumberAxis(1, 21, 0.1);
    yAxis.setTickUnit(1);
    yAxis.setPrefWidth(35);
    yAxis.setMinorTickCount(10);
    yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) {
        @Override
        public String toString(Number object) {
            String label;
            label = String.format("%7.2f", object.floatValue());
            return label;
        }
    });
    final LineChart<String, Number> lineChart = new LineChart<String, Number>(xAxis, yAxis);

    lineChart.setCreateSymbols(false);
    lineChart.setAlternativeRowFillVisible(false);
    lineChart.setLegendVisible(false);

    XYChart.Series series1 = new XYChart.Series();

    series1.getData().add(new XYChart.Data("Jan", 1));
    series1.getData().add(new XYChart.Data("Feb", 4));
    series1.getData().add(new XYChart.Data("Mar", 2.5));
    series1.getData().add(new XYChart.Data("Apr", 5));
    series1.getData().add(new XYChart.Data("May", 6));
    series1.getData().add(new XYChart.Data("Jun", 8));
    series1.getData().add(new XYChart.Data("Jul", 12));
    series1.getData().add(new XYChart.Data("Aug", 8));
    series1.getData().add(new XYChart.Data("Sep", 11));
    series1.getData().add(new XYChart.Data("Oct", 13));
    series1.getData().add(new XYChart.Data("Nov", 10));
    series1.getData().add(new XYChart.Data("Dec", 20));

    BorderPane bp = new BorderPane();
    bp.setCenter(lineChart);
    Scene scene = new Scene(bp, 800, 600);
    lineChart.setAnimated(false);
    lineChart.getData().addAll(series1);

    LinesEdit.MouseHandler mh = new LinesEdit.MouseHandler( bp );
    bp.setOnMouseClicked( mh );
    bp.setOnMouseMoved( mh );

    stage.setScene(scene);

    path = new Path();
    path.setStrokeWidth(1);
    path.setStroke(Color.BLACK);

    scene.setOnMouseDragged(mh);
    scene.setOnMousePressed(mh);
    bp.getChildren().add(path);
    stage.setScene(scene);
    stage.show();
}    

class MouseHandler implements EventHandler< MouseEvent > {
private boolean gotFirst    = false;
private Line    line;
private Pane    pane;
private double  x1, y1, x2, y2;
private LineHandler lineHandler;

public MouseHandler( Pane pane ) {
    this.pane = pane;
    lineHandler = new LineHandler(pane);
}

class LineHandler implements EventHandler< MouseEvent > {
double  x, y;
Pane pane;

public LineHandler(Pane pane){
    this.pane = pane;
}
@Override
public void handle( MouseEvent e ) {
    Line l = (Line) e.getSource();

    // remove line on right click
    if( e.getEventType() == MouseEvent.MOUSE_PRESSED
            && e.isSecondaryButtonDown() ) {
        pane.getChildren().remove( l );
    } else if( e.getEventType() == MouseEvent.MOUSE_DRAGGED
            && e.isPrimaryButtonDown() ) {
        double tx = e.getX();
        double ty = e.getY();
        double dx = tx - x;
        double dy = ty - y;
        l.setStartX( l.getStartX() + dx );
        l.setStartY( l.getStartY() + dy );
        l.setEndX( l.getEndX() + dx );
        l.setEndY( l.getEndY() + dy );
        x = tx;
        y = ty;
    } else if( e.getEventType() == MouseEvent.MOUSE_ENTERED ) {
        // just to show that the line is selected
        x = e.getX();
        y = e.getY();
        l.setStroke( Color.RED );
    } else if( e.getEventType() == MouseEvent.MOUSE_EXITED ) {
        l.setStroke( Color.BLACK );
    }
    // should not pass event to the parent
    e.consume();
}
}   
@Override
public void handle( MouseEvent event ) {
    if( event.getEventType() == MouseEvent.MOUSE_CLICKED ) {
        if( !gotFirst ) {
            x1 = x2 = event.getX();
            y1 = y2 = event.getY();
            line = new Line( x1, y1, x2, y2 );

            pane.getChildren().add( line );

            gotFirst = true;
        } 
        else {
            line.setOnMouseEntered( lineHandler );
            line.setOnMouseExited( lineHandler );
            line.setOnMouseDragged( lineHandler );
            line.setOnMousePressed( lineHandler );
            // to consume the event
            line.setOnMouseClicked( lineHandler );
            line.setOnMouseReleased( lineHandler );
            line = null;
            gotFirst = false;
        }
    } 
        else {
            if( line != null ) {
                x2 = event.getX();
                y2 = event.getY();
                // update line
                line.setEndX( x2 );
                line.setEndY( y2 );
        }
     }
  }
 }
}

私が今やりたいことは、端点またはテールポイント (図の A と B) のいずれかを選択して線の長さまたは勾配を変更し、新しい端点 x、y ポイントを設定することです

ここに画像の説明を入力

これを達成する方法は?

ありがとう。

4

1 に答える 1

4

代わりに次のクラスを使用してくださいLine...

public class EditLine extends Parent {
    private static final double radius  = 5;
    private Line                line;
    private Circle              c1, c2;

    private class MouseHandler implements EventHandler< MouseEvent > {
        private boolean isfirst;

        public MouseHandler( boolean first ) {
            isfirst = first;
        }

        public void handle( MouseEvent event ) {
            if( event.getEventType() == MouseEvent.MOUSE_ENTERED ) {
                if( isfirst )
                    c1.setOpacity( 1 );
                else c2.setOpacity( 1 );
            } else if( event.getEventType() == MouseEvent.MOUSE_EXITED ) {
                if( isfirst )
                    c1.setOpacity( 0 );
                else c2.setOpacity( 0 );
            } else if( event.getEventType() == MouseEvent.MOUSE_DRAGGED ) {
                double x = event.getSceneX();
                double y = event.getSceneY();
                if( isfirst ) {
                    line.setStartX( x );
                    line.setStartY( y );
                    c1.setCenterX( x );
                    c1.setCenterY( y );
                } else {
                    line.setEndX( x );
                    line.setEndY( y );
                    c2.setCenterX( x );
                    c2.setCenterY( y );
                }
            }
        }
    }

    public EditLine( double x1, double y1, double x2, double y2 ) {
        line = new Line( x1, y1, x2, y2 );
        line.setMouseTransparent( true );

        c1 = new Circle( x1, y1, radius, Color.RED );
        c1.setOpacity( 0 );
        MouseHandler mh1 = new MouseHandler( true );
        c1.setOnMouseEntered( mh1 );
        c1.setOnMouseExited( mh1 );
        c1.setOnMouseDragged( mh1 );
        c2 = new Circle( x2, y2, radius, Color.RED );
        c2.setOpacity( 0 );
        MouseHandler mh2 = new MouseHandler( false );
        c2.setOnMouseEntered( mh2 );
        c2.setOnMouseExited( mh2 );
        c2.setOnMouseDragged( mh2 );

        getChildren().addAll( c1, c2, line );
    }
}
于 2012-11-13T15:28:26.503 に答える