2012-11-13 2 views
1

이 코드는 왼쪽 마우스 클릭으로 XY LineChart와 (Bhupendra 덕분에 코드를 그립니다) 선을 그리며 마우스를 올리면 선택한 선이 빨간색으로 바뀌고 삭제되거나 이동 될 수 있습니다. I는 지금 싶은 것이JavaFx 2.x : 일단 그려진 선을 수정하는 방법은 무엇입니까?

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); 
     } 
    } 
    } 
} 
} 

새로운 단 X, Y 점 (그림에서 A와 B) 단부 또는 꼬리 포인트 중 하나를 선택함으로써 선로 길이 또는 경사를 변경하여 설정하는

enter image description here

어떻게 수행하나요?

감사합니다.

+0

, 나는 당신이 ('구성 요소의 "더러운"영역을 repaint'에있을 거라고 생각 즉 어디 검은 색을 선이 그려진다). – mre

+1

@mre JavaFX 렌더링은 Swing과는 완전히 다르며, 사용자 코드가 아닌 JavaFX 시스템에서 처리 한 더티 영역 및 다시 그리기가있는 유지 된 장면 그래프를 사용합니다. – jewelsea

+0

@jewelsea, 정보 주셔서 감사합니다! :) – mre

답변

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); 
    } 
} 
+0

대단히 Bhupendra 훌륭한 코드를 고맙습니다! –

+0

이제는 두 코드를 혼합하여 마우스 오른쪽 버튼으로 contextMenu를 클릭하여 항목을 편집 및 삭제하고 행을 첫 번째 상위 코드로 옮기는 것이 좋습니다. 그렇게 쉬운 ... –

관련 문제