2012-05-18 75 views
1

我有一個開關按鈕組有4點不同的指針JavaFX的2組通用類

enter image description here

當我選擇十字按鈕(最右邊的一個)我有作爲遵循 enter image description here

每個按鈕調用一個不同的行指針跟隨:

  1. 最左邊的一個按鈕:它是無林一個簡單的指針Ë;
  2. 第二顯示器只顯示垂直線指針的運動鏈接;
  3. 第三隻水平線指針運動鏈接;
  4. 十字準線。

我想創建一個泛型類來設置選定的行,以便我可以在繪製例程中調用它。

這個泛型/抽象類「將包含」特定的行指針跟隨器代碼,當選擇適當的按鈕時,這樣繪製例程只會引用泛型類來繪製選擇指針行跟隨器。

與十字線的代碼是:在手

public class JavaFXApplicationMove extends Application { 

Path path; 
BorderPane pane; 
Rectangle rect; 
Line LH; 
Line LV; 
XYChart.Series series1 = new XYChart.Series();  

SimpleDoubleProperty rectinitX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectinitY = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectX = new SimpleDoubleProperty(); 
SimpleDoubleProperty rectY = new SimpleDoubleProperty(); 

@Override 
public void start(Stage stage) { 

stage.setTitle("Lines plot"); 

final NumberAxis xAxis = new NumberAxis(1, 12, 1); 
final NumberAxis yAxis = new NumberAxis(0.53000, 0.53910, 0.0005); 

xAxis.setAnimated(false); 
yAxis.setAnimated(false); 

yAxis.setTickLabelFormatter(new NumberAxis.DefaultFormatter(yAxis) { 

    @Override 
    public String toString(Number object) { 
     return String.format("%7.5f", object); 
    } 
}); 


//final LineChart<String, Number> lineChart = new LineChart<String, Number> (xAxis, yAxis); 
final LineChart<Number, Number> lineChart = new LineChart<Number, Number>(xAxis, yAxis); 

lineChart.setCreateSymbols(false); 
lineChart.setAlternativeRowFillVisible(false); 
lineChart.setAnimated(true); 

series1.setName("Stock1"); 
series1.getData().add(new XYChart.Data(1, 0.53185)); 
series1.getData().add(new XYChart.Data(2, 0.532235)); 
series1.getData().add(new XYChart.Data(3, 0.53234)); 
series1.getData().add(new XYChart.Data(4, 0.538765)); 
series1.getData().add(new XYChart.Data(5, 0.53442)); 
series1.getData().add(new XYChart.Data(6, 0.534658)); 
series1.getData().add(new XYChart.Data(7, 0.53023)); 
series1.getData().add(new XYChart.Data(8, 0.53001)); 
series1.getData().add(new XYChart.Data(9, 0.53589)); 
series1.getData().add(new XYChart.Data(10, 0.53476)); 

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

stage.setScene(scene);   

path = new Path(); 
path.setStrokeWidth(5); 
path.setStroke(Color.RED); 


scene.setOnMouseClicked(mouseHandler); 
scene.setOnMouseDragged(mouseHandler); 
scene.setOnMouseEntered(mouseHandler); 
scene.setOnMouseExited(mouseHandler); 
scene.setOnMouseMoved(mouseHandler); 
scene.setOnMousePressed(mouseHandler); 
scene.setOnMouseReleased(mouseHandler); 


rect = new Rectangle(); 
rect.setFill(Color.web("yellow", 0.3)); 
rect.setStroke(Color.MAGENTA); 
rect.setStrokeDashOffset(50); 
rect.widthProperty().bind(rectX.subtract(rectinitX)); 
rect.heightProperty().bind(rectY.subtract(rectinitY)); 
pane.getChildren().add(rect); 

//LH=new Line(); 
LH=LineBuilder.create() 
     .startX(0) 
     .startY(0) 
     .endX(10) 
     .endY(.535) 
     .strokeWidth(1) 
     .stroke(Color.BLACK) 
     .build(); 
pane.getChildren().add(LH); 

LV=LineBuilder.create() 
     .startX(0) 
     .startY(0) 
     .endX(10) 
     .endY(.535) 
     .strokeWidth(1) 
     .stroke(Color.BLACK) 
     .build(); 
pane.getChildren().add(LV); 

stage.show(); 
} 

EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() { 

@Override 
public void handle(MouseEvent mouseEvent) { 

    if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) { 
     rect.setX(mouseEvent.getX()); 
     rect.setY(mouseEvent.getY()); 
     rectinitX.set(mouseEvent.getX()); 
     rectinitY.set(mouseEvent.getY()); 
     LH.setStartX(0); 
     LH.setStartY(0); 
     LH.setEndX(0); 
     LH.setEndY(0); 

     LV.setStartX(0); 
     LV.setStartY(0); 
     LV.setEndX(0); 
     LV.setEndY(0); 
    } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_RELEASED) { 
     rectX.set(mouseEvent.getX()); 
     rectY.set(mouseEvent.getY()); 
     // Hide the rectangle 
     rectX.set(0); 
     rectY.set(0); 
    } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED || mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED) { 
     LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter(); 
     NumberAxis yAxis = (NumberAxis) lineChart.getYAxis(); 
     NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); 
     System.out.println("(a) xAxis.getLowerBound() "+xAxis.getLowerBound()+" "+xAxis.getUpperBound()); 
     double Tgap = xAxis.getWidth()/(xAxis.getUpperBound() - xAxis.getLowerBound()); 
     double newXlower=xAxis.getLowerBound(), newXupper=xAxis.getUpperBound(); 
     double newYlower=yAxis.getLowerBound(), newYupper=yAxis.getUpperBound(); 

     double xAxisShift = getSceneShift(xAxis); 
     double yAxisShift = getSceneShift(yAxis); 

     double yAxisStep=yAxis.getHeight()/(yAxis.getUpperBound()-yAxis.getLowerBound()); 
     double CurrentPrice=yAxis.getUpperBound()-((mouseEvent.getY()-yAxisShift)/yAxisStep); 

     double Delta=0.3; 
     if(mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED){ 
     if(rectinitX.get() < mouseEvent.getX()){  
      newXlower=xAxis.getLowerBound()-Delta; 
      newXupper=xAxis.getUpperBound()-Delta; 
     } 
     else if(rectinitX.get() > mouseEvent.getX()){  
      newXlower=xAxis.getLowerBound()+Delta; 
      newXupper=xAxis.getUpperBound()+Delta; 
     }  
     xAxis.setLowerBound(newXlower); 
     xAxis.setUpperBound(newXupper); 

     if(rectinitY.get() < mouseEvent.getY()){  
      newYlower=yAxis.getLowerBound()+Delta/1000; 
      newYupper=yAxis.getUpperBound()+Delta/1000; 
     } 
     else if(rectinitY.get() > mouseEvent.getY()){  
      newYlower=yAxis.getLowerBound()-Delta/1000; 
      newYupper=yAxis.getUpperBound()-Delta/1000; 
     } 
     yAxis.setLowerBound(newYlower); 
     yAxis.setUpperBound(newYupper); 

     }   

     //System.out.println("(b) xAxis.getLowerBound() "+xAxis.getLowerBound()+" "+xAxis.getUpperBound()); 
     rectinitX.set(mouseEvent.getX()); 
     rectinitY.set(mouseEvent.getY()); 

     if(mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED && mouseEvent.getY()>yAxisShift && mouseEvent.getY()<yAxisShift+yAxis.getHeight() && mouseEvent.getX()>xAxisShift && mouseEvent.getX()<xAxisShift+xAxis.getWidth()){ 
     LH.setStartX(xAxisShift); 
     LH.setStartY(mouseEvent.getY()); 
     LH.setEndX(xAxisShift+xAxis.getWidth()); 
     LH.setEndY(mouseEvent.getY()); 

     LV.setStartX(mouseEvent.getX()); 
     LV.setStartY(yAxisShift); 
     LV.setEndX(mouseEvent.getX()); 
     LV.setEndY(yAxisShift+yAxis.getHeight()); 


     double XX=((mouseEvent.getX() - xAxisShift)/Tgap) + xAxis.getLowerBound(); 
     double YY=CurrentPrice; 
     series1.setName(String.format("%.2g%n",XX) + ", " + String.format("%.4g%n",YY)); 

     int XLB=(int) xAxis.getLowerBound(); 
     int XUB=(int) xAxis.getUpperBound(); 

     } 

    } 
    } 
    }; 
