支持函数表达式和change表达式

This commit is contained in:
billkiller
2019-07-27 22:37:52 +08:00
parent 7b5e56d6f7
commit bc421b87b9
50 changed files with 1434 additions and 1320 deletions

View File

@@ -2,10 +2,7 @@ package cn.edu.scau.biubiusuisui.annotation;
import java.lang.annotation.*;
/**
* @Author jack
* @Date:2019/7/4 13:58
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Inherited

View File

@@ -4,8 +4,8 @@ import java.lang.annotation.*;
/**
* This is use for marking A controller as FX-Plus Controller
* @Author jack
* @Date:2019/6/25 1:34
@Author jack
@Date:2019/6/25 1:34
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)

View File

@@ -0,0 +1,14 @@
package cn.edu.scau.biubiusuisui.annotation;
import java.lang.annotation.*;
/**
* @Author jack
* @Date:2019/7/27 3:06
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
@Inherited
public @interface FXValue {
String value();
}

View File

@@ -1,8 +1,8 @@
package cn.edu.scau.biubiusuisui.config;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import cn.edu.scau.biubiusuisui.expression.MyBeanAdapter;
import cn.edu.scau.biubiusuisui.expression.MyExpressionValue;
import cn.edu.scau.biubiusuisui.expression.data.MyBeanAdapter;
import cn.edu.scau.biubiusuisui.expression.data.MyExpressionValue;
import cn.edu.scau.biubiusuisui.factory.FXFactory;
import com.sun.javafx.beans.IDProperty;
import com.sun.javafx.fxml.BeanAdapter;

View File

@@ -18,7 +18,6 @@ import java.util.Set;
* @Author jack
* @Date:2019/6/25 2:54
*/
public class FXPlusApplication {
private static FXWindowParser windowAnnotationParser = new FXWindowParser();
@@ -62,7 +61,6 @@ public class FXPlusApplication {
private static void loadFXPlusClass(String className,BeanBuilder beanBuilder) throws ClassNotFoundException {
Class clazz = Class.forName(className);
if(clazz.getAnnotation(FXWindow.class)!=null) {
System.out.println(className);
FXFactory.loadFXController(clazz, beanBuilder);
}
}

View File

@@ -1,16 +1,16 @@
package cn.edu.scau.biubiusuisui.example.moveDemo;
package cn.edu.scau.biubiusuisui.example.actionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.annotation.FXSender;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* @Author jack
* @Date:2019/6/25 7:05
* @Date:2019/7/27 1:43
*/
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.moveDemo"})
//项目目录中带有中文字符会导致无法启动
@FXScan(base = "cn.edu.scau.biubiusuisui.example.actionDemo")
public class Demo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {

View File

@@ -0,0 +1,58 @@
package cn.edu.scau.biubiusuisui.example.actionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXBind;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXData;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import java.text.SimpleDateFormat;
/**
* @Author jack
* @Date:2019/7/27 1:43
*/
@FXController(path = "actionDemo.fxml")
@FXWindow(title = "actionDemo")
public class MainController extends FXBaseController {
@FXML
@FXBind("text=${@toUs(time.text)}")
private Label us;
@FXML
@FXBind("text=${@toJp(time.text)}")
private Label jp;
@FXML
private TextField time;
@FXML
@FXBind("text=${@toUk(time.text)}")
private Label uk;
public String toUs(String value){
double money = Double.valueOf(value);
double percent = 0.1454;
return String.valueOf(money * percent);
}
public String toJp(String value){
double money = Double.valueOf(value);
double percent = 15.797;
return String.valueOf(money * percent);
}
public String toUk(String value){
double money = Double.valueOf(value);
double percent = 0.1174;
return String.valueOf(money * percent);
}
}

View File

@@ -1,29 +1,19 @@
package cn.edu.scau.biubiusuisui.example;
package cn.edu.scau.biubiusuisui.example.actionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
import cn.edu.scau.biubiusuisui.annotation.FXField;
import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
/**
* @Author jack
* @Date:2019/6/27 20:02
* @Date:2019/7/27 12:19
*/
@FXEntity
@Component
public class Student {
public class User {
@FXField
private String name;
@FXField
private String password;
public String getName() {
return name;
}

View File

@@ -1,19 +0,0 @@
package cn.edu.scau.biubiusuisui.example.expressionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* @Author jack
* @Date:2019/6/25 7:05
*/
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.expressionDemo"})
//项目目录中带有中文字符会导致无法启动
public class Demo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXPlusApplication.start(Demo.class);
}
}

View File

@@ -1,74 +0,0 @@
package cn.edu.scau.biubiusuisui.example.expressionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXBind;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXData;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import cn.edu.scau.biubiusuisui.example.Student;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.StageStyle;
/**
* @Author jack
* @Date:2019/7/4 11:36
*/
@FXController(path = "Main.fxml")
@FXWindow(title = "hello", resizable = true, draggable = true)
public class Main2 extends FXBaseController {
@FXData
@FXBind(
{
"name=${usr.text}",
"password=${psw.text}"
}
)
Student student = new Student();
@FXML
private PasswordField psw;
@FXML
private Label label;
@FXML
private TextField usr;
@FXML
private Button resetBtn;
@FXML
private Button loginBtn;
@FXML
private Label usrMsg;
@FXBind("text=${student.name}")
@FXML
private Label pswMsg;
@FXML
void login(ActionEvent event) {
System.out.println("user:" + student.getName());
System.out.println("psw:" + student.getPassword());
if ("admin".equals(student.getName()) && "admin".equals(student.getPassword())) {
System.out.println("Ok");
} else {
System.out.println("fail");
}
}
@FXML
void reset(ActionEvent event) {
psw.setText("");
usr.setText("");
}
}

View File

@@ -1,19 +0,0 @@
package cn.edu.scau.biubiusuisui.example.listViewExpressionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import javafx.application.Application;
import javafx.stage.Stage;
/**
* @Author jack
* @Date:2019/7/24 22:56
*/
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.expressionDemo"})
//项目目录中带有中文字符会导致无法启动
public class Demo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
FXPlusApplication.start(Demo.class);
}
}

View File

@@ -1,11 +0,0 @@
package cn.edu.scau.biubiusuisui.example.listViewExpressionDemo;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
/**
* @Author jack
* @Date:2019/7/24 22:58
*/
public class MainController extends FXBaseController {
//待开发
}

View File

@@ -1,42 +0,0 @@
package cn.edu.scau.biubiusuisui.example.moveDemo;
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
import cn.edu.scau.biubiusuisui.annotation.FXField;
/**
* @Author jack
* @Date:2019/7/25 9:24
*/
@FXEntity
public class CircleBean {
@FXField
double x = 0;
@FXField
double y = 0;
public double getX() {
return x;
}
public void setX(double x) {
this.x = x;
}
public double getY() {
return y;
}
public void setY(double y) {
this.y = y;
}
@Override
public String toString() {
return "CircleBean{" +
"x=" + x +
", y=" + y +
'}';
}
}

View File

@@ -1,72 +0,0 @@
package cn.edu.scau.biubiusuisui.example.moveDemo;
import cn.edu.scau.biubiusuisui.annotation.FXBind;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXData;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import cn.edu.scau.biubiusuisui.example.Student;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.shape.Circle;
/**
* @Author jack
* @Date:2019/7/4 11:36
*/
@FXController(path = "moveDemo.fxml")
@FXWindow(title = "hello", resizable = true, draggable = true)
public class Main2 extends FXBaseController {
@FXML
@FXBind({"layoutX=${bean.x}","layoutY=${bean.y}"})
private Circle circle;
@FXData
CircleBean bean = new CircleBean();
@FXML
@FXBind("text=${bean.x}")
private TextField xinput;
@FXML
@FXBind("text=${bean.y}")
private TextField yinput;
@FXML
private Button xSub;
@FXML
private Button xAdd;
@FXML
private Button ySub;
@FXML
private Button yAdd;
@FXML
public void addX(){
double x = bean.getX() + 5 ;
bean.setX(x);
System.out.println("? ? " + bean);
}
@FXML
public void subX(){
double x = bean.getX() - 5 ;
bean.setX(x);
}
@FXML
public void addY(){
double y = bean.getY() + 5 ;
bean.setY(y);
}
@FXML
public void subY(){
double y = bean.getY() - 5 ;
bean.setY(y);
}
}

View File

@@ -1,54 +0,0 @@
package cn.edu.scau.biubiusuisui.example.springDemo;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
import cn.edu.scau.biubiusuisui.example.Student;
import cn.edu.scau.biubiusuisui.factory.FXEntityFactory;
import cn.edu.scau.biubiusuisui.factory.FXFactory;
import javafx.beans.property.Property;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.stage.StageStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @Author jack
* @Date:2019/7/4 11:36
*/
@FXController(path = "springDemo.fxml")
//@Component
//@FXWindow(title = "hello",resizable = true,style = StageStyle.UNDECORATED)
public class SpringController extends FXBaseController {
@Autowired
Student student;
@Autowired
Student studentProxy;
@FXML
Label label;
int count = 1;
@Override
public void initialize() {
System.out.println("為什麼");
}
@FXML
public void add(){
System.out.println("add");
}
public Student getStudent() {
return student;
}
public void setStudent(Student student) {
this.student = student;
}
}

View File

@@ -1,27 +0,0 @@
package cn.edu.scau.biubiusuisui.example.springDemo;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import cn.edu.scau.biubiusuisui.factory.BeanBuilder;
import javafx.application.Application;
import javafx.stage.Stage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author jack
* @Date:2019/7/7 10:43
*/
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.springDemo"})
public class SpringDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
FXPlusApplication.start(SpringDemo.class, new BeanBuilder() {
@Override
public Object getBean(Class type) {
return context.getBean(type);
}
});
}
}

