1

我有一个带有 4 个不同指针的切换按钮组

在此处输入图像描述

当我选择十字准线按钮(最右边的一个)时,我有如下 在此处输入图像描述

每个按钮调用一个不同的行指针跟随器:

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

1 回答 1

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_PRESSEDblock to start()、 from MouseEvent.MOUSE_RELEASEDto finish() 和 from MouseEvent.MOUSE_DRAGGEDto update()

现在,当您将所有绘图数据与鼠标事件分开并可以引入一个interface Crosshair看起来类似于上面的类和 make 时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());

            }

        }
    } 
于 2012-05-21T17:25:22.167 回答