private static double getSceneShift(Node node) { 
double shift = 0; 
do { 
    shift += node.getLayoutX(); 
    node = node.getParent(); 
} while (node != null); 
return shift; 
} 

private static String getHIstLOstY(XYChart.Series S,int XLowerBound,int XUpperBound) { 
double ValLOst=1000000; 
double ValHIst=-1000000; 
for(int i=XLowerBound; i<XUpperBound; i++){ 
    double P=GetPrice(S,i); 
    if(ValHIst<P){ 
     ValHIst=P; 
    } 
    if(ValLOst>P){ 
     ValLOst=P; 
    } 
} 
return Double.toString(ValLOst) + "," + Double.toString(ValHIst); 
} 

private static double GetPrice(XYChart.Series S,int IX) { 
Object SVal=S.getData().get(IX); 
//return SVal.toString().toLowerCase(); 
String Temp=SVal.toString().replaceAll("Data", ""); 
Temp=Temp.replace("[", ""); 
Temp=Temp.replace("]", ""); 
String[] TempArray=Temp.split(","); 
return Double.parseDouble(TempArray[1]);  
} 


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

回答

2

所有繪圖路由在EventHandler<MouseEvent>。因此,最簡單的方式來改變十字線類型將取代各種處理程序。

通過深入一點,您會發現每個十字線圖都基於相似的參數,可以分爲3個步驟:開始,更新和結束。