View File

@@ -1,35 +0,0 @@
package cn.edu.scau.biubiusuisui.example.springDemo2;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import cn.edu.scau.biubiusuisui.example.springDemo.SpringController;
import javafx.fxml.FXML;
import javafx.stage.StageStyle;
import org.springframework.stereotype.Component;
/**
* @Author jack
* @Date:2019/7/4 11:36
*/
@FXController(path = "springDemo2.fxml")
@Component
//@FXWindow(title = "hello",resizable = true,style = StageStyle.UNDECORATED)
public class SpringController2 extends FXBaseController {
@FXML
SpringController springController;
int count = 1;
@Override
public void initialize() {
}
@FXML
public void test(){
System.out.println("student"+springController.getStudent());
}
}

View File

@@ -1,27 +0,0 @@
package cn.edu.scau.biubiusuisui.example.springDemo2;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import cn.edu.scau.biubiusuisui.factory.BeanBuilder;
import javafx.application.Application;
import javafx.stage.Stage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author jack
* @Date:2019/7/7 10:43
*/
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.springDemo2"})
public class SpringDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
FXPlusApplication.start(SpringDemo.class, new BeanBuilder() {
@Override
public Object getBean(Class type) {
return context.getBean(type);
}
});
}
}

View File

@@ -1,29 +0,0 @@
package cn.edu.scau.biubiusuisui.example.springExpressionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXScan;
import cn.edu.scau.biubiusuisui.config.FXPlusApplication;
import cn.edu.scau.biubiusuisui.example.springDemo.SpringDemo;
import cn.edu.scau.biubiusuisui.factory.BeanBuilder;
import javafx.application.Application;
import javafx.stage.Stage;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
* @Author jack
* @Date:2019/6/25 7:05
*/
@FXScan(base = {"cn.edu.scau.biubiusuisui.example.springExpressionDemo"})
//项目目录中带有中文字符会导致无法启动
public class SpringExpressionDemo extends Application {
@Override
public void start(Stage primaryStage) throws Exception {
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
FXPlusApplication.start(SpringExpressionDemo.class, new BeanBuilder() {
@Override
public Object getBean(Class type) {
return context.getBean(type);
}
});
}
}

