2017-11-25 3 views
2

무한 2 차원 데카르트 좌표계처럼 동작하는 사용자 지정 창을 작성해야합니다. 처음에 내가 0,0을 창 가운데에 넣기를 원할 때. 사용자는 마우스 왼쪽 버튼을 누른 채 드래그하여 패널을 탐색 할 수 있어야합니다. 확대/축소 기능이 있어야합니다. 또한 특정 좌표에 노드를 배치 할 수 있어야합니다.Infinite JavaFX 좌표계 창

물론 저는 이것이 매우 구체적인 컨트롤이라는 것을 알고 있습니다. 단계별 지시 사항을 제공하거나 저에게 쓰도록 요청하는 사람은 없습니다.

저는 JFX 커스텀 컨트롤의 새로운 세계에 불과하며,이 문제, 특히 전체 무한한 것에 접근하는 방법을 모른다.

답변

2

생각보다 어렵지 않습니다. 간단한 창으로 시작하십시오. 그것은 이미 당신에게 infinte 좌표계를 제공합니다. 귀하의 요구 사항과 유일한 차이점은 0/0 점이 왼쪽 상단 모서리에 있고 중간 모서리에 있지 않다는 점입니다. 창에 변환 변환을 적용하면이 문제를 해결할 수 있습니다. 해당 마우스 리스너를 창에 추가하여 유사한 방식으로 확대/축소 및 패닝을 수행 할 수 있습니다.

+0

감사합니다! 너 나를 나를 올바른 길로 인도했다. 나는 ScrollPane에서 Pane을 사용하여 끝냈다. 나는 ScrollBar를 둘 다 사용하지 않기 때문에 ScrollPane은 패닝으로 만 이동할 수 있습니다. – DeLoreanDriver

2

here과 같이 임의의 콘텐츠를 Canvas에 렌더링하는 것이 하나의 방법입니다. 해당 GraphicsContext을 사용하면 좌표를 최대한 제어 할 수 있습니다. 구체적인 예로, jfreechart-fx을 사용하여 차트를 렌더링하고, ChartViewerCanvas을 확장하는 ChartCanvas을 보유합니다. 이 example부터 시작하여 아래의 변형은 세 축에 해당 점을 추가 한 후 도메인 축이 0을 중심으로하는 간격으로 확장되도록 설정합니다. 확대하려면 마우스 휠 또는 상황에 맞는 메뉴를 사용하십시오. 확대/축소 및 이동에 대한 자세한 내용은 관련 answer을 참조하십시오.

for (double t = -3; t <= 3; t += 0.5) { 
    series.add(t, Math.sin(t) + i); 
} 
… 
xAxis.setRange(-Math.PI, Math.PI); 
… 
plot.setDomainPannable(true); 

image

import javafx.application.Application; 
import javafx.scene.Scene; 
import javafx.stage.Stage; 
import org.jfree.chart.JFreeChart; 
import org.jfree.chart.axis.NumberAxis; 
import org.jfree.chart.entity.ChartEntity; 
import org.jfree.chart.entity.LegendItemEntity; 
import org.jfree.chart.entity.XYItemEntity; 
import org.jfree.chart.fx.ChartViewer; 
import org.jfree.chart.fx.interaction.ChartMouseEventFX; 
import org.jfree.chart.fx.interaction.ChartMouseListenerFX; 
import org.jfree.chart.labels.StandardXYToolTipGenerator; 
import org.jfree.chart.plot.XYPlot; 
import org.jfree.chart.renderer.xy.XYLineAndShapeRenderer; 
import org.jfree.data.xy.XYSeries; 
import org.jfree.data.xy.XYSeriesCollection; 

/** 
* @see https://stackoverflow.com/a/44967809/230513 
* @see https://stackoverflow.com/a/43286042/230513 
*/ 
public class VisibleTest extends Application { 

    @Override 
    public void start(Stage stage) { 
     XYSeriesCollection dataset = new XYSeriesCollection(); 
     for (int i = 0; i < 3; i++) { 
      XYSeries series = new XYSeries("value" + i); 
      for (double t = -3; t <= 3; t += 0.5) { 
       series.add(t, Math.sin(t) + i); 
      } 
      dataset.addSeries(series); 
     } 
     NumberAxis xAxis = new NumberAxis("domain"); 
     xAxis.setRange(-Math.PI, Math.PI); 
     NumberAxis yAxis = new NumberAxis("range"); 
     XYLineAndShapeRenderer renderer = new XYLineAndShapeRenderer(true, true); 
     renderer.setBaseToolTipGenerator(new StandardXYToolTipGenerator()); 
     XYPlot plot = new XYPlot(dataset, xAxis, yAxis, renderer); 
     JFreeChart chart = new JFreeChart("Test", plot); 
     ChartViewer viewer = new ChartViewer(chart); 
     viewer.addChartMouseListener(new ChartMouseListenerFX() { 
      @Override 
      public void chartMouseClicked(ChartMouseEventFX e) { 
       ChartEntity ce = e.getEntity(); 
       if (ce instanceof XYItemEntity) { 
        XYItemEntity item = (XYItemEntity) ce; 
        renderer.setSeriesVisible(item.getSeriesIndex(), false); 
       } else if (ce instanceof LegendItemEntity) { 
        LegendItemEntity item = (LegendItemEntity) ce; 
        Comparable key = item.getSeriesKey(); 
        renderer.setSeriesVisible(dataset.getSeriesIndex(key), false); 
       } else { 
        for (int i = 0; i < dataset.getSeriesCount(); i++) { 
         renderer.setSeriesVisible(i, true); 
        } 
       } 
      } 

      @Override 
      public void chartMouseMoved(ChartMouseEventFX e) {} 
     }); 
     stage.setScene(new Scene(viewer)); 
     stage.setTitle("JFreeChartFX"); 
     stage.setWidth(640); 
     stage.setHeight(480); 
     stage.show(); 
    } 

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

저는 여러 가지 아이디어를 활용했습니다. 많은 예제를 지적 해 주시고 그러한 상세한 답변을 쓸 시간을 내 주셔서 감사합니다! – DeLoreanDriver