Browse Source

event manager complete

master
Joe 4 years ago committed by Joe.Jiang
parent
commit
7298a9ef20
  1. 137
      build.xml
  2. 14
      plugin.xml
  3. 10
      src/main/java/com/fr/plugin/event/manager/core/FormEventManager.java
  4. 14
      src/main/java/com/fr/plugin/event/manager/core/WorkbookEventManager.java
  5. 5
      src/main/java/com/fr/plugin/event/manager/data/MyNode.java
  6. 47
      src/main/java/com/fr/plugin/event/manager/data/MyTree.java
  7. 15
      src/main/java/com/fr/plugin/event/manager/data/MyWidget.java
  8. 4
      src/main/java/com/fr/plugin/event/manager/provider/EventManagerProvider.java
  9. 14
      src/main/java/com/fr/plugin/event/manager/provider/LocaleProvider.java
  10. 82
      src/main/java/com/fr/plugin/event/manager/ui/CellWidgetPane.java
  11. 101
      src/main/java/com/fr/plugin/event/manager/ui/EventConfigPane.java
  12. 9
      src/main/java/com/fr/plugin/event/manager/ui/EventManagerPane.java
  13. 18
      src/main/java/com/fr/plugin/event/manager/ui/FormEventManagerPane.java
  14. 42
      src/main/java/com/fr/plugin/event/manager/ui/WorkbookEventManagerPane.java
  15. 20
      src/main/java/com/fr/plugin/event/manager/ui/tree/MyComponentCellRenderer.java
  16. 40
      src/main/java/com/fr/plugin/event/manager/ui/tree/MyComponentTree.java
  17. 9
      src/main/java/com/fr/plugin/event/manager/utils/CommonConstants.java
  18. 2
      src/main/java/com/fr/plugin/event/manager/utils/KeySetUtils.java
  19. 7
      src/main/resources/com/fr/plugin/event/manager/locale/main.properties
  20. 7
      src/main/resources/com/fr/plugin/event/manager/locale/main_en.properties
  21. 0
      src/main/resources/com/fr/plugin/event/manager/locale/main_ja_JP.properties
  22. 0
      src/main/resources/com/fr/plugin/event/manager/locale/main_ko_KR.properties
  23. 3
      src/main/resources/com/fr/plugin/event/manager/locale/main_zh.properties
  24. 0
      src/main/resources/com/fr/plugin/event/manager/locale/main_zh_TW.properties

137
build.xml

@ -0,0 +1,137 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<project basedir="." default="jar" name="plugin-event-manager">
<!-- JDK路径,根据自己机器上实际位置修改-->
<property name="jdk.home" value="C:/Program Files/Java/jdk1.8.0_181"/>
<property name="libs" value=""/>
<property name="dependenceLibs" value=""/>
<property name="FRLibs" value="${basedir}/../../webroot/WEB-INF/lib"/>
<property name="destLoc" value="."/>
<property name="classes" value="classes"/>
<xmlproperty file="${basedir}/plugin.xml"/>
<property name="current-version" value="${plugin.version}"/>
<property name="current-id" value="${plugin.id}"/>
<!-- 插件版本-->
<property name="plugin-version" value="${current-version}"/>
<!-- 插件名字-->
<property name="plugin-name" value="event-manager"/>
<property name="plugin-jar" value="fr-plugin-${plugin-name}-${plugin-version}.jar"/>
<target name="prepare">
<delete dir="${classes}"/>
</target>
<path id="compile.classpath">
<fileset dir="${FRLibs}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${libs}">
<include name="**/*.jar"/>
</fileset>
<fileset dir="${dependenceLibs}">
<include name="**/*.jar"/>
</fileset>
</path>
<patternset id="resources4Jar">
<exclude name="**/.settings/**"/>
<exclude name=".classpath"/>
<exclude name=".project"/>
<exclude name="**/*.java"/>
<exclude name="**/*.db"/>
<exclude name="**/*.g"/>
<exclude name="**/package.html"/>
</patternset>
<target name="copy_resources">
<echo message="从${resources_from}拷贝图片,JS,CSS等资源文件"/>
<delete dir="tmp"/>
<copy todir="tmp">
<fileset dir="${resources_from}\src\main\java">
<patternset refid="resources4Jar"/>
</fileset>
</copy>
<copy todir="tmp">
<fileset dir="${resources_from}\src\main\resources">
<patternset refid="resources4Jar"/>
</fileset>
</copy>
<copy todir="${classes}">
<fileset dir="tmp"/>
</copy>
<delete dir="tmp"/>
</target>
<target name="compile_javas">
<echo message="编译${compile_files}下的Java文件"/>
<javac destdir="${classes}" debug="false" optimize="on" source="${source_jdk_version}"
target="${target_jdk_version}"
fork="true" memoryMaximumSize="512m" listfiles="false" srcdir="${basedir}"
executable="${compile_jdk_version}/bin/javac" includeantruntime="on">
<src path="${basedir}/src"/>
<exclude name="**/.svn/**"/>
<compilerarg line="-encoding UTF8 "/>
<classpath refid="compile.classpath"/>
</javac>
<taskdef name="pretreatment" classname="com.fr.plugin.pack.PluginPretreatmentTask">
<classpath refid="compile.classpath"/>
</taskdef>
<pretreatment baseDir="${basedir}"/>
</target>
<target name="jar_classes">
<echo message="打Jar包:${jar_name}"/>
<delete file="${basedir}/${jar_name}"/>
<jar jarfile="${basedir}/${jar_name}">
<fileset dir="${classes}">
</fileset>
</jar>
</target>
<target name="super_jar" depends="prepare">
<antcall target="copy_resources">
<param name="resources_from" value="${basedir}"/>
</antcall>
<antcall target="compile_javas">
<param name="source_jdk_version" value="1.8"/>
<param name="target_jdk_version" value="1.8"/>
<param name="compile_jdk_version" value="${jdk.home}"/>
<param name="compile_files" value="${basedir}/src"/>
</antcall>
<echo message="compile plugin success!"/>
<antcall target="jar_classes">
<param name="jar_name" value="${plugin-jar}"/>
</antcall>
<delete dir="${classes}"/>
</target>
<target name="jar" depends="super_jar">
<antcall target="zip"/>
</target>
<target name="zip">
<property name="plugin-folder" value="fr-plugin-${plugin-name}-${plugin-version}"/>
<echo message="----------zip files----------"/>
<mkdir dir="${plugin-folder}"/>
<copy todir="${plugin-folder}">
<fileset dir=".">
<include name="*.jar"/>
<include name="plugin.xml"/>
</fileset>
</copy>
<copy todir="${plugin-folder}">
<fileset dir="${libs}">
<include name="**/*.jar"/>
</fileset>
</copy>
<zip destfile="${basedir}/${plugin-folder}.zip" basedir=".">
<include name="${plugin-folder}/*.jar"/>
<include name="${plugin-folder}/plugin.xml"/>
</zip>
<xmlproperty file="${basedir}/plugin.xml"/>
<!--
<move file="${plugin-folder}.zip" todir="${destLoc}/${plugin.name}"/>
-->
<delete dir="${plugin-folder}"/>
<delete file="${plugin-jar}"/>
<!--<delete file="${basedir}/${plugin-folder}.zip" />-->
</target>
</project>