View File

@@ -1,82 +0,0 @@
package cn.edu.scau.biubiusuisui.example.springExpressionDemo;
import cn.edu.scau.biubiusuisui.annotation.FXBind;
import cn.edu.scau.biubiusuisui.annotation.FXController;
import cn.edu.scau.biubiusuisui.annotation.FXData;
import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import cn.edu.scau.biubiusuisui.example.Student;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.stage.StageStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
/**
* @Author jack
* @Date:2019/7/4 11:36
*/
@FXController(path = "SpringExpressionDemo.fxml")
@Component
@FXWindow(title = "hello", resizable = true, style = StageStyle.UNDECORATED,draggable = true)
public class SpringExpressionDemoController extends FXBaseController {
@FXData
@Autowired
@FXBind(
{
"name=${usr.text}",
"password=${psw.text}"
}
)
Student student;
@FXML
private Label label;
@FXML
private TextField usr;
@FXML
private Button resetBtn;
@FXML
private Button loginBtn;
@FXML
private Label usrMsg;
@FXML
private PasswordField psw;
@FXML
private Label pswMsg;
@FXML
void login(ActionEvent event) {
System.out.println("user:" + student.getName());
System.out.println("psw:"+student.getPassword());
if("admin".equals(student.getName())&&"admin".equals(student.getPassword())){
System.out.println("Ok");
}else{
System.out.println("fail");
}
}
@FXML
void reset(ActionEvent event) {
psw.setText("");
usr.setText("");
}
}

