javafx 二维图形编程及可视化操作

   
    javaFx 2D编程  

 
java8开始,对java fx进行大力支持,弥补了fx对图形编程方面的缺失,重要的java终于支持硬件加速。
相信有兴趣的都已经看过fx3D编程推广视频,场面非常震撼。
学习过程中遇到很多问题,有一些个人的新的,拿出来同大家分享,本文原创,请支持。

相信对桌面端有编程经验的都知道WPF了,javaFx类似WPF的MVVM开发模式,将逐渐取代Swing,相对于Swing它能
帮助我们把视图与逻辑层解耦,是开发人员思绪非常清楚。本文将针对在javafx基础上的图形学进行介绍。

如果是初学者的话,建议先看看fx界面开发基础,我推荐这篇教程,比较详细: 点击打开链接

fx中布局非常复杂,建议搭建用JavaFX Scene Builder ,官方可以下载到。好了,正文开始啦

下面我们分别创建两个场景:

Fxml场景代码如下:

继承Application会强制重写 start方法,main.fxml是我们创建的界面布局

 
	public void start(Stage primaryStage){
	 
		     /******************创建Scene*********************/
		    Parent rootXml = null;
			try {
				rootXml = FXMLLoader.load(getClass()
				        .getResource("/application/main.fxml"));
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
		 
					   
		    Scene scene = new Scene(rootXml,1000,600);
		 	scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
		 	 
			primaryStage.setTitle("3DPluginDemo");		 
			primaryStage.setScene(scene);
			primaryStage.show();
 
	}
或者我们直接用代码创建,代码量太大,之后会将案例源码放上大家自己查看。

 Fxml一种以XML的格式表示JavaFX界面对象的文件,FXML文件中的每一个元素可以映射到JavaFX中的一个类,每个FXML元素的属性或方法都可以映射为该对应JavaFXML类的属性或方法,类似于html。

使用fxml需要我们创建一个类GetControl,专门用于获取fxml中每个元素相应属性或方法。

GetControl 获取元素需要继承 Initializable

获取main.fxml中元素需要注解@fxml,并且需要将当前控件的类型和fxml中相对性,其对象(but1)与fxml中元素的fx:id相同

public class GetControl implements Initializable {
 
  
 @FXML
	private Button but1;}
   


 
  main.fxml中需要添加映射类的路径 
   
  

 蓝色背景是我们添加映射类的方式。

fx:controller="application.GetControl.GetControl">

那么经过上面配置好映射关系,我们可以再getControl中拿到界面控件对象。

 注意:

 开发过程中我们需要可能会遇到子场景不会同步父窗体一起放大缩小,因为我们需要将子场景绑定父容器,这一点很重要。

 最后我们将绘制并捕获选中图形,我们将的绘制的对象进行封装和注册相应的响应事件,这样图形将不仅仅是绘制在界面的图形。这里我要提一下,fx本身不像Swing需要实现mouseListener类来监听控件所有操作。代码如下,下面CreateObj将直接返回场景。

	package com.GGB.Two;


 
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;


import javafx.event.Event;
import javafx.event.EventHandler;
import javafx.geometry.Point2D;
import javafx.scene.Group;
import javafx.scene.Parent;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.Circle;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.StrokeType;


/** 二维CAD逻辑控制系统*/
public class PlaneControl 
{ 
	
	/** 是否选中对象*/
 	public boolean SelectCircle=false;
 	/**当前选中的对象*/
	public Circle SelectCircleObj=null;
	
	/**当前选中图形的数据集合*/
	 List pList;
	 
	 public HashMap>  ModelhashMap =new HashMap<>(); 
	 
	public Group CreateObj() 
			/**创建图形组对象*/
		  //Creating a Group object  
	      Group root = new Group();
	      
	      /**创建图形对像*/
	       Path path = new Path(); 
	        pList =  new ArrayList<>();
	       double randomNum= (Math.random()*300);//随机生成起始值0~100
	       double Start_Y= (Math.random()*800);
	     
	     
	       int randomSize ; 
	       for (int i = 0; i < 300; i++) //生成随机线图
	       {
	    	   if(i==0)
	    	   {
	    		   MoveTo moveTo = new MoveTo(randomNum,Start_Y ); 
	    		   path.getElements().add(moveTo);//起始点
	    		   pList.add(new Point2D(randomNum,Start_Y));//数组保存线段点集
	    		   randomSize=(int)(Math.random()*10);
		    	   randomNum+=randomSize;
	    	   }  
	    	   else 
	    	   { 
		    	   randomSize=(int)(Math.random()*10);
		    	   randomNum+=randomSize;
		    	   randomSize=(int)(Math.random()*10);
		    	   Start_Y += randomSize;
		    	   LineTo point =new LineTo( randomNum,Start_Y);
		    	   path.getElements().addAll(point);
		    	   pList.add(new Point2D(randomNum,Start_Y));//数组保存线段点集
	    	   }
		   }	 
	       
	       ModelhashMap.put(path, pList);
	        
	      /**路径点击捕获,并生成结点*/
	      path.setOnMouseClicked(new EventHandler() {


	    	  /** 线点击事件,生成点击对像*/
			@Override
			public void handle(Event event) {
				MouseEvent  mouseEvent	=(MouseEvent )event;
				double x=mouseEvent.getX(); 
				double y=mouseEvent.getY();
				System.out.println("生成对象---------X"+x+"------------Y:"+y);
				pList= ModelhashMap.get(path);
				CreateEIrcle(x,y,3);
			}


			/** 
			 * 选中线下
			 * 点击生成对象方法
			 * */
			private void CreateEIrcle( double centerx,double centery,double radius) 
			{
			 
					Circle circle = new Circle(centerx, centery, radius);
					circle.setFill(Color.RED);
					root.getChildren().addAll(circle);
				 
					/**按下状态*/
					circle.setOnMousePressed(new EventHandler() {


						@Override
						public void handle(Event event) 
						{
							SelectCircleObj=circle;
							SelectCircle=true; 
							System.out.println("已右击选中目标!-->true" );
						}
					} );
					/**释放状态*/
					circle.setOnMouseReleased(new EventHandler() {


						@Override
						public void handle(Event event) {
							 
							SelectCircle=false; 
							System.out.println("已释放目标对象!-->false" );
							SelectCircleObj=null;
						}
					});
					/** 拖拽*/
					circle.setOnMouseDragged(new EventHandler() {


						@Override
						public void handle(Event event) {
							MouseEvent  mouseEvent	=(MouseEvent)event;
							System.err.println("----->"+mouseEvent.getX());
							if(SelectCircle) 
														Point2D point2d = Calculate(mouseEvent.getX(),mouseEvent.getY());
							SelectCircleObj.setCenterX(point2d.getX());
							SelectCircleObj.setCenterY(point2d.getY());
							}
						}
					});
				 
			}
			
		}); 
	      
	      root.getChildren().addAll(path); 	       
	      return root;   
	}


	/********************************计算当前拖拽点的坐标,时间有限,滑动坐标并没有精确计算 *************/
	/**
	 * 计算当前输入的坐标数据 
	 * @param X 
	 * @param Y
	 * @return 返回定位后的位置
	 */
	  
	public Point2D Calculate(double X,double Y) 
	{
		 // pList
	  Point2D point2d =	getApproach_X(X,Y,pList);
		 
		return point2d;
	}
	
	 
	/***
	 * 根据当前传如数据,得到最近接近的点
	 * @param x
	 * @param src
	 * @return 返回最接近的点
	 */
	 private Point2D getApproach_X(Double x,Double y , List src) {
		
		 if (src == null) {
             return null;
         }
         if (src.size() == 1) {
             return src.get(0);
         }
         double minDifference_X = Math.abs(src.get(0).getX() - x);
         double minDifference_Y = Math.abs(src.get(0).getY() - y);
         int minIndex = 0;
         for (int i = 1; i < src.size(); i++) {
            double temp_X = Math.abs(src.get(i).getX() - x);
            double temp_Y = Math.abs(src.get(i).getY() - y);
             if (temp_X  < minDifference_X) {//获取最小范围值
                 minIndex = i;
                 minDifference_X = temp_X;
		     }
            /* if (temp_Y  < minDifference_Y) {
                 minIndex = i;
                 minDifference_Y = temp_Y;
		     }*/ 
             
		  }
		     return src.get(minIndex);
	 }
	 
	 
}


最后将界面和效果展示给大家:

操作:点击生成对象,生成右边的曲线

 当鼠标选定曲线并在曲线上时,点击可生成红色节点

按住节点,可以拖拽使得红点在线上移动,红点不会脱离曲线


javafx 二维图形编程及可视化操作_第1张图片



好了,后面我们将继续3D图形的开发和学习,将在后面将本文源码一块发给大家。另:转发请注明出处。



你可能感兴趣的:(javaFx)