從我在代碼中看到的重要參數是sceneShiftX, sceneShiftY, mouseX, mouseY。所以,你需要重構出繪製從鼠標事件處理程序代碼到一個單獨的類下一個方法:

public class SimpleCrosshair { 
    public void start(double mouseX, double mouseY); 
    public void update(double sceneShiftX, double sceneShiftY, double mouseX, double mouseY); 
    public void finish(); 
} 

你把十字線相關的代碼從MouseEvent.MOUSE_PRESSEDstart(),從MouseEvent.MOUSE_RELEASED完成()和MouseEvent.MOUSE_DRAGGEDupdate()

現在,您將鼠標事件中的所有繪圖數據分開,並且可以引入一個interface Crosshair,它看上去類似於上面的類,並且會生成SimpleCrosshair implement Crosshair

其餘的很容易。創建實現Crosshair的類,該類將執行其他十字準線類型的繪製,並引入字段private Crosshair currentCrosshair;,您可以使用工具欄按鈕單擊上的具體實現來更新該字段。

而且你的鼠標事件處理程序將看起來像(除了變焦邏輯):

EventHandler<MouseEvent> mouseHandler = new EventHandler<MouseEvent>() { 
     @Override 
     public void handle(MouseEvent mouseEvent) { 

      if (mouseEvent.getEventType() == MouseEvent.MOUSE_PRESSED) { 
       currentCrosshair.start(mouseEvent.getX(), mouseEvent.getY()); 
      } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_RELEASED) { 
       currentCrosshair.finish(); 
      } else if (mouseEvent.getEventType() == MouseEvent.MOUSE_DRAGGED || mouseEvent.getEventType() == MouseEvent.MOUSE_MOVED) { 
       LineChart<Number, Number> lineChart = (LineChart<Number, Number>) pane.getCenter(); 
       NumberAxis yAxis = (NumberAxis) lineChart.getYAxis(); 
       NumberAxis xAxis = (NumberAxis) lineChart.getXAxis(); 

       double xAxisShift = getSceneShift(xAxis); 
       double yAxisShift = getSceneShift(yAxis); 
       currentCrosshair.update(xAxisShift, yAxisShift, mouseEvent.getX(), mouseEvent.getY()); 

      } 

     } 
    }