View File

@@ -0,0 +1,12 @@
package cn.edu.scau.biubiusuisui.exception;
/**
* @Author jack
* @Date:2019/7/27 3:00
*/
public class NoSuchChangeMethod extends Exception {
public NoSuchChangeMethod() {
super("No such change method");
}
}

View File

@@ -0,0 +1,9 @@
package cn.edu.scau.biubiusuisui.expression;
/**
* @Author jack
* @Date:2019/7/27 2:02
*/
public interface BindParser {
public void parse(Object target,String expression);
}

View File

@@ -1,78 +0,0 @@
package cn.edu.scau.biubiusuisui.expression;
import com.sun.istack.internal.NotNull;
import com.sun.javafx.fxml.expression.Expression;
import com.sun.javafx.fxml.expression.ExpressionValue;
import javafx.beans.property.Property;
/**
* 将FXBind中表达式建立绑定
* 格式如下
* 语法如下:
* FXBind("S")
* S -> left=right
* left -> property
* right -> ${expression}
* expression -> bean.field
*
* FXBind("text=${bean.field})
* textProperty 通过 adapter.getModelProeprty --> textProperty实例
* bean 通过namespace 获取因为bean有FXEntity标签所以返回包装过后的bean的property
* 最后
* left.bind(right)
*
* @Author jack
* @Date:2019/7/23 15:05
*/
public class ExpressionParser {
private Object namespace;
private static final String BIND_PREFIX = "${";
private static final String BIND_SUFIX = "}";
private static final String PROEPRTY = "Property";
public ExpressionParser(Object namespace) {
this.namespace = namespace;
}
private Property getLeftProperty(MyBeanAdapter myBeanAdapter, String key) {
return (Property) myBeanAdapter.getPropertyModel(key);
}
private MyExpressionValue getRightExpreesion(MyBeanAdapter myBeanAdapter,String key ,String rightExpression) {
Expression expression = Expression.valueOf(rightExpression);
Class clazz = myBeanAdapter.getType(key);
MyExpressionValue myExpressionValue = new MyExpressionValue(namespace, expression, clazz);
return myExpressionValue;
}
public void parse(Object object, @NotNull String expression) {
//check expression
int index = expression.indexOf("=");
if (index == -1) {
return;
}
String[] items = expression.split("=");
if (items.length != 2) {
return;
}
String left = items[0];
String right = items[1];
if (left == null || right == null) {
return;
}
right = right.trim();
if (right.startsWith(BIND_PREFIX) && right.endsWith(BIND_SUFIX)){
int length = right.length();
right = right.substring(2,length-1);
}
MyBeanAdapter myBeanAdapter = new MyBeanAdapter(object);
Property leftProperty = getLeftProperty(myBeanAdapter, left);
MyExpressionValue rightProperty = getRightExpreesion(myBeanAdapter,left,right);
leftProperty.bind(rightProperty);
}
}

View File

@@ -0,0 +1,17 @@
package cn.edu.scau.biubiusuisui.expression.action;
import cn.edu.scau.biubiusuisui.expression.BindParser;
/**
* @Author jack
* @Date:2019/7/27 2:03
*/
public class ChangeParser implements BindParser {
@Override
public void parse(Object target, String expression) {
}
}

View File

@@ -0,0 +1,10 @@
package cn.edu.scau.biubiusuisui.expression.data;
/**
* @Author jack
* @Date:2019/7/27 20:03
*/
@FunctionalInterface
public interface ExpFunction<T,U,R>{
R apply(T t, U u);
}

View File

