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;}
蓝色背景是我们添加映射类的方式。
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);
}
}
最后将界面和效果展示给大家:
操作:点击生成对象,生成右边的曲线
当鼠标选定曲线并在曲线上时,点击可生成红色节点
按住节点,可以拖拽使得红点在线上移动,红点不会脱离曲线
好了,后面我们将继续3D图形的开发和学习,将在后面将本文源码一块发给大家。另:转发请注明出处。