14
plugin.xml

@ -1,18 +1,22 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<plugin>
<id>com.fr.plugin.event.manager</id>
<name><![CDATA[Event Manager Demo]]></name>
<name><![CDATA[Component Event Manager]]></name>
<active>yes</active>
<version>1.0</version>
<env-version>10.0</env-version>
<jartime>2020-02-28</jartime>
<jartime>2020-09-04</jartime>
<vendor>finereport-joe</vendor>
<description><![CDATA[Event Manager Demo]]></description>
<change-notes><![CDATA[]]></change-notes>
<description><![CDATA[Provide an interface to manipulate those widgets with events.]]></description>
<change-notes>
<![CDATA[[2020-12-23] Initialization. <br/>]]>
</change-notes>
<main-package>com.fr.plugin.event.manager</main-package>
<extra-designer>
<MenuHandler class="com.fr.plugin.event.manager.provider.EventManagerProvider"/>
</extra-designer>
<extra-core>
<LocaleFinder class="com.fr.plugin.event.manager.provider.LocaleProvider"/>
</extra-core>
<function-recorder class="com.fr.plugin.event.manager.core.WorkbookEventManager"/>
</plugin>

10
src/main/java/com/fr/plugin/event/manager/core/FormEventManager.java

@ -22,6 +22,7 @@ import java.awt.event.WindowEvent;
/**
* 决策报表下的事件管理器
* @author Joe
* Created by Joe on 9/3/2020
*/
@ -40,13 +41,13 @@ public class FormEventManager extends JTemplateAction<JForm> {
public void actionPerformed(ActionEvent e) {
JForm jf = getEditingComponent();
if (jf == null) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), "无法获取模板对象!",
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Alert_No_Target"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.ERROR_MESSAGE);
return;
}
final Form form = jf.getTarget();
final EventManagerPane eventManagerPane = initEventManager(form);
final EventManagerPane eventManagerPane = initEventManagerPane(form);
UIDialog dialog = new EventManagerDialog(DesignerContext.getDesignerFrame(), eventManagerPane);
dialog.addWindowListener(new WindowAdapter() {
@ -64,10 +65,11 @@ public class FormEventManager extends JTemplateAction<JForm> {
}
/**
* @param form
* 初始化事件管理器面板
* @param form 当前表单对象
* @return
*/
private EventManagerPane initEventManager(Form form) {
private EventManagerPane initEventManagerPane(Form form) {
FormEventManagerPane eventManagerPane = new FormEventManagerPane();
eventManagerPane.setTarget(form);
return eventManagerPane;

14
src/main/java/com/fr/plugin/event/manager/core/WorkbookEventManager.java

@ -23,6 +23,7 @@ import java.awt.event.WindowEvent;
/**
* 普通报表下的事件管理器
* @author Joe
* Created by Joe on 9/3/2020
*/
@ -42,21 +43,21 @@ public class WorkbookEventManager extends JWorkBookAction {
public void actionPerformed(ActionEvent e) {
final JWorkBook jwb = getEditingComponent();
if (jwb == null) {
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), "无法获取模板对象!",
FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Alert_No_Target"),
com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Alert"), JOptionPane.ERROR_MESSAGE);
return;
}
final TemplateWorkBook workBook = jwb.getTarget();
final EventManagerPane eventManagerPane = initEventManager(workBook);
final EventManagerPane eventManagerPane = initEventManagerPane(workBook);
UIDialog dialog = new EventManagerDialog(DesignerContext.getDesignerFrame(), eventManagerPane);
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
eventManagerPane.update();
// todo 是否改成windowClosing
// 触发正在编辑的模板改变事件
DesignModelAdapter.getCurrentModelAdapter().fireTargetModified();
// 刷新一下右侧面板,避免事件显示不同步
jwb.refreshEastPropertiesPane();
super.windowClosed(e);
}
@ -65,12 +66,11 @@ public class WorkbookEventManager extends JWorkBookAction {
}
/**
* workbook返回tabPane
*
* @param workBook
* 初始化事件管理器面板返回tab pane
* @param workBook 当前表单对象
* @return
*/
private EventManagerPane initEventManager(TemplateWorkBook workBook) {
private EventManagerPane initEventManagerPane(TemplateWorkBook workBook) {
WorkbookEventManagerPane eventManagerPane = new WorkbookEventManagerPane();
eventManagerPane.setTarget(workBook);
return eventManagerPane;

5
src/main/java/com/fr/plugin/event/manager/data/MyNode.java

@ -3,15 +3,18 @@ package com.fr.plugin.event.manager.data;
import javax.swing.Icon;
/**
* 树节点
* @author Joe
* Created by Joe on 12/14/2020
*/
public class MyNode {
// 节点名
protected String nodeName;
// 节点图标
protected Icon icon;
public MyNode() {
}
public MyNode(String nodeName) {

47
src/main/java/com/fr/plugin/event/manager/data/MyTree.java

@ -4,39 +4,27 @@ import java.util.LinkedList;
import java.util.List;
/**
* 自定义的树用来存放数据
* @author Joe
* Created by Joe on 12/14/2020
*/
public class MyTree {
/**
* 树节点
*/
// 树节点
private MyNode data;
/**
* 父节点根没有父节点
*/
// 父节点,根没有父节点
private MyTree parent;
/**
* 子节点叶子节点没有子节点
*/
// 子节点,叶子节点没有子节点
private List<MyTree> children;
/**
* 保存了当前节点及其所有子节点方便查询
*/
// 保存了当前节点及其所有子节点,方便查询
private List<MyTree> elementsIndex;
public MyTree() {
this(new MyNode());
}
/**
* 构造函数
*
* @param data
*/
public MyTree(MyNode data) {
this.data = data;
this.children = new LinkedList<>();
@ -62,7 +50,6 @@ public class MyTree {
/**
* 判断是否为根根没有父节点
*
* @return
*/
public boolean isRoot() {
@ -71,7 +58,6 @@ public class MyTree {
/**
* 判断是否为叶子节点子节点没有子节点
*
* @return
*/
public boolean isLeaf() {
@ -80,7 +66,6 @@ public class MyTree {
/**
* 添加一个子节点
*
* @param child 子树
*/
public void addChild(MyTree child) {
@ -91,7 +76,7 @@ public class MyTree {
/**
* 添加一个子节点
* @param child 子树的数据
* @param child 子树的节点
* @return 子树
*/
public MyTree addChild(MyNode child) {
@ -102,6 +87,11 @@ public class MyTree {
return childNode;
}
/**
* 删除一个子树
*
* @param child 子树
*/
public void removeChild(MyTree child) {
// 如果是根的话,就保留
if (child.parent != null) {
@ -112,7 +102,6 @@ public class MyTree {
/**
* 递归为当前节点以及当前节点的所有父节点增加新的节点
*
* @param node
*/
private void registerChildForSearch(MyTree node) {
@ -122,14 +111,28 @@ public class MyTree {
}
}
/**
* 获取子树
* @param index 序号
* @return 子树
*/
public MyTree findChild(int index) {
return children.get(index);
}
/**
* 获取子树大小
* @return 子树大小
*/
public int getChildrenSize() {
return children.size();
}
/**
* 根据子树对象获取它的序号
* @param child
* @return
*/
public int getIndexOfChild(Object child) {
int count = getChildrenSize();
for (int i = 0; i < count; i++) {

15
src/main/java/com/fr/plugin/event/manager/data/MyWidget.java

@ -7,11 +7,16 @@ import com.fr.form.ui.Widget;
import javax.swing.Icon;
/**
* 树的节点包含一个控件对象
* 因为树节点可能是纯目录型的比如sheet,block也可能是带有控件的
* @author Joe
* Created by Joe on 12/14/2020
*/
public class MyWidget extends MyNode {
protected Widget widget;
private Widget widget;
// 是否含有事件
private boolean hasEvent = false;
public MyWidget(Widget widget) {
this.widget = widget;
@ -27,4 +32,12 @@ public class MyWidget extends MyNode {
public void setWidget(Widget widget) {
this.widget = widget;
}
public boolean isHasEvent() {
return hasEvent;
}
public void setHasEvent(boolean hasEvent) {
this.hasEvent = hasEvent;
}
}

4
src/main/java/com/fr/plugin/event/manager/provider/EventManagerProvider.java

@ -17,12 +17,12 @@ import com.fr.plugin.event.manager.core.WorkbookEventManager;
public class EventManagerProvider extends AbstractMenuHandler {
@Override
public int insertPosition(int i) {
return -1;
return 9;
}
@Override
public boolean insertSeparatorBefore() {
return true;
return false;
}
@Override

14
src/main/java/com/fr/plugin/event/manager/provider/LocaleProvider.java

@ -0,0 +1,14 @@
package com.fr.plugin.event.manager.provider;
import com.fr.stable.fun.impl.AbstractLocaleFinder;
/**
* @author Joe
* Created by Joe on 12/23/2020
*/
public class LocaleProvider extends AbstractLocaleFinder {
@Override
public String find() {
return "com/fr/plugin/event/manager/locale/main";
}
}

82
src/main/java/com/fr/plugin/event/manager/ui/CellWidgetPane.java

@ -28,6 +28,7 @@ import java.util.ArrayList;
import java.util.List;
/**
* 单元格控件面板包含一个sheet选择器和一个事件配置面板
* @author Joe
* Created by Joe on 12/13/2020
*/
@ -38,14 +39,21 @@ public class CellWidgetPane extends BasicPane {
private static final Icon DISABLED_RIGHT_ICON = IOUtils.readIcon("com/fr/design/images/sheet/right_hover@1x.png");
private static final String ELLIPSIS = "...";
// sheetFlowPane的最大宽度
private static final int MAX_WIDTH = 810;
// sheetChoosePane的理想高度
private static final int PREFERRED_HEIGHT = 24;
// flow布局的默认水平间距
private static final int FLOW_GAP = 5;
// 按钮的额外宽度,加上按钮文字长度可得整个按钮的宽度
private static final int BUTTON_EXTRA_WIDTH = 20;
private List<MyTree> cellWidgetTrees;
private EventConfigPane eventConfigPane;
private SheetChoosePane sheetChoosePane;
public CellWidgetPane(List<MyTree> cellWidgetTrees) {
this.cellWidgetTrees = cellWidgetTrees;
@ -54,33 +62,53 @@ public class CellWidgetPane extends BasicPane {
private void initComponentPane() {
setLayout(new BorderLayout(4, 0));
eventConfigPane = new EventConfigPane(new MyTree());
sheetChoosePane = new SheetChoosePane();
populate(cellWidgetTrees.size() > 0 ? cellWidgetTrees.get(0) : new MyTree());
refreshUI();
}
public String tabTitle() {
return "Cell Widget";
return com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Tab_Cell");
}
@Override
protected String title4PopupWindow() {
return "cell widget";
return com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Tab_Cell");
}
public void populate(MyTree myTree) {
/**
* 刷新整个面板
* 初始化和从para切换到cell时会触发
*/
public void refreshUI() {
removeAll();
eventConfigPane = new EventConfigPane(myTree);
eventConfigPane = new EventConfigPane(cellWidgetTrees.size() > 0 ? cellWidgetTrees.get(0) : new MyTree());
add(eventConfigPane, BorderLayout.CENTER);
SheetChoosePane sheetChoosePane = new SheetChoosePane();
add(sheetChoosePane, BorderLayout.NORTH);
repaint();
revalidate();
}
/**
* 刷新事件配置面板
* 当切换sheet时触发
*
* @param myTree sheet节点
*/
private void populate(MyTree myTree) {
eventConfigPane.setTree(myTree);
eventConfigPane.refreshUI();
}
/**
* 为了更新此对象包含的事件配置面板
*/
public void update() {
eventConfigPane.update();
}
/**
* Sheet选择器
*/
private class SheetChoosePane extends JPanel {
// 总sheet按钮数
private int totalCount;
@ -118,13 +146,14 @@ public class CellWidgetPane extends BasicPane {
private void initComponentPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(4, 8, 0, 8));
// 初始化右边按钮
add(createButtonPane(), BorderLayout.EAST);
// 初始化左边面板
initSheetFlowPane();
add(sheetFlowPane, BorderLayout.CENTER);
}
/**
* 初始化左边的sheet按钮面板
*/
private void initSheetFlowPane() {
sheetFlowPane = new JPanel(new FlowLayout(FlowLayout.LEFT));
initWidthAndButtonArray();
@ -132,6 +161,10 @@ public class CellWidgetPane extends BasicPane {
checkButton(showCount < widthArray.length);
}
/**
* 创建前后按钮面板
* @return
*/
private JPanel createButtonPane() {
leftButton = new UIButton(LEFT_ICON) {
@Override
@ -191,6 +224,9 @@ public class CellWidgetPane extends BasicPane {
return buttonPane;
}
/**
* 点击前一个
*/
private void moveLeft() {
if (scrollIndex > 0) {
scrollIndex--;
@ -198,6 +234,9 @@ public class CellWidgetPane extends BasicPane {
}
}
/**
* 点击后一个
*/
private void moveRight() {
if (scrollIndex < totalCount - showCount) {
scrollIndex++;
@ -205,6 +244,9 @@ public class CellWidgetPane extends BasicPane {
}
}
/**
* 刷新左边的sheet按钮面板
*/
private void refreshSheetFlowPane() {
sheetFlowPane.removeAll();
sheetFlowPane.repaint();
@ -212,6 +254,9 @@ public class CellWidgetPane extends BasicPane {
sheetFlowPane.revalidate();
}
/**
* 动态添加按钮到sheetFlowPane上
*/
private void addButton() {
showCount = 0;
int currentWidth = FLOW_GAP;
@ -222,7 +267,7 @@ public class CellWidgetPane extends BasicPane {
} else {
UIToggleButton button = buttonList.get(i);
if (selectedIndex == i) {
// 如果被选中
// 如果是选中状态
button.setSelected(true);
}
sheetFlowPane.add(button);
@ -231,6 +276,10 @@ public class CellWidgetPane extends BasicPane {
}
}
/**
* 更新前后按钮的可用状态
* @param buttonEnabled
*/
private void checkButton(boolean buttonEnabled) {
leftButton.setEnabled(buttonEnabled);
rightButton.setEnabled(buttonEnabled);
@ -268,6 +317,10 @@ public class CellWidgetPane extends BasicPane {
}
}
/**
* 当sheet被点击时的触发动作只有它本身是被选中状态
* @param index
*/
private void setSelectedStatus(int index) {
selectedIndex = index;
for (int i = 0; i < buttonList.size(); i++) {
@ -279,19 +332,22 @@ public class CellWidgetPane extends BasicPane {
}
}
/**
* 获取字符串宽度
* @param str
* @return
*/
private int getStringWidth(String str) {
return GraphHelper.getFontMetrics(this.getFont()).stringWidth(str);
}
/**
* 判断tab文字的长度大于能装下的最大文字长度要用省略号
*
* @param name
* @param maxStringlength
* @return
*/
private String getEllipsisName(String name, int maxStringlength) {
//若是名字长度大于能显示的长度,那能显示的文字的最大长度还要减去省略号的最大长度
int ellipsisWidth = getStringWidth(ELLIPSIS);
int leftKeyPoint = 0;

101
src/main/java/com/fr/plugin/event/manager/ui/EventConfigPane.java

@ -17,7 +17,6 @@ import com.fr.plugin.event.manager.ui.tree.MyComponentTree;
import javax.swing.BorderFactory;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
@ -25,16 +24,22 @@ import java.awt.BorderLayout;
import java.awt.Component;
/**
* 事件配置面板左边为组件树右边为/事件编辑面板
* 事件配置面板左边为组件树右边为空提示/事件编辑面板
* @author Joe
* Created by Joe on 12/11/2020
*/
public class EventConfigPane extends BasicPane implements TreeSelectionListener {
private MyTree tree;
// lastNode用来保存最新一个操作过的树节点
private MyTree lastNode;
private boolean rootVisible;
//事件属性容器
private MyComponentTree componentTree;
/**
* 事件编辑容器
*/
private JPanel rightPane;
private WidgetEventPane eventPane;
private UILabel emptyLabel;
@ -65,29 +70,47 @@ public class EventConfigPane extends BasicPane implements TreeSelectionListener
this.rootVisible = rootVisible;
}
/**
* 初始化面板
*/
private void initComponentPane() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
this.setBorder(BorderFactory.createEmptyBorder(4, 8, 4, 8));
setLayout(FRGUIPaneFactory.createBorderLayout());
setBorder(BorderFactory.createEmptyBorder(4, 8, 4, 8));
initRightPane();
// SplitPane
// 增加边框
JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, getLeftPane(), rightPane);
mainSplitPane.setBorder(BorderFactory.createLineBorder(GUICoreUtils.getTitleLineBorderColor()));
mainSplitPane.setOneTouchExpandable(true);
this.add(mainSplitPane, BorderLayout.CENTER);
add(mainSplitPane, BorderLayout.CENTER);
mainSplitPane.setDividerLocation(180);
}
/**
* 当切换sheet/tab时触发更新组件树右边为默认的空提示
*/
public void refreshUI() {
componentTree.refreshTree();
refreshRightPane(emptyLabel);
}
/**
* 初始化右边的面板默认是一个空提示
*/
private void initRightPane() {
rightPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
eventPane = new WidgetEventPaneNoPop(null);
eventPane.setBorder(BorderFactory.createEmptyBorder());
emptyLabel = new UILabel("当前组件没有设置过事件");
emptyLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Config_Right_Tip"));
emptyLabel.setHorizontalAlignment(SwingConstants.CENTER);
rightPane.add(emptyLabel, BorderLayout.CENTER);
}
/**
* 刷新右边的面板可能生成一个空提示也可能生成一个事件编辑面板
*
* @param component
*/
private void refreshRightPane(Component component) {
rightPane.removeAll();
rightPane.repaint();
@ -95,42 +118,50 @@ public class EventConfigPane extends BasicPane implements TreeSelectionListener
rightPane.revalidate();
}
/**
* 创建左边的面板里面放组件树
* @return
*/
private JPanel getLeftPane() {
JPanel leftPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 存放组件树
JPanel leftContentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
initLeftContentPane(leftContentPane);
leftPane.add(leftContentPane, BorderLayout.CENTER);
// 左上方 items with event
// 左上方文字
JPanel leftTopPane = getLeftTopPane();
leftTopPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 5, 0));
leftPane.add(leftTopPane, BorderLayout.NORTH);
return leftPane;
}
/**
* 初始化组件树父面板
* @param leftContentPane
*/
private void initLeftContentPane(JPanel leftContentPane) {
MyComponentTree componentTree = new MyComponentTree(tree, EventConfigPane.this, rootVisible);
componentTree = new MyComponentTree(this, rootVisible);
UIScrollPane scrollPane = new UIScrollPane(componentTree);
// 把树添加到滚动框中
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
leftContentPane.add(scrollPane, BorderLayout.CENTER);
}
/**
* 创建左上方的文字提示
* @return
*/
private JPanel getLeftTopPane() {
JPanel leftTopPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
leftTopPane.add(FRWidgetFactory.createLineWrapLabel("Items with Event"), BorderLayout.CENTER);
leftTopPane.add(FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Config_Left_Title")), BorderLayout.CENTER);
return leftTopPane;
}
@Override
protected String title4PopupWindow() {
return "event config";
return com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Config_Title");
}
/**
* 树节点的点击响应事件
*
* @param e
*/
@Override
@ -139,37 +170,22 @@ public class EventConfigPane extends BasicPane implements TreeSelectionListener
update();
MyComponentTree componentTree = (MyComponentTree) e.getSource();
MyTree tree = (MyTree) componentTree.getLastSelectedPathComponent();
// 记录当前节点
lastNode = tree;
if (hasEvent(tree)) {
// 如果点击的节点有(过)事件,则右侧为事件编辑面板
Widget widget = ((MyWidget) tree.getData()).getWidget();
refreshRightPane(eventPane);
populate(widget);
eventPane.populate(widget);
} else {
// 否则右侧为空提示
refreshRightPane(emptyLabel);
}
}
/**
* 判断节点是否是一个含有事件的控件
*
* @param tree
* @return
* 更新事件的方法基本上需要更新的地方都最终会到这个方法来
*/
private boolean hasEvent(MyTree tree) {
if (tree != null && tree.getData() instanceof MyWidget) {
MyWidget myWidget = (MyWidget) tree.getData();
if (myWidget != null) {
Widget widget = myWidget.getWidget();
return widget != null && widget.getListenerSize() > 0;
}
}
return false;
}
public void populate(Widget widget) {
eventPane.populate(widget);
}
public void update() {
if (hasEvent(lastNode)) {
Widget lastNodeWidget = ((MyWidget) lastNode.getData()).getWidget();
@ -183,4 +199,17 @@ public class EventConfigPane extends BasicPane implements TreeSelectionListener
lastNode = null;
}
/**
* 判断树节点是否有事件
*
* @param myTree
* @return
*/
private boolean hasEvent(MyTree myTree) {
if (myTree != null && myTree.getData() instanceof MyWidget) {
return ((MyWidget) myTree.getData()).isHasEvent();
}
return false;
}
}

9
src/main/java/com/fr/plugin/event/manager/ui/EventManagerPane.java

@ -5,7 +5,7 @@ import com.fr.design.gui.frpane.LoadingBasicPane;
import javax.swing.JPanel;
/**
* 普通报表和表单事件管理器的父类
* 普通报表和表单事件管理器面板的父类
* @author Joe
* Created by Joe on 12/11/2020
*/
@ -24,9 +24,14 @@ public abstract class EventManagerPane<T> extends LoadingBasicPane {
@Override
protected String title4PopupWindow() {
return "event manager";
return com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Title");
}
/**
* 初始化数据
*
* @param target
*/
protected abstract void initData(T target);
public void update() {

18
src/main/java/com/fr/plugin/event/manager/ui/FormEventManagerPane.java

@ -14,12 +14,20 @@ import javax.swing.JPanel;
import java.awt.BorderLayout;
/**
* 决策报表下的事件管理器面板
* @author Joe
* Created by Joe on 12/11/2020
*/
public class FormEventManagerPane extends EventManagerPane<Form> {
// 组件树
private MyTree tree;
/**
* 先调用super.initComponents()执行initData()
* 之后tree已经被初始化了
*
* @param container
*/
@Override
protected void initComponents(JPanel container) {
super.initComponents(container);
@ -55,6 +63,7 @@ public class FormEventManagerPane extends EventManagerPane<Form> {
if (widget instanceof CRBoundsWidget) {
traversalWidget(((CRBoundsWidget) widget).getWidget(), tree);
} else if (widget instanceof WLayout) {
// 容器型控件,可能存在子节点
MyNode node = new MyWidget(widget);
MyTree subTree = tree.addChild(node);
if (widget instanceof WCardLayout) {
@ -69,12 +78,17 @@ public class FormEventManagerPane extends EventManagerPane<Form> {
}
} else {
// 普通widget
tree.addChild(new MyWidget(widget));
MyWidget myWidget = new MyWidget(widget);
if (widget.getListenerSize() > 0) {
myWidget.setHasEvent(true);
}
tree.addChild(myWidget);
}
}
/**
* 从底向上如果节点的控件没有事件就把它删除
* 保留有事件的叶子节点 它们的父节点
*
* @param tree
*/
@ -82,7 +96,7 @@ public class FormEventManagerPane extends EventManagerPane<Form> {
for (int i = tree.getElementsIndex().size() - 1; i >= 0; i--) {
MyTree tempTree = tree.getElementsIndex().get(i);
if (tempTree.isLeaf() && tempTree.getData() instanceof MyWidget) {
if (((MyWidget) tempTree.getData()).getWidget().getListenerSize() <= 0) {
if (!((MyWidget) tempTree.getData()).isHasEvent()) {
tree.removeChild(tempTree);
}
}

42
src/main/java/com/fr/plugin/event/manager/ui/WorkbookEventManagerPane.java

@ -47,12 +47,15 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
eventConfigPane = new EventConfigPane(parameterTree, true);
initListener();
tabbedPane.addTab(cellWidgetPane.tabTitle(), cellWidgetPane);
tabbedPane.addTab("Parameter Widget", eventConfigPane);
tabbedPane.addTab(com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Tab_Para"), eventConfigPane);
container.setLayout(FRGUIPaneFactory.createBorderLayout());
container.add(tabbedPane, BorderLayout.CENTER);
}
/**
* 增加tab切换的监听
*/
private void initListener() {
tabbedPane.addChangeListener(new ChangeListener() {
@Override
@ -62,9 +65,11 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
if (selectedIndex == 0) {
// 从para到cell
eventConfigPane.update();
cellWidgetPane.refreshUI();
} else {
// 从cell到para
cellWidgetPane.update();
eventConfigPane.refreshUI();
}
}
});
@ -78,6 +83,11 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
initCellWidget(target);
}
/**
* 初始化参数面板组件树
*
* @param workBook
*/
private void initParaWidget(TemplateWorkBook workBook) {
// 获取模板的参数属性对象
ReportParameterAttr reportParameterAttr = workBook.getReportParameterAttr();
@ -85,20 +95,31 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
if (reportParameterAttr != null) {
FormParameterUI parameterUI = (FormParameterUI) reportParameterAttr.getParameterUI();
if (parameterUI != null) {
MyNode root = new MyWidget(parameterUI.getParaContainer());
Widget para = parameterUI.getParaContainer();
// 根节点
MyWidget root = new MyWidget(para);
if (para.getListenerSize() > 0) {
root.setHasEvent(true);
}
parameterTree.setData(root);
// 获取参数面板所有控件
Widget[] widgets = parameterUI.getAllWidgets();
for (int i = 1; i < widgets.length; i++) {
if (widgets[i].getListenerSize() > 0) {
// 控件有事件
parameterTree.addChild(new MyWidget(widgets[i]));
MyWidget paraWidget = new MyWidget(widgets[i]);
paraWidget.setHasEvent(true);
parameterTree.addChild(paraWidget);
}
}
}
}
}
/**
* 初始化单元格/条件属性控件的树数组
* @param workBook
*/
private void initCellWidget(TemplateWorkBook workBook) {
// 获取单元格控件
for (int i = 0; i < workBook.getReportCount(); i++) {
@ -130,12 +151,19 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
}
}
if (hasWidgetEvent) {
// 把有事件的sheet加入列表中
cellWidgetTrees.add(tempSheetTree);
}
}
}
}
/**
* 初始化单棵树一个报表块对应一棵树
* @param tree 树根
* @param elementCase 报表块
* @return 这棵树是否含带事件的组件
*/
private boolean initTree(MyTree tree, ElementCase elementCase) {
boolean hasWidgetEvent = false;
Iterator cellIterator = elementCase.cellIterator();
@ -150,6 +178,7 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
// 控件有事件
MyWidget cellWidget = new MyWidget(widget0);
cellWidget.setNodeName(cell.toString());
cellWidget.setHasEvent(true);
tree.addChild(cellWidget);
hasWidgetEvent = true;
}
@ -158,12 +187,16 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
if (((TemplateCellElement) cell).getHighlightGroup() != null) {
int highlightSize = ((TemplateCellElement) cell).getHighlightGroup().size();
for (int j = 0; j < highlightSize; j++) {
// 获取条件属性对象
DefaultHighlight highlight = (DefaultHighlight) ((TemplateCellElement) cell).getHighlightGroup().getHighlight(j);
for (int k = 0; k < highlight.actionCount(); k++) {
if (highlight.getHighlightAction(k) instanceof WidgetHighlightAction) {
// 获取条件属性控件
WidgetHighlightAction highlightAction = (WidgetHighlightAction) highlight.getHighlightAction(k);
MyWidget highlightWidget = new MyWidget(highlightAction.getWidget());
// 条件属性控件的命名不同于单元格控件
highlightWidget.setNodeName(cell.toString() + "(" + highlight.getName() + ")");
highlightWidget.setHasEvent(true);
tree.addChild(highlightWidget);
hasWidgetEvent = true;
}
@ -183,6 +216,9 @@ public class WorkbookEventManagerPane extends EventManagerPane<TemplateWorkBook>
// do nothing
}
/**
* 重写父类同时更新两个tab的内容
*/
@Override
public void update() {
eventConfigPane.update();

20
src/main/java/com/fr/plugin/event/manager/ui/tree/MyComponentCellRenderer.java

@ -1,5 +1,6 @@
package com.fr.plugin.event.manager.ui.tree;
import com.fr.plugin.event.manager.data.MyNode;
import com.fr.plugin.event.manager.data.MyTree;
import javax.swing.BorderFactory;
@ -10,6 +11,7 @@ import java.awt.Color;
import java.awt.Component;
/**
* 组件树节点渲染方式
* @author Joe
* Created by Joe on 12/14/2020
*/
@ -17,17 +19,31 @@ public class MyComponentCellRenderer extends DefaultTreeCellRenderer {
public MyComponentCellRenderer() {
}
/**
* 负责设置节点名称图标和提示文字
*
* @param tree
* @param value
* @param selected
* @param expanded
* @param leaf
* @param row
* @param hasFocus
* @return
*/
@Override
public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded,
boolean leaf, int row, boolean hasFocus) {
super.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
if (value instanceof MyTree) {
String name = ((MyTree) value).getData().getNodeName();
MyNode node = ((MyTree) value).getData();
String name = node.getNodeName();
setText(name);
Icon icon = ((MyTree) value).getData().getIcon();
Icon icon = node.getIcon();
if (icon != null) {
setIcon(icon);
}
setToolTipText(name);
}
this.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0));
this.setBackgroundNonSelectionColor(new Color(255, 255, 255));

40
src/main/java/com/fr/plugin/event/manager/ui/tree/MyComponentTree.java

@ -6,45 +6,55 @@ import com.fr.plugin.event.manager.ui.EventConfigPane;
import javax.swing.BorderFactory;
import javax.swing.JTree;
import javax.swing.ToolTipManager;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import java.awt.Color;
import java.util.List;
/**
* 组件树
* @author Joe
* Created by Joe on 12/14/2020
*/
public class MyComponentTree extends JTree {
private EventConfigPane configPane;
private MyComponentTreeModel model;
private UITreeUI uiTreeUI = new UITreeUI();
// 持有一个eventConfigPane对象,用来获取它的tree
private EventConfigPane eventConfigPane;
private static final int PADDING_LEFT = 5;
private static final int PADDING_TOP = 5;
public MyComponentTree(MyTree tree, EventConfigPane configPane, boolean rootVisible) {
this.configPane = configPane;
model = new MyComponentTreeModel(tree);
setModel(model);
public MyComponentTree(EventConfigPane eventConfigPane, boolean rootVisible) {
this.eventConfigPane = eventConfigPane;
setBackground(new Color(255, 255, 255));
// 根的可见性
setRootVisible(rootVisible);
setCellRenderer(new MyComponentCellRenderer());
getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);
setDragEnabled(false);
initListeners();
setEditable(false);
setUI(uiTreeUI);
// 注册tooltip
ToolTipManager.sharedInstance().registerComponent(this);
initListener();
refreshTree();
setUI(new UITreeUI());
setBorder(BorderFactory.createEmptyBorder(PADDING_TOP, PADDING_LEFT, 0, 0));
// 展开树
expandTree();
}
private void initListeners() {
addTreeSelectionListener(configPane);
/**
* 增加树节点选择的监听
*/
private void initListener() {
this.addTreeSelectionListener(eventConfigPane);
}
/**
* 刷新组件树
*/
public void refreshTree() {
MyComponentTreeModel model = new MyComponentTreeModel(eventConfigPane.getTree());
setModel(model);
expandTree();
repaint();
}
/**
* 最多展开一层

9
src/main/java/com/fr/plugin/event/manager/utils/CommonConstants.java

@ -0,0 +1,9 @@
package com.fr.plugin.event.manager.utils;
/**
* @author Joe
* Created by Joe on 12/18/2020
*/
public class CommonConstants {
public static final String BLOCK_ICON_PATH = "/com/fr/design/images/poly/toolbar/Poly-Report_Block.png";
}

2
src/main/java/com/fr/plugin/event/manager/utils/KeySetUtils.java

@ -18,7 +18,7 @@ public class KeySetUtils {
@Override
public String getMenuName() {
return "事件管理器";
return com.fr.design.i18n.Toolkit.i18nText("Fine-Plugin_Event_Manager_Title");
}
@Override

7
src/main/resources/com/fr/plugin/event/manager/locale/main.properties

@ -0,0 +1,7 @@
Fine-Plugin_Event_Manager_Alert_No_Target=Unable to get the editing component
Fine-Plugin_Event_Manager_Config_Left_Title=Items with Event
Fine-Plugin_Event_Manager_Config_Right_Tip=No events for this component
Fine-Plugin_Event_Manager_Config_Title=Event Config
Fine-Plugin_Event_Manager_Tab_Cell=Cell Widget
Fine-Plugin_Event_Manager_Tab_Para=Parameter Widget
Fine-Plugin_Event_Manager_Title=Component Event Manager

7
src/main/resources/com/fr/plugin/event/manager/locale/main_en.properties

@ -0,0 +1,7 @@
Fine-Plugin_Event_Manager_Alert_No_Target=Unable to get the editing component
Fine-Plugin_Event_Manager_Config_Left_Title=Items with Event
Fine-Plugin_Event_Manager_Config_Right_Tip=No events for this component
Fine-Plugin_Event_Manager_Config_Title=Event Config
Fine-Plugin_Event_Manager_Tab_Cell=Cell Widget
Fine-Plugin_Event_Manager_Tab_Para=Parameter Widget
Fine-Plugin_Event_Manager_Title=Component Event Manager

0
src/main/resources/com/fr/plugin/event/manager/locale/main_ja_JP.properties

0
src/main/resources/com/fr/plugin/event/manager/locale/main_ko_KR.properties

3
src/main/resources/com/fr/plugin/event/manager/locale/main_zh.properties

@ -0,0 +1,3 @@
Fine-Plugin_Event_Manager_Alert_No_Target=\u65E0\u6CD5\u83B7\u53D6\u6A21\u677F\u5BF9\u8C61
Fine-Plugin_Event_Manager_Config_Right_Tip=\u5F53\u524D\u7EC4\u4EF6\u6CA1\u6709\u8BBE\u7F6E\u8FC7\u4E8B\u4EF6
Fine-Plugin_Event_Manager_Config_Title=\u4E8B\u4EF6\u914D\u7F6E

0
src/main/resources/com/fr/plugin/event/manager/locale/main_zh_TW.properties

Loading…
Cancel
Save