@@ -0,0 +1,185 @@
package cn.edu.scau.biubiusuisui.expression.data;
import cn.edu.scau.biubiusuisui.annotation.FXValue;
import cn.edu.scau.biubiusuisui.exception.NoSuchChangeMethod;
import com.sun.istack.internal.NotNull;
import com.sun.javafx.fxml.expression.Expression;
import com.sun.javafx.fxml.expression.VariableExpression;
import javafx.beans.property.Property;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.NoSuchElementException;
/**
* 将FXBind中表达式建立绑定
* 格式如下
* 语法如下:
* FXBind("S")
* S -> left=right
* left -> property
* right -> ${expression}
* expression -> bean.field
* <p>
* FXBind("text=${bean.field})
* textProperty 通过 adapter.getModelProeprty --> textProperty实例
* bean 通过namespace 获取因为bean有FXEntity标签所以返回包装过后的bean的property
* 最后
* left.bind(right)
*
* @Author jack
* @Date:2019/7/23 15:05
*/
public class ExpressionParser {
private Object namespace;
private Object targetController;
private static final String BIND_PREFIX = "${";
private static final String BIND_SUFIX = "}";
private static final String PROEPRTY = "Property";
public enum ExpressionType {
DataExpression,
ActionExpression
}
public ExpressionParser(Object namespace, Object targetController) {
this.namespace = namespace;
this.targetController = targetController;
}
public ExpressionParser(Object namespace) {
this.namespace = namespace;
}
private Property getLeftProperty(MyBeanAdapter myBeanAdapter, String key) {
return (Property) myBeanAdapter.getPropertyModel(key);
}
private static final String FUNCTION_PREFIX = "@";
private MyExpressionValue getRightExpreesion(MyBeanAdapter myBeanAdapter, String key, String rightExpression) {
Expression expression = null;
if (rightExpression.startsWith(FUNCTION_PREFIX)) {
expression = getFunctionExpression(rightExpression);
} else {
expression = Expression.valueOf(rightExpression);
}
Class clazz = myBeanAdapter.getType(key);
MyExpressionValue myExpressionValue = new MyExpressionValue(namespace, expression, clazz);
return myExpressionValue;
}
private Expression getFunctionExpression(String rightExpression) {
Expression expression = null;
int indexLeft = rightExpression.indexOf("(");
String methodName = rightExpression.substring(1,indexLeft);
int indexRight = rightExpression.indexOf(")");
String argString = rightExpression.substring(indexLeft + 1, indexRight);
String[] args = null;
if(!"".equals(argString.trim())) {
args = argString.split(",");
}
Class clazz = targetController.getClass();
Method[] methods = clazz.getMethods();
Expression[] expressions = null;
if(args!=null) {
expressions = new Expression[args.length];
for (int i = 0; i < args.length; i++) {
if (!"".equals(args[i].trim())) {
expressions[i] = Expression.valueOf(args[i]);
}
}
}
for (Method method : methods) {
if (method.getName().equals(methodName)) {
expression = new FunctionExpression(method, targetController, expressions);
}
}
return expression;
}
public void parse(Object object, @NotNull String expression) throws NoSuchChangeMethod {
//check expression
int index = expression.indexOf("=");
if (index == -1) {
return;
}
String[] items = expression.split("=");
if (items.length != 2) {
return;
}
String left = items[0];
String right = items[1];
if (left == null || right == null) {
return;
}
right = right.trim();
ExpressionType expressionType;
if (right.startsWith(BIND_PREFIX) && right.endsWith(BIND_SUFIX)) {
int length = right.length();
right = right.substring(2, length - 1);
expressionType = ExpressionType.DataExpression;
} else {
right = right.substring(1); //#changeMethod -> changeMethod
expressionType = ExpressionType.ActionExpression;
}
MyBeanAdapter myBeanAdapter = new MyBeanAdapter(object);
Property leftProperty = getLeftProperty(myBeanAdapter, left);
switch (expressionType) {
case DataExpression:
bindDataExpression(left, right, myBeanAdapter, leftProperty);
break;
case ActionExpression:
//
bindActionExpression(right, leftProperty);
}
}
private void bindActionExpression(String right, Property leftProperty) throws NoSuchChangeMethod {
Class clazz = targetController.getClass();
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.getName().equals(right)) {
leftProperty.addListener((observable, oldValue, newValue) -> {
try {
Object[] objects = getArgs(method, observable, newValue, oldValue);
method.invoke(targetController, objects);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
});
}
}
}
private void bindDataExpression(String left, String right, MyBeanAdapter myBeanAdapter, Property leftProperty) {
MyExpressionValue rightProperty = getRightExpreesion(myBeanAdapter, left, right);
leftProperty.bind(rightProperty);
}
public Object[] getArgs(Method method, Object... args) {
Parameter[] parameters = method.getParameters();
Object[] objects = new Object[parameters.length];
for (int i = 0; i < parameters.length; i++) {
FXValue annotation = parameters[i].getAnnotation(FXValue.class);
switch (annotation.value()) {
case "target":
objects[i] = args[0];
break;
case "newValue":
objects[i] = args[1];
break;
case "oldValue":
objects[i] = args[2];
break;
}
}
return objects;
}
}

View File

@@ -0,0 +1,85 @@
package cn.edu.scau.biubiusuisui.expression.data;
import com.sun.javafx.fxml.expression.Expression;
import com.sun.javafx.fxml.expression.KeyPath;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
/**
* @Author jack
* @Date:2019/7/27 20:00
*/
public class FunctionExpression extends Expression {
private Method method;
private Object target;
private Expression []args;
public FunctionExpression(Method method, Object target, Expression[]expressions) {
this.method = method;
this.target = target;
this.args = expressions;
}
@Override
public List<KeyPath> getArguments() {
List<KeyPath> list = new ArrayList<>();
if(args !=null) {
for (Expression expression : args) {
list.addAll(expression.getArguments());
}
}
return list;
}
@Override
public Object evaluate(Object namespace) {
Object result = null;
if(args!=null){
Object[] values = new Object[args.length];
for(int i = 0 ;i<args.length;i++){
values[i] = args[i].evaluate(namespace);
}
try {
result = method.invoke(target, values);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return result;
}else{
try {
result = method.invoke(target);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return result;
}
@Override
public void update(Object namespace, Object value) {
}
@Override
public boolean isDefined(Object namespace) {
return false;
}
@Override
public boolean isLValue() {
return false;
}
@Override
protected void getArguments(List arguments) {
}
}

View File

@@ -1,4 +1,4 @@
package cn.edu.scau.biubiusuisui.expression;
package cn.edu.scau.biubiusuisui.expression.data;
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;

View File

@@ -1,8 +1,7 @@
package cn.edu.scau.biubiusuisui.expression;
package cn.edu.scau.biubiusuisui.expression.data;
import com.sun.javafx.fxml.BeanAdapter;
import com.sun.javafx.fxml.expression.Expression;
import com.sun.javafx.fxml.expression.ExpressionValue;
import com.sun.javafx.fxml.expression.KeyPath;
import javafx.beans.InvalidationListener;
import javafx.beans.value.ChangeListener;
@@ -17,10 +16,6 @@ import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
/**
* @Author jack
* @Date:2019/7/24 0:37
*/
public class MyExpressionValue extends ObservableValueBase<Object> {
// Monitors a namespace for changes along a key path

View File

@@ -7,7 +7,8 @@ import cn.edu.scau.biubiusuisui.annotation.FXWindow;
import cn.edu.scau.biubiusuisui.config.FXMLLoaderPlus;
import cn.edu.scau.biubiusuisui.entity.FXBaseController;
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
import cn.edu.scau.biubiusuisui.expression.ExpressionParser;
import cn.edu.scau.biubiusuisui.exception.NoSuchChangeMethod;
import cn.edu.scau.biubiusuisui.expression.data.ExpressionParser;
import cn.edu.scau.biubiusuisui.function.FXWindowParser;
import cn.edu.scau.biubiusuisui.messageQueue.MessageQueue;
import cn.edu.scau.biubiusuisui.proxy.FXControllerProxy;
@@ -16,7 +17,6 @@ import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Field;
import java.net.URL;
@@ -249,7 +249,7 @@ public class FXFactory {
private static void parseBind(ObservableMap namespace, Object object, Field field) {
FXBind fxBind = field.getAnnotation(FXBind.class);
field.setAccessible(true);
ExpressionParser expressionParser = new ExpressionParser(namespace);
ExpressionParser expressionParser = new ExpressionParser(namespace,object);
if (fxBind != null) {
String[] expressions = fxBind.value();
try {
@@ -259,6 +259,8 @@ public class FXFactory {
}
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchChangeMethod noSuchChangeMethod) {
noSuchChangeMethod.printStackTrace();
}
}
}

View File

@@ -0,0 +1,9 @@
package cn.edu.scau.biubiusuisui.function;
/**
* @Author jack
* @Date:2019/7/27 1:54
*/
public interface Draggale {
}

View File

@@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import cn.edu.scau.biubiusuisui.example.MainController?>
<?import cn.edu.scau.biubiusuisui.example.actionDemo.MainController?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.Pane?>

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.Pane?>
<fx:root prefHeight="191.0" prefWidth="607.0" type="Pane" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cn.edu.scau.biubiusuisui.example.actionDemo.MainController">
<children>
<TextField fx:id="time" layoutX="108.0" layoutY="28.0" prefHeight="28.0" prefWidth="330.0" />
<Label fx:id="us" layoutX="108.0" layoutY="75.0" prefHeight="24.0" prefWidth="330.0" text="US:" />
<Label fx:id="jp" layoutX="108.0" layoutY="107.0" prefHeight="24.0" prefWidth="330.0" text="JP:" />
<Label fx:id="uk" layoutX="108.0" layoutY="142.0" prefHeight="24.0" prefWidth="330.0" text="UK:" />
<Label layoutX="67.0" layoutY="77.0" text="US" />
<Label layoutX="69.0" layoutY="109.0" text="JP" />
<Label layoutX="66.0" layoutY="144.0" text="UK" />
</children>
</fx:root>

View File

@@ -1,14 +1,19 @@
import cn.edu.scau.biubiusuisui.example.Student;
import cn.edu.scau.biubiusuisui.factory.FXEntityFactory;
import org.junit.Test;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
/**
* @Author jack
* @Date:2019/6/25 2:11
*/
public class MainTest {
public void testMethod(String a,int b){
}
@Test
public void test(){
public void test() throws NoSuchMethodException {
}
}

View File

@@ -1,43 +1,13 @@
package cn.edu.scau.biubiusuisui.expression;
import cn.edu.scau.biubiusuisui.annotation.FXEntity;
import cn.edu.scau.biubiusuisui.example.Student;
import cn.edu.scau.biubiusuisui.factory.FXEntityFactory;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableMap;
import javafx.scene.control.Label;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.stage.Stage;
import org.junit.Before;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* @Author jack
* @Date:2019/7/24 11:55
*/
public class ExpressionParserTest extends Application{
public class ExpressionParserTest {
@Override
public void start(Stage primaryStage) throws Exception {
// test - ok
Label label = new Label("text");
ObservableMap<String, Object> namespace = FXCollections.observableHashMap();
Student student = new Student();
Student studentProxy = (Student) FXEntityFactory.createJavaBeanProxy(student);
studentProxy.setName("jack");
namespace.put("student", studentProxy);
ExpressionParser expressionParser = new ExpressionParser(namespace);
expressionParser.parse(label,"text=${student.name}");
System.out.println(label.textProperty());
studentProxy.setName("jack-modified");
System.out.println(label.textProperty());
System.out.println(label.textProperty().getValue());
}
public void testValueFactory(){
new PropertyValueFactory("password");
}
}

View File

@@ -0,0 +1,30 @@
package cn.edu.scau.biubiusuisui.expression.data;
import cn.edu.scau.biubiusuisui.annotation.FXValue;
import org.junit.Before;
import org.junit.Test;
import java.lang.reflect.Method;
import static org.junit.Assert.*;
/**
* @Author jack
* @Date:2019/7/27 3:13
*/
public class ExpressionParserTest {
private ExpressionParser expressionParser;
@Before
public void init(){
expressionParser = new ExpressionParser(null);
}
@Test
public void parse() {
}
@Test
public void getArgs() throws NoSuchMethodException {
}
}

View File

@@ -1,7 +1,5 @@
package cn.edu.scau.biubiusuisui.factory;
import cn.edu.scau.biubiusuisui.entity.FXPlusContext;
import cn.edu.scau.biubiusuisui.example.Student;
import org.junit.Test;
/**
@@ -36,12 +34,12 @@ public class FXEntityFactoryTest {
@Test
public void createJavaBeanProxy2() throws InstantiationException, IllegalAccessException {
Student student1 = (Student) FXEntityFactory.createJavaBeanProxy(Student.class);
System.out.println(student1);
FXPlusContext.getProxyByBeanObject(student1).getStringPropertyMap().forEach((k, v)->{
System.out.println("k " +k +"v" + v);
});
student1.setName("Jack");
// Student student1 = (Student) FXEntityFactory.createJavaBeanProxy(Student.class);
// System.out.println(student1);
// FXPlusContext.getProxyByBeanObject(student1).getStringPropertyMap().forEach((k, v)->{
// System.out.println("k " +k +"v" + v);
// });
// student1.setName("Jack");
}
@Test