Browse Source

merge

master
yaoh.wu 7 years ago
parent
commit
af81d37d31
  1. 1
      .gitignore
  2. 73
      designer/src/com/fr/aspectj/designer/TemplateProcessTracker.aj
  3. 2
      designer/src/com/fr/design/mainframe/InformationCollector.java
  4. 1
      designer/src/com/fr/design/mainframe/JPolyWorkBook.java
  5. 18
      designer/src/com/fr/design/mainframe/JWorkBook.java
  6. 74
      designer/src/com/fr/design/mainframe/templateinfo/JWorkBookProcessInfo.java
  7. 9
      designer/src/com/fr/grid/Grid.java
  8. 21
      designer/src/com/fr/start/ReportSplashPane.java
  9. 21
      designer_base/build.dev.gradle
  10. 70
      designer_base/build.dev.gradle.bak
  11. 60
      designer_base/src/com/fr/aspectj/designerbase/TemplateProcessTracker.aj
  12. 70
      designer_base/src/com/fr/design/actions/edit/CopyAction.java
  13. 25
      designer_base/src/com/fr/design/actions/help/AboutPane.java
  14. 1130
      designer_base/src/com/fr/design/beans/location/MoveUtils.java
  15. 7
      designer_base/src/com/fr/design/beans/location/WidgetForbidWindow.java
  16. 1
      designer_base/src/com/fr/design/dialog/BasicDialog.java
  17. 24
      designer_base/src/com/fr/design/dialog/BasicPane.java
  18. 2
      designer_base/src/com/fr/design/extra/PluginHelper.java
  19. 10
      designer_base/src/com/fr/design/locale/designer.properties
  20. 10
      designer_base/src/com/fr/design/locale/designer_en_US.properties
  21. 32
      designer_base/src/com/fr/design/locale/designer_ja_JP.properties
  22. 12
      designer_base/src/com/fr/design/locale/designer_ko_KR.properties
  23. 11
      designer_base/src/com/fr/design/locale/designer_zh_CN.properties
  24. 32
      designer_base/src/com/fr/design/locale/designer_zh_TW.properties
  25. 67
      designer_base/src/com/fr/design/mainframe/BaseJForm.java
  26. 48
      designer_base/src/com/fr/design/mainframe/JTemplate.java
  27. 325
      designer_base/src/com/fr/design/mainframe/templateinfo/TemplateInfoCollector.java
  28. 26
      designer_base/src/com/fr/design/mainframe/templateinfo/TemplateProcessInfo.java
  29. 20
      designer_base/src/com/fr/design/mainframe/toolbar/ToolBarMenuDockPlus.java
  30. 73
      designer_base/src/com/fr/design/parameter/ParameterDesignerProvider.java
  31. 303
      designer_base/src/com/fr/design/utils/ComponentUtils.java
  32. 20
      designer_chart/build.dev.gradle
  33. 85
      designer_chart/build.dev.gradle.bak
  34. 59
      designer_chart/src/com/fr/aspectj/designerchart/TemplateProcessTracker.aj
  35. 2
      designer_chart/src/com/fr/design/chart/series/SeriesCondition/impl/FormHyperlinkPane.java
  36. 20
      designer_chart/src/com/fr/design/mainframe/chart/gui/ChartTypePane.java
  37. 13
      designer_chart/src/com/fr/design/mainframe/chart/gui/style/ChartTextAttrPane.java
  38. 19
      designer_form/build.dev.gradle
  39. 4
      designer_form/build.dev.gradle.bak
  40. 59
      designer_form/src/com/fr/aspectj/designerform/TemplateProcessTracker.aj
  41. 177
      designer_form/src/com/fr/design/designer/beans/LayoutAdapter.java
  42. 59
      designer_form/src/com/fr/design/designer/beans/actions/CopyAction.java
  43. 361
      designer_form/src/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java
  44. 701
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java
  45. 2385
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java
  46. 210
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRTabFitLayoutAdapter.java
  47. 333
      designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java
  48. 744
      designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java
  49. 182
      designer_form/src/com/fr/design/designer/creator/DedicateLayoutContainer.java
  50. 7
      designer_form/src/com/fr/design/designer/creator/XElementCase.java
  51. 1388
      designer_form/src/com/fr/design/form/parameter/FormParaDesigner.java
  52. 170
      designer_form/src/com/fr/design/mainframe/ConnectorHelper.java
  53. 1239
      designer_form/src/com/fr/design/mainframe/EditingMouseListener.java
  54. 239
      designer_form/src/com/fr/design/mainframe/FormDesigner.java
  55. 481
      designer_form/src/com/fr/design/mainframe/FormEditToolBar.java
  56. 572
      designer_form/src/com/fr/design/mainframe/FormSelection.java
  57. 394
      designer_form/src/com/fr/design/mainframe/FormSelectionUtils.java
  58. 84
      designer_form/src/com/fr/design/mainframe/FormSettingToolBar.java
  59. 68
      designer_form/src/com/fr/design/mainframe/FormToolBar.java
  60. 164
      designer_form/src/com/fr/design/mainframe/FormToolBarButton.java
  61. 233
      designer_form/src/com/fr/design/mainframe/FormToolBarPane.java
  62. 54
      designer_form/src/com/fr/design/mainframe/FormWebWidgetConstants.java
  63. 1579
      designer_form/src/com/fr/design/mainframe/JForm.java
  64. 692
      designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java
  65. 736
      designer_form/src/com/fr/design/mainframe/WidgetPropertyPane.java
  66. 42
      designer_form/src/com/fr/design/mainframe/templateinfo/JFormProcessInfo.java
  67. 57
      designer_form/src/com/fr/design/mainframe/widget/accessibles/AccessibleElementCaseToolBarEditor.java
  68. 13
      designer_form/src/com/fr/design/mainframe/widget/editors/ElementCaseToolBarEditor.java
  69. 304
      designer_form/src/com/fr/design/mainframe/widget/editors/ElementCaseToolBarPane.java
  70. 34
      designer_form/src/com/fr/design/mainframe/widget/wrappers/ElementCaseToolBarWrapper.java

1
.gitignore vendored

@ -3,5 +3,6 @@ designer_base/bin
designer_chart/bin
designer_form/bin
*.iml
designer_base/src/com/fr/design/locale/.idea

73
designer/src/com/fr/aspectj/designer/TemplateProcessTracker.aj

@ -0,0 +1,73 @@
package com.fr.aspectj.designer;
/**
* 记录模板过程
* Created by plough on 2017/3/3.
*/
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import com.fr.grid.Grid;
import org.aspectj.lang.reflect.SourceLocation;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.util.Date;
public aspect TemplateProcessTracker {
//声明一个pointcut,匹配你需要的方法
pointcut onMouseClicked(MouseEvent e) :
execution(* mouseClicked(MouseEvent)) && args(e);
pointcut onMousePressed(MouseEvent e) :
execution(* mousePressed(MouseEvent)) && args(e);
pointcut onMouseReleased(MouseEvent e) :
execution(* mouseReleased(MouseEvent)) && args(e);
pointcut onActionPerformed(ActionEvent e) :
execution(* actionPerformed(ActionEvent)) && args(e);
pointcut onSetValueAt(Object v, int r, int c) :
execution(* setValueAt(java.lang.Object, int, int)) && args(v, r, c);
pointcut onSetValue4EditingElement(Grid g, Object v) :
call(* setValue4EditingElement(java.lang.Object)) && target(g) && args(v);
//before表示之前的意思
//这整个表示在MouseAdapter的public void mouseXXX(MouseEvent)方法调用之前,你想要执行的代码
before(MouseEvent e) : onMouseClicked(e) || onMousePressed(e) || onMouseReleased(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();//切面对应的代码位置
// String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(ActionEvent e) : onActionPerformed(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
// !within(LogHandlerBar) 没用, 手动过滤
if (e.getSource().toString().contains("javax.swing.Timer")) {
return;
}
//String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(Object v, int r, int c) : onSetValueAt(v, r, c) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
//String log = String.format("%s:\n%s\nset value: %s at (%d, %d)\n\n", new Date(), sl, v, r, c);
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(Grid g, Object v) : onSetValue4EditingElement(g, v) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
// String v = "test";
//String log = String.format("%s:\n%s\nset value: %s at %s\n\n", new Date(), sl, v, g.getEditingCellElement());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
}

2
designer/src/com/fr/design/mainframe/InformationCollector.java

@ -10,6 +10,7 @@ import com.fr.data.core.db.dml.Delete;
import com.fr.data.core.db.dml.Select;
import com.fr.data.core.db.dml.Table;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import com.fr.general.*;
import com.fr.general.http.HttpClient;
import com.fr.json.JSONArray;
@ -315,6 +316,7 @@ public class InformationCollector implements XMLReadable, XMLWriter {
}
sendFunctionsInfo();
sendUserInfo();
TemplateInfoCollector.getInstance().sendTemplateInfo();
}
});
sendThread.start();

1
designer/src/com/fr/design/mainframe/JPolyWorkBook.java

@ -24,7 +24,6 @@ public class JPolyWorkBook extends JWorkBook {
super(new WorkBook(new PolyWorkSheet()), DEFAULT_NAME);
populateReportParameterAttr();
}
/**
* 创建sheet名称tab面板

18
designer/src/com/fr/design/mainframe/JWorkBook.java

@ -3,6 +3,7 @@ package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.base.FRContext;
import com.fr.base.Parameter;
import com.fr.base.parameter.ParameterUI;
import com.fr.design.DesignModelAdapter;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.AllowAuthorityEditAction;
@ -26,6 +27,8 @@ import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icontainer.UIModeControlContainer;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.mainframe.cell.QuickEditorRegion;
import com.fr.design.mainframe.templateinfo.JWorkBookProcessInfo;
import com.fr.design.mainframe.templateinfo.TemplateProcessInfo;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.menu.*;
import com.fr.design.module.DesignModuleFactory;
@ -54,7 +57,10 @@ import com.fr.main.impl.WorkBook;
import com.fr.main.parameter.ReportParameterAttr;
import com.fr.poly.PolyDesigner;
import com.fr.privilege.finegrain.WorkSheetPrivilegeControl;
import com.fr.report.cellcase.CellCase;
import com.fr.report.elementcase.TemplateElementCase;
import com.fr.report.poly.PolyWorkSheet;
import com.fr.report.report.Report;
import com.fr.report.worksheet.WorkSheet;
import com.fr.stable.ArrayUtils;
import com.fr.stable.StableUtils;
@ -66,10 +72,7 @@ import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.*;
/**
* JWorkBook used to edit WorkBook.
@ -129,6 +132,13 @@ public class JWorkBook extends JTemplate<WorkBook, WorkBookUndoState> {
return centerPane;
}
public TemplateProcessInfo getProcessInfo() {
if (processInfo == null) {
processInfo = new JWorkBookProcessInfo(template);
}
return processInfo;
}
/**
* 判断sheet权限
*

74
designer/src/com/fr/design/mainframe/templateinfo/JWorkBookProcessInfo.java

@ -0,0 +1,74 @@
package com.fr.design.mainframe.templateinfo;
import com.fr.base.parameter.ParameterUI;
import com.fr.main.impl.WorkBook;
import com.fr.report.cellcase.CellCase;
import com.fr.report.poly.PolyWorkSheet;
import com.fr.report.worksheet.WorkSheet;
import java.util.Iterator;
/**
* Created by plough on 2017/3/17.
*/
public class JWorkBookProcessInfo extends TemplateProcessInfo<WorkBook> {
public JWorkBookProcessInfo(WorkBook wb) {
super(wb);
}
// 获取模板类型
public int getReportType() {
return template.isElementCaseBook() ? 0 : 1;
}
// 获取模板格子数
public int getCellCount() {
int cellCount = 0;
if (template.isElementCaseBook()) { // 如果是普通报表
for (int i = 0; i < template.getReportCount(); i++) {
WorkSheet r = (WorkSheet) template.getReport(i);
CellCase cc = r.getBlock().getCellCase();
for (int j = 0; j < cc.getRowCount(); j++) {
Iterator iter = cc.getRow(j);
while (iter.hasNext()) {
cellCount ++;
iter.next();
}
}
}
}
return cellCount;
}
// 获取模板悬浮元素个数
public int getFloatCount() {
int chartCount = 0;
if (template.isElementCaseBook()) { // 如果是普通报表
for (int i = 0; i < template.getReportCount(); i++) {
WorkSheet r = (WorkSheet) template.getReport(i);
Iterator fiter = r.getBlock().floatIterator();
while (fiter.hasNext()) {
chartCount ++;
fiter.next();
}
}
}
return chartCount;
}
// 获取模板聚合块个数
public int getBlockCount() {
int blockCount = 0;
if (!template.isElementCaseBook()) { // 如果是聚合报表
for (int i = 0; i < template.getReportCount(); i++) {
PolyWorkSheet r = (PolyWorkSheet) template.getReport(i);
blockCount += r.getBlockCount();
}
}
return blockCount;
}
// 获取模板控件数
public int getWidgetCount() {
ParameterUI pui = template.getReportParameterAttr().getParameterUI();
return pui == null ? 0 : (pui.getAllWidgets().length - 1);
}
}

9
designer/src/com/fr/grid/Grid.java

@ -10,6 +10,7 @@ import com.fr.design.constants.UIConstants;
import com.fr.design.fun.GridUIProcessor;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.mainframe.ElementCasePane;
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.ComparatorUtils;
import com.fr.grid.event.CellEditorEvent;
@ -35,6 +36,7 @@ import javax.swing.plaf.ComponentUI;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.geom.Point2D;
import java.util.Date;
import java.util.Hashtable;
import java.util.Iterator;
@ -1065,6 +1067,13 @@ public class Grid extends BaseGridComponent {
}
/**
* @return editingCellElement 的字符串表示
*/
public String getEditingCellElement() {
return editingCellElement.toString();
}
/**
* 将新值赋给editingCellElement
*

21
designer/src/com/fr/start/ReportSplashPane.java

@ -4,6 +4,7 @@
package com.fr.start;
import com.fr.base.BaseUtils;
import com.fr.base.FRContext;
import com.fr.base.GraphHelper;
import com.fr.design.mainframe.bbs.BBSConstants;
import com.fr.general.GeneralContext;
@ -18,6 +19,7 @@ import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.LineMetrics;
import java.awt.image.BufferedImage;
import java.util.Locale;
import java.util.Random;
import java.util.TimerTask;
@ -117,9 +119,22 @@ public class ReportSplashPane extends SplashPane{
GraphHelper.drawString(splashG2d, showText, MODULE_INFO_X, y);
//每次随机感谢一位论坛用户
splashG2d.setPaint(THANK_COLOR);
String content = Inter.getLocText("FR-Designer_Thanks-To") + GUEST;
GraphHelper.drawString(splashG2d, content, THANK_INFO_X, y);
if (shouldShowThanks()) {
splashG2d.setPaint(THANK_COLOR);
String content = Inter.getLocText("FR-Designer_Thanks-To") + GUEST;
GraphHelper.drawString(splashG2d, content, THANK_INFO_X, y);
}
}
// 是否显示鸣谢文字
private boolean shouldShowThanks() {
Locale[] hideLocales = {Locale.US, Locale.KOREA, Locale.JAPAN};
for (Locale loc : hideLocales) {
if (FRContext.getLocale().equals(loc)) {
return false;
}
}
return true;
}
private static String getRandomUser(){

21
designer_base/build.dev.gradle

@ -1,8 +1,25 @@
apply plugin: 'java'
tasks.withType(JavaCompile){
options.encoding = 'UTF-8'
}
buildscript {
repositories {
maven {
url "http://www.eveoh.nl/files/maven2"
}
}
dependencies {
classpath "nl.eveoh:gradle-aspectj:1.2"
}
}
ext.aspectjVersion = '1.7.4'
apply plugin: 'aspectj'
repositories {
mavenCentral()
}
//jdk版本
sourceCompatibility=1.7
//jar包版本

70
designer_base/build.dev.gradle.bak

@ -0,0 +1,70 @@
apply plugin: 'java'
tasks.withType(JavaCompile){
options.encoding = 'UTF-8'
}
//jdk版本
sourceCompatibility=1.7
//jar包版本
version='8.0'
//jar包重命名
jar{
baseName='fr-designer-core'
}
def srcDir="."
//
sourceSets{
main{
java{
srcDirs=["${srcDir}/src"]
}
}
}
//
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf ('\\'))
buildDir=buildDir.substring(0,buildDir.lastIndexOf ('\\'))
def branchName=buildDir.substring(buildDir.lastIndexOf ('\\')+1)
//
dependencies{
compile fileTree(dir:"../../../finereport-lib-stable/${branchName}",include:'**/*.jar')
compile fileTree(dir:'../../../',include:"finereport-*-stable/${branchName}/**/build/libs/*.jar")
testCompile 'junit:junit:4.12'
}
//.java文件到classes文件夹下参与打包
task copyFile(type:Copy,dependsOn:compileJava){
copy{
from ("${srcDir}/src"){
exclude '**/.setting/**','.classpath','.project','**/*.java','**/*.db','**/*.g','**/package.html'
}
into 'build/classes/main'
}
}
//js文件
task compressJS{
ant.taskdef(name:'yuicompress',classname:'com.yahoo.platform.yui.compressor.YUICompressTask'){
classpath {
fileset(dir:'../../../finereport-lib4build-stable',includes:'**/*.jar')
}
}
ant.yuicompress(linebreak:"500",warn:"false", munge:"yes",preserveallsemicolons:"false",charset:"utf-8",encoding:"utf-8",outputfolder:'build/classes/main'){
fileset (dir:"${srcDir}/src"){
include (name:'**/*.js')
include (name:'**/*.css')
}
}
}
jar.dependsOn compressJS

60
designer_base/src/com/fr/aspectj/designerbase/TemplateProcessTracker.aj

@ -0,0 +1,60 @@
package com.fr.aspectj.designerbase;
/**
* 记录模板过程
* Created by plough on 2017/3/3.
*/
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import org.aspectj.lang.reflect.SourceLocation;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.util.Date;
public aspect TemplateProcessTracker {
//声明一个pointcut,匹配你需要的方法
pointcut onMouseClicked(MouseEvent e) :
execution(* mouseClicked(MouseEvent)) && args(e);
pointcut onMousePressed(MouseEvent e) :
execution(* mousePressed(MouseEvent)) && args(e);
pointcut onMouseReleased(MouseEvent e) :
execution(* mouseReleased(MouseEvent)) && args(e);
pointcut onActionPerformed(ActionEvent e) :
execution(* actionPerformed(ActionEvent)) && args(e);
pointcut onSetValueAt(Object v, int r, int c) :
execution(* setValueAt(java.lang.Object, int, int)) && args(v, r, c);
//before表示之前的意思
//这整个表示在MouseAdapter的public void mouseXXX(MouseEvent)方法调用之前,你想要执行的代码
before(MouseEvent e) : onMouseClicked(e) || onMousePressed(e) || onMouseReleased(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();//切面对应的代码位置
//String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(ActionEvent e) : onActionPerformed(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
// !within(LogHandlerBar) 没用, 手动过滤
if (e.getSource().toString().contains("javax.swing.Timer")) {
return;
}
//String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(Object v, int r, int c) : onSetValueAt(v, r, c) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
//String log = String.format("%s:\n%s\nset value: %s at (%d, %d)\n\n", new Date(), sl, v, r, c);
String log = "";
TemplateInfoCollector.appendProcess(log);
}
}

70
designer_base/src/com/fr/design/actions/edit/CopyAction.java

@ -1,37 +1,35 @@
/*
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved.
*/
package com.fr.design.actions.edit;
import java.awt.event.KeyEvent;
import javax.swing.KeyStroke;
import com.fr.base.BaseUtils;
import com.fr.design.actions.TemplateComponentAction;
import com.fr.design.designer.TargetComponent;
import com.fr.general.Inter;
/**
* Copy.
*/
public class CopyAction extends TemplateComponentAction {
public CopyAction(TargetComponent t) {
super(t);
this.setName(Inter.getLocText("M_Edit-Copy"));
this.setMnemonic('C');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png"));
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK));
}
@Override
public boolean executeActionReturnUndoRecordNeeded() {
TargetComponent tc = getEditingComponent();
if (tc != null) {
tc.copy();
}
return false;
}
/*
* Copyright(c) 2001-2010, FineReport Inc, All Rights Reserved.
*/
package com.fr.design.actions.edit;
import com.fr.base.BaseUtils;
import com.fr.design.actions.TemplateComponentAction;
import com.fr.design.designer.TargetComponent;
import com.fr.general.Inter;
import javax.swing.*;
import java.awt.event.KeyEvent;
/**
* Copy.
*/
public class CopyAction extends TemplateComponentAction {
public CopyAction(TargetComponent t) {
super(t);
this.setName(Inter.getLocText("M_Edit-Copy"));
this.setMnemonic('C');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png"));
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, KeyEvent.CTRL_MASK));
}
@Override
public boolean executeActionReturnUndoRecordNeeded() {
TargetComponent tc = getEditingComponent();
if (tc != null) {
tc.copy();
}
return false;
}
}

25
designer_base/src/com/fr/design/actions/help/AboutPane.java

@ -68,10 +68,7 @@ public class AboutPane extends JPanel {
Inter.getLocText("FR-Designer-Basic_Activation_Key_Copy_OK")
}));
// 英文去掉服务电话和 QQ
if (FRContext.getLocale().equals(Locale.US)){
// do nothing
} else {
if (shouldShowPhoneAndQQ()){
if(ComparatorUtils.equals(ProductConstants.APP_NAME,FINEREPORT)){
boxCenterAlignmentPane = new BoxCenterAligmentPane(Inter.getLocText("FR-Designer_Service_Phone") + ProductConstants.COMPARE_TELEPHONE);
contentPane.add(boxCenterAlignmentPane);
@ -85,8 +82,24 @@ public class AboutPane extends JPanel {
contentPane.add(actionLabel);
contentPane.add(emailLabel);
addThankPane(contentPane);
if (shouldShowThanks()) {
addThankPane(contentPane);
}
}
// 是否显示服务电话和 qq
private boolean shouldShowPhoneAndQQ() {
return !FRContext.getLocale().equals(Locale.US);
}
// 是否显示鸣谢面板
private boolean shouldShowThanks() {
Locale[] hideLocales = {Locale.US, Locale.KOREA, Locale.JAPAN};
for (Locale loc : hideLocales) {
if (FRContext.getLocale().equals(loc)) {
return false;
}
}
return true;
}
//添加鸣谢面板

1130
designer_base/src/com/fr/design/beans/location/MoveUtils.java

File diff suppressed because it is too large Load Diff

7
designer_base/src/com/fr/design/beans/location/WidgetForbidWindow.java

@ -22,7 +22,6 @@ public class WidgetForbidWindow extends JWindow {
*/
public WidgetForbidWindow() {
this.add(promptButton);
this.setSize(WIDTH, HEIGHT);
}
@ -31,18 +30,16 @@ public class WidgetForbidWindow extends JWindow {
*
* @param x x坐标
* @param y y坐标
*
*/
public void showWindow(int x, int y){
public void showWindow(int x, int y) {
this.setLocation(x - WIDTH / 2, y - HEIGHT / 2);
this.setVisible(true);
}
/**
* 隐藏当前窗口
*
*/
public void hideWindow(){
public void hideWindow() {
this.setVisible(false);
}
}

1
designer_base/src/com/fr/design/dialog/BasicDialog.java

@ -13,6 +13,7 @@ public abstract class BasicDialog extends UIDialog {
public static final Dimension CHART = new Dimension(760, 560);
public static final Dimension MAP_SIZE = new Dimension(760, 450);
public static final Dimension UPDATE_ONLINE_SIZE = new Dimension(600,300);
public static final Dimension TOOLBAR_SIZE = new Dimension(660, 327);
public BasicDialog(Frame parent) {
super(parent);

24
designer_base/src/com/fr/design/dialog/BasicPane.java

@ -251,6 +251,30 @@ public abstract class BasicPane extends JPanel {
return dg;
}
/**
* 显示窗口
*
* @param window 窗口
* @param l 对话框监听器
* @return 对话框
*/
public BasicDialog showToolBarWindow(Window window, DialogActionListener l) {
BasicDialog dg;
if (window instanceof Frame) {
dg = new DIALOG((Frame) window);
} else {
dg = new DIALOG((Dialog) window);
}
if (l != null) {
dg.addDialogActionListener(l);
}
dg.setBasicDialogSize(BasicDialog.TOOLBAR_SIZE);
GUICoreUtils.centerWindow(dg);
dg.setResizable(false);
return dg;
}
protected abstract String title4PopupWindow();
public String getTitle() {

2
designer_base/src/com/fr/design/extra/PluginHelper.java

@ -319,6 +319,8 @@ public class PluginHelper {
if (plugin == null || env == null) {
return ArrayUtils.EMPTY_STRING_ARRAY;
}
//卸载前监听
plugin.preUninstall();
PluginLoader.getLoader().deletePlugin(plugin);
return env.deleteFileFromPluginAndLibFolder(plugin);
}

10
designer_base/src/com/fr/design/locale/designer.properties

@ -91,6 +91,7 @@ FR-Designer_DS-Dictionary=
FR-Designer_Data-confusion=
FR-Designer_Data_Type=
FR-Designer_Double_Click_Edit_OR_Clear=
FR-Designer_Edit_Button_ToolBar=
FR-Designer_Email=
FR-Designer_Enabled=
FR-Designer_End-Date=
@ -161,6 +162,7 @@ FR-Designer_Refresh_Parameter_In_SQL=
FR-Designer_Reg_Expressions=
FR-Designer_Reg_Max_Length=
FR-Designer_Reg_Min_Length=
FR-Designer_Remove_Button_ToolBar=
FR-Designer_ReportColumns-Columns=
FR-Designer_Return-Date=
FR-Designer_RichText=
@ -541,7 +543,7 @@ FR-Designer_Left_Display=Left
FR-Designer_About_Version=Version
FR-Designer_About_CopyRight=Copy Right
FR-Designer_Service_Phone=Service Phone
FR-Designer_Allow_Blank=Allow Blank
FR-Designer_Allow_Null=Allow Null
FR-Designer_PageSetup_Page=Page
FR-Designer_Custom_Job_Description=Description
FR-Designer_Property=Property
@ -578,4 +580,8 @@ FR-Designer_Background_Clear=
FR-Designer_Background_Image_Select=
FR-Designer_Initial_Background_Tips=
FR-Designer_Mouse_Move_Tips=
FR-Designer_Mouse_Click_Tips=
FR-Designer_Mouse_Click_Tips=
FR-Designer-Move_Tab_First=move to first
FR-Designer-Move_Tab_End=move to end
FR-Designer-Move_Tab_Next=move to next
FR-Designer-Move_Tab_Prev=move to previous

10
designer_base/src/com/fr/design/locale/designer_en_US.properties

@ -91,6 +91,7 @@ FR-Designer_DS-Dictionary=Data Dictionary
FR-Designer_Data-confusion=Data Confusion
FR-Designer_Data_Type=Data type
FR-Designer_Double_Click_Edit_OR_Clear=Double Click to Edit or Clear
FR-Designer_Edit_Button_ToolBar=Edit Button ToolBar
FR-Designer_Email=Mail
FR-Designer_Enabled=Enabled
FR-Designer_End-Date=End Date
@ -163,6 +164,7 @@ FR-Designer_Refresh_Parameter_In_SQL=Whether to refresh parameters in the SQL
FR-Designer_Reg_Expressions=Regular expressions
FR-Designer_Reg_Max_Length=max length
FR-Designer_Reg_Min_Length=min length
FR-Designer_Remove_Button_ToolBar=Remove Button ToolBar
FR-Designer_ReportColumns-Columns=Multi-columns/lines
FR-Designer_Return-Date=Return Date
FR-Designer_RichText=Insert Rich Text
@ -542,7 +544,7 @@ FR-Designer_Left_Display=Left
FR-Designer_About_Version=Version
FR-Designer_About_CopyRight=Copy Right
FR-Designer_Service_Phone=Service Phone
FR-Designer_Allow_Blank=Allow Null
FR-Designer_Allow_Null=Allow Null
FR-Designer_PageSetup_Page=Page
FR-Designer_Custom_Job_Description=Description
FR-Designer_Property=Property
@ -579,4 +581,8 @@ FR-Designer_Background_Clear=Clear
FR-Designer_Background_Image_Select=Select Picture
FR-Designer_Initial_Background_Tips=Initial background of the button
FR-Designer_Mouse_Move_Tips=Move the mouse to the button on the background, in the absence of not changing the background
FR-Designer_Mouse_Click_Tips=The background of the mouse to click the button, in the absence of not changing the background
FR-Designer_Mouse_Click_Tips=The background of the mouse to click the button, in the absence of not changing the background
FR-Designer-Move_Tab_First=move to first
FR-Designer-Move_Tab_End=move to end
FR-Designer-Move_Tab_Next=move to next
FR-Designer-Move_Tab_Prev=move to previous

32
designer_base/src/com/fr/design/locale/designer_ja_JP.properties

@ -91,6 +91,7 @@ FR-Designer_DS-Dictionary=\u30C7\u30FC\u30BF\u5B57\u5178
FR-Designer_Data-confusion=\u30C7\u30FC\u30BF\u6DF7\u4EA4
FR-Designer_Data_Type=\u30C7\u30FC\u30BF\u30BF\u30A4\u30D7
FR-Designer_Double_Click_Edit_OR_Clear=\u30C0\u30D6\u30EB\u30AF\u30EA\u30C3\u30AF\u3057\u3066\u7DE8\u96C6\u307E\u305F\u306F\u30AF\u30EA\u30A2\u3059\u308B
FR-Designer_Edit_Button_ToolBar=\u30DC\u30BF\u30F3\u306B\u3042\u308B\u30C4\u30FC\u30EB\u6B04\u7DE8\u96C6
FR-Designer_Email=\u30E1\u30FC\u30EB
FR-Designer_Enabled=\u4F7F\u7528\u53EF\u80FD
FR-Designer_End-Date=\u7D42\u4E86\u65E5\u671F
@ -162,6 +163,7 @@ FR-Designer_Refresh_Parameter_In_SQL=SQL\u4E2D\u306E\u30D1\u30E9\u30E1\u30FC\u30
FR-Designer_Reg_Expressions=\u6B63\u5247\u8868\u73FE\u5F0F
FR-Designer_Reg_Max_Length=\u6700\u5927\u9577\u3055
FR-Designer_Reg_Min_Length=\u6700\u5C0F\u9577\u3055
FR-Designer_Remove_Button_ToolBar=\u30DC\u30BF\u30F3\u304C\u3042\u308B\u30C4\u30FC\u30EB\u30D0\u30FC\u3092\u30EA\u30E0\u30FC\u30D6
FR-Designer_ReportColumns-Columns=\u6BB5\u7D44\u307F
FR-Designer_Return-Date=\u65E5\u671F\u306B\u623B\u308B
FR-Designer_RichText=\u30EA\u30C3\u30C1\u6587\u66F8\u633F\u5165
@ -516,7 +518,7 @@ FR-Designer_Left_Display=\u5DE6\u8868\u793A
FR-Designer_About_Version=\u30D0\u30FC\u30B8\u30E7\u30F3
FR-Designer_About_CopyRight=\u8457\u4F5C\u6A29\u6240\u6709
FR-Designer_Service_Phone=\u30B5\u30FC\u30D3\u30B9\u96FB\u8A71\uFF1A
FR-Designer_Allow_Blank=\u7A7A\u6B04\u3042\u308A
FR-Designer_Allow_Null=\u7A7A\u6B04\u3042\u308A
FR-Designer_PageSetup_Page=\u30DA\u30FC\u30B8
FR-Designer_Custom_Job_Description=\u8A18\u8FF0
FR-Designer_Property=\u5C5E\u6027
@ -539,14 +541,20 @@ FR-Designer_No=\u3044\u3044\u3048
FR-Designer_Pagination=\u30DA\u30FC\u30B8\u30F3\u30B0
FR-Designer_DS_TableData=\u30C7\u30FC\u30BF\u30BD\u30FC\u30B9
FR-Designer_Parameter-Formula=\u6570\u5F0F
FR-Designer_Background_Null=
FR-Designer_Background_Color=
FR-Designer_Background_Texture=
FR-Designer_Background_Pattern=
FR-Designer_Background_Gradient_Color=
FR-Designer_Background_Image=
FR-Designer_Background_Clear=
FR-Designer_Background_Image_Select=
FR-Designer_Initial_Background_Tips=
FR-Designer_Mouse_Move_Tips=
FR-Designer_Mouse_Click_Tips=
FR-Designer_Background_Null=\u80CC\u666F\u306A\u3057
FR-Designer_Background_Color=\u8272
FR-Designer_Background_Texture=\u67C4
FR-Designer_Background_Pattern=\u6A21\u69D8
FR-Designer_Background_Gradient_Color=\u30B0\u30E9\u30C7\u30FC\u30B7\u30E7\u30F3\u8272
FR-Designer_Background_Image=\u5199\u771F
FR-Designer_Background_Clear=\u30AF\u30EA\u30A2
FR-Designer_Background_Image_Select=\u5199\u771F\u3092\u9078\u629E
FR-Designer_Initial_Background_Tips=\u30DC\u30BF\u30F3\u306E\u521D\u671F\u80CC\u666F
FR-Designer_Mouse_Move_Tips=\u30DE\u30A6\u30B9\u304C\u30DC\u30BF\u30F3\u306B\u79FB\u3059\u6642\u306E\u80CC\u666F
FR-Designer_Mouse_Click_Tips=\u30DE\u30A6\u30B9\u304C\u30DC\u30BF\u30F3\u306B\u79FB\u3059\u6642\u306E\u80CC\u666F
FR-Designer-Move_Tab_First=\u30C8\u30C3\u30D7\u306B\u79FB\u3059
FR-Designer-Move_Tab_End=\u6700\u5F8C\u306B\u79FB\u3059
FR-Designer-Move_Tab_Next=\u5F8C\u308D\u306B\u79FB\u3059
FR-Designer-Move_Tab_Prev=\u524D\u306B\u79FB\u3059

12
designer_base/src/com/fr/design/locale/designer_ko_KR.properties

@ -91,6 +91,7 @@ FR-Designer_DS-Dictionary=\uB370\uC774\uD130\uC0AC\uC804
FR-Designer_Data-confusion=\uB370\uC774\uD130\uD63C\uD569
FR-Designer_Data_Type=\uB370\uC774\uD130\uC720\uD615
FR-Designer_Double_Click_Edit_OR_Clear=\uB354\uBE14\uD074\uB9AD\uD558\uC5EC\uD3B8\uC9D1\uB610\uB294\uD074\uB9AC\uC5B4\uC2E4\uD589
FR-Designer_Edit_Button_ToolBar=\uD0A4\uAC00\uC788\uB294\uD234\uBC14\uD3B8\uC9D1
FR-Designer_Email=\uBA54\uC77C
FR-Designer_Enabled=\uC0AC\uC6A9\uAC00\uB2A5
FR-Designer_End-Date=\uC885\uB8CC\uB0A0\uC9DC
@ -162,6 +163,7 @@ FR-Designer_Refresh_Parameter_In_SQL=SQL\uC758\uB9E4\uAC1C\uBCC0\uC218\uB97C\uC0
FR-Designer_Reg_Expressions=\uC815\uADDC\uD45C\uD604\uC2DD
FR-Designer_Reg_Max_Length=\uCD5C\uB300\uAE38\uC774
FR-Designer_Reg_Min_Length=\uCD5C\uC18C\uAE38\uC774
FR-Designer_Remove_Button_ToolBar=\uD0A4\uAC00\uC788\uB294\uD234\uBC14\uC81C\uAC70
FR-Designer_ReportColumns-Columns=\uC140\uB098\uB204\uAE30
FR-Designer_Return-Date=\uB0A0\uC9DC\uB3CC\uC544\uAC00\uAE30
FR-Designer_RichText=\uB9AC\uCE58\uD14D\uC2A4\uD2B8\uBC15\uC2A4\uC0BD\uC785
@ -512,7 +514,7 @@ FR-Designer_Left_Display=\uC67C\uCABD\uBCF4\uC774\uAE30
FR-Designer_About_Version=\uBC84\uC804
FR-Designer_About_CopyRight=\uD310\uAD8C\uC18C\uC720
FR-Designer_Service_Phone=\uC11C\uBE44\uC2A4\uC804\uD654\uFF1A
FR-Designer_Allow_Blank=\uBE48\uCE78\uD5C8\uC6A9
FR-Designer_Allow_Null=\uBE48\uCE78\uD5C8\uC6A9
FR-Designer_PageSetup_Page=\uC6F9\uD398\uC774\uC9C0
FR-Designer_Custom_Job_Description=\uC124\uBA85
FR-Designer_Property=\uC18D\uC131
@ -546,4 +548,10 @@ FR-Designer_Background_Clear=
FR-Designer_Background_Image_Select=
FR-Designer_Initial_Background_Tips=
FR-Designer_Mouse_Move_Tips=
FR-Designer_Mouse_Click_Tips=
FR-Designer_Mouse_Click_Tips=
FR-Designer-Move_Tab_First=
FR-Designer-Move_Tab_End=
FR-Designer-Move_Tab_Next=
FR-Designer-Move_Tab_Prev=

11
designer_base/src/com/fr/design/locale/designer_zh_CN.properties

@ -91,6 +91,7 @@ FR-Designer_DS-Dictionary=\u6570\u636E\u5B57\u5178
FR-Designer_Data-confusion=\u6570\u636E\u6DF7\u6DC6
FR-Designer_Data_Type=\u6570\u636E\u7C7B\u578B
FR-Designer_Double_Click_Edit_OR_Clear=\u53CC\u51FB\u8FDB\u884C\u7F16\u8F91\u6216\u6E05\u9664
FR-Designer_Edit_Button_ToolBar=\u7F16\u8F91\u6309\u94AE\u6240\u5728\u5DE5\u5177\u680F
FR-Designer_Email=\u90AE\u4EF6
FR-Designer_Enabled=\u53EF\u7528
FR-Designer_End-Date=\u7ED3\u675F\u65E5\u671F
@ -163,6 +164,7 @@ FR-Designer_Refresh_Parameter_In_SQL=\u662F\u5426\u5237\u65B0SQL\u4E2D\u7684\u53
FR-Designer_Reg_Expressions=\u6B63\u5219\u8868\u8FBE\u5F0F
FR-Designer_Reg_Max_Length=\u6700\u5927\u957F\u5EA6
FR-Designer_Reg_Min_Length=\u6700\u5C0F\u957F\u5EA6
FR-Designer_Remove_Button_ToolBar=\u79FB\u9664\u6309\u94AE\u6240\u5728\u5DE5\u5177\u680F
FR-Designer_ReportColumns-Columns=\u5206\u680F
FR-Designer_Return-Date=\u8FD4\u56DE\u65E5\u671F
FR-Designer_RichText=\u63D2\u5165\u5BCC\u6587\u672C
@ -546,7 +548,7 @@ FR-Designer_Left_Display=\u5DE6\u5C55\u793A
FR-Designer_About_Version=\u7248\u672C
FR-Designer_About_CopyRight=\u7248\u6743\u6240\u6709
FR-Designer_Service_Phone=\u670D\u52A1\u7535\u8BDD\uFF1A
FR-Designer_Allow_Blank=\u5141\u8BB8\u4E3A\u7A7A
FR-Designer_Allow_Null=\u5141\u8BB8\u4E3A\u7A7A
FR-Designer_PageSetup_Page=\u9875\u9762
FR-Designer_Custom_Job_Description=\u63CF\u8FF0
FR-Designer_Property=\u5C5E\u6027
@ -583,4 +585,9 @@ FR-Designer_Background_Clear=\u6E05\u9664
FR-Designer_Background_Image_Select=\u9009\u62E9\u56FE\u7247
FR-Designer_Initial_Background_Tips=\u6309\u94AE\u7684\u521D\u59CB\u80CC\u666F
FR-Designer_Mouse_Move_Tips=\u9F20\u6807\u79FB\u52A8\u5230\u6309\u94AE\u4E0A\u7684\u80CC\u666F\uFF0C\u82E5\u65E0\u5219\u4E0D\u6539\u53D8\u80CC\u666F
FR-Designer_Mouse_Click_Tips=\u9F20\u6807\u70B9\u51FB\u6309\u94AE\u65F6\u80CC\u666F\uFF0C\u82E5\u65E0\u5219\u4E0D\u6539\u53D8\u80CC\u666F
FR-Designer_Mouse_Click_Tips=\u9F20\u6807\u70B9\u51FB\u6309\u94AE\u65F6\u80CC\u666F\uFF0C\u82E5\u65E0\u5219\u4E0D\u6539\u53D8\u80CC\u666F
FR-Designer-Move_Tab_First=\u79FB\u52A8\u5230\u9996\u4F4D
FR-Designer-Move_Tab_End=\u79FB\u52A8\u5230\u672B\u5C3E
FR-Designer-Move_Tab_Next=\u5F80\u540E\u79FB\u52A8
FR-Designer-Move_Tab_Prev=\u5F80\u524D\u79FB\u52A8

32
designer_base/src/com/fr/design/locale/designer_zh_TW.properties

@ -91,6 +91,7 @@ FR-Designer_DS-Dictionary=\u8CC7\u6599\u5B57\u5178
FR-Designer_Data-confusion=\u8CC7\u6599\u6DF7\u6DC6
FR-Designer_Data_Type=\u8CC7\u6599\u985E\u578B
FR-Designer_Double_Click_Edit_OR_Clear=\u96D9\u64CA\u9032\u884C\u7DE8\u8F2F\u6216\u6E05\u9664
FR-Designer_Edit_Button_ToolBar=\u7DE8\u8F2F\u6309\u9215\u6240\u5728\u5DE5\u5177\u6B04
FR-Designer_Email=\u90F5\u4EF6
FR-Designer_Enabled=\u53EF\u7528
FR-Designer_End-Date=\u7D50\u675F\u65E5\u671F
@ -162,6 +163,7 @@ FR-Designer_Refresh_Parameter_In_SQL=\u5728SQL\u4E2D\u91CD\u65B0\u6574\u7406\u76
FR-Designer_Reg_Expressions=\u6B63\u5247\u8868\u9054\u5F0F
FR-Designer_Reg_Max_Length=\u6700\u5927\u9577\u5EA6
FR-Designer_Reg_Min_Length=\u6700\u5C0F\u9577\u5EA6
FR-Designer_Remove_Button_ToolBar=\u79FB\u9664\u6309\u9215\u6240\u5728\u5DE5\u5177\u6B04
FR-Designer_ReportColumns-Columns=\u5831\u8868\u6B04\u4F4D
FR-Designer_Return-Date=\u8FD4\u56DE\u65E5\u671F
FR-Designer_RichText= RTF
@ -534,7 +536,7 @@ FR-Designer_Left_Display=\u5DE6\u986F\u793A
FR-Designer_About_Version=\u7248\u672C
FR-Designer_About_CopyRight=\u7248\u6B0A\u6240\u6709
FR-Designer_Service_Phone=\u670D\u52D9\u96FB\u8A71\uFF1A
FR-Designer_Allow_Blank=\u5141\u8A31\u70BA\u7A7A\u767D
FR-Designer_Allow_Null=\u5141\u8A31\u70BA\u7A7A\u767D
FR-Designer_PageSetup_Page=\u9801\u9762
FR-Designer_Custom_Job_Description=\u63CF\u8FF0
FR-Designer_Property=\u5C6C\u6027
@ -561,14 +563,20 @@ FR-Designer_Plugin_Should_Update_Please_Contact_Developer=\u63D2\u4EF6\u7248\u67
FR-Designer_WidgetOrder=\u63A7\u4EF6\u9806\u5E8F
FR-Designer_Mobile_Form_Analysis_Annotation=\u6CE8\u91CB\uFF1A\u53EF\u4EE5\u901A\u904E\u8A72\u5C6C\u6027\u63A7\u5236\u8868\u55AE\u5728APP\u4E2D\u7684\u89E3\u6790\u65B9\u5F0F\u3002
FR-Designer_Mobile_Report_Analysis_Annotation=\u6CE8\u91CB\uFF1A\u53EF\u4EE5\u901A\u904E\u8A72\u5C6C\u6027\u63A7\u5236\u5831\u8868\u5728APP\u4E2D\u7684\u89E3\u6790\u65B9\u5F0F\uFF0C\u53EA\u652F\u6301\u5206\u9801\u9810\u89BD\uFF0C\u586B\u5831\u9810\u89BD\u6642\u5C6C\u6027\u7121\u6548\u3002
FR-Designer_Background_Null=
FR-Designer_Background_Color=
FR-Designer_Background_Texture=
FR-Designer_Background_Pattern=
FR-Designer_Background_Gradient_Color=
FR-Designer_Background_Image=
FR-Designer_Background_Clear=
FR-Designer_Background_Image_Select=
FR-Designer_Initial_Background_Tips=
FR-Designer_Mouse_Move_Tips=
FR-Designer_Mouse_Click_Tips=
FR-Designer_Background_Null=\u6C92\u6709\u80CC\u666F
FR-Designer_Background_Color=\u984F\u8272
FR-Designer_Background_Texture=\u7D0B\u7406
FR-Designer_Background_Pattern=\u5716\u6848
FR-Designer_Background_Gradient_Color=\u6F38\u8B8A\u8272
FR-Designer_Background_Image=\u5716\u7247
FR-Designer_Background_Clear=\u6E05\u9664
FR-Designer_Background_Image_Select=\u9078\u64C7\u5716\u7247
FR-Designer_Initial_Background_Tips=\u6309\u9215\u7684\u521D\u59CB\u80CC\u666F
FR-Designer_Mouse_Move_Tips=\u6ED1\u9F20\u79FB\u52D5\u5230\u6309\u9215\u4E0A\u7684\u80CC\u666F\uFF0C\u82E5\u7121\u5247\u4E0D\u6539\u8B8A\u80CC\u666F
FR-Designer_Mouse_Click_Tips=\u6ED1\u9F20\u9EDE\u64CA\u6309\u9215\u6642\u80CC\u666F\uFF0C\u82E5\u7121\u5247\u4E0D\u6539\u8B8A\u80CC\u666F
FR-Designer-Move_Tab_First=\u79FB\u52D5\u5230\u9996\u4F4D
FR-Designer-Move_Tab_End=\u79FB\u52D5\u5230\u672B\u5C3E
FR-Designer-Move_Tab_Next=\u5F80\u5F8C\u79FB\u52D5
FR-Designer-Move_Tab_Prev=\u5F80\u524D\u79FB\u52D5

67
designer_base/src/com/fr/design/mainframe/BaseJForm.java

@ -1 +1,66 @@
package com.fr.design.mainframe; import javax.swing.JComponent; import com.fr.form.FormElementCaseContainerProvider; /** * Author : Shockway * Date: 13-7-15 * Time: 上午10:28 */ public interface BaseJForm extends JTemplateProvider{ public static final String XML_TAG = "JForm"; public static final int FORM_TAB = 0; public static final int ELEMENTCASE_TAB = 1; public static final int ELEMENTCASE_CHANGE_TAB = 2; /** * 刷新所有控件 */ public void refreshAllNameWidgets(); /** * 刷新参数 */ public void populateParameter(); /** * 刷新选中的控件 */ public void refreshSelectedWidget(); /** * 获取当前的Target */ public Object getTarget(); /** * 执行撤销 * * @param o 之前保存的状态 */ public void applyUndoState4Form(BaseUndoState o); /** * 获取当前编辑的组件 */ public JComponent getEditingPane(); /** * 只在Form和ElementCase之间切换 * @param index 切换位置 */ public void tabChanged(int index); /** * 在Form和ElementCase, 以及ElementCase和ElementCase之间切换 * @param index 切换位置 * @param ecContainer ElementCase所在container */ public void tabChanged(int index, FormElementCaseContainerProvider ecContainer); }
package com.fr.design.mainframe;
import javax.swing.JComponent;
import com.fr.form.FormElementCaseContainerProvider;
/**
* Author : Shockway
* Date: 13-7-15
* Time: 上午10:28
*/
public interface BaseJForm extends JTemplateProvider {
String XML_TAG = "JForm";
int FORM_TAB = 0;
int ELEMENTCASE_TAB = 1;
int ELEMENTCASE_CHANGE_TAB = 2;
/**
* 刷新所有控件
*/
void refreshAllNameWidgets();
/**
* 刷新参数
*/
void populateParameter();
/**
* 刷新选中的控件
*/
void refreshSelectedWidget();
/**
* 获取当前的Target
*/
Object getTarget();
/**
* 执行撤销
*
* @param o 之前保存的状态
*/
void applyUndoState4Form(BaseUndoState o);
/**
* 获取当前编辑的组件
*/
JComponent getEditingPane();
/**
* 只在Form和ElementCase之间切换
*
* @param index 切换位置
*/
void tabChanged(int index);
/**
* 在Form和ElementCase, 以及ElementCase和ElementCase之间切换
*
* @param index 切换位置
* @param ecContainer ElementCase所在container
*/
void tabChanged(int index, FormElementCaseContainerProvider ecContainer);
}

48
designer_base/src/com/fr/design/mainframe/JTemplate.java

@ -27,6 +27,8 @@ import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.imenu.UIMenuItem;
import com.fr.design.gui.itree.filetree.TemplateFileTree;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import com.fr.design.mainframe.templateinfo.TemplateProcessInfo;
import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus;
import com.fr.design.menu.MenuDef;
import com.fr.design.menu.NameSeparator;
@ -72,16 +74,27 @@ public abstract class JTemplate<T extends IOFile, U extends BaseUndoState<?>> ex
private UndoManager authorityUndoManager;
protected U undoState;
protected U authorityUndoState = null;
protected T template; // 当前模板
protected TemplateProcessInfo processInfo; // 模板过程的相关信息
private static short currentIndex = 0;// 此变量用于多次新建模板时,让名字不重复
private DesignModelAdapter<T, ?> designModel;
private PreviewProvider previewType;
private long openTime = 0L; // 打开模板的时间点(包括新建模板)
private TemplateInfoCollector tic = TemplateInfoCollector.getInstance();
private StringBuilder process = new StringBuilder(""); // 制作模板的过程
public JTemplate(T t, String defaultFileName) {
this(t, new MemFILE(newTemplateNameByIndex(defaultFileName)));
this(t, new MemFILE(newTemplateNameByIndex(defaultFileName)), true);
initForCollect();
}
public JTemplate(T t, FILE file) {
this(t, file, false);
}
public JTemplate(T t, FILE file, boolean isNewFile) {
super(t);
this.template = t;
this.previewType = parserPreviewProvider(t.getPreviewType());
this.editingFILE = file;
this.setLayout(FRGUIPaneFactory.createBorderLayout());
@ -89,6 +102,36 @@ public abstract class JTemplate<T extends IOFile, U extends BaseUndoState<?>> ex
this.add(createCenterPane(), BorderLayout.CENTER);
this.undoState = createUndoState();
designModel = createDesignModel();
// 如果不是新建模板,并且在收集列表中
if (!isNewFile && tic.inList(t)) {
openTime = System.currentTimeMillis();
process.append(tic.loadProcess(t));
}
}
// 为收集模版信息作准备
private void initForCollect() {
template.initTemplateID(); // 为新模板设置 templateID 属性
if (openTime == 0) {
openTime = System.currentTimeMillis();
}
}
private void collectInfo() { // 执行收集操作
long saveTime = System.currentTimeMillis(); // 保存模板的时间点
tic.collectInfo(template, this, openTime, saveTime);
openTime = saveTime; // 更新 openTime,准备下一次计算
}
public abstract TemplateProcessInfo getProcessInfo();
// 追加过程记录
public void appendProcess(String s) {
process.append(s);
}
// 获取过程记录
public String getProcess() {
return process.toString();
}
public U getUndoState() {
@ -439,6 +482,7 @@ public abstract class JTemplate<T extends IOFile, U extends BaseUndoState<?>> ex
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("FR-Designer_No-Privilege") + "!", Inter.getLocText("FR-Designer_Message"), JOptionPane.WARNING_MESSAGE);
return false;
}
collectInfo();
return this.saveFile();
}
@ -487,6 +531,8 @@ public abstract class JTemplate<T extends IOFile, U extends BaseUndoState<?>> ex
boolean result = this.saveFile();
if (result) {
DesignerFrameFileDealerPane.getInstance().refresh();
initForCollect(); // 如果另存为新模板,则添加 templateID
collectInfo();
}
//更换最近打开
DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getFullPathName());

325
designer_base/src/com/fr/design/mainframe/templateinfo/TemplateInfoCollector.java

@ -0,0 +1,325 @@
package com.fr.design.mainframe.templateinfo;
import com.fr.base.FRContext;
import com.fr.base.io.IOFile;
import com.fr.design.DesignerEnvManager;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogger;
import com.fr.general.GeneralUtils;
import com.fr.general.SiteCenter;
import com.fr.general.http.HttpClient;
import com.fr.stable.*;
import org.json.JSONObject;
import java.io.*;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* 做模板的过程和耗时收集辅助类
* Created by plough on 2017/2/21.
*/
public class TemplateInfoCollector<T extends IOFile> implements Serializable {
private static final String FILE_NAME = "tplInfo.ser";
private static TemplateInfoCollector instance;
private HashMap<String, HashMap<String, Object>> templateInfoList;
private Set<String> removedTemplates; // 已经从 templateInfoList 中删除过的 id 列表,防止重复收集数据
private String designerOpenDate; //设计器最近一次打开日期
private static final int VALID_CELL_COUNT = 5; // 有效报表模板的格子数
private static final int VALID_WIDGET_COUNT = 5; // 有效报表模板的控件数
private static final int COMPLETE_DAY_COUNT = 15; // 判断模板是否完成的天数
private static final int ONE_THOUSAND = 1000;
@SuppressWarnings("unchecked")
private TemplateInfoCollector() {
templateInfoList = new HashMap<>();
removedTemplates = new ListSet<>();
setDesignerOpenDate();
}
/**
* 把设计器最近打开日期设定为当前日期
*/
private void setDesignerOpenDate() {
designerOpenDate = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());
}
/**
* 判断今天是否第一次打开设计器
*/
private boolean designerOpenFirstTime() {
String today = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());
return !ComparatorUtils.equals(today, designerOpenDate);
}
/**
* 获取缓存文件存放路径
*/
private static File getInfoFile() {
return new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FILE_NAME));
}
public static TemplateInfoCollector getInstance() {
if (instance == null) {
// 先尝试从文件读取
try{
ObjectInputStream is = new ObjectInputStream(new FileInputStream(getInfoFile()));
instance = (TemplateInfoCollector) is.readObject();
} catch (FileNotFoundException ex) {
// 如果之前没有存储过,则创建新对象
instance = new TemplateInfoCollector();
} catch (Exception ex) {
FRLogger.getLogger().error(ex.getMessage(), ex);
}
}
return instance;
}
private boolean shouldCollectInfo(T t) {
if (t.getTemplateID() == null || instance.removedTemplates.contains(t.getTemplateID())) { // 旧模板
return false;
}
return DesignerEnvManager.getEnvManager().isJoinProductImprove() && FRContext.isChineseEnv();
}
public void appendProcess(T t, String log) {
if (!shouldCollectInfo(t)) {
return;
}
// 获取当前编辑的模板
JTemplate jt = DesignerContext.getDesignerFrame().getSelectedJTemplate();
// 追加过程记录
jt.appendProcess(log);
}
/**
* 加载已经存储的模板过程
*/
@SuppressWarnings("unchecked")
public String loadProcess(T t) {
HashMap<String, Object> processMap = (HashMap<String, Object>) templateInfoList.get(t.getTemplateID()).get("processMap");
return (String)processMap.get("process");
}
/**
* 根据模板ID是否在收集列表中判断是否需要收集当前模板的信息
*/
public boolean inList(T t) {
return templateInfoList.containsKey(t.getTemplateID());
}
/**
* 将包含所有信息的对象保存到文件
*/
private void saveInfo() {
try {
ObjectOutputStream os = new ObjectOutputStream(new FileOutputStream(getInfoFile()));
String log = "";
int count = 1;
for (String key : templateInfoList.keySet()) {
String createTime = ((HashMap)templateInfoList.get(key).get("consumingMap")).get("create_time").toString();
log += (count + ". id: " + key + " " + createTime + "\n" + templateInfoList.get(key).toString() + "\n");
count ++;
}
FRLogger.getLogger().info("writing tplInfo: \n" + log);
os.writeObject(instance);
os.close();
} catch (Exception ex) {
FRLogger.getLogger().error(ex.getMessage());
}
}
/**
* 更新 day_count打开设计器却未编辑模板的连续日子
*/
private void addDayCount() {
if (designerOpenFirstTime()) {
for (String key : templateInfoList.keySet()) {
HashMap<String, Object> templateInfo = templateInfoList.get(key);
int dayCount = (int)templateInfo.get("day_count") + 1;
templateInfo.put("day_count", dayCount);
}
setDesignerOpenDate();
}
}
/**
* 收集模板信息如果之前没有记录则新增如果已有记录则更新
* 同时将最新数据保存到文件中
*/
@SuppressWarnings("unchecked")
public void collectInfo(T t, JTemplate jt, long openTime, long saveTime) {
if (!shouldCollectInfo(t)) {
return;
}
HashMap<String, Object> templateInfo;
long timeConsume = ((saveTime - openTime) / ONE_THOUSAND); // 制作模板耗时(单位:s)
String templateID = t.getTemplateID();
if (inList(t)) { // 已有记录
templateInfo = templateInfoList.get(t.getTemplateID());
// 更新 conusmingMap
HashMap<String, Object> consumingMap = (HashMap<String, Object>) templateInfo.get("consumingMap");
timeConsume += (long)consumingMap.get("time_consume"); // 加上之前的累计编辑时间
consumingMap.put("time_consume", timeConsume);
}
else { // 新增
templateInfo = new HashMap<>();
templateInfo.put("consumingMap", getNewConsumingMap(templateID, openTime, timeConsume));
}
// 直接覆盖 processMap
templateInfo.put("processMap", getProcessMap(templateID, jt));
// 保存模板时,让 day_count 归零
templateInfo.put("day_count", 0);
templateInfoList.put(templateID, templateInfo);
saveInfo(); // 每次更新之后,都同步到暂存文件中
}
private HashMap<String, Object> getNewConsumingMap(String templateID, long openTime, long timeConsume) {
HashMap<String, Object> consumingMap = new HashMap<>();
String username = DesignerEnvManager.getEnvManager().getBBSName();
String uuid = DesignerEnvManager.getEnvManager().getUUID();
String activitykey = DesignerEnvManager.getEnvManager().getActivationKey();
String createTime = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(Calendar.getInstance().getTime());
String jarTime = GeneralUtils.readBuildNO();
String version = ProductConstants.VERSION;
consumingMap.put("username", username);
consumingMap.put("uuid", uuid);
consumingMap.put("activitykey", activitykey);
consumingMap.put("templateID", templateID);
consumingMap.put("create_time", createTime);
consumingMap.put("time_consume", timeConsume);
consumingMap.put("jar_time", jarTime);
consumingMap.put("version", version);
return consumingMap;
}
private HashMap<String, Object> getProcessMap(String templateID, JTemplate jt) {
HashMap<String, Object> processMap = new HashMap<>();
processMap.put("templateID", templateID);
processMap.put("process", jt.getProcess());
TemplateProcessInfo info = jt.getProcessInfo();
processMap.put("report_type", info.getReportType());
processMap.put("cell_count", info.getCellCount());
processMap.put("float_count", info.getFloatCount());
processMap.put("block_count", info.getBlockCount());
processMap.put("widget_count", info.getWidgetCount());
return processMap;
}
/**
* 发送本地模板信息到服务器
*/
public void sendTemplateInfo() {
addDayCount();
String consumingUrl = SiteCenter.getInstance().acquireUrlByKind("tempinfo.consuming") + "/single";
String processUrl = SiteCenter.getInstance().acquireUrlByKind("tempinfo.process") + "/single";
ArrayList<HashMap<String, String>> completeTemplatesInfo = getCompleteTemplatesInfo();
for (HashMap<String, String> templateInfo : completeTemplatesInfo) {
String jsonConsumingMap = templateInfo.get("jsonConsumingMap");
String jsonProcessMap = templateInfo.get("jsonProcessMap");
if (sendSingleTemplateInfo(consumingUrl, jsonConsumingMap) && sendSingleTemplateInfo(processUrl, jsonProcessMap)) {
// 清空记录
FRLogger.getLogger().info("successfully send " + templateInfo.get("templateID"));
removeFromTemplateInfoList(templateInfo.get("templateID"));
}
}
saveInfo();
}
private boolean sendSingleTemplateInfo(String url, String content) {
HashMap<String, String> para = new HashMap<>();
String date = new SimpleDateFormat("yyyy-MM-dd").format(Calendar.getInstance().getTime());
para.put("token", CodeUtils.md5Encode(date, "", "MD5"));
para.put("content", content);
HttpClient httpClient = new HttpClient(url, para, true);
httpClient.setTimeout(5000);
httpClient.asGet();
if (!httpClient.isServerAlive()) {
return false;
}
String res = httpClient.getResponseText();
boolean success = ComparatorUtils.equals(new JSONObject(res).get("status"), "success");
return success;
}
/**
* 返回已完成的模板信息
*/
@SuppressWarnings("unchecked")
private ArrayList<HashMap<String, String>> getCompleteTemplatesInfo() {
ArrayList<HashMap<String, String>> completeTemplatesInfo = new ArrayList<>();
ArrayList<String> testTemplateKeys = new ArrayList<>(); // 保存测试模板的key
for (String key : templateInfoList.keySet()) {
HashMap<String, Object> templateInfo = templateInfoList.get(key);
if ((int)templateInfo.get("day_count") <= COMPLETE_DAY_COUNT) { // 未完成模板
continue;
}
if (isTestTemplate(templateInfo)) {
testTemplateKeys.add(key);
continue;
}
HashMap<String, Object> consumingMap = (HashMap<String, Object>) templateInfo.get("consumingMap");
HashMap<String, Object> processMap = (HashMap<String, Object>) templateInfo.get("processMap");
String jsonConsumingMap = new JSONObject(consumingMap).toString();
String jsonProcessMap = new JSONObject(processMap).toString();
HashMap<String, String> jsonTemplateInfo = new HashMap<>();
jsonTemplateInfo.put("jsonConsumingMap", jsonConsumingMap);
jsonTemplateInfo.put("jsonProcessMap", jsonProcessMap);
jsonTemplateInfo.put("templateID", key);
completeTemplatesInfo.add(jsonTemplateInfo);
}
// 删除测试模板
for (String key : testTemplateKeys) {
removeFromTemplateInfoList(key);
}
return completeTemplatesInfo;
}
private void removeFromTemplateInfoList(String key) {
templateInfoList.remove(key);
removedTemplates.add(key);
FRLogger.getLogger().info(key + " is removed...");
FRLogger.getLogger().info("removedTemplates: " + removedTemplates);
}
@SuppressWarnings("unchecked")
private boolean isTestTemplate(HashMap<String, Object> templateInfo) {
HashMap<String, Object> processMap = (HashMap<String, Object>) templateInfo.get("processMap");
int reportType = (int)processMap.get("report_type");
int cellCount = (int)processMap.get("cell_count");
int floatCount = (int)processMap.get("float_count");
int blockCount = (int)processMap.get("block_count");
int widgetCount = (int)processMap.get("widget_count");
boolean isTestTemplate = false;
if (reportType == 0) { // 普通报表
isTestTemplate = cellCount <= VALID_CELL_COUNT && floatCount <= 1 && widgetCount <= VALID_WIDGET_COUNT;
} else if (reportType == 1) { // 聚合报表
isTestTemplate = blockCount <= 1 && widgetCount <= VALID_WIDGET_COUNT;
} else { // 表单(reportType == 2)
isTestTemplate = widgetCount <= 1;
}
return isTestTemplate;
}
public static void main(String[] args) {
TemplateInfoCollector tic = TemplateInfoCollector.getInstance();
tic.sendTemplateInfo();
}
}

26
designer_base/src/com/fr/design/mainframe/templateinfo/TemplateProcessInfo.java

@ -0,0 +1,26 @@
package com.fr.design.mainframe.templateinfo;
import com.fr.base.io.IOFile;
/**
* Created by plough on 2017/3/17.
*/
public abstract class TemplateProcessInfo<T extends IOFile> {
protected T template;
public TemplateProcessInfo(T template) {
this.template = template;
}
// 获取模板类型。0 代表普通报表,1 代表聚合报表,2 代表表单
public abstract int getReportType();
// 获取模板格子数
public abstract int getCellCount();
// 获取模板悬浮元素个数
public abstract int getFloatCount();
// 获取模板聚合块个数
public abstract int getBlockCount();
// 获取模板控件数
public abstract int getWidgetCount();
}

20
designer_base/src/com/fr/design/mainframe/toolbar/ToolBarMenuDockPlus.java

@ -12,52 +12,52 @@ public interface ToolBarMenuDockPlus {
*
* @return 工具
*/
public ToolBarDef[] toolbars4Target();
ToolBarDef[] toolbars4Target();
/**
* 文件菜单的子菜单
*
* @return 子菜单
*/
public ShortCut[] shortcut4FileMenu();
ShortCut[] shortcut4FileMenu();
/**
* 目标的菜单
*
* @return 菜单
*/
public MenuDef[] menus4Target();
MenuDef[] menus4Target();
/**
* 表单的工具栏
*
* @return 表单工具栏
*/
public JPanel[] toolbarPanes4Form();
JPanel[] toolbarPanes4Form();
/**
* 表单的工具按钮
*
* @return 工具按钮
*/
public JComponent[] toolBarButton4Form();
JComponent[] toolBarButton4Form();
/**
* 权限细粒度状态下的工具面板
*
* @return 工具面板
*/
public JComponent toolBar4Authority();
JComponent toolBar4Authority();
public int getMenuState();
int getMenuState();
public int getToolBarHeight();
int getToolBarHeight();
/**
* 导出菜单的子菜单 目前用于图表设计器
*
* @return 子菜单
*/
public ShortCut[] shortcut4ExportMenu();
ShortCut[] shortcut4ExportMenu();
}

73
designer_base/src/com/fr/design/parameter/ParameterDesignerProvider.java

@ -1 +1,72 @@
package com.fr.design.parameter; import com.fr.base.Parameter; import com.fr.base.parameter.ParameterUI; import com.fr.design.mainframe.AuthorityEditPane; import javax.swing.*; import java.awt.*; /** * 参数设计界面接口 */ public interface ParameterDesignerProvider { public void addListener(ParaDefinitePane paraDefinitePane); public Component createWrapper(); public void setDesignHeight(int height); public Dimension getDesignSize(); public Dimension getPreferredSize(); public void populate(ParameterUI p); public void refreshAllNameWidgets(); public void refresh4TableData(String oldName, String newName); public void refreshParameter(ParaDefinitePane paraDefinitePane); public boolean isWithQueryButton(); public java.util.List<String> getAllXCreatorNameList(); public boolean isWithoutParaXCreator(Parameter[] ps); public boolean isBlank(); public ParameterUI getParaTarget(); public boolean addingParameter2Editor(Parameter parameter, int index); public boolean addingParameter2EditorWithQueryButton(Parameter parameter, int index); public void addingAllParameter2Editor(Parameter[] parameterArray, int currentIndex); public JPanel[] toolbarPanes4Form(); public JComponent[] toolBarButton4Form(); public void initBeforeUpEdit(); public void populateParameterPropertyPane(ParaDefinitePane p); public void initWidgetToolbarPane(); public AuthorityEditPane getAuthorityEditPane(); public JPanel getEastUpPane(); public JPanel getEastDownPane(); public boolean isSupportAuthority(); public void removeSelection(); public ParameterBridge getParaComponent(); }
package com.fr.design.parameter;
import com.fr.base.Parameter;
import com.fr.base.parameter.ParameterUI;
import com.fr.design.mainframe.AuthorityEditPane;
import javax.swing.*;
import java.awt.*;
/**
* 参数设计界面接口
*/
public interface ParameterDesignerProvider {
void addListener(ParaDefinitePane paraDefinitePane);
Component createWrapper();
void setDesignHeight(int height);
Dimension getDesignSize();
Dimension getPreferredSize();
void populate(ParameterUI p);
void refreshAllNameWidgets();
void refresh4TableData(String oldName, String newName);
void refreshParameter(ParaDefinitePane paraDefinitePane);
boolean isWithQueryButton();
java.util.List<String> getAllXCreatorNameList();
boolean isWithoutParaXCreator(Parameter[] ps);
boolean isBlank();
ParameterUI getParaTarget();
boolean addingParameter2Editor(Parameter parameter, int index);
boolean addingParameter2EditorWithQueryButton(Parameter parameter, int index);
void addingAllParameter2Editor(Parameter[] parameterArray, int currentIndex);
JPanel[] toolbarPanes4Form();
JComponent[] toolBarButton4Form();
void initBeforeUpEdit();
void populateParameterPropertyPane(ParaDefinitePane p);
void initWidgetToolbarPane();
AuthorityEditPane getAuthorityEditPane();
JPanel getEastUpPane();
JPanel getEastDownPane();
boolean isSupportAuthority();
void removeSelection();
ParameterBridge getParaComponent();
}

303
designer_base/src/com/fr/design/utils/ComponentUtils.java

@ -1,151 +1,154 @@
package com.fr.design.utils;
import com.fr.general.ComparatorUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
/**
* 工具类提供常用的工具方法
*/
public class ComponentUtils {
public static boolean isComponentVisible(Component comp) {
if (!comp.isVisible() && !isRootComponent(comp)) {
return false;
}
Component parent = comp.getParent();
return parent == null || isComponentVisible(parent);
}
/**
* 获取component所在的容器的绝对位置
*/
public static Rectangle getRelativeBounds(Component component) {
Rectangle bounds = new Rectangle(0, 0, component.getWidth(), component.getHeight());
Container parent = component.getParent();
while (parent != null) {
bounds.x += component.getX();
bounds.y += component.getY();
component = parent;
parent = component.getParent();
}
return bounds;
}
/**
* 恢复双缓冲状态dbcomponents保存着初始状态为启动双缓冲的组件
*/
public static void resetBuffer(ArrayList<JComponent> dbcomponents) {
for (JComponent jcomponent : dbcomponents) {
jcomponent.setDoubleBuffered(true);
}
}
/**
* 禁止双缓冲状态并将初始状态为启动双缓冲的组件保存到dbcomponents中
*/
public static void disableBuffer(Component comp, ArrayList<JComponent> dbcomponents) {
if ((comp instanceof JComponent) && comp.isDoubleBuffered()) {
JComponent jcomponent = (JComponent) comp;
dbcomponents.add(jcomponent);
jcomponent.setDoubleBuffered(false);
}
if (comp instanceof Container) {
Container container = (Container) comp;
int count = container.getComponentCount();
if (count > 0) {
for (int i = 0; i < count; i++) {
Component component = container.getComponent(i);
disableBuffer(component, dbcomponents);
}
}
}
}
public static int indexOfComponent(Container container, Component target) {
int count = container.getComponentCount();
for (int i = 0; i < count; i++) {
Component child = container.getComponent(i);
if (child == target) {
return i;
}
}
return -1;
}
/**
* 计算组件root相对于其顶层容器的可见区域
*/
public static Rectangle computeVisibleRectRel2Root(Component root) {
Container container = findAncestorScrollPane(root);
if (container == null) {
return getRelativeBounds(root);
} else {
// 如果是JScrollPane的子组件,需要计算其viewport与改组件的交叉的可见区域
return getBoundsRel2Parent(root, container);
}
}
/**
* 计算组件root相对于其顶层容器的可见区域
*/
public static Rectangle computeVisibleRect(JComponent root) {
Rectangle root_bounds = ComponentUtils.getRelativeBounds(root);
Rectangle rect = computeVisibleRectRel2Root(root);
rect.x -= root_bounds.x;
rect.y -= root_bounds.y;
return rect;
}
private static Rectangle getBoundsRel2Parent(Component child, Container parent) {
Rectangle cRect = getRelativeBounds(child);
Rectangle pRect = getRelativeBounds(parent);
Rectangle bounds = new Rectangle();
Rectangle2D.intersect(cRect, pRect, bounds);
return bounds;
}
public static Container findAncestorScrollPane(Component p) {
if ((p == null) || !(p instanceof Container)) {
return null;
}
Container c = p.getParent();
return findAncestorScrollPane(c);
}
public static boolean isRootComponent(Component root) {
Container parent = root.getParent();
return parent == null;
}
public static boolean isChildOf(Component component, Class parent) {
Container container = component.getParent();
if (container != null) {
if (ComparatorUtils.equals(container.getClass(), parent)) {
return true;
} else {
return isChildOf(container, parent);
}
}
return false;
}
package com.fr.design.utils;
import com.fr.general.ComparatorUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
import java.util.ArrayList;
/**
* 工具类提供常用的工具方法
*/
public class ComponentUtils {
private ComponentUtils() {
}
public static boolean isComponentVisible(Component comp) {
if (!comp.isVisible() && !isRootComponent(comp)) {
return false;
}
Component parent = comp.getParent();
return parent == null || isComponentVisible(parent);
}
/**
* 获取component所在的容器的绝对位置
*/
public static Rectangle getRelativeBounds(Component component) {
Rectangle bounds = new Rectangle(0, 0, component.getWidth(), component.getHeight());
Container parent = component.getParent();
while (parent != null) {
bounds.x += component.getX();
bounds.y += component.getY();
component = parent;
parent = component.getParent();
}
return bounds;
}
/**
* 恢复双缓冲状态dbcomponents保存着初始状态为启动双缓冲的组件
*/
public static void resetBuffer(ArrayList<JComponent> dbcomponents) {
for (JComponent jcomponent : dbcomponents) {
jcomponent.setDoubleBuffered(true);
}
}
/**
* 禁止双缓冲状态并将初始状态为启动双缓冲的组件保存到dbcomponents中
*/
public static void disableBuffer(Component comp, ArrayList<JComponent> dbcomponents) {
if ((comp instanceof JComponent) && comp.isDoubleBuffered()) {
JComponent jcomponent = (JComponent) comp;
dbcomponents.add(jcomponent);
jcomponent.setDoubleBuffered(false);
}
if (comp instanceof Container) {
Container container = (Container) comp;
int count = container.getComponentCount();
if (count > 0) {
for (int i = 0; i < count; i++) {
Component component = container.getComponent(i);
disableBuffer(component, dbcomponents);
}
}
}
}
public static int indexOfComponent(Container container, Component target) {
int count = container.getComponentCount();
for (int i = 0; i < count; i++) {
Component child = container.getComponent(i);
if (child.equals(target)) {
return i;
}
}
return -1;
}
/**
* 计算组件root相对于其顶层容器的可见区域
*/
public static Rectangle computeVisibleRectRel2Root(Component root) {
Container container = findAncestorScrollPane(root);
if (container == null) {
return getRelativeBounds(root);
} else {
// 如果是JScrollPane的子组件,需要计算其viewport与改组件的交叉的可见区域
return getBoundsRel2Parent(root, container);
}
}
/**
* 计算组件root相对于其顶层容器的可见区域
*/
public static Rectangle computeVisibleRect(JComponent root) {
Rectangle rootBounds = ComponentUtils.getRelativeBounds(root);
Rectangle rect = computeVisibleRectRel2Root(root);
rect.x -= rootBounds.x;
rect.y -= rootBounds.y;
return rect;
}
private static Rectangle getBoundsRel2Parent(Component child, Container parent) {
Rectangle cRect = getRelativeBounds(child);
Rectangle pRect = getRelativeBounds(parent);
Rectangle bounds = new Rectangle();
Rectangle2D.intersect(cRect, pRect, bounds);
return bounds;
}
public static Container findAncestorScrollPane(Component p) {
if ((p == null) || !(p instanceof Container)) {
return null;
}
Container c = p.getParent();
return findAncestorScrollPane(c);
}
public static boolean isRootComponent(Component root) {
Container parent = root.getParent();
return parent == null;
}
public static boolean isChildOf(Component component, Class parent) {
Container container = component.getParent();
if (container != null) {
if (ComparatorUtils.equals(container.getClass(), parent)) {
return true;
} else {
return isChildOf(container, parent);
}
}
return false;
}
}

20
designer_chart/build.dev.gradle

@ -1,8 +1,26 @@
apply plugin: 'java'
tasks.withType(JavaCompile){
options.encoding = 'UTF-8'
}
buildscript {
repositories {
maven {
url "http://www.eveoh.nl/files/maven2"
}
}
dependencies {
classpath "nl.eveoh:gradle-aspectj:1.2"
}
}
ext.aspectjVersion = '1.7.4'
apply plugin: 'aspectj'
repositories {
mavenCentral()
}
//jdk版本
sourceCompatibility=1.7
//jar包的版本

85
designer_chart/build.dev.gradle.bak

@ -0,0 +1,85 @@
apply plugin: 'java'
tasks.withType(JavaCompile){
options.encoding = 'UTF-8'
}
buildscript {
repositories {
maven {
url "http://www.eveoh.nl/files/maven2"
}
}
dependencies {
classpath "nl.eveoh:gradle-aspectj:1.2"
}
}
ext.aspectjVersion = '1.7.4'
apply plugin: 'aspectj'
repositories {
mavenCentral()
}
//jdk版本
sourceCompatibility=1.7
//jar包的版本
version='8.0'
def srcDir="."
//jar包进行重命名
jar{
baseName='fr-designer-chart'
}
sourceSets{
main{
java{
srcDirs=["${srcDir}/src"]
}
}
}
FileTree files =fileTree(dir:'./',include:'build.*.gradle')
def buildDir=files[0].path.substring(0,files[0].path.lastIndexOf ('\\'))
buildDir=buildDir.substring(0,buildDir.lastIndexOf ('\\'))
def branchName=buildDir.substring(buildDir.lastIndexOf ('\\')+1)
//
dependencies{
compile fileTree(dir:"../../../finereport-lib-stable/${branchName}",include:'**/*.jar')
compile fileTree(dir:'../../../',include:"finereport-*-stable/${branchName}/**/build/libs/*.jar")
testCompile 'junit:junit:4.12'
}
//.java classes文件夹下参与打包
task copyFile(type:Copy,dependsOn:compileJava){
copy{
from ("${srcDir}/src"){
exclude '**/.setting/**','.classpath','.project','**/*.java','**/*.db','**/*.g','**/package.html'
}
into 'build/classes/main'
}
}
//js文件
task compressJS{
ant.taskdef(name:'yuicompress',classname:'com.yahoo.platform.yui.compressor.YUICompressTask'){
classpath {
fileset(dir:'../../../finereport-lib4build-stable',includes:'**/*.jar')
}
}
ant.yuicompress(linebreak:"500",warn:"false", munge:"yes",preserveallsemicolons:"false",charset:"utf-8",encoding:"utf-8",outputfolder:'build/classes/main'){
fileset (dir:"${srcDir}/src"){
include (name:'**/*.js')
include (name:'**/*.css')
}
}
}
jar.dependsOn compressJS

59
designer_chart/src/com/fr/aspectj/designerchart/TemplateProcessTracker.aj

@ -0,0 +1,59 @@
package com.fr.aspectj.designerchart;
/**
* Created by plough on 2017/3/3.
*/
import com.fr.chart.chartattr.Chart;
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import org.aspectj.lang.reflect.SourceLocation;
import javax.swing.event.ListSelectionEvent;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.util.Date;
public aspect TemplateProcessTracker {
//声明一个pointcut,匹配你需要的方法
pointcut onMouseClicked(MouseEvent e) :
execution(* mouseClicked(MouseEvent)) && args(e);
pointcut onMousePressed(MouseEvent e) :
execution(* mousePressed(MouseEvent)) && args(e);
pointcut onMouseReleased(MouseEvent e) :
execution(* mouseReleased(MouseEvent)) && args(e);
pointcut onActionPerformed(ActionEvent e) :
execution(* actionPerformed(ActionEvent)) && args(e);
pointcut onChartUpdate(Chart c) :
execution(* update(Chart)) && args(c);
//before表示之前的意思
//这整个表示在MouseAdapter的public void mouseXXX(MouseEvent)方法调用之前,你想要执行的代码
before(MouseEvent e) : onMouseClicked(e) || onMousePressed(e) || onMouseReleased(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();//切面对应的代码位置
//String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(ActionEvent e) : onActionPerformed(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
// !within(LogHandlerBar) 没用, 手动过滤
if (e.getSource().toString().contains("javax.swing.Timer")) {
return;
}
//String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(Chart c) : onChartUpdate(c) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
//String log = String.format("%s:\n%s\n插入新图表:%s\n\n", new Date(), sl, c.getChartName());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
}

2
designer_chart/src/com/fr/design/chart/series/SeriesCondition/impl/FormHyperlinkPane.java

@ -95,6 +95,8 @@ public class FormHyperlinkPane extends BasicBeanPane<FormHyperlinkProvider> {
parameterList.toArray(parameters);
formHyperlink.setParameters(parameters);
} else {
formHyperlink.setParameters(null);
}
}

20
designer_chart/src/com/fr/design/mainframe/chart/gui/ChartTypePane.java

@ -33,7 +33,7 @@ import java.util.List;
* @version 创建时间2012-12-26 上午10:56:51
*/
public class ChartTypePane extends AbstractChartAttrPane{
private ComboBoxPane chartTypePane;
private ComboBoxPane chartTypeComBox;
private ChartTypeButtonPane buttonPane;
private ChartEditPane editPane;
private ChartCollection editingCollection;
@ -72,13 +72,13 @@ public class ChartTypePane extends AbstractChartAttrPane{
if (editingCollection != null) {
relayoutChartTypePane(editingCollection);
}else {
chartTypePane = new ComboBoxPane();
chartTypeComBox = new ComboBoxPane();
}
BasicScrollPane scrollPane = new BasicScrollPane() {
@Override
protected JPanel createContentPane() {
return chartTypePane;
return chartTypeComBox;
}
@Override
@ -99,7 +99,7 @@ public class ChartTypePane extends AbstractChartAttrPane{
};
content.add(scrollPane, BorderLayout.CENTER);
buttonPane.setEditingChartPane(chartTypePane);
buttonPane.setEditingChartPane(chartTypeComBox);
return content;
}
@ -286,7 +286,7 @@ public class ChartTypePane extends AbstractChartAttrPane{
public void relayoutChartTypePane(ChartCollection collection){
if (needRelayout(collection)) {
chartTypePane.relayout(collection);
chartTypeComBox.relayout(collection);
//设置面板切换状态
updatePaneState(collection);
}
@ -314,7 +314,7 @@ public class ChartTypePane extends AbstractChartAttrPane{
initContentPane();
buttonPane.populateBean(collection);
chartTypePane.populateBean(chart);
chartTypeComBox.populateBean(chart);
this.initAllListeners();
}
@ -326,7 +326,7 @@ public class ChartTypePane extends AbstractChartAttrPane{
editingCollection = collection;
buttonPane.update(collection);// 内部操作时 已经做过处理.
Chart chart = collection.getSelectedChart();
chartTypePane.updateBean(chart);
chartTypeComBox.updateBean(chart);
}
/**
@ -334,7 +334,7 @@ public class ChartTypePane extends AbstractChartAttrPane{
* @return 类型界面
*/
public FurtherBasicBeanPane[] getPaneList(){
return chartTypePane.getCards().toArray(new FurtherBasicBeanPane[0]);
return chartTypeComBox.getCards().toArray(new FurtherBasicBeanPane[0]);
}
/**
@ -342,7 +342,7 @@ public class ChartTypePane extends AbstractChartAttrPane{
* @return 当前选中的图表的index
*/
public int getSelectedIndex(){
return chartTypePane.getSelectedIndex();
return chartTypeComBox.getSelectedIndex();
}
/**
@ -350,7 +350,7 @@ public class ChartTypePane extends AbstractChartAttrPane{
* @return 选中的图标的序号
*/
public int getSelectedChartIndex(){
return chartTypePane.getSelectedIndex();
return chartTypeComBox.getSelectedIndex();
}
/**

13
designer_chart/src/com/fr/design/mainframe/chart/gui/style/ChartTextAttrPane.java

@ -23,16 +23,19 @@ import com.fr.design.utils.gui.GUICoreUtils;
public class ChartTextAttrPane extends BasicPane {
private static final long serialVersionUID = 6731679928019436869L;
private static final int FONT_START = 6;
private static final int FONT_END = 72;
protected UIComboBox fontNameComboBox;
protected UIComboBox fontSizeComboBox;
protected UIToggleButton bold;
protected UIToggleButton italic;
protected UIColorButton fontColor;
public static Integer[] Font_Sizes = {new Integer(6), new Integer(8), new Integer(9), new Integer(10), new Integer(11), new Integer(12), new Integer(14), new Integer(16),
new Integer(18), new Integer(20), new Integer(22), new Integer(24), new Integer(26), new Integer(28), new Integer(36), new Integer(48), new Integer(72)};
public static Integer[] Font_Sizes = new Integer[FONT_END-FONT_START+1];
static{
for(int i = FONT_START; i <= FONT_END; i++){
Font_Sizes [i - FONT_START] = new Integer(i);
}
}
public ChartTextAttrPane() {
initComponents();
}

19
designer_form/build.dev.gradle

@ -1,8 +1,25 @@
apply plugin: 'java'
tasks.withType(JavaCompile){
options.encoding = 'UTF-8'
}
buildscript {
repositories {
maven {
url "http://www.eveoh.nl/files/maven2"
}
}
dependencies {
classpath "nl.eveoh:gradle-aspectj:1.2"
}
}
ext.aspectjVersion = '1.7.4'
apply plugin: 'aspectj'
repositories {
mavenCentral()
}
//jdk版本
sourceCompatibility=1.7
//jar包版本

4
designer_form/build.dev.gradle.bak

@ -4,7 +4,7 @@ tasks.withType(JavaCompile){
options.encoding = 'UTF-8'
}
//jdk版本
sourceCompatibility=1.8
sourceCompatibility=1.7
//jar包版本
version='8.0'
@ -20,7 +20,7 @@ sourceSets{
main{
java{
srcDirs=["${srcDir}/src",
"${srcDir}/../designer/src"]
"${srcDir}/../designer/src"]
}
}
}

59
designer_form/src/com/fr/aspectj/designerform/TemplateProcessTracker.aj

@ -0,0 +1,59 @@
package com.fr.aspectj.designerform;
/**
* Created by plough on 2017/3/3.
*/
import com.fr.design.mainframe.templateinfo.TemplateInfoCollector;
import org.aspectj.lang.reflect.SourceLocation;
import java.awt.event.ActionEvent;
import java.awt.event.MouseEvent;
import java.util.Date;
public aspect TemplateProcessTracker {
//声明一个pointcut,匹配你需要的方法
pointcut onMouseClicked(MouseEvent e) :
execution(* mouseClicked(MouseEvent)) && args(e);
pointcut onMousePressed(MouseEvent e) :
execution(* mousePressed(MouseEvent)) && args(e);
pointcut onMouseReleased(MouseEvent e) :
execution(* mouseReleased(MouseEvent)) && args(e);
pointcut onActionPerformed(ActionEvent e) :
execution(* actionPerformed(ActionEvent)) && args(e);
pointcut onSetValueAt(Object v, int r, int c) :
execution(* setValueAt(java.lang.Object, int, int)) && args(v, r, c);
//before表示之前的意思
//这整个表示在MouseAdapter的public void mouseXXX(MouseEvent)方法调用之前,你想要执行的代码
before(MouseEvent e) : onMouseClicked(e) || onMousePressed(e) || onMouseReleased(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();//切面对应的代码位置
//String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(ActionEvent e) : onActionPerformed(e) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
// !within(LogHandlerBar) 没用, 手动过滤
if (e.getSource().toString().contains("javax.swing.Timer")) {
return;
}
//String log = String.format("%s:\n%s\n%s\n%s\n\n", new Date(), sl, e, e.getSource());
String log = "";
TemplateInfoCollector.appendProcess(log);
}
//同上
before(Object v, int r, int c) : onSetValueAt(v, r, c) {
SourceLocation sl = thisJoinPoint.getSourceLocation();
//String log = String.format("%s:\n%s\nset value: %s at (%d, %d)\n\n", new Date(), sl, v, r, c);
String log = "";
TemplateInfoCollector.appendProcess(log);
}
}

177
designer_form/src/com/fr/design/designer/beans/LayoutAdapter.java

@ -1,85 +1,94 @@
package com.fr.design.designer.beans;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.creator.XCreator;
/**
* 该接口是LayoutManager的BeanInfo类标准Java平台没有提供布局管理器的BeanInfo类
* 对于界面设计工具来说还需一些特殊的行为
* @since 6.5.3
*/
public interface LayoutAdapter {
/**
* 在添加组件状态时当鼠标移动到某个容器上方时如果该容器有布局管理器则会调用该布局
* 管理适配器的accept来决定当前位置是否可以放置并提供特殊的标识比如红色区域标识
* 如在BorderLayout中如果某个方位已经放置了组件则此时应该返回false标识该区域不可以
* 放置
*@param creator 组件
*@param x 添加的位置x该位置是相对于container的
*@param y 添加的位置y该位置是相对于container的
*@return 是否可以放置
*/
boolean accept(XCreator creator, int x, int y);
/**
* 有的控件在拖拽调整大小后需要根据自身内容重新计算下当前的尺寸是否合适如果不合适就需要重新fix一下
* @param creator 组件
*/
void fix(XCreator creator);
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
boolean addBean(XCreator creator, int x, int y);
/**
* 返回该布局管理适配器的Painter为容器提供放置位置的标识
*/
HoverPainter getPainter();
/**
* 显示parent的字组件child解决CardLayout中显示某个非显示组件的特殊情况
* @param child 组件
*/
void showComponent(XCreator child);
void addNextComponent(XCreator dragged);
/**
* 组件叠放顺序前插入
* @param target 目标组件
* @param added 插入组件
*/
void addBefore(XCreator target, XCreator added);
/**
* 组件叠放顺序后插入
* @param target 目标组件
* @param added 放置组件
*/
void addAfter(XCreator target, XCreator added);
/**
* 能否放置更多组件
* @return 能则返回true
*/
boolean canAcceptMoreComponent();
ConstraintsGroupModel getLayoutConstraints(XCreator creator);
GroupModel getLayoutProperties();
/**
* 删除组件
* @param creator 组件
* @param initWidth 组件之前宽度
* @param initHeight 组件之前高度
*/
void removeBean(XCreator creator, int initWidth, int initHeight);
package com.fr.design.designer.beans;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.creator.XCreator;
/**
* 该接口是LayoutManager的BeanInfo类标准Java平台没有提供布局管理器的BeanInfo类
* 对于界面设计工具来说还需一些特殊的行为
*
* @since 6.5.3
*/
public interface LayoutAdapter {
/**
* 在添加组件状态时当鼠标移动到某个容器上方时如果该容器有布局管理器则会调用该布局
* 管理适配器的accept来决定当前位置是否可以放置并提供特殊的标识比如红色区域标识
* 如在BorderLayout中如果某个方位已经放置了组件则此时应该返回false标识该区域不可以
* 放置
*
* @param creator 组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否可以放置
*/
boolean accept(XCreator creator, int x, int y);
/**
* 有的控件在拖拽调整大小后需要根据自身内容重新计算下当前的尺寸是否合适如果不合适就需要重新fix一下
*
* @param creator 组件
*/
void fix(XCreator creator);
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
*
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
boolean addBean(XCreator creator, int x, int y);
/**
* 返回该布局管理适配器的Painter为容器提供放置位置的标识
*/
HoverPainter getPainter();
/**
* 显示parent的字组件child解决CardLayout中显示某个非显示组件的特殊情况
*
* @param child 组件
*/
void showComponent(XCreator child);
void addNextComponent(XCreator dragged);
/**
* 组件叠放顺序前插入
*
* @param target 目标组件
* @param added 插入组件
*/
void addBefore(XCreator target, XCreator added);
/**
* 组件叠放顺序后插入
*
* @param target 目标组件
* @param added 放置组件
*/
void addAfter(XCreator target, XCreator added);
/**
* 能否放置更多组件
*
* @return 能则返回true
*/
boolean canAcceptMoreComponent();
ConstraintsGroupModel getLayoutConstraints(XCreator creator);
GroupModel getLayoutProperties();
/**
* 删除组件
*
* @param creator 组件
* @param initWidth 组件之前宽度
* @param initHeight 组件之前高度
*/
void removeBean(XCreator creator, int initWidth, int initHeight);
}

59
designer_form/src/com/fr/design/designer/beans/actions/CopyAction.java

@ -1,31 +1,30 @@
package com.fr.design.designer.beans.actions;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import javax.swing.KeyStroke;
import com.fr.base.BaseUtils;
import com.fr.general.Inter;
import com.fr.design.mainframe.FormDesigner;
public class CopyAction extends FormEditAction {
public CopyAction(FormDesigner t) {
super(t);
this.setName(Inter.getLocText("M_Edit-Copy"));
this.setMnemonic('C');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png"));
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
}
@Override
public boolean executeActionReturnUndoRecordNeeded() {
FormDesigner tc = getEditingComponent();
if (tc != null) {
tc.copy();
}
return false;
}
package com.fr.design.designer.beans.actions;
import com.fr.base.BaseUtils;
import com.fr.design.mainframe.FormDesigner;
import com.fr.general.Inter;
import javax.swing.*;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
public class CopyAction extends FormEditAction {
public CopyAction(FormDesigner t) {
super(t);
this.setName(Inter.getLocText("M_Edit-Copy"));
this.setMnemonic('C');
this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_edit/copy.png"));
this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK));
}
@Override
public boolean executeActionReturnUndoRecordNeeded() {
FormDesigner tc = getEditingComponent();
if (tc != null) {
tc.copy();
}
return false;
}
}

361
designer_form/src/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java

@ -1,174 +1,189 @@
package com.fr.design.designer.beans.adapters.layout;
import java.awt.LayoutManager;
import com.fr.general.ComparatorUtils;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.beans.ConstraintsGroupModel;
import com.fr.design.designer.beans.HoverPainter;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.painters.NullPainter;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWidgetCreator;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
public abstract class AbstractLayoutAdapter implements LayoutAdapter {
protected XLayoutContainer container;
protected LayoutManager layout;
public AbstractLayoutAdapter(XLayoutContainer container) {
this.container = container;
this.layout = container.getLayout();
}
/**
* 是否使用控件备份大小
* @param xCreator 控件
* @return 所在容器相同且支持备份的话返回true
*/
public boolean whetherUseBackupSize(XCreator xCreator) {
Class clazz = container.getClass();
Class bkClazz = null;
if(xCreator.getBackupParent() != null) {
bkClazz = xCreator.getBackupParent().getClass();
}
return ComparatorUtils.equals(bkClazz, clazz)
&& supportBackupSize();
}
/**
* 是否支持用备份大小
* @return
*/
public boolean supportBackupSize() {
return false;
}
/**
* 有的控件在拖拽调整大小后需要根据自身内容重新计算下当前的尺寸是否合适如果不合适就需要重新fix一下
* @param creator 组件
*/
public void fix(XCreator creator) {
}
/**
* 显示parent的字组件child解决CardLayout中显示某个非显示组件的特殊情况
* @param child 组件
*/
@Override
public void showComponent(XCreator child) {
child.setVisible(true);
}
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
@Override
public boolean addBean(XCreator creator, int x, int y) {
if (!accept(creator, x, y)) {
return false;
}
addComp(creator, x, y);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
/**
* 删除组件
* @param creator 组件
* @param initWidth 组件之前宽度
* @param initHeight 组件之前高度
*/
public void removeBean(XCreator creator, int creatorWidth, int creatorHeight) {
delete(creator, creatorWidth, creatorHeight);
}
protected void delete(XCreator creator, int creatorWidth, int creatorHeight) {
}
protected abstract void addComp(XCreator creator, int x, int y);
/**
* 增加下一个组件
* @param dragged 组件
*/
@Override
public void addNextComponent(XCreator dragged) {
container.add(dragged);
LayoutUtils.layoutRootContainer(container);
}
/**
* 目标控件位置插入组件
* @param target 目标
* @param added 增加组件
*/
@Override
public void addBefore(XCreator target, XCreator added) {
int index = ComponentUtils.indexOfComponent(container, target);
if (index == -1) {
container.add(added, 0);
} else {
container.add(added, index);
}
LayoutUtils.layoutRootContainer(container);
}
/**
* 插在目标组件后面
* @param target 目标
* @param added 增加组件
*/
@Override
public void addAfter(XCreator target, XCreator added) {
int index = ComponentUtils.indexOfComponent(container, target);
if (index == -1) {
container.add(added);
} else {
index++;
if (index >= container.getComponentCount()) {
container.add(added);
} else {
container.add(added, index);
}
}
LayoutUtils.layoutRootContainer(container);
}
@Override
public HoverPainter getPainter() {
return new NullPainter(container);
}
/**
* 是否能接收更多的组件
* @return 能则返回true
*/
@Override
public boolean canAcceptMoreComponent() {
return true;
}
@Override
public ConstraintsGroupModel getLayoutConstraints(XCreator creator) {
return null;
}
@Override
public GroupModel getLayoutProperties() {
return null;
}
package com.fr.design.designer.beans.adapters.layout;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.beans.ConstraintsGroupModel;
import com.fr.design.designer.beans.HoverPainter;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.painters.NullPainter;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWidgetCreator;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.general.ComparatorUtils;
import java.awt.*;
public abstract class AbstractLayoutAdapter implements LayoutAdapter {
protected XLayoutContainer container;
protected LayoutManager layout;
public AbstractLayoutAdapter(XLayoutContainer container) {
this.container = container;
this.layout = container.getLayout();
}
/**
* 是否使用控件备份大小
*
* @param xCreator 控件
* @return 所在容器相同且支持备份的话返回true
*/
public boolean whetherUseBackupSize(XCreator xCreator) {
Class clazz = container.getClass();
Class bkClazz = null;
if (xCreator.getBackupParent() != null) {
bkClazz = xCreator.getBackupParent().getClass();
}
return ComparatorUtils.equals(bkClazz, clazz)
&& supportBackupSize();
}
/**
* 是否支持用备份大小
*
* @return
*/
public boolean supportBackupSize() {
return false;
}
/**
* 有的控件在拖拽调整大小后需要根据自身内容重新计算下当前的尺寸是否合适如果不合适就需要重新fix一下
*
* @param creator 组件
*/
public void fix(XCreator creator) {
}
/**
* 显示parent的字组件child解决CardLayout中显示某个非显示组件的特殊情况
*
* @param child 组件
*/
@Override
public void showComponent(XCreator child) {
child.setVisible(true);
}
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
*
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
@Override
public boolean addBean(XCreator creator, int x, int y) {
if (!accept(creator, x, y)) {
return false;
}
addComp(creator, x, y);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
/**
* 删除组件
*
* @param creator 组件
* @param creatorWidth
* @param creatorHeight
*/
public void removeBean(XCreator creator, int creatorWidth, int creatorHeight) {
delete(creator, creatorWidth, creatorHeight);
}
protected void delete(XCreator creator, int creatorWidth, int creatorHeight) {
}
protected abstract void addComp(XCreator creator, int x, int y);
/**
* 增加下一个组件
*
* @param dragged 组件
*/
@Override
public void addNextComponent(XCreator dragged) {
container.add(dragged);
LayoutUtils.layoutRootContainer(container);
}
/**
* 目标控件位置插入组件
*
* @param target 目标
* @param added 增加组件
*/
@Override
public void addBefore(XCreator target, XCreator added) {
int index = ComponentUtils.indexOfComponent(container, target);
if (index == -1) {
container.add(added, 0);
} else {
container.add(added, index);
}
LayoutUtils.layoutRootContainer(container);
}
/**
* 插在目标组件后面
*
* @param target 目标
* @param added 增加组件
*/
@Override
public void addAfter(XCreator target, XCreator added) {
int index = ComponentUtils.indexOfComponent(container, target);
if (index == -1) {
container.add(added);
} else {
index++;
if (index >= container.getComponentCount()) {
container.add(added);
} else {
container.add(added, index);
}
}
LayoutUtils.layoutRootContainer(container);
}
@Override
public HoverPainter getPainter() {
return new NullPainter(container);
}
/**
* 是否能接收更多的组件
*
* @return 能则返回true
*/
@Override
public boolean canAcceptMoreComponent() {
return true;
}
@Override
public ConstraintsGroupModel getLayoutConstraints(XCreator creator) {
return null;
}
@Override
public GroupModel getLayoutProperties() {
return null;
}
public XLayoutContainer getContainer() {
return this.container;
}
}

701
designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java

@ -1,354 +1,349 @@
package com.fr.design.designer.beans.adapters.layout;
import java.awt.*;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.beans.ConstraintsGroupModel;
import com.fr.design.designer.beans.HoverPainter;
import com.fr.design.designer.beans.painters.FRAbsoluteLayoutPainter;
import com.fr.design.designer.creator.*;
import com.fr.design.designer.properties.BoundsGroupModel;
import com.fr.design.designer.properties.FRAbsoluteLayoutPropertiesGroupModel;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogger;
public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter {
//是不是添加到父容器上
private boolean isAdd2ParentLayout = false;
private HoverPainter painter;
public FRAbsoluteLayoutAdapter(XLayoutContainer container) {
super(container);
painter = new FRAbsoluteLayoutPainter(container);
initMinSize();
}
private void initMinSize() {
XWAbsoluteLayout layout = (XWAbsoluteLayout) container;
minWidth = layout.getActualMinWidth();
minHeight = layout.getActualMinHeight();
actualVal = layout.getAcualInterval();
margin = layout.toData().getMargin();
}
@Override
public HoverPainter getPainter() {
return painter;
}
/**
* 是否能在指定位置添加组件
* @param creator 组件
* @param x 坐标x
* @param y 坐标y
* @return 能则返回true
*/
//这个地方的逻辑非常复杂,
// 1.当前绝对布局是不可编辑且是最外层,那么其他控件添加在它周围,
// 2.当前绝对布局是不可编辑且不是最外层,那么控件不可添加,(嵌套)
// 3.当前绝对布局可编辑,那么控件添加
@Override
public boolean accept(XCreator creator, int x, int y) {
Component comp = container.getComponentAt(x, y);
//布局控件要先判断是不是可编辑
//可以编辑,按原有逻辑判断
//不可编辑,当成一整个控件处理
if (comp == null){
return false;
}
//参数面板内的组件不允许拖往绝对布局中
if (creator.getParent() != null && ((XCreator)creator.getParent()).acceptType(XWParameterLayout.class)){
Rectangle rec = creator.getBounds();
rec.y = creator.getParent().getHeight() - rec.height;
creator.setBounds(rec);
return false;
}
//判断下组件能不能拖入绝对布局
if (!creator.canEnterIntoAbsolutePane()){
return false;
}
XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator)comp).getTopLayout();
if(topLayout != null){
if (topLayout.isEditable()){
return topLayoutAccept(creator, x, y, topLayout);
}
//绝对布局嵌套,处于内层,不可编辑,不添加,topLayout只能获取到最外层可编辑的布局
else if (((XLayoutContainer)topLayout.getParent()).acceptType(XWAbsoluteLayout.class)) {
return false;
}
else {
return acceptWidget(creator, x, y);
}
}
else{
FRLogger.getLogger().error("top layout is null!");
}
return false;
}
//toplayout假如可以编辑的话就往里面添加组件
private boolean topLayoutAccept(XCreator creator, int x, int y, XLayoutContainer topLayout) {
//判断有没有和当前控件重叠
//先计算当前控件的位置
int creatorX, creatorY;
if (XCreatorUtils.getParentXLayoutContainer(creator) != null) {
Rectangle creatorRectangle = ComponentUtils.getRelativeBounds(creator);
creatorX = creatorRectangle.x;
creatorY = creatorRectangle.y;
} else {
int w = creator.getWidth() / 2;
int h = creator.getHeight() / 2;
creatorX = x - w;
creatorY = y - h;
}
//再判断和布局中其他控件重叠
Rectangle curRec = new Rectangle(creatorX, creatorY, creator.getWidth(), creator.getHeight());
WAbsoluteLayout wAbsoluteLayout = (WAbsoluteLayout)topLayout.toData();
for (int i = 0, count = wAbsoluteLayout.getWidgetCount(); i < count; i++) {
BoundsWidget temp = (BoundsWidget) wAbsoluteLayout.getWidget(i);
Rectangle rectangle = temp.getBounds();
if (curRec.intersects(rectangle)){
return false;
}
}
if (creatorX < 0 || creatorX + creator.getWidth() > container.getWidth()) {
return false;
}
if (creatorY < 0 || creatorY + creator.getHeight() > container.getHeight()){
return false;
}
return x >= 0 && y >= 0 && creator.getHeight() <= container.getHeight()
&& creator.getWidth() <= container.getWidth();
}
/**
* 判断是否鼠标在组件的三等分区域如果组件在布局管理器中间上下左右都可能会三等分
* @param parentComp 鼠标所在区域的组件
* @param x 坐标x
* @param y 坐标y
* @return 是则返回true
*/
public boolean isTrisectionArea(Component parentComp, int x, int y) {
XCreator creator = (XCreator)parentComp;
trisectAreaDirect = 0;
if (container.getComponentCount()<=1) {
return false;
}
int maxWidth = parentComp.getWidth();
int maxHeight = parentComp.getHeight();
int xL = parentComp.getX();
int yL = parentComp.getY();
// 组件宽高的十分之一和默认值取大
int minRangeWidth = Math.max(maxWidth/BORDER_PROPORTION, DEFAULT_AREA_LENGTH);
int minRangeHeight = Math.max(maxHeight/BORDER_PROPORTION, DEFAULT_AREA_LENGTH);
if(y<yL+minRangeHeight ) {
// 在组件上侧三等分
trisectAreaDirect = COMP_TOP;
} else if(y>yL+maxHeight-minRangeHeight) {
// 在组件下侧三等分
trisectAreaDirect = COMP_BOTTOM;
} else if (x<xL+minRangeWidth) {
// 在组件左侧三等分
trisectAreaDirect = COMP_LEFT;
} else if(x>xL+maxWidth-minRangeWidth) {
// 在组件右侧三等分
trisectAreaDirect = COMP_RIGHT;
}
// tab布局的边界特殊处理,不进行三等分
if(!creator.getTargetChildrenList().isEmpty()){
return false;
}
return !ComparatorUtils.equals(trisectAreaDirect, 0);
}
//当前绝对布局不可编辑,就当成一个控件,组件添加在周围
private boolean acceptWidget(XCreator creator, int x, int y){
isFindRelatedComps = false;
//拖入组件判断时,先判断是否为交叉点区域,其次三等分区域,再次平分区域
Component comp = container.getComponentAt(x, y);
boolean isMatchEdge = false;
//如果当前处于边缘地带, 那么就把他贴到父容器上
XLayoutContainer parent = container.findNearestFit();
container = parent != null ? parent : container;
isAdd2ParentLayout = true;
int componentHeight = comp.getHeight();
int componentWidth = comp.getWidth();
//上半部分高度
int upHeight = (int) (componentHeight * TOP_HALF) + comp.getY();
//下半部分高度
int downHeight = (int) (componentHeight * BOTTOM_HALF) + comp.getY();
if (isCrossPointArea(comp, x, y)) {
return canAcceptWhileCrossPoint(comp, x, y);
}
if (isTrisectionArea(comp, x, y)) {
return canAcceptWhileTrisection(comp, x, y);
}
boolean horizonValid = componentWidth >= minWidth * 2 + actualVal;
boolean verticalValid = componentHeight >= minHeight * 2 + actualVal;
return y > upHeight && y < downHeight ? horizonValid : verticalValid;
}
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
*
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
@Override
public boolean addBean(XCreator creator, int x, int y) {
Rectangle rect = ComponentUtils.getRelativeBounds(container);
int posX = x + rect.x;
int posY = y + rect.y;
if (!accept(creator, x, y)) {
return false;
}
addComp(creator, posX, posY);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
@Override
protected void addComp(XCreator creator, int x, int y) {
if(!isAdd2ParentLayout) {
Rectangle r = ComponentUtils.getRelativeBounds(container);
x = x - r.x;
y = y - r.y;
if (XCreatorUtils.getParentXLayoutContainer(creator) != null) {
Rectangle creatorRectangle = ComponentUtils.getRelativeBounds(creator);
x = creatorRectangle.x - r.x;
y = creatorRectangle.y - r.y;
} else {
int w = creator.getWidth() / 2;
int h = creator.getHeight() / 2;
x = x - w;
y = y - h;
}
fix(creator, x, y);
if (creator.hasTitleStyle()) {
addParentCreator(creator);
} else {
container.add(creator, creator.toData().getWidgetName());
}
XWAbsoluteLayout layout = (XWAbsoluteLayout) container;
layout.updateBoundsWidget(creator);
updateCreatorBackBound();
LayoutUtils.layoutRootContainer(container);
}else{
fixAbsolute(creator, x, y);
if (creator.shouldScaleCreator() || creator.hasTitleStyle()) {
addParentCreator(creator);
} else {
container.add(creator, creator.toData().getWidgetName());
}
XWFitLayout layout = (XWFitLayout) container;
// 更新对应的BoundsWidget
layout.updateBoundsWidget();
updateCreatorBackBound();
}
}
private void updateCreatorBackBound() {
for (int i=0,size=container.getComponentCount(); i<size; i++) {
XCreator creator = (XCreator) container.getComponent(i);
creator.updateChildBound(minHeight);
creator.setBackupBound(creator.getBounds());
}
}
private void addParentCreator(XCreator child) {
XLayoutContainer parentPanel = child.initCreatorWrapper(child.getHeight());
container.add(parentPanel, child.toData().getWidgetName());
}
/**
* 新拖入组件时计算调整其他关联组件位置大小
* @param child 新拖入的组件
* @param x 鼠标所在x坐标
* @param y 鼠标所在y坐标
*/
private void fixAbsolute(XCreator child, int x, int y) {
Component parentComp = container.getComponentAt(x, y);
if (container.getComponentCount()==0){
child.setLocation(0, 0);
child.setSize(parentComp.getWidth(), parentComp.getHeight());
} else if(isCrossPointArea(parentComp, x, y)){
//交叉区域插入组件时,根据具体位置进行上下或者左右或者相邻三个组件的位置大小插入
fixCrossPointArea(parentComp, child, x, y);
return;
} else if (isTrisectionArea(parentComp, x, y)) {
// 在边界三等分区域,就不再和组件二等分了
fixTrisect(parentComp, child, x, y);
return;
} else{
fixHalve(parentComp, child, x, y);
}
}
/**
* 组件拖拽后调整大小
* @param creator 组件
*/
@Override
public void fix(XCreator creator) {
WAbsoluteLayout wabs = (WAbsoluteLayout)container.toData();
fix(creator,creator.getX(),creator.getY());
wabs.setBounds(creator.toData(),creator.getBounds());
XWAbsoluteLayout layout = (XWAbsoluteLayout) container;
layout.updateBoundsWidget(creator);
}
/**
* 调整组件大小到合适尺寸位置
* @param creator 组件
* @param x 坐标x
* @param y 坐标y
*/
public void fix(XCreator creator ,int x, int y) {
int height = creator.getHeight();
int width = creator.getWidth();
if (x < 0) {
width += x;
x = 0;
} else if (x + creator.getWidth() > container.getWidth()) {
width = container.getWidth() - x;
}
if (y < 0) {
height += y;
y = 0;
} else if (y + creator.getHeight() > container.getHeight()) {
height = container.getHeight() - y;
}
creator.setBounds(x, y, width, height);
}
@Override
public ConstraintsGroupModel getLayoutConstraints(XCreator creator) {
return new BoundsGroupModel((XWAbsoluteLayout)container, creator);
}
@Override
public GroupModel getLayoutProperties() {
XWAbsoluteLayout xwAbsoluteLayout = (XWAbsoluteLayout) container;
return new FRAbsoluteLayoutPropertiesGroupModel(xwAbsoluteLayout);
}
package com.fr.design.designer.beans.adapters.layout;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.beans.ConstraintsGroupModel;
import com.fr.design.designer.beans.HoverPainter;
import com.fr.design.designer.beans.painters.FRAbsoluteLayoutPainter;
import com.fr.design.designer.creator.*;
import com.fr.design.designer.properties.BoundsGroupModel;
import com.fr.design.designer.properties.FRAbsoluteLayoutPropertiesGroupModel;
import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogger;
import java.awt.*;
public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter {
//是不是添加到父容器上
private boolean isAdd2ParentLayout = false;
private HoverPainter painter;
public FRAbsoluteLayoutAdapter(XLayoutContainer container) {
super(container);
painter = new FRAbsoluteLayoutPainter(container);
initMinSize();
}
private void initMinSize() {
XWAbsoluteLayout layout = (XWAbsoluteLayout) container;
minWidth = layout.getActualMinWidth();
minHeight = layout.getActualMinHeight();
actualVal = layout.getAcualInterval();
margin = layout.toData().getMargin();
}
@Override
public HoverPainter getPainter() {
return painter;
}
/**
* 是否能在指定位置添加组件
*
* @param creator 组件
* @param x 坐标x
* @param y 坐标y
* @return 能则返回true
*/
//这个地方的逻辑非常复杂,
// 1.当前绝对布局是不可编辑且是最外层,那么其他控件添加在它周围,
// 2.当前绝对布局是不可编辑且不是最外层,那么控件不可添加,(嵌套)
// 3.当前绝对布局可编辑,那么控件添加
@Override
public boolean accept(XCreator creator, int x, int y) {
Component comp = container.getComponentAt(x, y);
//布局控件要先判断是不是可编辑
//可以编辑,按原有逻辑判断
//不可编辑,当成一整个控件处理
if (comp == null) {
return false;
}
//参数面板内的组件不允许拖往绝对布局中
if (creator.getParent() != null && ((XCreator) creator.getParent()).acceptType(XWParameterLayout.class)) {
Rectangle rec = creator.getBounds();
rec.y = creator.getParent().getHeight() - rec.height;
creator.setBounds(rec);
return false;
}
//判断组件能不能拖入绝对布局
if (!creator.canEnterIntoAbsolutePane()) {
return false;
}
XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator) comp).getTopLayout();
if (topLayout != null) {
if (topLayout.isEditable()) {
return topLayoutAccept(creator, x, y);
}
//绝对布局嵌套,处于内层,不可编辑,不添加,topLayout只能获取到最外层可编辑的布局
else if (((XLayoutContainer) topLayout.getParent()).acceptType(XWAbsoluteLayout.class)) {
return false;
} else {
return acceptWidget(x, y);
}
} else {
FRLogger.getLogger().error("top layout is null!");
}
return false;
}
//topLayout假如可以编辑的话就往里面添加组件
private boolean topLayoutAccept(XCreator creator, int x, int y) {
//允许组件重叠,可以不判断有没有和当前控件重叠
//先计算当前控件的位置
int creatorX, creatorY;
if (XCreatorUtils.getParentXLayoutContainer(creator) != null) {
Rectangle creatorRectangle = ComponentUtils.getRelativeBounds(creator);
creatorX = creatorRectangle.x;
creatorY = creatorRectangle.y;
} else {
//这边计算得到的组件其实位置是正确的,
//因为传入的x和y已经加上了宽度或者高度的一半,再减去相同的宽度和高度的一半是没区别的,
// 例如高度为21,那么就是+10-10;
// 高度为20,那么就是+10-10; 没区别
int w = creator.getWidth() / 2;
int h = creator.getHeight() / 2;
creatorX = x - w;
creatorY = y - h;
}
if (creatorX < 0 || creatorX + creator.getWidth() > container.getWidth()) {
return false;
}
if (creatorY < 0 || creatorY + creator.getHeight() > container.getHeight()) {
return false;
}
return x >= 0 && y >= 0 && creator.getHeight() <= container.getHeight()
&& creator.getWidth() <= container.getWidth();
}
/**
* 判断是否鼠标在组件的三等分区域如果组件在布局管理器中间上下左右都可能会三等分
*
* @param parentComp 鼠标所在区域的组件
* @param x 坐标x
* @param y 坐标y
* @return 是则返回true
*/
public boolean isTrisectionArea(Component parentComp, int x, int y) {
XCreator creator = (XCreator) parentComp;
trisectAreaDirect = 0;
if (container.getComponentCount() <= 1) {
return false;
}
int maxWidth = parentComp.getWidth();
int maxHeight = parentComp.getHeight();
int xL = parentComp.getX();
int yL = parentComp.getY();
// 组件宽高的十分之一和默认值取大
int minRangeWidth = Math.max(maxWidth / BORDER_PROPORTION, DEFAULT_AREA_LENGTH);
int minRangeHeight = Math.max(maxHeight / BORDER_PROPORTION, DEFAULT_AREA_LENGTH);
if (y < yL + minRangeHeight) {
// 在组件上侧三等分
trisectAreaDirect = COMP_TOP;
} else if (y > yL + maxHeight - minRangeHeight) {
// 在组件下侧三等分
trisectAreaDirect = COMP_BOTTOM;
} else if (x < xL + minRangeWidth) {
// 在组件左侧三等分
trisectAreaDirect = COMP_LEFT;
} else if (x > xL + maxWidth - minRangeWidth) {
// 在组件右侧三等分
trisectAreaDirect = COMP_RIGHT;
}
// tab布局的边界特殊处理,不进行三等分
if (!creator.getTargetChildrenList().isEmpty()) {
return false;
}
return !ComparatorUtils.equals(trisectAreaDirect, 0);
}
//当前绝对布局不可编辑,就当成一个控件,组件添加在周围
private boolean acceptWidget(int x, int y) {
isFindRelatedComps = false;
//拖入组件判断时,先判断是否为交叉点区域,其次三等分区域,再次平分区域
Component comp = container.getComponentAt(x, y);
//如果当前处于边缘地带, 那么就把他贴到父容器上
XLayoutContainer parent = container.findNearestFit();
container = parent != null ? parent : container;
isAdd2ParentLayout = true;
int componentHeight = comp.getHeight();
int componentWidth = comp.getWidth();
//上半部分高度
int upHeight = (int) (componentHeight * TOP_HALF) + comp.getY();
//下半部分高度
int downHeight = (int) (componentHeight * BOTTOM_HALF) + comp.getY();
if (isCrossPointArea(comp, x, y)) {
return canAcceptWhileCrossPoint(comp, x, y);
}
if (isTrisectionArea(comp, x, y)) {
return canAcceptWhileTrisection(comp, x, y);
}
boolean horizonValid = componentWidth >= minWidth * 2 + actualVal;
boolean verticalValid = componentHeight >= minHeight * 2 + actualVal;
return y > upHeight && y < downHeight ? horizonValid : verticalValid;
}
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
*
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
@Override
public boolean addBean(XCreator creator, int x, int y) {
Rectangle rect = ComponentUtils.getRelativeBounds(container);
int posX = x + rect.x;
int posY = y + rect.y;
if (!accept(creator, x, y)) {
return false;
}
addComp(creator, posX, posY);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
@Override
protected void addComp(XCreator creator, int x, int y) {
if (!isAdd2ParentLayout) {
Rectangle r = ComponentUtils.getRelativeBounds(container);
x = x - r.x;
y = y - r.y;
if (XCreatorUtils.getParentXLayoutContainer(creator) != null) {
Rectangle creatorRectangle = ComponentUtils.getRelativeBounds(creator);
x = creatorRectangle.x - r.x;
y = creatorRectangle.y - r.y;
} else {
int w = creator.getWidth() / 2;
int h = creator.getHeight() / 2;
x = x - w;
y = y - h;
}
fix(creator, x, y);
if (creator.hasTitleStyle()) {
addParentCreator(creator);
} else {
container.add(creator, creator.toData().getWidgetName());
}
XWAbsoluteLayout layout = (XWAbsoluteLayout) container;
layout.updateBoundsWidget(creator);
updateCreatorBackBound();
LayoutUtils.layoutRootContainer(container);
} else {
fixAbsolute(creator, x, y);
if (creator.shouldScaleCreator() || creator.hasTitleStyle()) {
addParentCreator(creator);
} else {
container.add(creator, creator.toData().getWidgetName());
}
XWFitLayout layout = (XWFitLayout) container;
// 更新对应的BoundsWidget
layout.updateBoundsWidget();
updateCreatorBackBound();
}
}
private void updateCreatorBackBound() {
for (int i = 0, size = container.getComponentCount(); i < size; i++) {
XCreator creator = (XCreator) container.getComponent(i);
creator.updateChildBound(minHeight);
creator.setBackupBound(creator.getBounds());
}
}
private void addParentCreator(XCreator child) {
XLayoutContainer parentPanel = child.initCreatorWrapper(child.getHeight());
container.add(parentPanel, child.toData().getWidgetName());
}
/**
* 新拖入组件时计算调整其他关联组件位置大小
*
* @param child 新拖入的组件
* @param x 鼠标所在x坐标
* @param y 鼠标所在y坐标
*/
private void fixAbsolute(XCreator child, int x, int y) {
Component parentComp = container.getComponentAt(x, y);
if (container.getComponentCount() == 0) {
child.setLocation(0, 0);
child.setSize(parentComp.getWidth(), parentComp.getHeight());
} else if (isCrossPointArea(parentComp, x, y)) {
//交叉区域插入组件时,根据具体位置进行上下或者左右或者相邻三个组件的位置大小插入
fixCrossPointArea(parentComp, child, x, y);
//TODO 尽量不要出现这种写法吧?if else条件要么互斥,要么多个if判断return,不要在一条if else语句里面return吧?
return;
} else if (isTrisectionArea(parentComp, x, y)) {
// 在边界三等分区域,就不再和组件二等分了
fixTrisect(parentComp, child, x, y);
return;
} else {
fixHalve(parentComp, child, x, y);
}
}
/**
* 组件拖拽后调整大小
*
* @param creator 组件
*/
@Override
public void fix(XCreator creator) {
WAbsoluteLayout wabs = (WAbsoluteLayout) container.toData();
fix(creator, creator.getX(), creator.getY());
wabs.setBounds(creator.toData(), creator.getBounds());
XWAbsoluteLayout layout = (XWAbsoluteLayout) container;
layout.updateBoundsWidget(creator);
}
/**
* 调整组件大小到合适尺寸位置
*
* @param creator 组件
* @param x 坐标x
* @param y 坐标y
*/
public void fix(XCreator creator, int x, int y) {
int height = creator.getHeight();
int width = creator.getWidth();
if (x < 0) {
width += x;
x = 0;
} else if (x + creator.getWidth() > container.getWidth()) {
width = container.getWidth() - x;
}
if (y < 0) {
height += y;
y = 0;
} else if (y + creator.getHeight() > container.getHeight()) {
height = container.getHeight() - y;
}
creator.setBounds(x, y, width, height);
}
@Override
public ConstraintsGroupModel getLayoutConstraints(XCreator creator) {
return new BoundsGroupModel((XWAbsoluteLayout) container, creator);
}
@Override
public GroupModel getLayoutProperties() {
XWAbsoluteLayout xwAbsoluteLayout = (XWAbsoluteLayout) container;
return new FRAbsoluteLayoutPropertiesGroupModel(xwAbsoluteLayout);
}
}

2385
designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java

File diff suppressed because it is too large Load Diff

210
designer_form/src/com/fr/design/designer/beans/adapters/layout/FRTabFitLayoutAdapter.java

@ -1,108 +1,104 @@
/**
*
*/
package com.fr.design.designer.beans.adapters.layout;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.creator.XWidgetCreator;
import com.fr.design.designer.creator.cardlayout.XWCardLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.designer.creator.cardlayout.XWTabFitLayout;
import com.fr.design.designer.properties.FRTabFitLayoutPropertiesGroupModel;
import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.container.WBorderLayout;
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import com.fr.general.ComparatorUtils;
import java.awt.*;
/**
* tab布局tabFit适配器
*
* @author focus
* @date 2014-6-24
*/
public class FRTabFitLayoutAdapter extends FRFitLayoutAdapter {
//标题栏高度对tab布局内部组件的y坐标造成了偏移
private static int TAB_HEIGHT = 40;
/**
* 构造函数
*
* @param container XWTabFitLayout容器
*/
public FRTabFitLayoutAdapter(XLayoutContainer container) {
super(container);
}
/**
* 返回布局自身属性方便一些特有设置在layout刷新时处理
*/
@Override
public GroupModel getLayoutProperties() {
XWTabFitLayout xfl = (XWTabFitLayout) container;
return new FRTabFitLayoutPropertiesGroupModel(xfl);
}
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
*
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
@Override
public boolean addBean(XCreator creator, int x, int y) {
// 经过accept判断后,container会被改变,先备份
XLayoutContainer backUpContainer = container;
Rectangle rect = ComponentUtils.getRelativeBounds(container);
int posX = x - rect.x;
int posY = y - rect.y;
if (!accept(creator, posX, posY)) {
return false;
}
// posX,posY是新拖入组件相对于容器的位置,若在tab布局的边缘,则需要把新组件添加到
// 父层自适应布局中,这时候的添加位置就是tab布局所在的位置
if (this.intersectsEdge(posX, posY, backUpContainer)) {
if (!ComparatorUtils.equals(backUpContainer.getOuterLayout(), backUpContainer.getBackupParent())) {
XWTabFitLayout tabLayout = (XWTabFitLayout) backUpContainer;
y = adjustY(y, tabLayout);
}
addComp(creator, x, y);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
// 如果不在边缘,容器为本自适应布局,增加组件的位置就是相对于容器的位置
addComp(creator, posX, posY);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
// tab布局的纵坐标受到tab高度的影响,判断的上边界取得是里面XWTabFitLayout的上边界,
// 实际计算的时候的纵坐标用了外层的CardMainBorerLayout,需要将tab高度减掉
//将y值变为相对坐标以实现获取到鼠标drop位置的控件
//TODO 可以直接在这边将x,y都变成相对坐标,这样在后面判断拖进来的新控件放置方式的时候就不用再判断了
private int adjustY(int y, XWTabFitLayout tabLayout) {
XWCardLayout cardLayout = (XWCardLayout) tabLayout.getBackupParent();
LayoutBorderStyle style = cardLayout.toData().getBorderStyle();
if (container.getLocation().y == WBorderLayout.DEFAULT_SIZE) {
y = y - WBorderLayout.DEFAULT_SIZE;
}
if (ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)) {
y = y - WCardMainBorderLayout.TAB_HEIGHT;
}
return y;
}
protected Rectangle getLayoutBound(XWCardMainBorderLayout mainLayout) {
return ComponentUtils.getRelativeBounds(mainLayout);
}
/**
*
*/
package com.fr.design.designer.beans.adapters.layout;
import com.fr.design.beans.GroupModel;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWidgetCreator;
import com.fr.design.designer.creator.cardlayout.XWCardLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.designer.creator.cardlayout.XWTabFitLayout;
import com.fr.design.designer.properties.FRTabFitLayoutPropertiesGroupModel;
import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.container.WBorderLayout;
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import com.fr.general.ComparatorUtils;
import java.awt.*;
/**
* tab布局tabFit适配器
*
* @author focus
* @date 2014-6-24
*/
public class FRTabFitLayoutAdapter extends FRFitLayoutAdapter {
/**
* 构造函数
*
* @param container XWTabFitLayout容器
*/
public FRTabFitLayoutAdapter(XLayoutContainer container) {
super(container);
}
/**
* 返回布局自身属性方便一些特有设置在layout刷新时处理
*/
@Override
public GroupModel getLayoutProperties() {
XWTabFitLayout xfl = (XWTabFitLayout) container;
return new FRTabFitLayoutPropertiesGroupModel(xfl);
}
/**
* 组件的ComponentAdapter在添加组件时如果发现布局管理器不为空会继而调用该布局管理器的
* addComp方法来完成组件的具体添加在该方法内布局管理器可以提供额外的功能
*
* @param creator 被添加的新组件
* @param x 添加的位置x该位置是相对于container的
* @param y 添加的位置y该位置是相对于container的
* @return 是否添加成功成功返回true否则false
*/
@Override
public boolean addBean(XCreator creator, int x, int y) {
// 经过accept判断后,container会被改变,先备份
XLayoutContainer backUpContainer = container;
Rectangle rect = ComponentUtils.getRelativeBounds(container);
int posX = x - rect.x;
int posY = y - rect.y;
if (!accept(creator, posX, posY)) {
return false;
}
// posX,posY是新拖入组件相对于容器的位置,若在tab布局的边缘,则需要把新组件添加到l
// 父层自适应布局中,这时候的添加位置就是tab布局所在的位置
if (this.intersectsEdge(posX, posY, backUpContainer)) {
if (!ComparatorUtils.equals(backUpContainer.getOuterLayout(), backUpContainer.getBackupParent())) {
XWTabFitLayout tabLayout = (XWTabFitLayout) backUpContainer;
y = adjustY(y, tabLayout);
}
addComp(creator, x, y);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
// 如果不在边缘,容器为本自适应布局,增加组件的位置就是相对于容器的位置
addComp(creator, posX, posY);
((XWidgetCreator) creator).recalculateChildrenSize();
return true;
}
// tab布局的纵坐标受到tab高度的影响,判断的上边界取得是里面XWTabFitLayout的上边界,
// 实际计算的时候的纵坐标用了外层的CardMainBorerLayout,需要将tab高度减掉
//将y值变为相对坐标以实现获取到鼠标drop位置的控件
//TODO 可以直接在这边将x,y都变成相对坐标,这样在后面判断拖进来的新控件放置方式的时候就不用再判断了
private int adjustY(int y, XWTabFitLayout tabLayout) {
XWCardLayout cardLayout = (XWCardLayout) tabLayout.getBackupParent();
LayoutBorderStyle style = cardLayout.toData().getBorderStyle();
if (container.getLocation().y == WBorderLayout.DEFAULT_SIZE) {
y = y - WBorderLayout.DEFAULT_SIZE;
}
if (ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)) {
y = y - WCardMainBorderLayout.TAB_HEIGHT;
}
return y;
}
protected Rectangle getLayoutBound(XWCardMainBorderLayout mainLayout) {
return ComponentUtils.getRelativeBounds(mainLayout);
}
}

333
designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java

@ -3,19 +3,17 @@
*/
package com.fr.design.designer.beans.location;
import java.awt.*;
import com.fr.design.beans.location.Absorptionline;
import com.fr.design.beans.location.MoveUtils;
import com.fr.design.designer.creator.*;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelection;
import com.fr.design.utils.ComponentUtils;
import com.fr.form.main.Form;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.form.ui.container.WParameterLayout;
import com.fr.form.ui.widget.BoundsWidget;
import java.awt.*;
/**
* @author richer
* @since 6.5.3
@ -26,197 +24,184 @@ public abstract class AccessDirection implements Direction {
private int ymin;
private int xmin;
abstract int getCursor();
protected abstract Rectangle getDraggedBounds(int dx, int dy, Rectangle current_bounds, FormDesigner designer,
Rectangle oldbounds);
protected int[] sorption(int x, int y,Rectangle current_bounds, FormDesigner designer) {
// 自适应布局不需要吸附线,但需要对齐线,对齐线后面处理
if (!designer.hasWAbsoluteLayout()) {
designer.getStateModel().setEquidistantLine(null);
designer.getStateModel().setXAbsorptionline(null);
designer.getStateModel().setYAbsorptionline(null);
return new int[] { x, y };
} else {
int posy = current_bounds.y;
Point relativePoint = getRelativePoint(x, y, current_bounds,designer);
sorptionPoint(relativePoint,current_bounds, designer);
return new int[] { relativePoint.x, relativePoint.y };
}
}
protected Point getRelativePoint(int x, int y, Rectangle current_bounds,FormDesigner designer) {
if (x < 0) {
x = 0;
} else if (x > designer.getRootComponent().getWidth() && designer.getSelectionModel().hasSelectionComponent()) {
x = designer.getRootComponent().getWidth();
}
abstract int getCursor();
protected abstract Rectangle getDraggedBounds(int dx, int dy, Rectangle currentBounds, FormDesigner designer,
Rectangle oldBounds);
protected int[] sorption(int x, int y, Rectangle currentBounds, FormDesigner designer) {
// 自适应布局不需要吸附线,但需要对齐线,对齐线后面处理
if (!designer.hasWAbsoluteLayout()) {
designer.getStateModel().setEquidistantLine(null);
designer.getStateModel().setXAbsorptionline(null);
designer.getStateModel().setYAbsorptionline(null);
return new int[]{x, y};
} else {
Point relativePoint = getRelativePoint(x, y, currentBounds, designer);
sorptionPoint(relativePoint, currentBounds, designer);
return new int[]{relativePoint.x, relativePoint.y};
}
}
protected Point getRelativePoint(int x, int y, Rectangle currentBounds, FormDesigner designer) {
if (x < 0) {
x = 0;
} else if (x > designer.getRootComponent().getWidth() && designer.getSelectionModel().hasSelectionComponent()) {
x = designer.getRootComponent().getWidth();
}
//参数面板可以无下限拉长
if (y < 0) {
y = 0;
} else if (y > designer.getRootComponent().getHeight() + designer.getParaHeight() && designer.getSelectionModel().hasSelectionComponent()
if (y < 0) {
y = 0;
} else if (y > designer.getRootComponent().getHeight() + designer.getParaHeight() && designer.getSelectionModel().hasSelectionComponent()
&& !designer.getSelectionModel().getSelection().getSelectedCreator().acceptType(XWParameterLayout.class)) {
y = designer.getRootComponent().getHeight() + designer.getParaHeight();
}
return new Point(x, y);
}
protected void sorptionPoint(Point point, Rectangle current_bounds,FormDesigner designer) {
boolean findInX = current_bounds.getWidth() <= MoveUtils.SORPTION_UNIT ? true : false;
boolean findInY = current_bounds.getHeight() <= MoveUtils.SORPTION_UNIT ? true : false;
WAbsoluteLayout layout =getLayout(designer);
FormSelection selection = designer.getSelectionModel().getSelection();
boolean isWidgetsIntersect = false;
for (int i = 0, count = layout.getWidgetCount(); i < count; i++) {
BoundsWidget temp = (BoundsWidget) layout.getWidget(i);
if (!temp.isVisible() || selection.contains(temp.getWidget())) {
continue;
}
Rectangle bounds = getWidgetRelativeBounds(temp.getBounds(), selection);
if (!findInX) {
int x1 = bounds.x;
if (Math.abs(x1 - point.x) <= MoveUtils.SORPTION_UNIT) {
point.x = x1;
findInX = true;
}
int x2 = bounds.x + bounds.width;
if (Math.abs(x2 - point.x) <= MoveUtils.SORPTION_UNIT) {
point.x = x2;
findInX = true;
}
}
if (!findInY) {
int y1 = bounds.y;
if (Math.abs(y1 - point.y) <= MoveUtils.SORPTION_UNIT) {
point.y = y1;
findInY = true;
}
int y2 = bounds.y + bounds.height;
if (Math.abs(y2 - point.y) <= MoveUtils.SORPTION_UNIT) {
point.y = y2;
findInY = true;
}
}
if (findInX && findInY) {
break;
}
if (current_bounds.intersects(bounds) && !(layout instanceof WParameterLayout)){
isWidgetsIntersect = true;
}
}
processRectangleIntersects(designer, point.x, point.y, isWidgetsIntersect);
setDesignerStateModelProperties(designer, findInX, findInY, current_bounds, point);
}
private void setDesignerStateModelProperties (FormDesigner designer, boolean findInX, boolean findInY, Rectangle current_bounds, Point point) {
designer.getStateModel().setXAbsorptionline(findInX && current_bounds.getWidth() > MoveUtils.SORPTION_UNIT ? Absorptionline.createXAbsorptionline(point.x) : null);
designer.getStateModel().setYAbsorptionline(findInY && current_bounds.getHeight() > MoveUtils.SORPTION_UNIT ? Absorptionline.createYAbsorptionline(point.y) : null);
designer.getStateModel().setEquidistantLine(null);
}
private Rectangle getWidgetRelativeBounds(Rectangle bounds, FormSelection selection){
Rectangle relativeRec = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator());
if (parent == null) {
return relativeRec;
}
Rectangle rec = ComponentUtils.getRelativeBounds(parent);
relativeRec.x += rec.x;
relativeRec.y += rec.y;
return relativeRec;
}
private void processRectangleIntersects(FormDesigner designer, int x, int y, boolean isIntersects){
if(isIntersects){
if(designer.getLocationOnScreen() != null) {
MoveUtils.displayForbidWindow(x + designer.getLocationOnScreen().x, y + designer.getLocationOnScreen().y);
}
designer.setWidgetsIntersect(true);
}
else{
MoveUtils.hideForbidWindow();
designer.setWidgetsIntersect(false);
}
}
private WAbsoluteLayout getLayout(final FormDesigner designer){
y = designer.getRootComponent().getHeight() + designer.getParaHeight();
}
return new Point(x, y);
}
protected void sorptionPoint(Point point, Rectangle currentBounds, FormDesigner designer) {
boolean findInX = currentBounds.getWidth() <= MoveUtils.SORPTION_UNIT;
boolean findInY = currentBounds.getHeight() <= MoveUtils.SORPTION_UNIT;
WAbsoluteLayout layout = getLayout(designer);
FormSelection selection = designer.getSelectionModel().getSelection();
for (int i = 0, count = layout.getWidgetCount(); i < count; i++) {
BoundsWidget temp = (BoundsWidget) layout.getWidget(i);
if (!temp.isVisible() || selection.contains(temp.getWidget())) {
continue;
}
Rectangle bounds = getWidgetRelativeBounds(temp.getBounds(), selection);
if (!findInX) {
int x1 = bounds.x;
if (Math.abs(x1 - point.x) <= MoveUtils.SORPTION_UNIT) {
point.x = x1;
findInX = true;
}
int x2 = bounds.x + bounds.width;
if (Math.abs(x2 - point.x) <= MoveUtils.SORPTION_UNIT) {
point.x = x2;
findInX = true;
}
}
if (!findInY) {
int y1 = bounds.y;
if (Math.abs(y1 - point.y) <= MoveUtils.SORPTION_UNIT) {
point.y = y1;
findInY = true;
}
int y2 = bounds.y + bounds.height;
if (Math.abs(y2 - point.y) <= MoveUtils.SORPTION_UNIT) {
point.y = y2;
findInY = true;
}
}
if (findInX && findInY) {
break;
}
}
setDesignerStateModelProperties(designer, findInX, findInY, currentBounds, point);
}
private void setDesignerStateModelProperties(FormDesigner designer, boolean findInX, boolean findInY, Rectangle
currentBounds, Point point) {
designer.getStateModel().setXAbsorptionline(findInX && currentBounds.getWidth() > MoveUtils.SORPTION_UNIT ? Absorptionline.createXAbsorptionline(point.x) : null);
designer.getStateModel().setYAbsorptionline(findInY && currentBounds.getHeight() > MoveUtils.SORPTION_UNIT ? Absorptionline.createYAbsorptionline(point.y) : null);
designer.getStateModel().setEquidistantLine(null);
}
private Rectangle getWidgetRelativeBounds(Rectangle bounds, FormSelection selection) {
Rectangle relativeRec = new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator());
if (parent == null) {
return relativeRec;
}
Rectangle rec = ComponentUtils.getRelativeBounds(parent);
relativeRec.x += rec.x;
relativeRec.y += rec.y;
return relativeRec;
}
private WAbsoluteLayout getLayout(final FormDesigner designer) {
XLayoutContainer formLayoutContainer = (XLayoutContainer) XCreatorUtils.createXCreator(
designer.getTarget().getContainer());
WAbsoluteLayout layout;
if (formLayoutContainer.acceptType(XWBorderLayout.class)){//看起来这边的作用应该是为了区别cpt(得到XWParameterLayout)还是frm(得到XWBorderLayout)的参数界面
Container container = designer.getSelectionModel().getSelection().getSelectedCreator().getParent();
if(container instanceof XWAbsoluteLayout){
layout = ((XWAbsoluteLayout)container).toData();
}
else {
layout = (WAbsoluteLayout) designer.getParaComponent().toData();
}
} else{
if (formLayoutContainer.acceptType(XWBorderLayout.class)) {//看起来这边的作用应该是为了区别cpt(得到XWParameterLayout)还是frm(得到XWBorderLayout)的参数界面
Container container = designer.getSelectionModel().getSelection().getSelectedCreator().getParent();
if (container instanceof XWAbsoluteLayout) {
layout = ((XWAbsoluteLayout) container).toData();
} else {
layout = (WAbsoluteLayout) designer.getParaComponent().toData();
}
} else {
layout = (WAbsoluteLayout) designer.getTarget().getContainer();
}
return layout;
return layout;
}
/**
* 拖拽
* @param dx 坐标x
* @param dy 坐标y
* @param designer 设计界面
*/
public void drag(int dx, int dy, FormDesigner designer) {
Rectangle rec = getDraggedBounds(dx, dy, designer.getSelectionModel().getSelection().getRelativeBounds(), designer, designer.getSelectionModel().getSelection().getBackupBounds());
/**
* 拖拽
*
* @param dx 坐标x
* @param dy 坐标y
* @param designer 设计界面
*/
public void drag(int dx, int dy, FormDesigner designer) {
Rectangle rec = getDraggedBounds(dx, dy, designer.getSelectionModel().getSelection().getRelativeBounds(), designer, designer.getSelectionModel().getSelection().getBackupBounds());
if (rec != null) {
designer.getSelectionModel().getSelection().setSelectionBounds(rec, designer);
} else {
return;
}
//设定控件最小高度21,因每次拖曳至少移动1,防止控件高度等于21时,拖曳导致rec.y的变化使得控件不停的向上或向下移动。
if(rec.height == MINHEIGHT){
if (rec.height == MINHEIGHT) {
ymin = rec.y;
}
if(rec.height == MINHEIGHT - 1){
if (rec.height == MINHEIGHT - 1) {
ymin = ymin == rec.y ? rec.y : rec.y - 1;
}
if(rec.height < MINHEIGHT){
if (rec.height < MINHEIGHT) {
rec.height = MINHEIGHT;
rec.y = ymin;
}
// 增加下宽度也设最小为21
if (rec.width == MINWIDTH) {
xmin = rec.x;
xmin = rec.x;
}
if(rec.width == MINWIDTH - 1){
xmin = xmin == rec.x ? rec.x : rec.x - 1;
if (rec.width == MINWIDTH - 1) {
xmin = xmin == rec.x ? rec.x : rec.x - 1;
}
if (rec.width < MINWIDTH) {
rec.width = MINWIDTH;
rec.x = xmin;
rec.width = MINWIDTH;
rec.x = xmin;
}
}
/**
* 更新鼠标指针形状
*
* @param formEditor 设计界面组件
*/
public void updateCursor(FormDesigner formEditor) {
// 调用位置枚举的多态方法getCursor获取鼠标形状
int type = getCursor();
if (type != formEditor.getCursor().getType()) {
// 设置当前形状
formEditor.setCursor(Cursor.getPredefinedCursor(type));
}
if(rec != null) {
designer.getSelectionModel().getSelection().setSelectionBounds(rec, designer);
}
}
/**
* 更新鼠标指针形状
* @param formEditor 设计界面组件
*/
public void updateCursor(FormDesigner formEditor) {
// 调用位置枚举的多态方法getCursor获取鼠标形状
int type = getCursor();
if (type != formEditor.getCursor().getType()) {
// 设置当前形状
formEditor.setCursor(Cursor.getPredefinedCursor(type));
}
}
/**
* 生成组件备用的bound
* @param formEditor 设计界面组件
*/
public void backupBounds(FormDesigner formEditor) {
formEditor.getSelectionModel().getSelection().backupBounds();
}
}
/**
* 生成组件备用的bound
*
* @param formEditor 设计界面组件
*/
public void backupBounds(FormDesigner formEditor) {
formEditor.getSelectionModel().getSelection().backupBounds();
}
}

744
designer_form/src/com/fr/design/designer/beans/models/SelectionModel.java

@ -1,328 +1,418 @@
package com.fr.design.designer.beans.models;
import java.awt.LayoutManager;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.beans.location.Direction;
import com.fr.design.designer.beans.location.Location;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelection;
import com.fr.design.mainframe.FormSelectionUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.stable.ArrayUtils;
/**
* 该model保存当前选择的组件和剪切版信息
*/
public class SelectionModel {
private static final int DELTA_X_Y = 20; //粘贴时候的偏移距离
private static FormSelection CLIP_BOARD = new FormSelection();
private FormDesigner designer;
private FormSelection selection;
private Rectangle hotspot_bounds;
public SelectionModel(FormDesigner designer) {
this.designer = designer;
selection = new FormSelection();
}
/**
* 重置清空formSelction以及选择区域
*/
public void reset() {
selection.reset();
hotspot_bounds = null;
}
/**
* formSelction是否为空
* @return 是否为空
*/
public static boolean isEmpty(){
return CLIP_BOARD.isEmpty();
}
/**
* 鼠标点击一下所选中的单个组件按下Ctrl或者shift键时鼠标可以进行多选
* @param e 鼠标事件
*/
public void selectACreatorAtMouseEvent(MouseEvent e) {
if (!e.isControlDown() && !e.isShiftDown()) {
// 如果Ctrl或者Shift键盘没有按下,则清除已经选择的组件
selection.reset();
}
// 获取e所在的组件
XCreator comp = designer.getComponentAt(e);
//布局组件的顶层布局如不可编辑,要获取其顶层布局
XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer(comp).getTopLayout();
if(topLayout != null && !topLayout.isEditable()){
comp = topLayout;
}
// 如果父层是scale和title两个专属容器,返回其父层,组件本身是不让被选中的
if (comp != designer.getRootComponent() && comp != designer.getParaComponent()) {
XCreator parentContainer = (XCreator) comp.getParent();
comp = parentContainer.isDedicateContainer() ? parentContainer : comp;
}
if (selection.removeSelectedCreator(comp) || selection.addSelectedCreator(comp)) {
designer.getEditListenerTable().fireCreatorModified(comp, DesignerEvent.CREATOR_SELECTED);
designer.repaint();
}
}
/**
* 将所选组件剪切到剪切板上
*/
public void cutSelectedCreator2ClipBoard() {
if (hasSelectionComponent()) {
selection.cut2ClipBoard(CLIP_BOARD);
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_CUTED);
designer.repaint();
}
}
/**
* 复制当前选中的组件到剪切板
*/
public void copySelectedCreator2ClipBoard() {
if (!selection.isEmpty()) {
selection.copy2ClipBoard(CLIP_BOARD);
}
}
/**
* 从剪切板粘帖组件
* @return
*/
public boolean pasteFromClipBoard() {
if (!CLIP_BOARD.isEmpty()) {
XLayoutContainer parent = null;
if (!hasSelectionComponent()) {
FormSelectionUtils.paste2Container(designer, designer.getRootComponent(),CLIP_BOARD, DELTA_X_Y, DELTA_X_Y);
} else {
parent = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator());
if (parent != null) {
Rectangle rec = selection.getSelctionBounds();
FormSelectionUtils.paste2Container(designer, parent,CLIP_BOARD, rec.x + DELTA_X_Y, rec.y + DELTA_X_Y);
}
}
} else {
Toolkit.getDefaultToolkit().beep();
}
return false;
}
public FormSelection getSelection() {
return selection;
}
/**
* 删除当前所有选择的组件
*/
public void deleteSelection() {
XCreator[] roots = selection.getSelectedCreators();
if (roots.length > 0) {
for (XCreator creator : roots) {
if(creator.acceptType(XWParameterLayout.class)){
designer.removeParaComponent();
}
removeCreatorFromContainer(creator, creator.getWidth(), creator.getHeight());
creator.removeAll();
// 清除被选中的组件
selection.reset();
}
setSelectedCreator(designer.getRootComponent());
// 触发事件
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_DELETED);
designer.repaint();
}
}
/**
* 从选择组件中删除某组件
*
* @param creator 组件
* @param creatorWidth 组件之前宽度
* @param creatorHeight 组件之前高度
*/
public void removeCreator(XCreator creator, int creatorWidth, int creatorHeight) {
selection.removeCreator(creator);
removeCreatorFromContainer(creator, creatorWidth, creatorHeight);
designer.repaint();
}
/**
* 设置选择区域
*/
public void setHotspotBounds(Rectangle rect) {
hotspot_bounds = rect;
}
/**
* 获得当前选择区域
*/
public Rectangle getHotspotBounds() {
return hotspot_bounds;
}
private void removeCreatorFromContainer(XCreator creator, int creatorWidth, int creatorHeight) {
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator);
if (parent == null) {
return;
}
boolean changeCreator = creator.shouldScaleCreator() || creator.hasTitleStyle();
if (parent.acceptType(XWFitLayout.class) && changeCreator) {
creator = (XCreator) creator.getParent();
}
parent.getLayoutAdapter().removeBean(creator, creatorWidth, creatorHeight);
// 删除其根组件,同时就删除了同时被选择的叶子组件
parent.remove(creator);
LayoutManager layout = parent.getLayout();
if (layout != null) {
// 刷新组件容器的布局
LayoutUtils.layoutContainer(parent);
}
}
/**
* 是否有组件被选择如果所选组件是最底层容器也视为无选择
* @return 是则返回true
*/
public boolean hasSelectionComponent() {
return !selection.isEmpty() && selection.getSelectedCreator().getParent() != null;
}
/**
* 移动组件至指定位置
* @param x 坐标x
* @param y 坐标y
*/
public void move(int x, int y) {
for (XCreator creator : selection.getSelectedCreators()) {
creator.setLocation(creator.getX() + x, creator.getY() + y);
LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator);
if (layoutAdapter != null) {
layoutAdapter.fix(creator);
}
}
designer.getEditListenerTable().fireCreatorModified(selection.getSelectedCreator(),
DesignerEvent.CREATOR_SELECTED);
}
/**
* 释放捕获
*/
public void releaseDragging() {
designer.setPainter(null);
selection.fixCreator(designer);
designer.getEditListenerTable().fireCreatorModified(selection.getSelectedCreator(),
DesignerEvent.CREATOR_RESIZED);
}
public Direction getDirectionAt(MouseEvent e) {
Direction dir;
if (e.isControlDown() || e.isShiftDown()) {
XCreator creator = designer.getComponentAt(e.getX(), e.getY(), selection.getSelectedCreators());
if (creator != designer.getRootComponent() && selection.addedable(creator)) {
return Location.add;
}
}
if (hasSelectionComponent()) {
int x = e.getX() + designer.getArea().getHorizontalValue();
int y = e.getY() + designer.getArea().getVerticalValue();
dir = getDirection(selection.getRelativeBounds(), x, y);
if (selection.size() == 1) {
if (!ArrayUtils.contains(selection.getSelectedCreator().getDirections(), dir.getActual())) {
dir = Location.outer;
}
}
} else {
dir = Location.outer;
}
if (designer.getDesignerMode().isFormParameterEditor() && dir == Location.outer) {
dir = designer.getLoc2Root(e);
}
return dir;
}
private Direction getDirection(Rectangle bounds, int x, int y) {
if (x < (bounds.x - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((x >= (bounds.x - XCreatorConstants.RESIZE_BOX_SIZ)) && (x <= bounds.x)) {
if (y < (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((y >= (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) && (y <= bounds.y)) {
return Location.left_top;
} else if ((y > bounds.y) && (y < (bounds.y + bounds.height))) {
return Location.left;
} else if ((y >= (bounds.y + bounds.height))
&& (y <= (bounds.y + bounds.height + XCreatorConstants.RESIZE_BOX_SIZ))) {
return Location.left_bottom;
} else {
return Location.outer;
}
} else if ((x > bounds.x) && (x < (bounds.x + bounds.width))) {
if (y < (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((y >= (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) && (y <= bounds.y)) {
return Location.top;
} else if ((y > bounds.y) && (y < (bounds.y + bounds.height))) {
return Location.inner;
} else if ((y >= (bounds.y + bounds.height))
&& (y <= (bounds.y + bounds.height + XCreatorConstants.RESIZE_BOX_SIZ))) {
return Location.bottom;
} else {
return Location.outer;
}
} else if ((x >= (bounds.x + bounds.width))
&& (x <= (bounds.x + bounds.width + XCreatorConstants.RESIZE_BOX_SIZ))) {
if (y < (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((y >= (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) && (y <= bounds.y)) {
return Location.right_top;
} else if ((y > bounds.y) && (y < (bounds.y + bounds.height))) {
return Location.right;
} else if ((y >= (bounds.y + bounds.height))
&& (y <= (bounds.y + bounds.height + XCreatorConstants.RESIZE_BOX_SIZ))) {
return Location.right_bottom;
} else {
return Location.outer;
}
} else {
return Location.outer;
}
}
private void fireCreatorSelected() {
designer.getEditListenerTable().fireCreatorModified(selection.getSelectedCreator(),
DesignerEvent.CREATOR_SELECTED);
}
public void setSelectedCreator(XCreator rootComponent) {
selection.setSelectedCreator(rootComponent);
fireCreatorSelected();
}
public void setSelectedCreators(ArrayList<XCreator> rebuildSelection) {
selection.setSelectedCreators(rebuildSelection);
fireCreatorSelected();
}
package com.fr.design.designer.beans.models;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.beans.location.Direction;
import com.fr.design.designer.beans.location.Location;
import com.fr.design.designer.creator.*;
import com.fr.design.designer.creator.cardlayout.XWCardLayout;
import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout;
import com.fr.design.designer.creator.cardlayout.XWTabFitLayout;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelection;
import com.fr.design.mainframe.FormSelectionUtils;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.stable.ArrayUtils;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
/**
* 该model保存当前选择的组件和剪切版信息
*/
public class SelectionModel {
//被粘贴组件在所选组件位置处往下、往右各错开20像素。执行多次粘贴时,在上一次粘贴的位置处错开20像素。
private static final int DELTA_X_Y = 20; //粘贴时候的偏移距离
private static final int BORDER_PROPORTION = 20;
private static FormSelection clipboard = new FormSelection();
private FormDesigner designer;
private FormSelection selection;
private Rectangle hotspotBounds;
public SelectionModel(FormDesigner designer) {
this.designer = designer;
selection = new FormSelection();
}
/**
* 重置清空formSelction以及选择区域
*/
public void reset() {
selection.reset();
hotspotBounds = null;
}
/**
* formSelction是否为空
*
* @return 是否为空
*/
public static boolean isEmpty() {
return clipboard.isEmpty();
}
/**
* 鼠标点击一下所选中的单个组件按下Ctrl或者shift键时鼠标可以进行多选
*
* @param e 鼠标事件
*/
public void selectACreatorAtMouseEvent(MouseEvent e) {
if (!e.isControlDown() && !e.isShiftDown()) {
// 如果Ctrl或者Shift键盘没有按下,则清除已经选择的组件
selection.reset();
}
// 获取e所在的组件
XCreator comp = designer.getComponentAt(e);
//布局组件的顶层布局如不可编辑,要获取其顶层布局
XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer(comp).getTopLayout();
if (topLayout != null && !topLayout.isEditable()) {
comp = topLayout;
}
// 如果父层是scale和title两个专属容器,返回其父层,组件本身是不让被选中的
if (comp != designer.getRootComponent() && comp != designer.getParaComponent()) {
XCreator parentContainer = (XCreator) comp.getParent();
comp = parentContainer.isDedicateContainer() ? parentContainer : comp;
}
if (selection.removeSelectedCreator(comp) || selection.addSelectedCreator(comp)) {
designer.getEditListenerTable().fireCreatorModified(comp, DesignerEvent.CREATOR_SELECTED);
designer.repaint();
}
}
/**
* 将所选组件剪切到剪切板上
*/
public void cutSelectedCreator2ClipBoard() {
if (hasSelectionComponent()) {
selection.cut2ClipBoard(clipboard);
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_CUTED);
designer.repaint();
}
}
/**
* 复制当前选中的组件到剪切板
*/
public void copySelectedCreator2ClipBoard() {
if (!selection.isEmpty()) {
selection.copy2ClipBoard(clipboard);
}
}
/**
* 从剪切板粘帖组件
*
* @return
*/
public boolean pasteFromClipBoard() {
if (!clipboard.isEmpty()) {
if (!hasSelectionComponent()) {
//未选
unselectedPaste();
} else {
//已选
selectedPaste();
}
} else {
Toolkit.getDefaultToolkit().beep();
}
return false;
}
public FormSelection getSelection() {
return selection;
}
/**
* 粘贴时未选择组件
*/
private void unselectedPaste() {
if (designer.getClass().equals(FormDesigner.class)) {
if (selection.getSelectedCreator() instanceof XWFitLayout) {
if (selection.getSelectedCreator().getClass().equals(XWTabFitLayout.class)) {
Rectangle rec = selection.getRelativeBounds();
//Tab布局
FormSelectionUtils.paste2Container(designer, (XLayoutContainer) selection.getSelectedCreator(),
clipboard,
rec.x + rec.width / 2,
rec.y + BORDER_PROPORTION);
} else {
Rectangle rec = selection.getRelativeBounds();
//自适应布局
FormSelectionUtils.paste2Container(designer, designer.getRootComponent(),
clipboard,
rec.x + rec.width / 2,
rec.y + BORDER_PROPORTION);
}
} else {
//绝对布局
//编辑器外面还有两层容器,使用designer.getRootComponent()获取到的是编辑器中层的容器,不是编辑器表层
//当前选择的就是编辑器表层
FormSelectionUtils.paste2Container(designer, (XLayoutContainer) selection.getSelectedCreator(),
clipboard,
DELTA_X_Y,
DELTA_X_Y);
}
} else {
//cpt本地组件复用,编辑器就一层,是最底层,使用designer.getRootComponent()就可以获取到
//使用selection.getSelectedCreator()也应该是可以获取到的。
FormSelectionUtils.paste2Container(designer, designer.getRootComponent(),
clipboard,
DELTA_X_Y,
DELTA_X_Y);
}
}
/**
* 粘贴时选择组件
*/
private void selectedPaste() {
XLayoutContainer parent = null;
//获取到编辑器的表层容器(已选的组件的父容器就是表层容器)
parent = XCreatorUtils.getParentXLayoutContainer(selection.getSelectedCreator());
if (parent != null && selection.getSelectedCreator().getParent() instanceof XWFitLayout) {
//自适应布局
Rectangle rec = selection.getRelativeBounds();
FormSelectionUtils.paste2Container(designer, parent, clipboard, rec.x + rec.width / 2, rec.y +
rec.height - BORDER_PROPORTION);
} else if (parent != null && selection.getSelectedCreator().getParent() instanceof XWAbsoluteLayout) {
//绝对布局
Rectangle rec = selection.getSelctionBounds();
FormSelectionUtils.paste2Container(designer, parent, clipboard, rec.x + DELTA_X_Y, rec.y + DELTA_X_Y);
}
}
/**
* 删除当前所有选择的组件
*/
public void deleteSelection() {
XCreator[] roots = selection.getSelectedCreators();
if (roots.length > 0) {
for (XCreator creator : roots) {
if (creator.acceptType(XWParameterLayout.class)) {
designer.removeParaComponent();
}
removeCreatorFromContainer(creator, creator.getWidth(), creator.getHeight());
creator.removeAll();
// 清除被选中的组件
selection.reset();
}
setSelectedCreator(designer.getRootComponent());
// 触发事件
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_DELETED);
designer.repaint();
}
}
/**
* 从选择组件中删除某组件
*
* @param creator 组件
* @param creatorWidth 组件之前宽度
* @param creatorHeight 组件之前高度
*/
public void removeCreator(XCreator creator, int creatorWidth, int creatorHeight) {
selection.removeCreator(creator);
removeCreatorFromContainer(creator, creatorWidth, creatorHeight);
designer.repaint();
}
/**
* 设置选择区域
*/
public void setHotspotBounds(Rectangle rect) {
hotspotBounds = rect;
}
/**
* 获得当前选择区域
*/
public Rectangle getHotspotBounds() {
return hotspotBounds;
}
private void removeCreatorFromContainer(XCreator creator, int creatorWidth, int creatorHeight) {
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator);
if (parent == null) {
return;
}
boolean changeCreator = creator.shouldScaleCreator() || creator.hasTitleStyle();
if (parent.acceptType(XWFitLayout.class) && changeCreator) {
creator = (XCreator) creator.getParent();
}
parent.getLayoutAdapter().removeBean(creator, creatorWidth, creatorHeight);
// 删除其根组件,同时就删除了同时被选择的叶子组件
parent.remove(creator);
LayoutManager layout = parent.getLayout();
if (layout != null) {
// 刷新组件容器的布局
LayoutUtils.layoutContainer(parent);
}
}
/**
* 是否有组件被选择如果所选组件是最底层容器也视为无选择
*
* @return 是则返回true
* yaoh.wu 不应该通过判断是否是最底层容器来判断是否选择了组件
* 而是应该判断选择的容器是否是编辑器的最表层容器,也就是点击空白地方选择的容器
* 但是直接判断选择的容器是否是编辑器最表层类型又会引发拖动时选不上的情况
* 因此通过判断父容器来实现
* <p>
* 举例frm组件复用 绝对布局情况下不选择时有三层容器
* 底层@see {@link com.fr.design.designer.creator.XWBorderLayout}
* 中层@see {@link XWFitLayout}
* 表层@see {@link com.fr.design.designer.creator.XWAbsoluteBodyLayout}
* <p>
* 但是编辑窗口的最外层其实是表层@see {@link com.fr.design.designer.creator.XWAbsoluteBodyLayout},
* 其他两层不是靠添加组件就可以编辑的
*/
public boolean hasSelectionComponent() {
XCreator selectionXCreator = selection.getSelectedCreator();
if (designer.getClass().equals(FormDesigner.class)) {
//frm本地组件复用
if (selectionXCreator != null) {
//选中的是否是tab布局编辑器本身
boolean tabEditor = selectionXCreator.getClass().equals(XWCardMainBorderLayout.class)
|| selectionXCreator.getClass().equals(XWCardLayout.class)
|| selectionXCreator.getClass().equals(XWTabFitLayout.class);
//选中的是否是frm绝对布局编辑器本身
boolean absoluteEditor = selectionXCreator.getClass().equals(XWAbsoluteBodyLayout.class);
//选中的是否是相对布局编辑器本身
boolean relativeEditor = selectionXCreator.getClass().equals(XWFitLayout.class);
return !(tabEditor || absoluteEditor || relativeEditor);
} else {
return false;
}
} else {
//cpt本地组件复用,selection.getSelectedCreator().getParent()=@XWParameterLayout instanceof @XWAbsoluteLayout
return selectionXCreator != null && selectionXCreator.getParent() != null;
}
}
/**
* 移动组件至指定位置
*
* @param x 坐标x
* @param y 坐标y
*/
public void move(int x, int y) {
for (XCreator creator : selection.getSelectedCreators()) {
creator.setLocation(creator.getX() + x, creator.getY() + y);
LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator);
if (layoutAdapter != null) {
layoutAdapter.fix(creator);
}
}
designer.getEditListenerTable().fireCreatorModified(selection.getSelectedCreator(),
DesignerEvent.CREATOR_SELECTED);
}
/**
* 释放捕获
*/
public void releaseDragging() {
designer.setPainter(null);
selection.fixCreator(designer);
designer.getEditListenerTable().fireCreatorModified(selection.getSelectedCreator(),
DesignerEvent.CREATOR_RESIZED);
}
public Direction getDirectionAt(MouseEvent e) {
Direction dir;
if (e.isControlDown() || e.isShiftDown()) {
XCreator creator = designer.getComponentAt(e.getX(), e.getY(), selection.getSelectedCreators());
if (creator != designer.getRootComponent() && selection.addedable(creator)) {
return Location.add;
}
}
if (hasSelectionComponent()) {
int x = e.getX() + designer.getArea().getHorizontalValue();
int y = e.getY() + designer.getArea().getVerticalValue();
dir = getDirection(selection.getRelativeBounds(), x, y);
if (selection.size() == 1 && !ArrayUtils.contains(selection.getSelectedCreator().getDirections(), dir
.getActual())) {
dir = Location.outer;
}
} else {
dir = Location.outer;
}
if (designer.getDesignerMode().isFormParameterEditor() && dir == Location.outer) {
dir = designer.getLoc2Root(e);
}
return dir;
}
private Direction getDirection(Rectangle bounds, int x, int y) {
if (x < (bounds.x - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((x >= (bounds.x - XCreatorConstants.RESIZE_BOX_SIZ)) && (x <= bounds.x)) {
if (y < (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((y >= (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) && (y <= bounds.y)) {
return Location.left_top;
} else if ((y > bounds.y) && (y < (bounds.y + bounds.height))) {
return Location.left;
} else if ((y >= (bounds.y + bounds.height))
&& (y <= (bounds.y + bounds.height + XCreatorConstants.RESIZE_BOX_SIZ))) {
return Location.left_bottom;
} else {
return Location.outer;
}
} else if ((x > bounds.x) && (x < (bounds.x + bounds.width))) {
if (y < (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((y >= (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) && (y <= bounds.y)) {
return Location.top;
} else if ((y > bounds.y) && (y < (bounds.y + bounds.height))) {
return Location.inner;
} else if ((y >= (bounds.y + bounds.height))
&& (y <= (bounds.y + bounds.height + XCreatorConstants.RESIZE_BOX_SIZ))) {
return Location.bottom;
} else {
return Location.outer;
}
} else if ((x >= (bounds.x + bounds.width))
&& (x <= (bounds.x + bounds.width + XCreatorConstants.RESIZE_BOX_SIZ))) {
if (y < (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) {
return Location.outer;
} else if ((y >= (bounds.y - XCreatorConstants.RESIZE_BOX_SIZ)) && (y <= bounds.y)) {
return Location.right_top;
} else if ((y > bounds.y) && (y < (bounds.y + bounds.height))) {
return Location.right;
} else if ((y >= (bounds.y + bounds.height))
&& (y <= (bounds.y + bounds.height + XCreatorConstants.RESIZE_BOX_SIZ))) {
return Location.right_bottom;
} else {
return Location.outer;
}
} else {
return Location.outer;
}
}
private void fireCreatorSelected() {
designer.getEditListenerTable().fireCreatorModified(selection.getSelectedCreator(),
DesignerEvent.CREATOR_SELECTED);
}
public void setSelectedCreator(XCreator rootComponent) {
selection.setSelectedCreator(rootComponent);
fireCreatorSelected();
}
public void setSelectedCreators(ArrayList<XCreator> rebuildSelection) {
selection.setSelectedCreators(rebuildSelection);
fireCreatorSelected();
}
}

182
designer_form/src/com/fr/design/designer/creator/DedicateLayoutContainer.java

@ -1,88 +1,96 @@
/**
*
*/
package com.fr.design.designer.creator;
import com.fr.form.ui.container.WLayout;
import java.awt.*;
import java.beans.IntrospectionException;
import java.util.ArrayList;
/**
* 一些控件专属的容器如标题容器sclae容器
* @author jim
* @date 2014-11-7
*/
public abstract class DedicateLayoutContainer extends XLayoutContainer {
public DedicateLayoutContainer(WLayout widget, Dimension initSize) {
super(widget, initSize);
}
/**
* 得到属性名
* @return 属性名
* @throws IntrospectionException
*/
public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException {
return new CRPropertyDescriptor[0];
}
/**
* 返回容器图标
*
* @return
*/
@Override
public String getIconPath() {
if(this.getXCreator(XWScaleLayout.INDEX) != null){
return this.getXCreator(XWScaleLayout.INDEX).getIconPath();
}
return "/com/fr/web/images/form/resources/text_field_16.png";
}
/**
* 控件树不显示此组件
* @param path 控件树list
*/
public void notShowInComponentTree(ArrayList<Component> path) {
path.remove(path.size()-1);
}
/**
* 重置组件的名称
* @param name 名称
*/
public void resetCreatorName(String name) {
super.resetCreatorName(name);
XCreator child = getXCreator(XWScaleLayout.INDEX);
child.toData().setWidgetName(name);
}
/**
* 返回对应属性表的组件scale和title返回其子组件
* @return 组件
*/
public XCreator getPropertyDescriptorCreator() {
return getXCreator(XWScaleLayout.INDEX);
}
/**
* 是否作为控件树的叶子节点
* @return 是则返回true
*/
public boolean isComponentTreeLeaf() {
return true;
}
/**
* 是否为sclae和title专属容器
* @return 是则返回true
*/
public boolean isDedicateContainer() {
return true;
}
/**
*
*/
package com.fr.design.designer.creator;
import com.fr.form.ui.container.WLayout;
import java.awt.*;
import java.beans.IntrospectionException;
import java.util.ArrayList;
/**
* 一些控件专属的容器如标题容器sclae容器
*
* @author jim
* @date 2014-11-7
*/
public abstract class DedicateLayoutContainer extends XLayoutContainer {
public DedicateLayoutContainer(WLayout widget, Dimension initSize) {
super(widget, initSize);
}
/**
* 得到属性名
*
* @return 属性名
* @throws IntrospectionException
*/
public CRPropertyDescriptor[] supportedDescriptor() throws IntrospectionException {
return new CRPropertyDescriptor[0];
}
/**
* 返回容器图标
*
* @return
*/
@Override
public String getIconPath() {
if (this.getXCreator(XWScaleLayout.INDEX) != null) {
return this.getXCreator(XWScaleLayout.INDEX).getIconPath();
}
return "/com/fr/web/images/form/resources/text_field_16.png";
}
/**
* 控件树不显示此组件
*
* @param path 控件树list
*/
public void notShowInComponentTree(ArrayList<Component> path) {
path.remove(path.size() - 1);
}
/**
* 重置组件的名称
*
* @param name 名称
*/
public void resetCreatorName(String name) {
super.resetCreatorName(name);
XCreator child = getXCreator(XWScaleLayout.INDEX);
//实现WTitleLayout的SetWidgetName
child.toData().setWidgetName(name);
}
/**
* 返回对应属性表的组件scale和title返回其子组件
*
* @return 组件
*/
public XCreator getPropertyDescriptorCreator() {
return getXCreator(XWScaleLayout.INDEX);
}
/**
* 是否作为控件树的叶子节点
*
* @return 是则返回true
*/
public boolean isComponentTreeLeaf() {
return true;
}
/**
* 是否为sclae和title专属容器
*
* @return 是则返回true
*/
public boolean isDedicateContainer() {
return true;
}
}

7
designer_form/src/com/fr/design/designer/creator/XElementCase.java

@ -10,11 +10,9 @@ import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.design.fun.impl.AbstractFormElementCaseEditorProvider;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.mainframe.*;
import com.fr.design.mainframe.widget.editors.BooleanEditor;
import com.fr.design.mainframe.widget.editors.ElementCaseToolBarEditor;
import com.fr.design.mainframe.widget.editors.PaddingMarginEditor;
import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor;
import com.fr.design.mainframe.widget.renderer.LayoutBorderStyleRenderer;
import com.fr.design.mainframe.widget.renderer.PaddingMarginCellRenderer;
import com.fr.form.FormElementCaseContainerProvider;
import com.fr.form.FormElementCaseProvider;
import com.fr.form.FormProvider;
@ -99,11 +97,12 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme
public void propertyChange() {
initStyle();
}
}),
new CRPropertyDescriptor("margin", this.data.getClass()).setEditorClass(PaddingMarginEditor.class)
.setI18NName(Inter.getLocText("FR-Layout_Padding"))
.putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Advanced"),
new CRPropertyDescriptor("showToolBar", this.data.getClass()).setEditorClass(BooleanEditor.class)
new CRPropertyDescriptor("ToolBars", this.data.getClass()).setEditorClass(ElementCaseToolBarEditor.class)
.setI18NName(Inter.getLocText("Form-EC_toolbar"))
.putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, "Advanced")
};

1388
designer_form/src/com/fr/design/form/parameter/FormParaDesigner.java

File diff suppressed because it is too large Load Diff

170
designer_form/src/com/fr/design/mainframe/ConnectorHelper.java

@ -15,96 +15,96 @@ import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.form.ui.Connector;
public class ConnectorHelper {
//这个类是用来画连接线的,暂时用不到
public static final int NEAR = 5;
private static double ratio = 0.5;
private final static int ADSORPTION = 15; // 吸附距离
private ArrayList<Point> drawingPoint;
private FormDesigner designer;
private boolean drawing;
//这个类是用来画连接线的,暂时用不到
public ConnectorHelper(FormDesigner formEditor) {
this.designer = formEditor;
}
public void resetConnector(Connector connector) {
ConnectorCreator cc = new ConnectorCreator(designer.getTarget().getContainer(),connector.getStartPoint(),connector.getEndPoint());
connector.addAll(cc.createPointList());
}
public boolean drawLining() {
return this.drawing;
}
public static final int NEAR = 5;
private static double ratio = 0.5;
private final static int ADSORPTION = 15; // 吸附距离
private ArrayList<Point> drawingPoint;
private FormDesigner designer;
private boolean drawing;
public void setDrawLine(boolean d) {
this.drawing = d;
}
private boolean near(Point p1, Point p2) {
return p1.x - p2.x < NEAR && p2.x - p1.x < NEAR && p1.y - p2.y < NEAR && p2.y - p1.y < NEAR;
}
public ConnectorHelper(FormDesigner formEditor) {
this.designer = formEditor;
}
private Point getNearPoint(MouseEvent e, Rectangle r) {
Point p1 = new Point((int) (r.x + r.getWidth() * ratio), r.y);
Point p2 = new Point((int) (r.x + r.getWidth()), (int) (r.y + r.getHeight() * ratio));
Point p3 = new Point((int) (r.x + r.getWidth() * (1 - ratio)), (int) (r.y + r.getHeight()));
Point p4 = new Point(r.x, (int) (r.y + r.getHeight() * (1 - ratio)));
Point p = new Point(e.getX() + designer.getArea().getHorizontalValue(), e.getY() + designer.getArea().getVerticalValue());
if (near(p, p1)) {
return p1;
} else if (near(p, p2)) {
return p2;
} else if (near(p, p3)) {
return p3;
} else if (near(p, p4)) {
return p4;
}
return null;
}
private ArrayList<Point> createDefalutNode(Point startPoint, Point endPoint) {
long s = System.currentTimeMillis();
ConnectorCreator cc = new ConnectorCreator(designer.getTarget().getContainer(), new Point(startPoint), new Point(endPoint));
ArrayList<Point> p = cc.createPointList();
long e = System.currentTimeMillis();
return p;
}
public void resetConnector(Connector connector) {
ConnectorCreator cc = new ConnectorCreator(designer.getTarget().getContainer(), connector.getStartPoint(), connector.getEndPoint());
connector.addAll(cc.createPointList());
}
public void drawAuxiliaryLine(Graphics g) {
Point startPoint = designer.getStateModel().getStartPoint();
Point endPoint = designer.getStateModel().getEndPoint();
drawingPoint = createDefalutNode(startPoint, endPoint);
Point[] p = drawingPoint.toArray(new Point[drawingPoint.size()]);
g.setColor(Color.green);
for (int i = 0; i < p.length - 1; i++) {
GraphHelper.drawLine(g, p[i].x - designer.getArea().getHorizontalValue(), p[i].y
- designer.getArea().getVerticalValue(), p[i + 1].x - designer.getArea().getHorizontalValue(),
p[i + 1].y - designer.getArea().getVerticalValue(), Constants.LINE_HAIR);
}
}
public boolean drawLining() {
return this.drawing;
}
public void createDefalutLine() {
if (drawingPoint != null
&& drawingPoint.size() > 1
&& ConnectorCreator.getMinimumDistance(drawingPoint.get(0), drawingPoint.get(drawingPoint.size() - 1)) > ADSORPTION) {
((XWAbsoluteLayout) designer.getRootComponent()).addConnector(new Connector().addAll(drawingPoint));
}
drawingPoint = null;
}
public void setDrawLine(boolean d) {
this.drawing = d;
}
public Point getNearWidgetPoint(MouseEvent e) {
BoundsWidget widget;
Point p = null;
for (int i = 0, size = designer.getTarget().getContainer().getWidgetCount(); i < size; i++) {
widget = ((BoundsWidget) designer.getTarget().getContainer().getWidget(i));
if (widget.isVisible()) {
if ((p = getNearPoint(e, widget.getBounds())) != null) {
break;
}
}
}
return p;
}
private boolean near(Point p1, Point p2) {
return p1.x - p2.x < NEAR && p2.x - p1.x < NEAR && p1.y - p2.y < NEAR && p2.y - p1.y < NEAR;
}
private Point getNearPoint(MouseEvent e, Rectangle r) {
Point p1 = new Point((int) (r.x + r.getWidth() * ratio), r.y);
Point p2 = new Point((int) (r.x + r.getWidth()), (int) (r.y + r.getHeight() * ratio));
Point p3 = new Point((int) (r.x + r.getWidth() * (1 - ratio)), (int) (r.y + r.getHeight()));
Point p4 = new Point(r.x, (int) (r.y + r.getHeight() * (1 - ratio)));
Point p = new Point(e.getX() + designer.getArea().getHorizontalValue(), e.getY() + designer.getArea().getVerticalValue());
if (near(p, p1)) {
return p1;
} else if (near(p, p2)) {
return p2;
} else if (near(p, p3)) {
return p3;
} else if (near(p, p4)) {
return p4;
}
return null;
}
private ArrayList<Point> createDefalutNode(Point startPoint, Point endPoint) {
long s = System.currentTimeMillis();
ConnectorCreator cc = new ConnectorCreator(designer.getTarget().getContainer(), new Point(startPoint), new Point(endPoint));
ArrayList<Point> p = cc.createPointList();
long e = System.currentTimeMillis();
return p;
}
public void drawAuxiliaryLine(Graphics g) {
Point startPoint = designer.getStateModel().getStartPoint();
Point endPoint = designer.getStateModel().getEndPoint();
drawingPoint = createDefalutNode(startPoint, endPoint);
Point[] p = drawingPoint.toArray(new Point[drawingPoint.size()]);
g.setColor(Color.green);
for (int i = 0; i < p.length - 1; i++) {
GraphHelper.drawLine(g, p[i].x - designer.getArea().getHorizontalValue(), p[i].y
- designer.getArea().getVerticalValue(), p[i + 1].x - designer.getArea().getHorizontalValue(),
p[i + 1].y - designer.getArea().getVerticalValue(), Constants.LINE_HAIR);
}
}
public void createDefalutLine() {
if (drawingPoint != null
&& drawingPoint.size() > 1
&& ConnectorCreator.getMinimumDistance(drawingPoint.get(0), drawingPoint.get(drawingPoint.size() - 1)) > ADSORPTION) {
((XWAbsoluteLayout) designer.getRootComponent()).addConnector(new Connector().addAll(drawingPoint));
}
drawingPoint = null;
}
public Point getNearWidgetPoint(MouseEvent e) {
BoundsWidget widget;
Point p = null;
for (int i = 0, size = designer.getTarget().getContainer().getWidgetCount(); i < size; i++) {
widget = ((BoundsWidget) designer.getTarget().getContainer().getWidget(i));
if (widget.isVisible()) {
if ((p = getNearPoint(e, widget.getBounds())) != null) {
break;
}
}
}
return p;
}
}

1239
designer_form/src/com/fr/design/mainframe/EditingMouseListener.java

File diff suppressed because it is too large Load Diff

239
designer_form/src/com/fr/design/mainframe/FormDesigner.java

@ -6,7 +6,10 @@ import com.fr.design.DesignState;
import com.fr.design.designer.TargetComponent;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.Painter;
import com.fr.design.designer.beans.actions.CopyAction;
import com.fr.design.designer.beans.actions.CutAction;
import com.fr.design.designer.beans.actions.FormDeleteAction;
import com.fr.design.designer.beans.actions.PasteAction;
import com.fr.design.designer.beans.adapters.layout.FRParameterLayoutAdapter;
import com.fr.design.designer.beans.events.CreatorEventListenerTable;
import com.fr.design.designer.beans.events.DesignerEditListener;
@ -43,7 +46,6 @@ import com.fr.form.ui.container.WFitLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogger;
import com.fr.general.Inter;
import com.fr.plugin.ExtraClassManager;
import com.fr.stable.ArrayUtils;
import com.fr.stable.bridge.StableFactory;
@ -65,11 +67,10 @@ import java.util.List;
/**
* 设计界面组件该组件是界面设计工具的核心主要负责的是被设计界面的显示界面设计操作状态的 显示编辑状态的显示等等
*/
public class FormDesigner extends TargetComponent<Form> implements TreeSelectionListener, InvocationHandler, BaseFormDesigner ,ParaDefinitePane{
public class FormDesigner extends TargetComponent<Form> implements TreeSelectionListener, InvocationHandler, BaseFormDesigner, ParaDefinitePane {
protected static final ArrayList<String> NAME_ARRAY_LIST = new ArrayList<String>(
Arrays.asList(new String[]{Inter.getLocText("M_Edit-Cut"), Inter.getLocText("M_Edit-Copy"), Inter.getLocText("M_Edit-Delete")})
);
private static final int BORDER_WIDTH = 6;
//底层容器的默认大小
protected static final Dimension LARGE_PREFERRED_SIZE = new Dimension(WBorderLayout.DEFAULT_WIDTH, WBorderLayout.DEFAULT_HEIGHT);
private int paraHeight = 0;
@ -81,7 +82,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
private XLayoutContainer paraComponent;
private boolean drawLineMode;
private FormArea formArea;
private ConnectorHelper ConnectorHelper;
private ConnectorHelper connectorHelper;
private boolean isReportBlockEditing = false;
//组件重叠
@ -104,7 +105,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
// 编辑状态的事件表
private CreatorEventListenerTable edit;
protected Action[] designer_actions;
protected Action[] designerActions;
private FormDesignerModeForSpecial<?> desigerMode;
private Action switchAction;
private FormElementCaseContainerProvider elementCaseContainer;
@ -159,7 +160,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
ParameterPropertyPane.getInstance().populateBean(this);
}
public Parameter[] getNoRepeatParas(Parameter[] paras){
public Parameter[] getNoRepeatParas(Parameter[] paras) {
List<Parameter> paraList = new ArrayList<Parameter>();
java.util.Set set = new java.util.HashSet();
for (Parameter p : paras) {
@ -171,23 +172,23 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
return paraList.toArray(new Parameter[paraList.size()]);
}
public void setParameterArray(Parameter[] ps){
public void setParameterArray(Parameter[] ps) {
parameterArray = ps;
}
public Parameter[] getParameterArray(){
public Parameter[] getParameterArray() {
return parameterArray;
}
/**
* 刷新参数
*/
public void refreshParameter(){
public void refreshParameter() {
XLayoutContainer rootContainer = this.getParaComponent();
if (rootContainer != null){
if (rootContainer != null) {
java.util.List<String> namelist = new ArrayList<String>();
rootContainer.getAllXCreatorNameList(rootContainer,namelist);
rootContainer.getAllXCreatorNameList(rootContainer, namelist);
// parameterArray是报表的所有参数, nameList是已经在参数面板添加过控件的参数名
// 与已有的参数列表比较 如果已经存在 就除去
Parameter[] ps = getParameterArray();
@ -201,7 +202,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
EastRegionContainerPane.getInstance().setParameterHeight(ParameterPropertyPane.getInstance(this).getPreferredSize().height);
}
private void removeSame(Parameter[] parameters, List<String> namelist){
private void removeSame(Parameter[] parameters, List<String> namelist) {
for (Parameter parameter : parameters) {
for (String name : namelist) {
if (name.equalsIgnoreCase(parameter.getName())) {
@ -214,20 +215,22 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 是否有查询按钮
* @return 有无查询按钮
*
* @return 有无查询按钮
*/
public boolean isWithQueryButton(){
public boolean isWithQueryButton() {
XLayoutContainer rootContainer = this.getParaComponent();
return rootContainer != null && rootContainer.SearchQueryCreators(rootContainer);
}
/**
* 加入参数到参数面板
*
* @param parameter 参数
* @return 是否加入
*/
public void addingParameter2Editor(Parameter parameter){
if(getParaComponent() == null){
public void addingParameter2Editor(Parameter parameter) {
if (getParaComponent() == null) {
addParaPaneTooltips();
return;
}
@ -242,11 +245,11 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
if (!(this.autoAddComponent(xLabel, H_COMPONENT_GAP * (currentIndex % NUM_IN_A_LINE)
+ FIRST_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP * (currentIndex / NUM_IN_A_LINE)))) {
return ;
return;
}
if (!(this.autoAddComponent(xCreator, H_COMPONENT_GAP * (currentIndex % NUM_IN_A_LINE)
+ SECOND_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP * (currentIndex / NUM_IN_A_LINE)))) {
return ;
return;
}
currentIndex++;
parameterArray = (Parameter[]) ArrayUtils.removeElement(parameterArray, parameter);
@ -256,11 +259,12 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 加入参数到参数面板有查询按钮
*
* @param parameter 参数
* @return 是否加入
*/
public void addingParameter2EditorWithQueryButton(Parameter parameter){
if(getParaComponent() == null){
public void addingParameter2EditorWithQueryButton(Parameter parameter) {
if (getParaComponent() == null) {
addParaPaneTooltips();
return;
}
@ -276,12 +280,12 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
if (!(this.autoAddComponent(xLabel, FIRST_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP
* (currentIndex / NUM_IN_A_LINE)))) {
return ;
return;
}
if (!(this.autoAddComponent(xCreator, SECOND_H_LOCATION, FIRST_V_LOCATION + V_COMPONENT_GAP
* (currentIndex / NUM_IN_A_LINE)))) {
return ;
return;
}
FormSubmitButton formSubmitButton = new FormSubmitButton();
formSubmitButton.setWidgetName("Search");
@ -289,7 +293,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
xCreator = XCreatorUtils.createXCreator(formSubmitButton);
if (!(this.autoAddComponent(xCreator, 270, FIRST_V_LOCATION + V_COMPONENT_GAP
* (currentIndex / NUM_IN_A_LINE)))) {
return ;
return;
}
currentIndex = currentIndex + NUM_IN_A_LINE - currentIndex % NUM_IN_A_LINE;
parameterArray = (Parameter[]) ArrayUtils.removeElement(parameterArray, parameter);
@ -300,8 +304,8 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 一键添加所有参数
*/
public void addingAllParameter2Editor(){
if(getParaComponent() == null){
public void addingAllParameter2Editor() {
if (getParaComponent() == null) {
addParaPaneTooltips();
return;
}
@ -350,16 +354,17 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
EastRegionContainerPane.getInstance().refreshDownPane();
}
private void addParaPaneTooltips(){
JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(),Inter.getLocText("FR-Designer-Form-Please_Drag_ParaPane"),
private void addParaPaneTooltips() {
JOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("FR-Designer-Form-Please_Drag_ParaPane"),
Inter.getLocText("FR-Designer_Tooltips"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.WARNING_MESSAGE);
}
/**
* 自动添加组件
* @param xCreator 组件
* @param x 横坐标
* @param y 纵坐标
*
* @param xCreator 组件
* @param x 横坐标
* @param y 纵坐标
* @return 是否添加成功
*/
public boolean autoAddComponent(XCreator xCreator, int x, int y) {
@ -375,10 +380,11 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 在参数很多时全部添加的时候可以向下一次排版若去掉就会在参数面板堆到一起
*
* @param creator 组件
* @param x 长度
* @param y 长度
* @param layout 布局
* @param x 长度
* @param y 长度
* @param layout 布局
* @return 是否扩展
*/
public boolean prepareForAdd(XCreator creator, int x, int y, XWParameterLayout layout) {
@ -404,9 +410,9 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 加入参数面板
*/
public void addParaComponent(){
public void addParaComponent() {
if (paraComponent != null) {
return ;
return;
}
paraHeight = WBorderLayout.DEFAULT_SIZE;
paraComponent = new XWParameterLayout();
@ -414,7 +420,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
paraComponent.setSize(paraComponent.initEditorSize());
XWBorderLayout formLayoutContainer = (XWBorderLayout) rootComponent.getParent();
formLayoutContainer.toData().setNorthSize(paraHeight);
formLayoutContainer.add(paraComponent,WBorderLayout.NORTH);
formLayoutContainer.add(paraComponent, WBorderLayout.NORTH);
//设下northSize,增加para后,重置border大小,这时候para和root的大小会自适应调整
formLayoutContainer.setSize(formLayoutContainer.getWidth(), formLayoutContainer.getHeight() + paraHeight);
selectionModel.reset();
@ -424,30 +430,33 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
/**
* 返回根节点父容器
* @return 父容器
* 返回根节点父容器
*
* @return 父容器
*/
public Component getTopContainer(){
if(rootComponent != null){
public Component getTopContainer() {
if (rootComponent != null) {
// 返回root所在的父容器,非designer
return LayoutUtils.getTopContainer(rootComponent);
}
return XCreatorUtils.createXCreator(this.getTarget().getContainer());
return XCreatorUtils.createXCreator(this.getTarget().getContainer());
}
/**
* 返回参数界面高度
* @return para高度
*
* @return para高度
*/
public int getParaHeight(){
public int getParaHeight() {
return paraHeight;
}
/**
* 重置para的高度
* @param height 高度
*
* @param height 高度
*/
public void setParaHeight(int height){
public void setParaHeight(int height) {
XWBorderLayout container = (XWBorderLayout) getTopContainer();
container.toData().setNorthSize(height);
container.setSize(container.getWidth(), container.getHeight() + height - getParaHeight());
@ -457,7 +466,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 删除参数界面
*/
public void removeParaComponent(){
public void removeParaComponent() {
XWBorderLayout formLayoutContainer = (XWBorderLayout) getTopContainer();
formLayoutContainer.toData().removeWidget(paraComponent.toData());
paraHeight = 0;
@ -472,41 +481,42 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 切换
* @param elementCaseContainer 容器
*
* @param elementCaseContainer 容器
*/
public void switchTab(FormElementCaseContainerProvider elementCaseContainer){
if(this.switchAction == null){
public void switchTab(FormElementCaseContainerProvider elementCaseContainer) {
if (this.switchAction == null) {
return;
}
this.elementCaseContainer = elementCaseContainer;
this.switchAction.actionPerformed(null);
}
public void setElementCaseContainer(FormElementCaseContainerProvider elementCaseContainer){
public void setElementCaseContainer(FormElementCaseContainerProvider elementCaseContainer) {
this.elementCaseContainer = elementCaseContainer;
}
public FormElementCaseProvider getElementCase(){
public FormElementCaseProvider getElementCase() {
return this.elementCaseContainer.getElementCase();
}
public String getElementCaseContainerName(){
public String getElementCaseContainerName() {
return this.elementCaseContainer.getElementCaseContainerName();
}
public void setElementCase(FormElementCaseProvider elementCase){
public void setElementCase(FormElementCaseProvider elementCase) {
this.elementCaseContainer.setElementCase(elementCase);
}
public void setElementCaseBackground(BufferedImage image){
public void setElementCaseBackground(BufferedImage image) {
this.elementCaseContainer.setBackground(image);
}
public Dimension getElementCaseContainerSize(){
public Dimension getElementCaseContainerSize() {
return this.elementCaseContainer.getSize();
}
public FormElementCaseContainerProvider getElementCaseContainer(){
public FormElementCaseContainerProvider getElementCaseContainer() {
return this.elementCaseContainer;
}
@ -524,6 +534,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 增加监听事件
*
* @param listener 界面组件编辑事件
*/
public void addDesignerEditListener(DesignerEditListener listener) {
@ -539,15 +550,15 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 表单则判断参数面板是否为绝对布局
*
* @return 是则返回true
*/
public boolean hasWAbsoluteLayout() {
if (paraComponent != null && paraComponent.acceptType(XWParameterLayout.class)){
if (paraComponent != null && paraComponent.acceptType(XWParameterLayout.class)) {
return true;
}
else{
} else {
if (this.getSelectionModel().getSelection().getSelectedCreator().getParent() != null
&& ((XLayoutContainer)this.getSelectionModel().getSelection().getSelectedCreator().getParent()).acceptType(XWAbsoluteLayout.class)){
&& ((XLayoutContainer) this.getSelectionModel().getSelection().getSelectedCreator().getParent()).acceptType(XWAbsoluteLayout.class)) {
return true;
}
}
@ -555,7 +566,8 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
/**
* 设置是否为报表块编辑
* 设置是否为报表块编辑
*
* @param isEditing 是否为报表块编辑
*/
public void setReportBlockEditing(boolean isEditing) {
@ -564,25 +576,27 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 是否为报表块编辑
*
* @return 是否为报表块编辑
*/
public boolean isReportBlockEditing() {
return this.isReportBlockEditing;
}
public void setWidgetsIntersect(boolean isWidgetsIntersect){
public void setWidgetsIntersect(boolean isWidgetsIntersect) {
this.isWidgetsIntersect = isWidgetsIntersect;
}
public boolean isWidgetsIntersect(){
public boolean isWidgetsIntersect() {
return this.isWidgetsIntersect;
}
/**
* 是否重命名控件
*
* @param creator 组件
* @param newName 新的组件名
* @return 组件名有变化且不和其他一样返回true
* @return 组件名有变化且不和其他一样返回true
*/
public boolean renameCreator(XCreator creator, String newName) {
if (ComparatorUtils.equals(creator.toData().getWidgetName(), newName)) {
@ -609,16 +623,17 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 更新界面布局重绘
* @param proxy 动态代理类
*
* @param proxy 动态代理类
* @param method 接口方法
* @param args 参数
* @param args 参数
* @return 不返回任何对象
*/
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if(rootComponent != null){
if (rootComponent != null) {
LayoutUtils.layoutRootContainer(rootComponent);
}
if(paraComponent != null){
if (paraComponent != null) {
LayoutUtils.layoutRootContainer(paraComponent);
}
repaint();
@ -654,6 +669,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 增加组件事件
*
* @param h 动态代理
*/
public void addInvocationHandler(InvocationHandler h) {
@ -678,7 +694,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
/**
* 设置其UI类为DesignerUI负责渲染
* 设置其UI类为DesignerUI负责渲染
*/
@Override
public void updateUI() {
@ -741,15 +757,13 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 更新边框线状态
*
* @param e 鼠标事件
*/
public void updateDrawLineMode(MouseEvent e) {
Point p = ConnectorHelper.getNearWidgetPoint(e);
if (p == null) {
XComponent comp = getComponentAt(e);
if (comp == rootComponent) {
p = new Point(e.getX() + formArea.getHorizontalValue(), e.getY() + formArea.getVerticalValue());
}
Point p = connectorHelper.getNearWidgetPoint(e);
if (p == null && getComponentAt(e) == rootComponent) {
p = new Point(e.getX() + formArea.getHorizontalValue(), e.getY() + formArea.getVerticalValue());
}
stateModel.startDrawLine(p);
}
@ -761,7 +775,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
// 撤销恢复操作都会refreshRoot,这时候的target.getContainer里的widget会和之前不一样,所以不用root判断来取
XLayoutContainer formLayoutContainer = (XLayoutContainer) XCreatorUtils.createXCreator(this.getTarget().getContainer());
// 布局默认都是1,底层的border改为0,不然没意义
this.getTarget().getContainer().setMargin(new PaddingMargin(0,0,0,0));
this.getTarget().getContainer().setMargin(new PaddingMargin(0, 0, 0, 0));
formLayoutContainer.setBorder(null);
if (formLayoutContainer.acceptType(XWBorderLayout.class)) {
WBorderLayout borderLayout = (WBorderLayout) formLayoutContainer.toData();
@ -774,7 +788,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
refreshNorth(northWidget, formLayoutContainer);
refreshCenter(centerWidget, formLayoutContainer);
} else {
} else {
formLayoutContainer.setSize(LARGE_PREFERRED_SIZE);
setRootComponent(formLayoutContainer);
}
@ -790,9 +804,9 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
XLayoutContainer northContainer = (XLayoutContainer) XCreatorUtils.createXCreator(northWidget);
paraHeight = ((XWBorderLayout)formLayoutContainer).toData().getNorthSize();
paraHeight = ((XWBorderLayout) formLayoutContainer).toData().getNorthSize();
paraComponent = northContainer;
northContainer.setSize(0,paraHeight);
northContainer.setSize(0, paraHeight);
formLayoutContainer.add(northContainer, WBorderLayout.NORTH);
}
@ -841,14 +855,16 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 是否是报表的参数面板
* @return (表单的)
*
* @return (表单的)
*/
public boolean isFormParaDesigner(){
public boolean isFormParaDesigner() {
return false;
}
/**
* 是否为底层容器
* 是否为底层容器
*
* @param comp 组件
* @return 是则返回true
*/
@ -923,10 +939,10 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
public SelectionModel getSelectionModel() {
if (paraComponent!=null){
paraComponent.setSize(paraComponent.getWidth(),getParaHeight());
if (paraComponent != null) {
paraComponent.setSize(paraComponent.getWidth(), getParaHeight());
Rectangle rec = rootComponent.getBounds();
rootComponent.setBounds(rec.x,getParaHeight(),rec.width,rec.height);
rootComponent.setBounds(rec.x, getParaHeight(), rec.width, rec.height);
}
return selectionModel;
}
@ -941,6 +957,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 拖拽准备
*
* @param xCreator 组件
*/
public void startDraggingBean(XCreator xCreator) {
@ -953,11 +970,12 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
/**
* 拖拽时相关处理
* @param xCreator 组件
* 拖拽时相关处理
*
* @param xCreator 组件
* @param lastPressEvent 鼠标事件
* @param x 坐标x
* @param y 坐标y
* @param x 坐标x
* @param y 坐标y
*/
public void startDraggingComponent(XCreator xCreator, MouseEvent lastPressEvent, int x, int y) {
// 根据所选择的组件的BeanInfo生成相应的AddingModel
@ -978,6 +996,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 改变组件值
*
* @param e 组件选择事件
*/
@Override
@ -1024,6 +1043,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 是否支持权限编辑
*
* @return 是则返回true
*/
public boolean isSupportAuthority() {
@ -1048,7 +1068,8 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
}
/**
* 是否含有action名
* 是否含有action名
*
* @param name action名
* @return 有则返回true
*/
@ -1058,6 +1079,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 显示组件
*
* @param comp 组件
*/
public void makeVisible(XCreator comp) {
@ -1088,16 +1110,16 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 返回复制粘贴删除等动作
* 鼠标右键菜单
*
* @return 同上
*/
public Action[] getActions() {
if (designer_actions == null) {
//先把复制粘贴按钮去掉,只留下删除
// designer_actions = new Action[]{new CutAction(this), new CopyAction(this), new PasteAction(this),
// new FormDeleteAction(this)};
designer_actions = new Action[]{new FormDeleteAction(this)};
if (designerActions == null) {
designerActions = new Action[]{new CutAction(this), new CopyAction(this), new PasteAction(this),
new FormDeleteAction(this)};
}
return designer_actions;
return designerActions;
}
protected Border getOuterBorder() {
@ -1120,6 +1142,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 返回表单区域
*
* @return 表单区域
*/
public FormArea getArea() {
@ -1128,6 +1151,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 设置上层区域
*
* @param formArea 表单区域
*/
public void setParent(FormArea formArea) {
@ -1136,14 +1160,15 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 绘制组件根节点
*
* @param clipg 图形
*/
public void paintContent(Graphics clipg) {
rootComponent.paint(clipg);
}
public void paintPara(Graphics clipg){
if(paraComponent != null){
public void paintPara(Graphics clipg) {
if (paraComponent != null) {
paraComponent.paint(clipg);
}
}
@ -1157,14 +1182,16 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 返回连线类
*
* @return ConnectorHelper类
*/
public ConnectorHelper getDrawLineHelper() {
return ConnectorHelper;
return connectorHelper;
}
/**
* 是否画线模式
* 是否画线模式
*
* @return 是则返回true
*/
public boolean isDrawLineMode() {
@ -1173,6 +1200,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 设置DrawLineMode
*
* @param mode 是or或
*/
public void setDrawLineMode(boolean mode) {
@ -1199,6 +1227,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 返回表单控件权限编辑pane
*
* @return 同上
*/
public AuthorityEditPane createAuthorityEditPane() {
@ -1249,6 +1278,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 粘贴
*
* @return
*/
@Override
@ -1259,6 +1289,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 剪切
*
* @return
*/
@Override
@ -1273,6 +1304,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 工具栏菜单
*
* @return 同上
*/
@Override
@ -1286,6 +1318,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 模版菜单
*
* @return 同上
*/
@Override
@ -1295,6 +1328,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 权限菜单
*
* @return 同上
*/
public ShortCut[] shortCuts4Authority() {
@ -1304,6 +1338,7 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 返回ToolBarDef
*
* @return 同上
*/
@Override
@ -1313,10 +1348,12 @@ public class FormDesigner extends TargetComponent<Form> implements TreeSelection
/**
* 返回工具栏按钮组件
*
* @return 同上
*/
public JComponent[] toolBarButton4Form() {
return new JComponent[0];
return new JComponent[]{new CutAction(this).createToolBarComponent(), new CopyAction(this).createToolBarComponent(), new PasteAction(this).createToolBarComponent(),
new FormDeleteAction(this).createToolBarComponent()};
}

481
designer_form/src/com/fr/design/mainframe/FormEditToolBar.java

@ -0,0 +1,481 @@
package com.fr.design.mainframe;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itoolbar.UIToolbar;
import com.fr.design.javascript.JavaScriptActionPane;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.menu.ToolBarDef;
import com.fr.design.style.background.BackgroundPane;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.design.widget.IconDefinePane;
import com.fr.form.ui.*;
import com.fr.form.ui.Button;
import com.fr.form.web.button.Export;
import com.fr.general.Background;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
import com.fr.stable.StringUtils;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.*;
/**
* Created by harry on 2017-3-2.
*/
public class FormEditToolBar extends BasicPane {
private JList list;
private DefaultListModel listModel;
private JPanel right;
private CardLayout card;
private ButtonPane bp;
private FormToolBarButton lastButton;
private Background background = null;
private UICheckBox defaultCheckBox;
private ListSelectionListener listSelectionListener = new ListSelectionListener() {
public void valueChanged(ListSelectionEvent evt) {
if (lastButton != null) {
lastButton.setWidget(bp.update());
}
if (list.getSelectedValue() instanceof FormToolBarButton) {
lastButton = (FormToolBarButton) list.getSelectedValue();
if (lastButton.getWidget() instanceof Button) {
card.show(right, "button");
bp.populate(lastButton.getWidget());
} else {
bp.populate(lastButton.getWidget());
card.show(right, "none");
}
}
}
};
private ActionListener actioner = new ActionListener() {
/**
*
*/
public void actionPerformed(ActionEvent arg0) {
final BackgroundPane backgroundPane = new BackgroundPane();
BasicDialog dialog = backgroundPane.showWindow(DesignerContext.getDesignerFrame());
backgroundPane.populate(FormEditToolBar.this.background);
dialog.addDialogActionListener(new DialogActionAdapter() {
public void doOk() {
FormEditToolBar.this.background = backgroundPane.update();
if (FormEditToolBar.this.background != null) {
FormEditToolBar.this.defaultCheckBox.setSelected(false);
}
}
});
dialog.setVisible(true);
}
};
public FormEditToolBar() {
initComponent();
}
/**
* 初始化
*/
public void initComponent() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel left = FRGUIPaneFactory.createBorderLayout_S_Pane();
listModel = new DefaultListModel();
list = new JList(listModel);
list.setCellRenderer(render);
left.add(new JScrollPane(list), BorderLayout.CENTER);
if (listModel.getSize() > 0) {
list.setSelectedIndex(0);
}
ToolBarDef toolbarDef = new ToolBarDef();
toolbarDef.addShortCut(new MoveUpItemAction());
toolbarDef.addShortCut(new MoveDownItemAction());
toolbarDef.addShortCut(new RemoveAction());
UIToolbar toolBar = ToolBarDef.createJToolBar();
toolbarDef.updateToolBar(toolBar);
left.add(toolBar, BorderLayout.NORTH);
right = FRGUIPaneFactory.createCardLayout_S_Pane();
card = new CardLayout();
right.setLayout(card);
bp = new ButtonPane();
right.add("none", FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane());
right.add("button", bp);
JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, left, right);
// splitPane.setDividerLocation(left.getMinimumSize().width);
splitPane.setDividerLocation(120);
this.add(splitPane);
list.addListSelectionListener(listSelectionListener);
JPanel backgroundPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
UIButton bgButton = new UIButton(Inter.getLocText("FR-Designer-Output_Background_Set"));
defaultCheckBox = new UICheckBox(Inter.getLocText("FR-Designer-Output_Default_Background"));
bgButton.addActionListener(actioner);
backgroundPane.add(defaultCheckBox);
backgroundPane.add(bgButton);
backgroundPane.setBorder(BorderFactory.createTitledBorder(Inter.getLocText("FR-Designer-Output_Background_Set")));
this.add(backgroundPane, BorderLayout.SOUTH);
}
ListCellRenderer render = new DefaultListCellRenderer() {
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof FormToolBarButton) {
FormToolBarButton button = (FormToolBarButton) value;
this.setText(button.getNameOption().optionName());
this.setIcon(button.getNameOption().optionIcon());
}
return this;
}
};
@Override
protected String title4PopupWindow() {
return Inter.getLocText("FR-Designer_Edit");
}
public void populate(FormToolBar ftoolbar) {
this.populate(ftoolbar, null);
}
public void populate(FormToolBar ftoolbar, FormToolBarButton button) {
if (ftoolbar == null) {
return;
}
for (int i = 0; i < ftoolbar.getButtonlist().size(); i++) {
listModel.addElement(ftoolbar.getButtonlist().get(i));
}
this.list.validate();
this.list.repaint();
if (ftoolbar.getButtonlist().size() > 0) {
this.list.setSelectedIndex(0);
}
if (button != null) {
this.list.setSelectedValue(button, true);
}
this.background = ftoolbar.getBackground();
this.defaultCheckBox.setSelected(ftoolbar.isDefault() ? true : false);
}
public FormToolBar update() {
if (this.list.getSelectedIndex() > -1) {
for (int i = 0; i < listModel.getSize(); i++) {
this.list.setSelectedIndex(i);
FormToolBarButton toolBarButton = (FormToolBarButton) this.list.getSelectedValue();
Widget widget = this.bp.update();
toolBarButton.setWidget(widget);
if (widget instanceof Button) {
String iconname = ((Button) widget).getIconName();
if (StringUtils.isNotBlank(iconname)) {
Image iimage = WidgetManager.getProviderInstance().getIconManager().getIconImage(iconname);
toolBarButton.setIcon(new ImageIcon(iimage));
}
}
}
}
java.util.List<FormToolBarButton> list = new ArrayList<FormToolBarButton>();
for (int i = 0; i < listModel.size(); i++) {
list.add((FormToolBarButton) listModel.get(i));
}
FormToolBar ftoolBar = new FormToolBar();
ftoolBar.setButtonlist(list);
ftoolBar.setDefault(this.defaultCheckBox.isSelected());
if (!ftoolBar.isDefault()) {
ftoolBar.setBackground(this.background);
}
return ftoolBar;
}
private class MoveUpItemAction extends UpdateAction {
public MoveUpItemAction() {
this.setName(Inter.getLocText("Utils-Move_Up"));
this.setMnemonic('U');
this.setSmallIcon(IOUtils.readIcon("/com/fr/design/images/control/up.png"));
}
/**
*
*/
public void actionPerformed(ActionEvent evt) {
int selectedIndex = list.getSelectedIndex();
if (selectedIndex == -1) {
return;
}
// 上移
if (selectedIndex > 0) {
DefaultListModel listModel = (DefaultListModel) list.getModel();
Object selecteObj1 = listModel.get(selectedIndex - 1);
listModel.set(selectedIndex - 1, listModel.get(selectedIndex));
listModel.set(selectedIndex, selecteObj1);
list.setSelectedIndex(selectedIndex - 1);
list.ensureIndexIsVisible(selectedIndex - 1);
list.validate();
}
}
}
private class MoveDownItemAction extends UpdateAction {
public MoveDownItemAction() {
this.setName(Inter.getLocText("Utils-Move_Down"));
this.setMnemonic('D');
this.setSmallIcon(IOUtils.readIcon("/com/fr/design/images/control/down.png"));
}
/**
*
*/
public void actionPerformed(ActionEvent evt) {
int selectedIndex = list.getSelectedIndex();
if (selectedIndex == -1) {
return;
}
// 下移
if (selectedIndex == -1) {
return;
}
if (selectedIndex < list.getModel().getSize() - 1) {
DefaultListModel listModel = (DefaultListModel) list.getModel();
Object selecteObj1 = listModel.get(selectedIndex + 1);
listModel.set(selectedIndex + 1, listModel.get(selectedIndex));
listModel.set(selectedIndex, selecteObj1);
list.setSelectedIndex(selectedIndex + 1);
list.ensureIndexIsVisible(selectedIndex + 1);
list.validate();
}
}
}
public class RemoveAction extends UpdateAction {
public RemoveAction() {
this.setName(Inter.getLocText("FR-Designer_Delete"));
this.setSmallIcon(IOUtils.readIcon("/com/fr/base/images/cell/control/remove.png"));
}
/**
* 动作
* @param e 事件
*/
public void actionPerformed(ActionEvent e) {
int i = list.getSelectedIndex();
if (i < 0 || !(listModel.getElementAt(i) instanceof FormToolBarButton)) {
return;
}
int val = JOptionPane.showConfirmDialog(FormEditToolBar.this, Inter.getLocText("FR-Designer_Are_You_Sure_To_Delete_The_Data") + "?", "Message", JOptionPane.YES_NO_OPTION);
if (val != JOptionPane.YES_OPTION) {
return;
}
listModel.removeElementAt(i);
list.validate();
if (listModel.size() > 0) {
list.setSelectedIndex(0);
} else {
card.show(right, "none");
}
}
}
public class ButtonPane extends BasicPane {
private CardLayout card;
private JPanel centerPane;
private UICheckBox icon, text, excelP, excelO;
private Widget widget;
private UITextField nameField;
private IconDefinePane iconPane;
private UIButton button;
private JavaScriptActionPane javaScriptPane;
public ButtonPane() {
this.initComponents();
}
/**
* 初始化元素
*/
public void initComponents() {
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel north = FRGUIPaneFactory.createBorderLayout_S_Pane();
icon = new UICheckBox(Inter.getLocText("FR-Designer_Show_Icon"));
text = new UICheckBox(Inter.getLocText("FR-Designer_Show_Text"));
north.add(icon, BorderLayout.NORTH);
north.add(text, BorderLayout.CENTER);
nameField = new UITextField(8);
iconPane = new IconDefinePane();
javaScriptPane = JavaScriptActionPane.createDefault();
double p = TableLayout.PREFERRED;
double rowSize[] = {p, p};
double columnSize[] = {p, p};
Component[][] coms = new Component[][]{{new UILabel(Inter.getLocText(new String[]{"Widget", "Printer-Alias"}) + ":"), nameField}, {new UILabel(Inter.getLocText(new String[]{"Widget", "Icon"}) + ":"), iconPane}};
JPanel nameIconPane = TableLayoutHelper.createTableLayoutPane(coms, rowSize, columnSize);
north.add(nameIconPane, BorderLayout.SOUTH);
north.setBorder(BorderFactory.createTitledBorder(Inter.getLocText(new String[]{"Form-Button", "Property", "Set"})));
this.add(north, BorderLayout.NORTH);
JPanel none = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
centerPane = FRGUIPaneFactory.createCardLayout_S_Pane();
card = new CardLayout();
centerPane.setLayout(card);
centerPane.add("custom", getCustomPane());
centerPane.add("export", getExport());
centerPane.add("none", none);
this.add(centerPane, BorderLayout.CENTER);
}
private JPanel getCustomPane() {
JPanel customPane = FRGUIPaneFactory.createCenterFlowInnerContainer_S_Pane();
button = new UIButton(Inter.getLocText("FR-Designer_User_Defined_Event"));
customPane.add(button);
customPane.setBorder(GUICoreUtils.createTitledBorder(Inter.getLocText("FR-Designer_Edit") + "JS", null));
button.addActionListener(l);
return customPane;
}
private JPanel getExport() {
JPanel export = FRGUIPaneFactory.createY_AXISBoxInnerContainer_L_Pane();
// export.setLayout(new BoxLayout(export, BoxLayout.Y_AXIS));
excelP = new UICheckBox(Inter.getLocText("FR-Designer-Output_Excel_Page"));
excelO = new UICheckBox(Inter.getLocText("FR-Designer-Output_Excel_Simple"));
export.add(excelP);
export.add(Box.createVerticalStrut(2));
export.add(excelO);
export.add(Box.createVerticalStrut(2));
export.setBorder(GUICoreUtils.createTitledBorder(Inter.getLocText(new String[]{"Form-Button", "Property", "Set"}), null));
return export;
}
@Override
protected String title4PopupWindow() {
return "Button";
}
ActionListener l = new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (!(widget instanceof CustomToolBarButton)) {
return;
}
if (javaScriptPane == null || ((CustomToolBarButton)widget).getJSImpl() == null) {
javaScriptPane = JavaScriptActionPane.createDefault();
}
javaScriptPane.setPreferredSize(new Dimension(750, 500));
BasicDialog dialog = javaScriptPane.showWindow(SwingUtilities.getWindowAncestor(ButtonPane.this));
dialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
((CustomToolBarButton) widget).setJSImpl(javaScriptPane.updateBean());
}
});
dialog.setVisible(true);
}
};
/**
* 更新
* @param widget 对应组件
*/
public void populate(Widget widget) {
this.widget = widget;
card.show(centerPane, "none");
if (widget instanceof Button) {
populateDefault();
}
if (widget instanceof Export) {
populateExport();
} else if (widget instanceof CustomToolBarButton) {
populateCustomToolBarButton();
}
}
private void populateExport(){
card.show(centerPane, "export");
Export export = (Export) widget;
this.excelP.setSelected(export.isExcelPAvailable());
this.excelO.setSelected(export.isExcelOAvailable());
}
private void populateCustomToolBarButton(){
card.show(centerPane, "custom");
CustomToolBarButton customToolBarButton = (CustomToolBarButton) widget;
if (customToolBarButton.getJSImpl() != null) {
this.javaScriptPane.populateBean(customToolBarButton.getJSImpl());
}
}
private void populateDefault(){
Button button = (Button) widget;
this.icon.setSelected(button.isShowIcon());
this.text.setSelected(button.isShowText());
this.nameField.setText(button.getText());
this.iconPane.populate(((Button) widget).getIconName());
}
/**
* 更新
*
* @return 对应组件
*/
public Widget update() {
if (widget instanceof Export) {
updateExport();
} else if (widget instanceof CustomToolBarButton) {
((CustomToolBarButton) widget).setJSImpl(this.javaScriptPane.updateBean());
}
if (widget instanceof Button) {
updateDefault();
}
return widget;
}
private void updateDefault(){
((Button) widget).setShowIcon(this.icon.isSelected());
((Button) widget).setShowText(this.text.isSelected());
((Button) widget).setText(this.nameField.getText());
((Button) widget).setIconName(this.iconPane.update());
}
private void updateExport(){
Export export = (Export) widget;
export.setExcelPAvailable(this.excelP.isSelected());
export.setExcelOAvailable(this.excelO.isSelected());
}
}
}

572
designer_form/src/com/fr/design/mainframe/FormSelection.java

@ -20,288 +20,300 @@ import com.fr.design.utils.gui.LayoutUtils;
public class FormSelection {
private ArrayList<XCreator> selection;
private Rectangle backupBounds;
private ArrayList<Rectangle> recs = new ArrayList<Rectangle>();
public FormSelection() {
selection = new ArrayList<XCreator>();
}
/**
* 重置选中的组件
*/
public void reset() {
selection.clear();
}
/**
* 是否没有选中的组件
* @return 为空返回true
*/
public boolean isEmpty() {
return selection.isEmpty();
}
/**
* 选中的组件数量
* @return 选中的组件数量
*/
public int size() {
return selection.size();
}
/**
* 去除选中的组件中指定组件
* @param creator 待去除组件
*/
public void removeCreator(XCreator creator) {
selection.remove(creator);
}
/**
* 是否成功删除选择的组件
* @param comp 组件
* @return 是则返回true
*/
public boolean removeSelectedCreator(XCreator comp) {
if (selection.size() > 1 && selection.contains(comp)) {
removeCreator(comp);
return true;
}
return false;
}
/**
* 成功增加选中的组件
* @param creator 组件
* @return 成功增加返回true
*/
public boolean addSelectedCreator(XCreator creator) {
if (addedable(creator)) {
selection.add(creator);
return true;
}
return false;
}
/**
* 是否是可以增加的
* @param creator 组件
* @return 是则返回true
*/
public boolean addedable(XCreator creator) {
if (selection.isEmpty()) {
return true;
}
XLayoutContainer container = XCreatorUtils.getParentXLayoutContainer(creator);
if (!(container instanceof XWAbsoluteLayout)) {
return false;
}
for (XCreator selected : selection) {
if (selected == creator || XCreatorUtils.getParentXLayoutContainer(selected) != container) {
return false;
}
}
return true;
}
/**
* 返回选中的第一个组件为空返回null
* @return 返回选中组件
*/
public XCreator getSelectedCreator() {
return !selection.isEmpty() ? selection.get(0) : null;
}
/**
* 返回选中的所有组件
* @return 所有组件s
*/
public XCreator[] getSelectedCreators() {
return selection.toArray(new XCreator[selection.size()]);
}
public Widget[] getSelectedWidgets() {
Widget[] selectWidget = new Widget[selection.size()];
for (int i = 0; i < selection.size(); i++) {
selectWidget[i] = selection.get(i).toData();
}
return selectWidget;
}
public void setSelectedCreator(XCreator creator) {
reset();
selection.add(creator);
}
public void setSelectedCreators(ArrayList<XCreator> selections) {
reset();
for (XCreator creator : selections) {
if (addedable(creator)) {
selection.add(creator);
}
}
}
/**
* 是否包含当前控件
* @param widget 控件
* @return 是则返回true
*/
public boolean contains(Widget widget) {
for (XCreator creator : selection) {
if (creator.toData() == widget) {
return true;
}
}
return false;
}
public int[] getDirections() {
if (this.selection.size() > 1) {
return Direction.ALL;
} else if (this.selection.size() == 1) {
return this.selection.get(0).getDirections();
} else {
return new int[0];
}
}
/**
* 备份组件的bound
*/
public void backupBounds() {
backupBounds = getRelativeBounds();
recs.clear();
for (XComponent comp : selection) {
recs.add(comp.getBounds());
}
}
public Rectangle getBackupBounds() {
return backupBounds;
}
public Rectangle getRelativeBounds() {
Rectangle bounds = getSelctionBounds();
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.get(0));
if (parent == null) {
return bounds;
}
Rectangle rec = ComponentUtils.getRelativeBounds(parent);
bounds.x += rec.x;
bounds.y += rec.y;
return bounds;
}
public Rectangle getSelctionBounds() {
if(selection.isEmpty()) {
return new Rectangle();
}
Rectangle bounds = selection.get(0).getBounds();
for (int i = 1, len = selection.size(); i < len; i++) {
bounds = bounds.union(selection.get(i).getBounds());
}
return bounds;
}
public void setSelectionBounds(Rectangle rec, FormDesigner designer) {
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.get(0));
Rectangle backupBounds = new Rectangle(this.backupBounds);
if (parent != null) {
Rectangle r = ComponentUtils.getRelativeBounds(parent);
rec.x -= r.x;
rec.y -= r.y;
backupBounds.x -= r.x;
backupBounds.y -= r.y;
}
int size = selection.size();
if (size == 1) {
XCreator creator = selection.get(0);
creator.setBounds(rec);
if(creator.acceptType(XWParameterLayout.class)){
designer.setParaHeight((int)rec.getHeight());
private ArrayList<XCreator> selection;
private Rectangle backupBounds;
private ArrayList<Rectangle> recs = new ArrayList<Rectangle>();
public FormSelection() {
selection = new ArrayList<XCreator>();
}
/**
* 重置选中的组件
*/
public void reset() {
selection.clear();
}
/**
* 是否没有选中的组件
*
* @return 为空返回true
*/
public boolean isEmpty() {
return selection.isEmpty();
}
/**
* 选中的组件数量
*
* @return 选中的组件数量
*/
public int size() {
return selection.size();
}
/**
* 去除选中的组件中指定组件
*
* @param creator 待去除组件
*/
public void removeCreator(XCreator creator) {
selection.remove(creator);
}
/**
* 是否成功删除选择的组件
*
* @param comp 组件
* @return 是则返回true
*/
public boolean removeSelectedCreator(XCreator comp) {
if (selection.size() > 1 && selection.contains(comp)) {
removeCreator(comp);
return true;
}
return false;
}
/**
* 成功增加选中的组件
*
* @param creator 组件
* @return 成功增加返回true
*/
public boolean addSelectedCreator(XCreator creator) {
if (addedable(creator)) {
selection.add(creator);
return true;
}
return false;
}
/**
* 是否是可以增加的
*
* @param creator 组件
* @return 是则返回true
*/
public boolean addedable(XCreator creator) {
if (selection.isEmpty()) {
return true;
}
XLayoutContainer container = XCreatorUtils.getParentXLayoutContainer(creator);
if (!(container instanceof XWAbsoluteLayout)) {
return false;
}
for (XCreator selected : selection) {
if (selected == creator || XCreatorUtils.getParentXLayoutContainer(selected) != container) {
return false;
}
}
return true;
}
/**
* 返回选中的第一个组件为空返回null
*
* @return 返回选中组件
*/
public XCreator getSelectedCreator() {
return !selection.isEmpty() ? selection.get(0) : null;
}
/**
* 返回选中的所有组件
*
* @return 所有组件s
*/
public XCreator[] getSelectedCreators() {
return selection.toArray(new XCreator[selection.size()]);
}
public Widget[] getSelectedWidgets() {
Widget[] selectWidget = new Widget[selection.size()];
for (int i = 0; i < selection.size(); i++) {
selectWidget[i] = selection.get(i).toData();
}
return selectWidget;
}
public void setSelectedCreator(XCreator creator) {
reset();
selection.add(creator);
}
public void setSelectedCreators(ArrayList<XCreator> selections) {
reset();
for (XCreator creator : selections) {
if (addedable(creator)) {
selection.add(creator);
}
}
}
/**
* 是否包含当前控件
*
* @param widget 控件
* @return 是则返回true
*/
public boolean contains(Widget widget) {
for (XCreator creator : selection) {
if (creator.toData() == widget) {
return true;
}
}
return false;
}
public int[] getDirections() {
if (this.selection.size() > 1) {
return Direction.ALL;
} else if (this.selection.size() == 1) {
return this.selection.get(0).getDirections();
} else {
return new int[0];
}
}
/**
* 备份组件的bound
*/
public void backupBounds() {
backupBounds = getRelativeBounds();
recs.clear();
for (XComponent comp : selection) {
recs.add(comp.getBounds());
}
}
public Rectangle getBackupBounds() {
return backupBounds;
}
public Rectangle getRelativeBounds() {
Rectangle bounds = getSelctionBounds();
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.get(0));
if (parent == null) {
return bounds;
}
Rectangle rec = ComponentUtils.getRelativeBounds(parent);
bounds.x += rec.x;
bounds.y += rec.y;
return bounds;
}
public Rectangle getSelctionBounds() {
if (selection.isEmpty()) {
return new Rectangle();
}
Rectangle bounds = selection.get(0).getBounds();
for (int i = 1, len = selection.size(); i < len; i++) {
bounds = bounds.union(selection.get(i).getBounds());
}
return bounds;
}
public void setSelectionBounds(Rectangle rec, FormDesigner designer) {
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(selection.get(0));
Rectangle backupBounds = new Rectangle(this.backupBounds);
if (parent != null) {
Rectangle r = ComponentUtils.getRelativeBounds(parent);
rec.x -= r.x;
rec.y -= r.y;
backupBounds.x -= r.x;
backupBounds.y -= r.y;
}
int size = selection.size();
if (size == 1) {
XCreator creator = selection.get(0);
creator.setBounds(rec);
if (creator.acceptType(XWParameterLayout.class)) {
designer.setParaHeight((int) rec.getHeight());
designer.getArea().doLayout();
}
LayoutUtils.layoutContainer(creator);
} else if (size > 1) {
for (int i = 0; i < selection.size(); i++) {
Rectangle newBounds = new Rectangle(recs.get(i));
newBounds.x = rec.x + (newBounds.x - backupBounds.x) * rec.width / backupBounds.width;
newBounds.y = rec.y + (newBounds.y - backupBounds.y) * rec.height / backupBounds.height;
newBounds.width = rec.width * newBounds.width / backupBounds.width;
newBounds.height = rec.height * newBounds.height / backupBounds.height;
XCreator creator = selection.get(i);
creator.setBounds(newBounds);
if(creator.acceptType(XWParameterLayout.class)){
designer.setParaHeight((int)rec.getHeight());
LayoutUtils.layoutContainer(creator);
} else if (size > 1) {
for (int i = 0; i < selection.size(); i++) {
Rectangle newBounds = new Rectangle(recs.get(i));
newBounds.x = rec.x + (newBounds.x - backupBounds.x) * rec.width / backupBounds.width;
newBounds.y = rec.y + (newBounds.y - backupBounds.y) * rec.height / backupBounds.height;
newBounds.width = rec.width * newBounds.width / backupBounds.width;
newBounds.height = rec.height * newBounds.height / backupBounds.height;
XCreator creator = selection.get(i);
creator.setBounds(newBounds);
if (creator.acceptType(XWParameterLayout.class)) {
designer.setParaHeight((int) rec.getHeight());
designer.getArea().doLayout();
}
}
LayoutUtils.layoutRootContainer(designer.getRootComponent());
}
}
/**
* 调整组件大小
* @param designer 设计界面组件
*/
public void fixCreator(FormDesigner designer) {
for (XCreator creator : selection) {
LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator);
if (layoutAdapter != null) {
creator.setBackupBound(backupBounds);
layoutAdapter.fix(creator);
}
}
}
private void removeCreatorFromContainer(XCreator creator) {
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator);
if (parent == null) {
return;
}
// 删除其根组件,同时就删除了同时被选择的叶子组件
parent.remove(creator);
LayoutManager layout = parent.getLayout();
if (layout != null) {
// 刷新组件容器的布局
LayoutUtils.layoutContainer(parent);
}
}
/**
* 剪切选中的所有组件
* @param clipBoard 剪切板
*/
public void cut2ClipBoard(FormSelection clipBoard) {
clipBoard.reset();
clipBoard.selection.addAll(selection);
for (XCreator creator : selection) {
removeCreatorFromContainer(creator);
}
reset();
}
/**
* 复制选中的所有组件
* @param clipBoard 复制板
*/
public void copy2ClipBoard(FormSelection clipBoard) {
clipBoard.reset();
for (XCreator root : selection) {
try {
XCreator creator = XCreatorUtils.createXCreator((Widget) root.toData().clone());
creator.setBounds(root.getBounds());
clipBoard.selection.add(creator);
} catch (CloneNotSupportedException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
}
}
}
LayoutUtils.layoutRootContainer(designer.getRootComponent());
}
}
/**
* 调整组件大小
*
* @param designer 设计界面组件
*/
public void fixCreator(FormDesigner designer) {
for (XCreator creator : selection) {
LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator);
if (layoutAdapter != null) {
creator.setBackupBound(backupBounds);
layoutAdapter.fix(creator);
}
}
}
private void removeCreatorFromContainer(XCreator creator) {
XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(creator);
if (parent == null) {
return;
}
// 删除其根组件,同时就删除了同时被选择的叶子组件
parent.remove(creator);
LayoutManager layout = parent.getLayout();
if (layout != null) {
// 刷新组件容器的布局
LayoutUtils.layoutContainer(parent);
}
}
/**
* 剪切选中的所有组件
*
* @param clipBoard 剪切板
*/
public void cut2ClipBoard(FormSelection clipBoard) {
clipBoard.reset();
clipBoard.selection.addAll(selection);
for (XCreator creator : selection) {
removeCreatorFromContainer(creator);
}
reset();
}
/**
* 复制选中的所有组件
*
* @param clipBoard 复制板
*/
public void copy2ClipBoard(FormSelection clipBoard) {
clipBoard.reset();
for (XCreator root : selection) {
try {
XCreator creator = XCreatorUtils.createXCreator((Widget) root.toData().clone());
creator.setBounds(root.getBounds());
clipBoard.selection.add(creator);
} catch (CloneNotSupportedException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
}
}
}

394
designer_form/src/com/fr/design/mainframe/FormSelectionUtils.java

@ -1,126 +1,270 @@
package com.fr.design.mainframe;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import com.fr.base.FRContext;
import com.fr.general.ComparatorUtils;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.form.main.ClonedWidgetCreator;
import com.fr.form.ui.Widget;
public class FormSelectionUtils {
public static void paste2Container(FormDesigner designer, XLayoutContainer parent, FormSelection selection, int x,
int y) {
LayoutAdapter adapter = parent.getLayoutAdapter();
if (selection.size() == 1) {
try {
XCreator creator = selection.getSelectedCreator();
Widget cloned = new ClonedWidgetCreator(designer.getTarget()).clonedWidgetWithNoRepeatName(creator
.toData());
XCreator clondCreator = XCreatorUtils.createXCreator(cloned, creator.getSize());
if (adapter.addBean(clondCreator, x + clondCreator.getWidth() / 2, y + clondCreator.getHeight() / 2)) {
designer.getSelectionModel().getSelection().setSelectedCreator(clondCreator);
designer.getEditListenerTable().fireCreatorModified(clondCreator, DesignerEvent.CREATOR_PASTED);
return;
}
} catch (CloneNotSupportedException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
} else if (selection.size() > 1) {
if (parent instanceof XWAbsoluteLayout) {
designer.getSelectionModel().getSelection().reset();
Rectangle rec = selection.getSelctionBounds();
for (XCreator creator : selection.getSelectedCreators()) {
try {
Widget cloned = new ClonedWidgetCreator(designer.getTarget())
.clonedWidgetWithNoRepeatName(creator.toData());
XCreator clondCreator = XCreatorUtils.createXCreator(cloned, creator.getSize());
// 设置位置,移动20x20,防止被粘帖的组件重叠,照顾表单布局情况下
adapter.addBean(clondCreator, x + creator.getX() - rec.x + clondCreator.getWidth() / 2, y
+ creator.getY() - rec.y + clondCreator.getHeight() / 2);
designer.getSelectionModel().getSelection().addSelectedCreator(clondCreator);
} catch (CloneNotSupportedException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
}
designer.getEditListenerTable().fireCreatorModified(
designer.getSelectionModel().getSelection().getSelectedCreator(), DesignerEvent.CREATOR_PASTED);
return;
}
}
Toolkit.getDefaultToolkit().beep();
}
public static void rebuildSelection(FormDesigner designer) {
ArrayList<XCreator> newSelection = new ArrayList<XCreator>();
List<Widget> widgetList = new ArrayList<Widget>();
for (XCreator comp : designer.getSelectionModel().getSelection().getSelectedCreators()) {
widgetList.add(comp.toData());
}
designer.getSelectionModel().setSelectedCreators(
rebuildSelection(designer.getRootComponent(), widgetList, newSelection));
}
public static ArrayList<XCreator> rebuildSelection(XCreator rootComponent, Widget[] selectWidgets) {
List<Widget> selectionWidget = new ArrayList<Widget>();
if(selectWidgets != null){
selectionWidget.addAll(Arrays.asList(selectWidgets));
}
return FormSelectionUtils.rebuildSelection(rootComponent, selectionWidget, new ArrayList<XCreator>());
}
private static ArrayList<XCreator> rebuildSelection(XCreator rootComponent, List<Widget> selectionWidget,
ArrayList<XCreator> newSelection) {
FormSelectionUtils._rebuild(rootComponent, selectionWidget, newSelection);
if (newSelection.isEmpty()) {
newSelection.add(rootComponent);
}
return newSelection;
}
private static void _rebuild(XCreator root, List<Widget> selectionWidget, List<XCreator> newSelection) {
if (selectionWidget.isEmpty()) {
return;
}
for (Widget x : selectionWidget) {
if (ComparatorUtils.equals(x, root.toData())) {
if (!newSelection.contains(root)) {
newSelection.add(root);
selectionWidget.remove(x);
}
break;
}
}
int count = root.getComponentCount();
for (int i = 0; i < count && !selectionWidget.isEmpty(); i++) {
Component c = root.getComponent(i);
if (c instanceof XCreator) {
XCreator creator = (XCreator) c;
for (Widget x : selectionWidget) {
if (ComparatorUtils.equals(x, creator.toData())) {
newSelection.add(creator);
selectionWidget.remove(x);
break;
}
}
if (c instanceof XLayoutContainer) {
_rebuild((XLayoutContainer) c, selectionWidget, newSelection);
} else {
continue;
}
}
}
}
package com.fr.design.mainframe;
import com.fr.base.FRContext;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.AbstractLayoutAdapter;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.creator.*;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WTitleLayout;
import com.fr.general.ComparatorUtils;
import java.awt.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
public class FormSelectionUtils {
//组件复制时坐标偏移
private static final int DELAY_X = 20;
private static final int DELAY_Y = 20;
//组件复制时是否已经向左上偏移
private static boolean backoffset = false;
//组件重命名后缀
private static final String POSTFIX = "_c";
private FormSelectionUtils() {
}
/**
* @param designer 编辑器
* @param parent 粘贴依据的组件
* @param clipboard 剪贴板内容
* @param x x
* @param y y
*/
public static void paste2Container(FormDesigner designer, XLayoutContainer parent,
FormSelection clipboard, int x, int y) {
LayoutAdapter adapter = parent.getLayoutAdapter();
if (parent instanceof XWAbsoluteLayout) {
//绝对布局
absolutePaste(designer, clipboard, adapter, x, y);
return;
} else if (parent instanceof XWFitLayout) {
//相对布局
relativePaste(designer, clipboard, adapter, x, y);
return;
}
Toolkit.getDefaultToolkit().beep();
}
/**
* 绝对布局粘贴
*
* @param designer
* @param clipboard
* @param adapter
* @param x
* @param y
*/
private static void absolutePaste(FormDesigner designer, FormSelection clipboard, LayoutAdapter adapter, int x, int y) {
designer.getSelectionModel().getSelection().reset();
Rectangle rec = clipboard.getSelctionBounds();
for (XCreator creator : clipboard.getSelectedCreators()) {
try {
Widget copied = copyWidget(designer, creator);
XCreator copiedCreator = XCreatorUtils.createXCreator(copied, creator.getSize());
// 获取位置
Point point = getPasteLocation((AbstractLayoutAdapter) adapter,
copiedCreator,
x + creator.getX() - rec.x + copiedCreator.getWidth() / 2,
y + creator.getY() - rec.y + copiedCreator.getHeight() / 2);
boolean addSuccess = adapter.addBean(copiedCreator, point.x, point.y);
if (addSuccess) {
designer.getSelectionModel().getSelection().addSelectedCreator(copiedCreator);
}
} catch (CloneNotSupportedException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
}
rebuildSelection(designer);
designer.getEditListenerTable().fireCreatorModified(
designer.getSelectionModel().getSelection().getSelectedCreator(), DesignerEvent.CREATOR_PASTED);
}
/**
* 相对布局粘贴
*
* @param designer
* @param clipboard
* @param adapter
* @param x
* @param y
*/
private static void relativePaste(FormDesigner designer, FormSelection clipboard, LayoutAdapter adapter, int x, int y) {
designer.getSelectionModel().getSelection().reset();
for (XCreator creator : clipboard.getSelectedCreators()) {
try {
Widget copied = copyWidget(designer, creator);
XCreator copiedCreator = XCreatorUtils.createXCreator(copied, creator.getSize());
boolean addSuccess = adapter.addBean(copiedCreator, x, y);
if (addSuccess) {
designer.getSelectionModel().getSelection().addSelectedCreator(copiedCreator);
}
} catch (CloneNotSupportedException e) {
FRContext.getLogger().error(e.getMessage(), e);
}
}
rebuildSelection(designer);
designer.getEditListenerTable().fireCreatorModified(
designer.getSelectionModel().getSelection().getSelectedCreator(), DesignerEvent.CREATOR_PASTED);
}
/**
* 组件复用绝对布局获取粘贴组件位置
*
* @param layoutAdapter 绝对布局容器AbstractLayoutAdapter
* @param copiedCreator 复制的组件
* @param x x=组件x + clonedCreator.getWidth() / 2
* @param y y=组件y + clonedCreator.getHeight() / 2
* 除2的步骤会导致当宽度或者高度为奇数是中心点向左上各偏移一个像素
* 由于中心点向左上各偏移一个像素依赖中心点计算的右下点就会相应的想做上偏移一个像素导致结果不准确
* @return 新位置坐标
*/
private static Point getPasteLocation(AbstractLayoutAdapter layoutAdapter, XCreator copiedCreator, int x, int y) {
//当宽度为奇数时 设置偏移
int xoffset = (copiedCreator.getWidth() & 1) == 1 ? 1 : 0;
//当高度为奇数时 设置偏移
int yoffset = (copiedCreator.getHeight() & 1) == 1 ? 1 : 0;
if (!layoutAdapter.accept(copiedCreator, x, y)) {
XLayoutContainer container = layoutAdapter.getContainer();
boolean xOut = x < 0 || x + copiedCreator.getWidth() / 2 + xoffset > container.getWidth();
boolean yOut = y < 0 || y + copiedCreator.getHeight() / 2 + yoffset > container.getHeight();
/*
* 组件原始位置位于布局的右下角
* 和布局右下边界线紧挨
* 粘贴时组件在原始位置向左错开20像素
* x,y同时越界
*/
if (xOut && yOut) {
x = backoffset ? container.getWidth() - copiedCreator.getWidth() / 2 - xoffset
: container.getWidth() - copiedCreator.getWidth() / 2 - DELAY_X - xoffset;
y = backoffset ?
container.getHeight() - copiedCreator.getHeight() / 2 - yoffset
: container.getHeight() - copiedCreator.getHeight() / 2 - DELAY_Y - yoffset;
backoffset = !backoffset;
return new Point(x, y);
}
/*
* 组件原始位置与布局边界距离小于20像素下边界&右边界同时小于或者任意一个边界小于
* 则粘贴时距离小于20像素一侧直接贴近布局边界
* 距离大于20像素的一侧正常错开
* x,y中只有一个越界
*/
else if ((xOut || yOut)) {
x = xOut ? container.getWidth() - copiedCreator.getWidth() / 2 - xoffset : x;
y = yOut ? container.getHeight() - copiedCreator.getHeight() / 2 - yoffset : y;
return new Point(x, y);
}
}
return new Point(x, y);
}
/**
* 拷贝组件
*
* @param formDesigner
* @param xCreator
* @return
* @throws CloneNotSupportedException
*/
private static Widget copyWidget(FormDesigner formDesigner, XCreator xCreator) throws
CloneNotSupportedException {
ArrayList<String> nameSpace = new ArrayList<String>();
Widget copied = (Widget) xCreator.toData().clone();
//重命名拷贝的组件
String name = getCopiedName(formDesigner, copied, nameSpace);
if (copied instanceof WTitleLayout) {
XWTitleLayout xwTitleLayout = new XWTitleLayout((WTitleLayout) copied, xCreator.getSize());
xwTitleLayout.resetCreatorName(name);
} else {
copied.setWidgetName(name);
}
return copied;
}
/**
* 组件拷贝命名规则
*
* @param formDesigner
* @param copied
* @param nameSpace
* @return name
*/
private static String getCopiedName(FormDesigner formDesigner, Widget copied, ArrayList<String> nameSpace) {
StringBuffer name = new StringBuffer(copied.getWidgetName());
do {
name.append(POSTFIX);
} while (formDesigner.getTarget().isNameExist(name.toString()) || nameSpace.contains(name.toString()));
nameSpace.add(name.toString());
return name.toString();
}
public static void rebuildSelection(FormDesigner designer) {
ArrayList<XCreator> newSelection = new ArrayList<XCreator>();
List<Widget> widgetList = new ArrayList<Widget>();
for (XCreator comp : designer.getSelectionModel().getSelection().getSelectedCreators()) {
widgetList.add(comp.toData());
}
designer.getSelectionModel().setSelectedCreators(
rebuildSelection(designer.getRootComponent(), widgetList, newSelection));
}
public static ArrayList<XCreator> rebuildSelection(XCreator rootComponent, Widget[] selectWidgets) {
List<Widget> selectionWidget = new ArrayList<Widget>();
if (selectWidgets != null) {
selectionWidget.addAll(Arrays.asList(selectWidgets));
}
return FormSelectionUtils.rebuildSelection(rootComponent, selectionWidget, new ArrayList<XCreator>());
}
private static ArrayList<XCreator> rebuildSelection(XCreator rootComponent, List<Widget> selectionWidget,
ArrayList<XCreator> newSelection) {
FormSelectionUtils.rebuild(rootComponent, selectionWidget, newSelection);
if (newSelection.isEmpty()) {
newSelection.add(rootComponent);
}
return newSelection;
}
private static void rebuild(XCreator root, List<Widget> selectionWidget, List<XCreator> newSelection) {
if (selectionWidget.isEmpty()) {
return;
}
for (Widget x : selectionWidget) {
if (ComparatorUtils.equals(x, root.toData())) {
if (!newSelection.contains(root)) {
newSelection.add(root);
selectionWidget.remove(x);
}
break;
}
}
int count = root.getComponentCount();
for (int i = 0; i < count && !selectionWidget.isEmpty(); i++) {
Component c = root.getComponent(i);
if (c instanceof XCreator) {
XCreator creator = (XCreator) c;
for (Widget x : selectionWidget) {
if (ComparatorUtils.equals(x, creator.toData())) {
newSelection.add(creator);
selectionWidget.remove(x);
break;
}
}
if (c instanceof XLayoutContainer) {
rebuild((XLayoutContainer) c, selectionWidget, newSelection);
}
}
}
}
}

84
designer_form/src/com/fr/design/mainframe/FormSettingToolBar.java

@ -0,0 +1,84 @@
package com.fr.design.mainframe;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
/**
* Created by harry on 2017-3-2.
*/
public class FormSettingToolBar extends JPanel {
private Icon setIcon = IOUtils.readIcon("com/fr/design/images/toolbarbtn/toolbarbtnsetting.png");
private Icon delIcon = IOUtils.readIcon("com/fr/design/images/toolbarbtn/toolbarbtnclear.png");
private UIButton setButton;
private UIButton delButton;
private FormToolBarPane toolBarPane;
public FormSettingToolBar(String name, FormToolBarPane toolBarPane) {
super();
this.setBackground(Color.lightGray);
this.add(new UILabel(name));
this.toolBarPane = toolBarPane;
setButton = GUICoreUtils.createTransparentButton(setIcon, setIcon, setIcon);
setButton.setToolTipText(Inter.getLocText("FR-Designer_Edit_Button_ToolBar"));
setButton.setAction(new SetAction());
delButton = GUICoreUtils.createTransparentButton(delIcon, delIcon, delIcon);
delButton.setToolTipText(Inter.getLocText("FR-Designer_Remove_Button_ToolBar"));
delButton.setAction(new DelAction());
this.add(setButton);
this.add(delButton);
}
public void setEnabled(boolean b) {
setButton.setEnabled(b);
delButton.setEnabled(b);
}
public void addActionListener(ActionListener l){
setButton.addActionListener(l);
delButton.addActionListener(l);
}
private class SetAction extends AbstractAction {
public SetAction() {
this.putValue(Action.SMALL_ICON, setIcon);
}
@Override
public void actionPerformed(ActionEvent arg0) {
final FormEditToolBar tb = new FormEditToolBar();
tb.populate(toolBarPane.getFToolBar());
BasicDialog dialog = tb.showWindow(DesignerContext.getDesignerFrame());
dialog.addDialogActionListener(new DialogActionAdapter() {
public void doOk() {
toolBarPane.setFToolBar(tb.update());
}
});
dialog.setVisible(true);
}
}
private class DelAction extends AbstractAction {
public DelAction() {
this.putValue(Action.SMALL_ICON, delIcon);
}
@Override
public void actionPerformed(ActionEvent arg0) {
toolBarPane.removeAll();
toolBarPane.removeButtonList();
toolBarPane.repaint();
}
}
}

68
designer_form/src/com/fr/design/mainframe/FormToolBar.java

@ -0,0 +1,68 @@
package com.fr.design.mainframe;
import com.fr.form.ui.ToolBar;
import com.fr.form.ui.Widget;
import com.fr.general.Background;
import java.util.ArrayList;
import java.util.List;
/**
* Created by harry on 2017-3-2.
*/
public class FormToolBar {
private List<FormToolBarButton> buttonlist = new ArrayList<FormToolBarButton>();
private Background background = null;
private boolean isDefault = true;
public List<FormToolBarButton> getButtonlist() {
return buttonlist;
}
public void setButtonlist(List<FormToolBarButton> buttonlist) {
if (buttonlist == null || buttonlist.size() < 0) {
this.buttonlist = new ArrayList<FormToolBarButton>();
} else {
this.buttonlist = buttonlist;
}
}
public void addButton(FormToolBarButton toolBarButton) {
this.buttonlist.add(toolBarButton);
}
public void removeButton(FormToolBarButton toolBarButton) {
this.buttonlist.remove(toolBarButton);
}
public void clearButton() {
this.buttonlist.clear();
}
public Background getBackground() {
return background;
}
public void setBackground(Background background) {
this.background = background;
}
public boolean isDefault() {
return isDefault;
}
public void setDefault(boolean isDefault) {
this.isDefault = isDefault;
}
public ToolBar getToolBar() {
Widget[] widgets = new Widget[this.getButtonlist().size()];
for (int j = 0; j < this.getButtonlist().size(); j++) {
widgets[j] = this.getButtonlist().get(j).getWidget();
}
ToolBar toolBar = new ToolBar(widgets);
toolBar.setBackground(this.background);
toolBar.setDefault(this.isDefault);
return toolBar;
}
}

164
designer_form/src/com/fr/design/mainframe/FormToolBarButton.java

@ -0,0 +1,164 @@
package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.core.WidgetOption;
import com.fr.design.roleAuthority.ReportAndFSManagePane;
import com.fr.design.utils.gui.GUIPaintUtils;
import com.fr.form.ui.Widget;
import com.fr.form.ui.WidgetManager;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
/**
* Created by harry on 2017-3-2.
*/
public class FormToolBarButton extends JButton implements MouseListener {
private Widget widget;
private WidgetOption widgetOption;
public FormToolBarButton(Icon icon, Widget widget) {
this(null, icon, widget);
}
public FormToolBarButton(String text, Icon icon, Widget widget) {
super(text, icon);
setBackground(null);
setRolloverEnabled(true);
this.widget = widget;
if (widget instanceof com.fr.form.ui.Button) {
com.fr.form.ui.Button button = (com.fr.form.ui.Button) widget;
String iconName = button.getIconName();
if (StringUtils.isNotEmpty(iconName)) {
Image iimage = WidgetManager.getProviderInstance().getIconManager().getIconImage(iconName);
if (iimage != null) {
setIcon(new ImageIcon(iimage));
}
}
}
this.addMouseListener(this);
setMargin(new Insets(0, 0, 0, 0));
}
/**
* 改变按钮的权限细粒度状态
*
* @param selectedRole 选择的角色
* @param isVisible 是否可见
*/
public void changeAuthorityState(String selectedRole, boolean isVisible) {
this.widget.changeOnlyVisibleAuthorityState(selectedRole, isVisible);
}
/**
* 是都做过权限细粒度
*
* @param role 选择的角色
* @return 若是对应的该角色做过权限细粒度则返回true
*/
public boolean isDoneAuthorityEdited(String role) {
return this.widget.isDoneVisibleAuthority(role);
}
public Widget getWidget() {
return this.widget;
}
public void setWidget(Widget widget) {
this.widget = widget;
}
public WidgetOption getNameOption() {
return this.widgetOption;
}
public void setNameOption(WidgetOption widgetOption) {
this.widgetOption = widgetOption;
}
protected void paintBorder(Graphics g) {
paintBorder(g, this);
}
protected void paintBorder(Graphics g, FormToolBarButton b) {
String selectedRoles = ReportAndFSManagePane.getInstance().getRoleTree().getSelectedRoleName();
GUIPaintUtils.drawBorder((Graphics2D) g, 0, 0, b.getWidth(), b.getHeight(), true, Constants.NULL, b.isDoneAuthorityEdited(selectedRoles));
}
/**
* 处理鼠标点击事件
*
* @param e 鼠标点击事件
*/
public void mouseClicked(MouseEvent e) {
//该button只在报表块工具栏中使用,
//parent只有FormToolBarPane一种,故可以直接强转
final FormToolBarPane toolBarPane = (FormToolBarPane) this.getParent();
if (BaseUtils.isAuthorityEditing()) {
auhtorityMouseAction();
return;
}
if (e.getClickCount() >= 2) {
final FormEditToolBar editToolBar = new FormEditToolBar();
editToolBar.populate(toolBarPane.getFToolBar(), this);
BasicDialog dialog = editToolBar.showWindow(DesignerContext.getDesignerFrame());
dialog.addDialogActionListener(new DialogActionAdapter() {
public void doOk() {
toolBarPane.setFToolBar(editToolBar.update());
}
});
dialog.setVisible(true);
}
}
private void auhtorityMouseAction() {
if (this.isEnabled()) {
this.setSelected(!this.isSelected());
}
}
/**
* 鼠标进入事件
*
* @param e 鼠标进入事件
*/
public void mouseEntered(MouseEvent e) {
}
/**
* 鼠标退出事件
*
* @param e 鼠标退出事件
*/
public void mouseExited(MouseEvent e) {
}
/**
* 鼠标按下事件
*
* @param e 鼠标事件
*/
public void mousePressed(MouseEvent e) {
}
/**
* 鼠标释放事件
*
* @param e 鼠标事件
*/
public void mouseReleased(MouseEvent e) {
}
}

233
designer_form/src/com/fr/design/mainframe/FormToolBarPane.java

@ -0,0 +1,233 @@
package com.fr.design.mainframe;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.core.WidgetOption;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.form.ui.ToolBar;
import com.fr.form.ui.Widget;
import javax.swing.*;
import java.awt.*;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
/**
* Created by harry on 2017-3-2.
*/
public class FormToolBarPane extends BasicBeanPane<ToolBar> {
private FormToolBar ftoolbar = new FormToolBar();
public FormToolBarPane() {
super();
this.initComponent();
}
/**
* 添加鼠标监听
*
* @param mouselistener 鼠标监听
*/
public void addAuthorityListener(MouseListener mouselistener) {
List<FormToolBarButton> list = ftoolbar.getButtonlist();
for (int i = 0; i < list.size(); i++) {
list.get(i).addMouseListener(mouselistener);
}
}
public FormToolBarPane(FormToolBarButton button) {
super();
this.initComponent();
this.add(button);
}
/**
* 初始化组件
*/
public void initComponent() {
this.addMouseListener(listener);
this.setLayout(FRGUIPaneFactory.createBoxFlowLayout());
this.setTransferHandler(new ToolBarHandler(TransferHandler.COPY));
this.setBorder(BorderFactory.createTitledBorder(""));
}
/**
* 删除鼠标事件
*/
public void removeDefaultMouseListener() {
this.removeMouseListener(listener);
}
@Override
protected String title4PopupWindow() {
return "Toolbar";
}
public void setSelectedButton(FormToolBarButton button) {
this.ftoolbar.addButton(button);
}
/**
* 添加组件
*
* @param comp 组件
*
* @return 被添加的组件
*/
public Component add(Component comp) {
if (comp instanceof FormToolBarButton) {
this.ftoolbar.addButton((FormToolBarButton) comp);
}
return super.add(comp);
}
private Component addComp(Component comp) {
return super.add(comp);
}
public void removeButtonList() {
this.ftoolbar.clearButton();
}
protected void setFToolBar(FormToolBar ftoolbar) {
if (ftoolbar == null) {
ftoolbar = new FormToolBar();
}
this.ftoolbar = ftoolbar;
this.setToolBar(this.ftoolbar.getButtonlist());
}
public List<FormToolBarButton> getToolBarButtons() {
return ftoolbar.getButtonlist();
}
protected FormToolBar getFToolBar() {
return this.ftoolbar;
}
public boolean isEmpty() {
return this.ftoolbar.getButtonlist().size() <= 0;
}
private void setToolBar(List<FormToolBarButton> list) {
if (list == null || list.size() < 0) {
return;
}
this.removeAll();
for (int i = 0; i < list.size(); i++) {
this.addComp(list.get(i));
}
this.validate();
this.repaint();
}
@Override
public void populateBean(ToolBar toolbar) {
this.removeAll();
this.getFToolBar().clearButton();
for (int j = 0; j < toolbar.getWidgetSize(); j++) {
Widget widget = toolbar.getWidget(j);
WidgetOption no = WidgetOption.getToolBarButton(widget.getClass());
if (no == null){
//如果装了什么插件, 放到了工具栏上, 后来删除了插件, 模板里还存着之前的控件
continue;
}
FormToolBarButton button = new FormToolBarButton(no.optionIcon(), widget);
button.setNameOption(no);
this.add(button);
this.validate();
this.repaint();
}
this.getFToolBar().setBackground(toolbar.getBackground());
this.getFToolBar().setDefault(toolbar.isDefault());
}
@Override
public ToolBar updateBean() {
return this.ftoolbar.getToolBar();
}
MouseListener listener = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() >= 2 && !SwingUtilities.isRightMouseButton(e)) {
final FormEditToolBar tb = new FormEditToolBar();
tb.populate(getFToolBar());
BasicDialog dialog = tb.showWindow(SwingUtilities.getWindowAncestor(FormToolBarPane.this));
dialog.addDialogActionListener(new DialogActionAdapter() {
@Override
public void doOk() {
FormToolBarPane.this.setFToolBar(tb.update());
}
});
dialog.setVisible(true);
}
}
};
/*
* 拖拽属性设置
*/
private class ToolBarHandler extends TransferHandler {
private int action;
public ToolBarHandler(int action) {
this.action = action;
}
@Override
public boolean canImport(TransferHandler.TransferSupport support) {
if (!support.isDrop()) {
return false;
}
if (!support.isDataFlavorSupported(DataFlavor.stringFlavor)) {
return false;
}
boolean actionSupported = (action & support.getSourceDropActions()) == action;
if (actionSupported) {
support.setDropAction(action);
return true;
}
return false;
}
@Override
public boolean importData(TransferHandler.TransferSupport support) {
if (!canImport(support)) {
return false;
}
WidgetOption data;
try {
data = (WidgetOption) support.getTransferable().getTransferData(DataFlavor.stringFlavor);
} catch (UnsupportedFlavorException e) {
return false;
} catch (java.io.IOException e) {
return false;
}
Widget widget = data.createWidget();
FormToolBarButton btn = new FormToolBarButton(data.optionIcon(), widget);
btn.setNameOption(data);
FormToolBarPane.this.add(btn);
FormToolBarPane.this.validate();
FormToolBarPane.this.repaint();
return true;
}
}
}

54
designer_form/src/com/fr/design/mainframe/FormWebWidgetConstants.java

@ -0,0 +1,54 @@
package com.fr.design.mainframe;
import com.fr.design.gui.core.WidgetOption;
import com.fr.design.gui.core.WidgetOptionFactory;
import com.fr.form.ui.CustomToolBarButton;
import com.fr.form.web.button.ExcelO;
import com.fr.form.web.button.ExcelP;
import com.fr.form.web.button.Export;
import com.fr.form.web.button.page.*;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
/**
* Created by harry on 2017-3-3.
*/
public class FormWebWidgetConstants {
private FormWebWidgetConstants() {
}
public static WidgetOption[] getFormElementCaseToolBarInstance() {
return new WidgetOption[]{FIRST, PREVIOUS, PAGENAVI, NEXT, LAST, EXPORT, EXCELP, EXCELO, CUSTOM_BUTTON};
}
// 当前页/总页数
public static final WidgetOption PAGENAVI = WidgetOptionFactory.createByWidgetClass(Inter.getLocText(new String[]{"HJS-Current_Page", "HF-Number_of_Page"}, new String[]{"/", ""}),
IOUtils.readIcon("/com/fr/web/images/pageNumber.png"), PageNavi.class);
// 首页
public static final WidgetOption FIRST = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Engine_ReportServerP-First"), IOUtils.readIcon("/com/fr/web/images/first.png"),
First.class);
// 末页
public static final WidgetOption LAST = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Engine_ReportServerP-Last"), IOUtils.readIcon("/com/fr/web/images/last.png"),
Last.class);
// 前一页
public static final WidgetOption PREVIOUS = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Engine_ReportServerP-Previous"),
IOUtils.readIcon("/com/fr/web/images/previous.png"), Previous.class);
// 后一页
public static final WidgetOption NEXT = WidgetOptionFactory.createByWidgetClass(Inter.getLocText("FR-Engine_ReportServerP-Next"), IOUtils.readIcon("/com/fr/web/images/next.png"),
Next.class);
// 导出成Excel 分页导出
public static final WidgetOption EXCELP = WidgetOptionFactory.createByWidgetClass(Inter.getLocText(new String[]{"Excel", "FR-Designer_Export_Excel_Page"}, new String[]{"(", ")"}),
IOUtils.readIcon("/com/fr/web/images/excel.png"), ExcelP.class);
// 导出成Excel 原样导出
public static final WidgetOption EXCELO = WidgetOptionFactory.createByWidgetClass(Inter.getLocText(new String[]{"Excel", "FR-Designer_Export_Excel_Simple"}, new String[]{"(", ")"}),
IOUtils.readIcon("/com/fr/web/images/excel.png"), ExcelO.class);
// 导出
public static final WidgetOption EXPORT = WidgetOptionFactory
.createByWidgetClass(Inter.getLocText("FR-Engine_Export"), IOUtils.readIcon("/com/fr/web/images/export.png"), Export.class);
public static final WidgetOption CUSTOM_BUTTON = WidgetOptionFactory
.createByWidgetClass(Inter.getLocText(new String[]{"Custom", "Form-Button"}), CustomToolBarButton.class);
}

1579
designer_form/src/com/fr/design/mainframe/JForm.java

File diff suppressed because it is too large Load Diff

692
designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java

@ -1,346 +1,348 @@
package com.fr.design.mainframe;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.*;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itable.GroupRenderer;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.*;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.stable.StringUtils;
/**
* MobileWidgetTable类主要显示各种容器的控件列表bodytab绝对布局快不包括参数面板
* Created with IntelliJ IDEA.
* User: zx
* Date: 14-9-15
* Time: 下午4:52
* Modified by fanglei at 2017/01/23
*/
public class MobileWidgetTable extends JTable {
private FormDesigner designer;
private String[][] cellData;
private String[] headers = {Inter.getLocText("Form-Widget_Name")};
private static final int WIDGET_TABLE_ROW_HEIGHT = 22;
private UILabel moveComponent = new UILabel(); // 作为拖动时候随鼠标移动的那个半透明控件
private int selectedRow = -1;
private int GAP = 11;
private boolean draging = false;
private boolean collapsed = false; // 控件列表是否折叠
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
//第一行渲染成为标题的样子
if (row == 0) {
return new GroupRenderer();
}
return super.getCellRenderer(row, column);
}
public MobileWidgetTable(FormDesigner designer) {
this.designer = designer;
cellData = getData();
this.setTableProperties();
TableModel defaultModel = new BeanTableModel();
this.setModel(defaultModel);
this.repaint();
this.setDefaultRenderer(Object.class,new DefaultTableCellRenderer());
refreshData();
this.addMouseListener(mouseAdapter);
this.addMouseMotionListener(mouseAdapter);
add(moveComponent);
}
private void setTableProperties() {
JTableHeader header = getTableHeader();
header.setReorderingAllowed(false);
header.setPreferredSize(new Dimension(0, 0)); // 隐藏表头
GroupRenderer headerRenderer = new GroupRenderer();
headerRenderer.setPreferredSize(new Dimension(0, 0)); //这行代码隐藏表头。因为要实现折叠效果,表头不好监听事件
headerRenderer.setHorizontalAlignment(JLabel.LEFT);
header.setDefaultRenderer(headerRenderer);
this.setRowHeight(WIDGET_TABLE_ROW_HEIGHT);
this.setGridColor(new Color(212, 208, 200));
this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setColumnSelectionAllowed(false);
this.setRowSelectionAllowed(false);
this.setFillsViewportHeight(false);
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}
private MouseAdapter mouseAdapter = new MouseAdapter() {
/**
* 鼠标按下时处理的事件设置当前选中的行列
* @param e
*/
@Override
public void mousePressed(MouseEvent e) {
getInstance().setCellSelected();
if (selectedRow == 0 && !e.isPopupTrigger() && e.getClickCount() == 1 && e.getX() < WIDGET_TABLE_ROW_HEIGHT / 2){ // 如果是点击在第一行
toggleCollapse();
}
}
/**
* 鼠标放开时处理的事件如果是正在拖动则执行换位操作重新绘制属性表如果不是则什么也不做
* 所谓的换行就是简单的重新拿到一次表格数据然后重新绘制表格
* @param e
*/
@Override
public void mouseReleased(MouseEvent e) {
if(!draging){
return;
}
draging = false;
moveComponent.setVisible(false);
int toIndex = e.getY() < GAP ? 0 : (int)Math.rint((e.getY() - GAP)/WIDGET_TABLE_ROW_HEIGHT) + 1;
//当鼠标放开时,将选中的容器调整至新的顺序
((WSortLayout)designer.getSelectionModel().getSelection().getSelectedCreator().toData()).adjustOrder(selectedRow - 1, toIndex - 1);
//拿取排序后表格数据,然后重绘表格
getInstance().refreshData();
getInstance().repaint();
designer.fireTargetModified();
getInstance().setCellSelected();
}
/**
* 设置鼠标在属性表区域移动时候的事件
* @param e
*/
@Override
public void mouseMoved(MouseEvent e) {
int overRow = 0;
for (int i = 0;i < getRowCount();i++) {
if (e.getY() > i * WIDGET_TABLE_ROW_HEIGHT && e.getY() <= (i + 1) * WIDGET_TABLE_ROW_HEIGHT){
overRow = i; //判断鼠标在哪一行
}
}
//如果鼠标移动到当前选中的行上面的时候
if (overRow == selectedRow && selectedRow > 0) {
//把当前选中的那一行的光标改成(除了第一列)移动样式MOVE_CURSOR
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
/**
* 鼠标拖动事件如果鼠标当前是<code>MOVE_CURSOR</code>状态则执行开始拖动的代码
* 绘制一个<code>moveComponent</code>来跟随鼠标移动
* @param e
*/
@Override
public void mouseDragged(MouseEvent e) {
int width = getColumnModel().getColumn(0).getWidth();
//如果当前选中的行的范围是合理的话,就可以拖动
if (selectedRow < getRowCount() && selectedRow > 0){
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
draging = true;
moveComponent.setText(getValueAt(selectedRow,0).toString());
moveComponent.setLocation(0, e.getY() - GAP);
moveComponent.setSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT));
moveComponent.setVisible(true);
moveComponent.setForeground(Color.lightGray);
moveComponent.setBorder(BorderFactory.createLineBorder(Color.lightGray));
}
}
/**
* 设置鼠标单击时处理的事件单击控件列表进入控件属性表
* @param e
*/
@Override
public void mouseClicked(MouseEvent e) {
if(selectedRow > 0){
//当前点击的控件的名字
String widgetName = cellData[selectedRow][0];
if (StringUtils.isNotEmpty(widgetName)){
//当前选择的容器
XCreator selectedContainer = designer.getSelectionModel().getSelection().getSelectedCreator();
WLayout selectedWidget = (WLayout)selectedContainer.toData();
//当前选择的容器中的控件数量
int count = selectedWidget.getWidgetCount();
for (int i = 0;i < count ;i++){
XCreator xCreator = (XCreator) selectedContainer.getComponent(i);
Widget widget = xCreator.toData();
if (ComparatorUtils.equals(widgetName, widget.getWidgetName())) {
getEditingDesigner().getSelectionModel().setSelectedCreator(xCreator);
}
}
}
} else if (selectedRow == 0){ // 如果是点击在第一行
if (!e.isPopupTrigger() && e.getClickCount() > 1) {
toggleCollapse();
}
}
}
/**
* 鼠标离开属性表区域事件
* @param e
*/
public void mouseExited(MouseEvent e) {
draging = false;
moveComponent.setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
};
public MobileWidgetTable getInstance(){
return this;
}
public FormDesigner getEditingDesigner(){
return designer;
}
/**
* 设置当前get到的行列的单元格为选中状态
*/
private void setCellSelected() {
selectedRow = getSelectedRow();
if (selectedRow != -1) {
this.setRowSelectionInterval(selectedRow, selectedRow);
this.setColumnSelectionInterval(0, 0);
}
}
/**
* 切换属性组折叠属性true/false
*/
private void toggleCollapse() {
this.setCollapsed(!this.isCollapsed());
//这里获取表格的父控件是为了当表格被折叠了后,装表格的父控件也要相应的重新布局一下
//比如折叠之后表格行数应该比原来的少,占用父容器空间应该小点,不重新布局父容器,表格大小不会改变
Container parent = MobileWidgetTable.this.getParent();
if (parent != null) {
parent.revalidate();
}
repaint();
}
/**
* 重新get排序后的数据
*/
public void refreshData(){
cellData = getData();
}
/**
* 获取选中控件的控件列表
*
* @return String[][] 二维数组[0][0]widgetName
*/
private String[][] getData(){
if(designer.isFormParaDesigner()){
return new String[0][0];
}
//选择的控件
Widget selectedModel = designer.getSelectionModel().getSelection().getSelectedCreator().toData();
if(selectedModel == null){
return new String[0][0];
}
// 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件
if (selectedModel.acceptType(WSortLayout.class)) {
List<String> mobileWidgetList = ((WSortLayout)selectedModel).getOrderedMobileWidgetList();
String[][] widgetName = new String[mobileWidgetList.size() + 1][1];
widgetName[0][0] = Inter.getLocText("FR-Designer_WidgetOrder");
for (int i = 0; i < mobileWidgetList.size(); i++) {
widgetName[i + 1][0] = mobileWidgetList.get(i);
}
return widgetName;
} else {
return new String[0][0];
}
}
public boolean isCollapsed() {
return collapsed;
}
public void setCollapsed(boolean collapsed) {
this.collapsed = collapsed;
}
/**
* 自定义的tableEditor类
*/
public class BeanTableModel extends DefaultTableModel {
public BeanTableModel() {
super(cellData,headers);
}
@Override
public int getRowCount() {
if (isCollapsed()) {
return 1;
}
return cellData.length;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int row, int column) {
if (row >= getRowCount() || column >= getColumnCount()) {
return null;
}
if (row == 0) {
return (isCollapsed()? "+" : "-") + cellData[row][0];
}
return cellData[row][0];
}
@Override
public String getColumnName(int column) {
return headers[0];
}
@Override
public void setValueAt(Object aValue, int row, int column) {
if (row >= getRowCount() || column >= getColumnCount()) {
return;
}
if (aValue == null) {
cellData[row] = null;
return;
}
cellData[row][0] = aValue.toString();
}
/**
* 是否可编辑
* @param row 行号
* @param column 列号
* @return 是否可编辑
*/
public boolean isCellEditable(int row, int column) {
return false;
}
}
package com.fr.design.mainframe;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.*;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itable.GroupRenderer;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.*;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.stable.StringUtils;
/**
* MobileWidgetTable类主要显示各种容器的控件列表bodytab绝对布局快不包括参数面板
* Created with IntelliJ IDEA.
* User: zx
* Date: 14-9-15
* Time: 下午4:52
* Modified by fanglei at 2017/01/23
*/
public class MobileWidgetTable extends JTable {
private FormDesigner designer;
private String[][] cellData;
private String[] headers = {Inter.getLocText("Form-Widget_Name")};
private static final int WIDGET_TABLE_ROW_HEIGHT = 22;
private UILabel moveComponent = new UILabel(); // 作为拖动时候随鼠标移动的那个半透明控件
private int selectedRow = -1;
private static final int GAP = 11;
private boolean draging = false;
private boolean collapsed = false; // 控件列表是否折叠
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
//第一行渲染成为标题的样子
if (row == 0) {
return new GroupRenderer();
}
return super.getCellRenderer(row, column);
}
public MobileWidgetTable(FormDesigner designer) {
this.designer = designer;
cellData = getData();
this.setTableProperties();
TableModel defaultModel = new BeanTableModel();
this.setModel(defaultModel);
this.repaint();
this.setDefaultRenderer(Object.class, new DefaultTableCellRenderer());
refreshData();
this.addMouseListener(mouseAdapter);
this.addMouseMotionListener(mouseAdapter);
add(moveComponent);
}
private void setTableProperties() {
JTableHeader header = getTableHeader();
header.setReorderingAllowed(false);
header.setPreferredSize(new Dimension(0, 0)); // 隐藏表头
GroupRenderer headerRenderer = new GroupRenderer();
headerRenderer.setPreferredSize(new Dimension(0, 0)); //这行代码隐藏表头。因为要实现折叠效果,表头不好监听事件
headerRenderer.setHorizontalAlignment(JLabel.LEFT);
header.setDefaultRenderer(headerRenderer);
this.setRowHeight(WIDGET_TABLE_ROW_HEIGHT);
this.setGridColor(new Color(212, 208, 200));
this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setColumnSelectionAllowed(false);
this.setRowSelectionAllowed(false);
this.setFillsViewportHeight(false);
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}
private MouseAdapter mouseAdapter = new MouseAdapter() {
/**
* 鼠标按下时处理的事件设置当前选中的行列
* @param e
*/
@Override
public void mousePressed(MouseEvent e) {
getInstance().setCellSelected();
if (selectedRow == 0 && !e.isPopupTrigger() && e.getClickCount() == 1 && e.getX() < WIDGET_TABLE_ROW_HEIGHT / 2) { // 如果是点击在第一行
toggleCollapse();
}
}
/**
* 鼠标放开时处理的事件如果是正在拖动则执行换位操作重新绘制属性表如果不是则什么也不做
* 所谓的换行就是简单的重新拿到一次表格数据然后重新绘制表格
* @param e
*/
@Override
public void mouseReleased(MouseEvent e) {
if (!draging) {
return;
}
draging = false;
moveComponent.setVisible(false);
int toIndex = e.getY() < GAP ? 0 : (int) Math.rint((e.getY() - GAP) / WIDGET_TABLE_ROW_HEIGHT) + 1;
//当鼠标放开时,将选中的容器调整至新的顺序
((WSortLayout) designer.getSelectionModel().getSelection().getSelectedCreator().toData()).adjustOrder(selectedRow - 1, toIndex - 1);
//拿取排序后表格数据,然后重绘表格
getInstance().refreshData();
getInstance().repaint();
designer.fireTargetModified();
getInstance().setCellSelected();
}
/**
* 设置鼠标在属性表区域移动时候的事件
* @param e
*/
@Override
public void mouseMoved(MouseEvent e) {
int overRow = 0;
for (int i = 0; i < getRowCount(); i++) {
if (e.getY() > i * WIDGET_TABLE_ROW_HEIGHT && e.getY() <= (i + 1) * WIDGET_TABLE_ROW_HEIGHT) {
overRow = i; //判断鼠标在哪一行
}
}
//如果鼠标移动到当前选中的行上面的时候
if (overRow == selectedRow && selectedRow > 0) {
//把当前选中的那一行的光标改成(除了第一列)移动样式MOVE_CURSOR
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
/**
* 鼠标拖动事件如果鼠标当前是<code>MOVE_CURSOR</code>状态则执行开始拖动的代码
* 绘制一个<code>moveComponent</code>来跟随鼠标移动
* @param e
*/
@Override
public void mouseDragged(MouseEvent e) {
int width = getColumnModel().getColumn(0).getWidth();
//如果当前选中的行的范围是合理的话,就可以拖动
if (selectedRow < getRowCount() && selectedRow > 0) {
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
draging = true;
moveComponent.setText(getValueAt(selectedRow, 0).toString());
moveComponent.setLocation(0, e.getY() - GAP);
moveComponent.setSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT));
moveComponent.setVisible(true);
moveComponent.setForeground(Color.lightGray);
moveComponent.setBorder(BorderFactory.createLineBorder(Color.lightGray));
}
}
/**
* 设置鼠标单击时处理的事件单击控件列表进入控件属性表
* @param e
*/
@Override
public void mouseClicked(MouseEvent e) {
if (selectedRow > 0) {
//当前点击的控件的名字
String widgetName = cellData[selectedRow][0];
if (StringUtils.isNotEmpty(widgetName)) {
//当前选择的容器
XCreator selectedContainer = designer.getSelectionModel().getSelection().getSelectedCreator();
WLayout selectedWidget = (WLayout) selectedContainer.toData();
//当前选择的容器中的控件数量
int count = selectedWidget.getWidgetCount();
for (int i = 0; i < count; i++) {
XCreator xCreator = (XCreator) selectedContainer.getComponent(i);
Widget widget = xCreator.toData();
if (ComparatorUtils.equals(widgetName, widget.getWidgetName())) {
getEditingDesigner().getSelectionModel().setSelectedCreator(xCreator);
}
}
}
} else if (selectedRow == 0) { // 如果是点击在第一行
if (!e.isPopupTrigger() && e.getClickCount() > 1) {
toggleCollapse();
}
}
}
/**
* 鼠标离开属性表区域事件
* @param e
*/
public void mouseExited(MouseEvent e) {
draging = false;
moveComponent.setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
};
public MobileWidgetTable getInstance() {
return this;
}
public FormDesigner getEditingDesigner() {
return designer;
}
/**
* 设置当前get到的行列的单元格为选中状态
*/
private void setCellSelected() {
selectedRow = getSelectedRow();
if (selectedRow != -1) {
this.setRowSelectionInterval(selectedRow, selectedRow);
this.setColumnSelectionInterval(0, 0);
}
}
/**
* 切换属性组折叠属性true/false
*/
private void toggleCollapse() {
this.setCollapsed(!this.isCollapsed());
//这里获取表格的父控件是为了当表格被折叠了后,装表格的父控件也要相应的重新布局一下
//比如折叠之后表格行数应该比原来的少,占用父容器空间应该小点,不重新布局父容器,表格大小不会改变
Container parent = MobileWidgetTable.this.getParent();
if (parent != null) {
parent.revalidate();
}
repaint();
}
/**
* 重新get排序后的数据
*/
public void refreshData() {
cellData = getData();
}
/**
* 获取选中控件的控件列表
*
* @return String[][] 二维数组[0][0]widgetName
*/
private String[][] getData() {
if (designer.isFormParaDesigner()) {
return new String[0][0];
}
//选择的控件
XCreator selectedCreator = designer.getSelectionModel().getSelection().getSelectedCreator();
Widget selectedModel = selectedCreator != null ? selectedCreator.toData() : null;
if (selectedModel == null) {
return new String[0][0];
}
// 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件
if (selectedModel.acceptType(WSortLayout.class)) {
List<String> mobileWidgetList = ((WSortLayout) selectedModel).getOrderedMobileWidgetList();
String[][] widgetName = new String[mobileWidgetList.size() + 1][1];
widgetName[0][0] = Inter.getLocText("FR-Designer_WidgetOrder");
for (int i = 0; i < mobileWidgetList.size(); i++) {
widgetName[i + 1][0] = mobileWidgetList.get(i);
}
return widgetName;
} else {
return new String[0][0];
}
}
public boolean isCollapsed() {
return collapsed;
}
public void setCollapsed(boolean collapsed) {
this.collapsed = collapsed;
}
/**
* 自定义的tableEditor类
*/
public class BeanTableModel extends DefaultTableModel {
public BeanTableModel() {
super(cellData, headers);
}
@Override
public int getRowCount() {
if (isCollapsed()) {
return 1;
}
return cellData.length;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int row, int column) {
if (row >= getRowCount() || column >= getColumnCount()) {
return null;
}
if (row == 0) {
return (isCollapsed() ? "+" : "-") + cellData[row][0];
}
return cellData[row][0];
}
@Override
public String getColumnName(int column) {
return headers[0];
}
@Override
public void setValueAt(Object aValue, int row, int column) {
if (row >= getRowCount() || column >= getColumnCount()) {
return;
}
if (aValue == null) {
cellData[row] = null;
return;
}
cellData[row][0] = aValue.toString();
}
/**
* 是否可编辑
*
* @param row 行号
* @param column 列号
* @return 是否可编辑
*/
public boolean isCellEditable(int row, int column) {
return false;
}
}
}

736
designer_form/src/com/fr/design/mainframe/WidgetPropertyPane.java

@ -1,366 +1,372 @@
package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.designer.beans.events.DesignerEditListener;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.properties.EventPropertyTable;
import com.fr.design.designer.properties.WidgetPropertyTable;
import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.itable.AbstractPropertyTable;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.form.ui.Widget;
import com.fr.general.Inter;
import com.fr.stable.ArrayUtils;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.table.JTableHeader;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 控件属性表绘制
* Modified by fanglei
*/
public class WidgetPropertyPane extends FormDockView implements BaseWidgetPropertyPane {
private static final String PARA = "para";
private static final String BODY = "body";
private WidgetPropertyTable propertyTable; // 控件的属性表
private EventPropertyTable eventTable; // 控件的事件表
private List<AbstractPropertyTable> widgetPropertyTables; // 这个变量应该是保存控件拓展的属性tab
private FormDesigner designer; // 当前designer
private UIScrollPane psp; // 用来装载属性表table的容器
private UIScrollPane esp; //用来装载事件table的容器
private JPanel wsp; // 装载移动端tab的容器,包括移动端属性表和控件拓展的移动端属性表
private MobileParaWidgetTable mobileParaWidgetTable; // 参数面板的移动端属性tab(和body的移动端属性tab区别是没有标签名column)
private MobileWidgetTable mobileWidgetTable; // body的移动端属性tab
private UIScrollPane downPanel; // 这个滚动容器是用于装载centerPane的
private JPanel centerPane; // 此centerPane采用的是cardLayout布局,装载着mobileWidgetTable和mobileBodyWidgetTable
private CardLayout cardLayout; // 卡片布局,选中参数面板时显示mobileWidgetTable,选中body时显示mobileBodyWidgetTable
private JTableHeader header;//把表头单独get出来作为一个组件
public static WidgetPropertyPane getInstance() {
if (HOLDER.singleton == null) {
HOLDER.singleton = new WidgetPropertyPane();
}
return HOLDER.singleton;
}
public static WidgetPropertyPane getInstance(FormDesigner formEditor) {
HOLDER.singleton.setEditingFormDesigner(formEditor);
HOLDER.singleton.refreshDockingView();
return HOLDER.singleton;
}
private static class HOLDER {
private static WidgetPropertyPane singleton = new WidgetPropertyPane();
}
private WidgetPropertyPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
}
@Override
public String getViewTitle() {
return Inter.getLocText("Form-Widget_Property_Table");
}
@Override
public Icon getViewIcon() {
return BaseUtils.readIcon("/com/fr/design/images/m_report/attributes.png");
}
@Override
/**
* 绘制属性表tab
*/
public void refreshDockingView() {
designer = this.getEditingFormDesigner();
removeAll();
if (designer == null) {
clearDockingView();
return;
}
widgetPropertyTables = new ArrayList<AbstractPropertyTable>();
//依次创建属性表、事件表、移动端表,再将它们整合到TabPane中去
this.createPropertyTable();
this.createEventTable();
this.createMobileWidgetTable();
this.createTabPane();
this.initTables();
}
/**
* 初始化属性表事件表移动端拓展的属性表
*/
private void initTables() {
propertyTable.initPropertyGroups(null);
eventTable.refresh();
for (AbstractPropertyTable propertyTable : widgetPropertyTables) {
propertyTable.initPropertyGroups(designer);
}
}
/**
* 创建属性表table
*/
private void createPropertyTable() {
propertyTable = new WidgetPropertyTable(designer);
designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable));
propertyTable.setBorder(null);
psp = new UIScrollPane(propertyTable); // 用来装载属性表table
psp.setBorder(null);
}
/**
* 创建事件表事件选项卡不是JTable
*/
private void createEventTable() {
eventTable = new EventPropertyTable(designer);
designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable));
eventTable.setBorder(null);
esp = new UIScrollPane(eventTable); //用来装载事件table
esp.setBorder(null);
}
/**
* 创建移动端控件列表
*/
private void createMobileWidgetTable() {
//加上表头后,这里不再使用borderLayout布局,而采用BoxLayout布局
wsp = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
wsp.setBorder(null);
mobileParaWidgetTable = new MobileParaWidgetTable(designer);
mobileWidgetTable = new MobileWidgetTable(designer);
designer.addDesignerEditListener(new mobileWidgetDesignerAdapter());
centerPane = FRGUIPaneFactory.createCardLayout_S_Pane();
cardLayout = (CardLayout) centerPane.getLayout();
centerPane.add(mobileParaWidgetTable, PARA);// 采用卡片布局的容器必须指定卡片名字,如果没有卡片名字
// 就会出现:Exception in thread "main" java.lang.IllegalArgumentException:
// cannot add to layout: constraint must be a string
// 第二个参数代表卡片的名字。后来show方法调用时通过名字找到要显示的卡片
centerPane.add(mobileWidgetTable, BODY); //这两句代码,是把JTable放到一个JPanel中去了,表头不会显示,
//只有放到JScrollPanel中去表头才能正常显示,这就是MobileWidgetTable中定义了表头却没有显示的原因!
//解决方案:MobileWidgetTable实在无法直接放到JScrollPanel中去的时候,应该把表头get出来单独作为一个组件显示
if(hasSelectParaPane(designer)){
cardLayout.show(centerPane,PARA);
header = mobileParaWidgetTable.getTableHeader();
} else {
cardLayout.show(centerPane,BODY);
header = mobileWidgetTable.getTableHeader();
}
downPanel = new UIScrollPane(centerPane);
downPanel.setBorder(new LineBorder(Color.GRAY));
//获取拓展移动端属性tab
WidgetPropertyUIProvider[] widgetAttrProviders = getExtraPropertyUIProviders();
addWidgetAttr(widgetAttrProviders);
}
/**
* 将属性表事件表移动端控件列表整合到TabPane里面去
*/
private void createTabPane() {
UITabbedPane tabbedPane = new UITabbedPane(); // tab选项卡容器
initTabPane(tabbedPane);
add(tabbedPane, BorderLayout.CENTER);
}
/**
* 获取当前控件扩展的属性tab
* 来源有两个:
* 1, 各个控件从各自的Xcreator里扩展例如手机重布局的tab就是从Xcreator中扩展的;
* 2, 所有的控件从插件里扩展.
*
* @return 扩展的tab
*/
private WidgetPropertyUIProvider[] getExtraPropertyUIProviders() {
FormSelection selection = designer.getSelectionModel().getSelection();
WidgetPropertyUIProvider[] embeddedPropertyUIProviders = null;
if (selection != null && selection.getSelectedCreator() != null) {
embeddedPropertyUIProviders = selection.getSelectedCreator().getWidgetPropertyUIProviders();
}
Set<WidgetPropertyUIProvider> set = ExtraDesignClassManager.getInstance().getArray(WidgetPropertyUIProvider.XML_TAG);
return ArrayUtils.addAll(embeddedPropertyUIProviders, set.toArray(new WidgetPropertyUIProvider[set.size()]));
}
/**
* 判断是将拓展的tab放入属性表还是将原来的tab放入属性表
* @param widgetAttrProviders 拓展的tab
*/
private void addWidgetAttr(WidgetPropertyUIProvider[] widgetAttrProviders) {
if (widgetAttrProviders.length == 0) { // 判断有没有拓展的tab,没有就使用原来的
wsp.add(header);
wsp.add(downPanel);
} else {
for (WidgetPropertyUIProvider widgetAttrProvider : widgetAttrProviders) {
AbstractPropertyTable propertyTable = widgetAttrProvider.createWidgetAttrTable();
widgetPropertyTables.add(propertyTable);
designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable));
UIScrollPane uiScrollPane = new UIScrollPane(getExtraBodyTable(propertyTable));
wsp.add(uiScrollPane);
}
}
}
/**
* 如果是body的拓展属性表那么要额外加上一张控件顺序表
* @return
*/
private Component getExtraBodyTable(AbstractPropertyTable abstractPropertyTable) {
Widget selection = designer.getSelectionModel().getSelection().getSelectedCreator().toData();
if (selection.getWidgetName().equals("body")) {
JPanel jPanel = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
jPanel.add(abstractPropertyTable);
MobileWidgetTable mobileWidgetTable = new MobileWidgetTable(designer);
jPanel.add(mobileWidgetTable.getTableHeader());
jPanel.add(mobileWidgetTable);
return jPanel;
}
return abstractPropertyTable;
}
private void initTabPane(UITabbedPane tabbedPane) {
tabbedPane.setOpaque(true);
tabbedPane.setBorder(null);
tabbedPane.setTabPlacement(SwingConstants.BOTTOM);
tabbedPane.addTab(Inter.getLocText("FR-Designer_Properties"), psp);
tabbedPane.addTab(Inter.getLocText("FR-Designer_Event"), esp);
tabbedPane.addTab(Inter.getLocText("FR-Widget_Mobile_Terminal"), wsp);
}
//
/**
* 选中的组件是否在参数面板里
* @param designer 设计器
* @return 是则返回true
*/
public boolean hasSelectParaPane(FormDesigner designer){
XCreator xCreator = designer.getSelectionModel().getSelection().getSelectedCreator();
if(xCreator == null){
xCreator = designer.getRootComponent();
}
XLayoutContainer container = XCreatorUtils.getHotspotContainer(xCreator);
return xCreator.acceptType(XWParameterLayout.class) || container.acceptType(XWParameterLayout.class);
}
public void setEditingFormDesigner(BaseFormDesigner editor) {
FormDesigner fd = (FormDesigner) editor;
super.setEditingFormDesigner(fd);
}
private void clearDockingView() {
propertyTable = null;
eventTable = null;
if (widgetPropertyTables != null) {
widgetPropertyTables.clear();
}
JScrollPane psp = new JScrollPane();
psp.setBorder(null);
this.add(psp, BorderLayout.CENTER);
}
/**
* 属性表监听界面事件(编辑删除选中改变大小)
*/
private class WidgetPropertyDesignerAdapter implements DesignerEditListener {
AbstractPropertyTable propertyTable;
WidgetPropertyDesignerAdapter(AbstractPropertyTable propertyTable) {
this.propertyTable = propertyTable;
}
@Override
public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_DELETED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) {
propertyTable.initPropertyGroups(designer);
} else if (evt.getCreatorEventID() == DesignerEvent.CREATOR_RESIZED) {
repaint();
}
}
@Override
public boolean equals(Object o) {
return o instanceof WidgetPropertyDesignerAdapter && ((WidgetPropertyDesignerAdapter) o).propertyTable == this.propertyTable;
}
}
/**
* 事件表监听界面事件编辑选中
*/
private class EventPropertyDesignerAdapter implements DesignerEditListener {
EventPropertyTable propertyTable;
EventPropertyDesignerAdapter(EventPropertyTable eventTable) {
this.propertyTable = eventTable;
}
@Override
public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) {
propertyTable.refresh();
}
}
@Override
public boolean equals(Object o) {
return o instanceof EventPropertyDesignerAdapter;
}
}
/**
* 移动端属性表监听界面事件改变大小编辑选中增加控件
*/
private class mobileWidgetDesignerAdapter implements DesignerEditListener {
mobileWidgetDesignerAdapter() {
}
/**
* 响应界面改变事件
* @param evt 事件
*/
public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_RESIZED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_ADDED) {
int value = downPanel.getVerticalScrollBar().getValue();
if(hasSelectParaPane(getEditingFormDesigner())){
cardLayout.show(centerPane,PARA);
mobileParaWidgetTable.refreshData();
} else {
cardLayout.show(centerPane,BODY);
mobileWidgetTable.refreshData();
}
//出现滚动条
downPanel.doLayout();
//控件列表选中某组件,触发表单中选中控件,选中事件又触发列表刷新,滚动条回到0
//此处设置滚动条值为刷新前
downPanel.getVerticalScrollBar().setValue(value);
}
}
}
@Override
public Location preferredLocation() {
return Location.WEST_BELOW;
}
package com.fr.design.mainframe;
import com.fr.base.BaseUtils;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.designer.beans.events.DesignerEditListener;
import com.fr.design.designer.beans.events.DesignerEvent;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XCreatorUtils;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.design.designer.properties.EventPropertyTable;
import com.fr.design.designer.properties.WidgetPropertyTable;
import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.icontainer.UIScrollPane;
import com.fr.design.gui.itable.AbstractPropertyTable;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.form.ui.Widget;
import com.fr.general.Inter;
import com.fr.stable.ArrayUtils;
import javax.swing.*;
import javax.swing.border.LineBorder;
import javax.swing.table.JTableHeader;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
* 控件属性表绘制
* Modified by fanglei
*/
public class WidgetPropertyPane extends FormDockView implements BaseWidgetPropertyPane {
private static final String PARA = "para";
private static final String BODY = "body";
private WidgetPropertyTable propertyTable; // 控件的属性表
private EventPropertyTable eventTable; // 控件的事件表
private List<AbstractPropertyTable> widgetPropertyTables; // 这个变量应该是保存控件拓展的属性tab
private FormDesigner designer; // 当前designer
private UIScrollPane psp; // 用来装载属性表table的容器
private UIScrollPane esp; //用来装载事件table的容器
private JPanel wsp; // 装载移动端tab的容器,包括移动端属性表和控件拓展的移动端属性表
private MobileParaWidgetTable mobileParaWidgetTable; // 参数面板的移动端属性tab(和body的移动端属性tab区别是没有标签名column)
private MobileWidgetTable mobileWidgetTable; // body的移动端属性tab
private UIScrollPane downPanel; // 这个滚动容器是用于装载centerPane的
private JPanel centerPane; // 此centerPane采用的是cardLayout布局,装载着mobileWidgetTable和mobileBodyWidgetTable
private CardLayout cardLayout; // 卡片布局,选中参数面板时显示mobileWidgetTable,选中body时显示mobileBodyWidgetTable
private JTableHeader header;//把表头单独get出来作为一个组件
public static WidgetPropertyPane getInstance() {
if (HOLDER.singleton == null) {
HOLDER.singleton = new WidgetPropertyPane();
}
return HOLDER.singleton;
}
public static WidgetPropertyPane getInstance(FormDesigner formEditor) {
HOLDER.singleton.setEditingFormDesigner(formEditor);
HOLDER.singleton.refreshDockingView();
return HOLDER.singleton;
}
private static class HOLDER {
private static WidgetPropertyPane singleton = new WidgetPropertyPane();
}
private WidgetPropertyPane() {
setLayout(FRGUIPaneFactory.createBorderLayout());
}
@Override
public String getViewTitle() {
return Inter.getLocText("Form-Widget_Property_Table");
}
@Override
public Icon getViewIcon() {
return BaseUtils.readIcon("/com/fr/design/images/m_report/attributes.png");
}
@Override
/**
* 绘制属性表tab
*/
public void refreshDockingView() {
designer = this.getEditingFormDesigner();
removeAll();
if (designer == null) {
clearDockingView();
return;
}
widgetPropertyTables = new ArrayList<AbstractPropertyTable>();
//依次创建属性表、事件表、移动端表,再将它们整合到TabPane中去
this.createPropertyTable();
this.createEventTable();
this.createMobileWidgetTable();
this.createTabPane();
this.initTables();
}
/**
* 初始化属性表事件表移动端拓展的属性表
*/
private void initTables() {
propertyTable.initPropertyGroups(null);
eventTable.refresh();
for (AbstractPropertyTable propertyTable : widgetPropertyTables) {
propertyTable.initPropertyGroups(designer);
}
}
/**
* 创建属性表table
*/
private void createPropertyTable() {
propertyTable = new WidgetPropertyTable(designer);
designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable));
propertyTable.setBorder(null);
psp = new UIScrollPane(propertyTable); // 用来装载属性表table
psp.setBorder(null);
}
/**
* 创建事件表事件选项卡不是JTable
*/
private void createEventTable() {
eventTable = new EventPropertyTable(designer);
designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable));
eventTable.setBorder(null);
esp = new UIScrollPane(eventTable); //用来装载事件table
esp.setBorder(null);
}
/**
* 创建移动端控件列表
*/
private void createMobileWidgetTable() {
//加上表头后,这里不再使用borderLayout布局,而采用BoxLayout布局
wsp = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
wsp.setBorder(null);
mobileParaWidgetTable = new MobileParaWidgetTable(designer);
mobileWidgetTable = new MobileWidgetTable(designer);
designer.addDesignerEditListener(new mobileWidgetDesignerAdapter());
centerPane = FRGUIPaneFactory.createCardLayout_S_Pane();
cardLayout = (CardLayout) centerPane.getLayout();
centerPane.add(mobileParaWidgetTable, PARA);
// 采用卡片布局的容器必须指定卡片名字,如果没有卡片名字
// 就会出现:Exception in thread "main" java.lang.IllegalArgumentException:
// cannot add to layout: constraint must be a string
// 第二个参数代表卡片的名字。后来show方法调用时通过名字找到要显示的卡片
centerPane.add(mobileWidgetTable, BODY); //这两句代码,是把JTable放到一个JPanel中去了,表头不会显示,
//只有放到JScrollPanel中去表头才能正常显示,这就是MobileWidgetTable中定义了表头却没有显示的原因!
//解决方案:MobileWidgetTable实在无法直接放到JScrollPanel中去的时候,应该把表头get出来单独作为一个组件显示
if (hasSelectParaPane(designer)) {
cardLayout.show(centerPane, PARA);
header = mobileParaWidgetTable.getTableHeader();
} else {
cardLayout.show(centerPane, BODY);
header = mobileWidgetTable.getTableHeader();
}
downPanel = new UIScrollPane(centerPane);
downPanel.setBorder(new LineBorder(Color.GRAY));
//获取拓展移动端属性tab
WidgetPropertyUIProvider[] widgetAttrProviders = getExtraPropertyUIProviders();
addWidgetAttr(widgetAttrProviders);
}
/**
* 将属性表事件表移动端控件列表整合到TabPane里面去
*/
private void createTabPane() {
UITabbedPane tabbedPane = new UITabbedPane(); // tab选项卡容器
initTabPane(tabbedPane);
add(tabbedPane, BorderLayout.CENTER);
}
/**
* 获取当前控件扩展的属性tab
* 来源有两个:
* 1, 各个控件从各自的Xcreator里扩展例如手机重布局的tab就是从Xcreator中扩展的;
* 2, 所有的控件从插件里扩展.
*
* @return 扩展的tab
*/
private WidgetPropertyUIProvider[] getExtraPropertyUIProviders() {
FormSelection selection = designer.getSelectionModel().getSelection();
WidgetPropertyUIProvider[] embeddedPropertyUIProviders = null;
if (selection != null && selection.getSelectedCreator() != null) {
embeddedPropertyUIProviders = selection.getSelectedCreator().getWidgetPropertyUIProviders();
}
Set<WidgetPropertyUIProvider> set = ExtraDesignClassManager.getInstance().getArray(WidgetPropertyUIProvider.XML_TAG);
return ArrayUtils.addAll(embeddedPropertyUIProviders, set.toArray(new WidgetPropertyUIProvider[set.size()]));
}
/**
* 判断是将拓展的tab放入属性表还是将原来的tab放入属性表
*
* @param widgetAttrProviders 拓展的tab
*/
private void addWidgetAttr(WidgetPropertyUIProvider[] widgetAttrProviders) {
if (widgetAttrProviders.length == 0) { // 判断有没有拓展的tab,没有就使用原来的
wsp.add(header);
wsp.add(downPanel);
} else {
for (WidgetPropertyUIProvider widgetAttrProvider : widgetAttrProviders) {
AbstractPropertyTable propertyTable = widgetAttrProvider.createWidgetAttrTable();
widgetPropertyTables.add(propertyTable);
designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable));
UIScrollPane uiScrollPane = new UIScrollPane(getExtraBodyTable(propertyTable));
wsp.add(uiScrollPane);
}
}
}
/**
* 如果是body的拓展属性表那么要额外加上一张控件顺序表
*
* @return
*/
private Component getExtraBodyTable(AbstractPropertyTable abstractPropertyTable) {
Widget selection = designer.getSelectionModel().getSelection().getSelectedCreator().toData();
if (selection.getWidgetName().equals("body")) {
JPanel jPanel = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
jPanel.add(abstractPropertyTable);
MobileWidgetTable mobileWidgetTable = new MobileWidgetTable(designer);
jPanel.add(mobileWidgetTable.getTableHeader());
jPanel.add(mobileWidgetTable);
return jPanel;
}
return abstractPropertyTable;
}
private void initTabPane(UITabbedPane tabbedPane) {
tabbedPane.setOpaque(true);
tabbedPane.setBorder(null);
tabbedPane.setTabPlacement(SwingConstants.BOTTOM);
tabbedPane.addTab(Inter.getLocText("FR-Designer_Properties"), psp);
tabbedPane.addTab(Inter.getLocText("FR-Designer_Event"), esp);
tabbedPane.addTab(Inter.getLocText("FR-Widget_Mobile_Terminal"), wsp);
}
/**
* 选中的组件是否在参数面板里
*
* @param designer 设计器
* @return 是则返回true
*/
public boolean hasSelectParaPane(FormDesigner designer) {
XCreator xCreator = designer.getSelectionModel().getSelection().getSelectedCreator();
if (xCreator == null) {
xCreator = designer.getRootComponent();
}
XLayoutContainer container = XCreatorUtils.getHotspotContainer(xCreator);
//TODO container可能为空,引发空指针异常
return xCreator.acceptType(XWParameterLayout.class) || container.acceptType(XWParameterLayout.class);
}
public void setEditingFormDesigner(BaseFormDesigner editor) {
FormDesigner fd = (FormDesigner) editor;
super.setEditingFormDesigner(fd);
}
private void clearDockingView() {
propertyTable = null;
eventTable = null;
if (widgetPropertyTables != null) {
widgetPropertyTables.clear();
}
JScrollPane psp = new JScrollPane();
psp.setBorder(null);
this.add(psp, BorderLayout.CENTER);
}
/**
* 属性表监听界面事件(编辑删除选中改变大小)
*/
private class WidgetPropertyDesignerAdapter implements DesignerEditListener {
AbstractPropertyTable propertyTable;
WidgetPropertyDesignerAdapter(AbstractPropertyTable propertyTable) {
this.propertyTable = propertyTable;
}
@Override
public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_DELETED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) {
propertyTable.initPropertyGroups(designer);
} else if (evt.getCreatorEventID() == DesignerEvent.CREATOR_RESIZED) {
repaint();
}
}
@Override
public boolean equals(Object o) {
return o instanceof WidgetPropertyDesignerAdapter && ((WidgetPropertyDesignerAdapter) o).propertyTable == this.propertyTable;
}
}
/**
* 事件表监听界面事件编辑选中
*/
private class EventPropertyDesignerAdapter implements DesignerEditListener {
EventPropertyTable propertyTable;
EventPropertyDesignerAdapter(EventPropertyTable eventTable) {
this.propertyTable = eventTable;
}
@Override
public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) {
propertyTable.refresh();
}
}
@Override
public boolean equals(Object o) {
return o instanceof EventPropertyDesignerAdapter;
}
}
/**
* 移动端属性表监听界面事件改变大小编辑选中增加控件
*/
private class mobileWidgetDesignerAdapter implements DesignerEditListener {
mobileWidgetDesignerAdapter() {
}
/**
* 响应界面改变事件
*
* @param evt 事件
*/
public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_RESIZED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_ADDED) {
int value = downPanel.getVerticalScrollBar().getValue();
if (hasSelectParaPane(getEditingFormDesigner())) {
cardLayout.show(centerPane, PARA);
mobileParaWidgetTable.refreshData();
} else {
cardLayout.show(centerPane, BODY);
mobileWidgetTable.refreshData();
}
//出现滚动条
downPanel.doLayout();
//控件列表选中某组件,触发表单中选中控件,选中事件又触发列表刷新,滚动条回到0
//此处设置滚动条值为刷新前
downPanel.getVerticalScrollBar().setValue(value);
}
}
}
@Override
public Location preferredLocation() {
return Location.WEST_BELOW;
}
}

42
designer_form/src/com/fr/design/mainframe/templateinfo/JFormProcessInfo.java

@ -0,0 +1,42 @@
package com.fr.design.mainframe.templateinfo;
import com.fr.form.main.Form;
import com.fr.form.ui.container.WLayout;
/**
* Created by plough on 2017/3/17.
*/
public class JFormProcessInfo extends TemplateProcessInfo<Form> {
public JFormProcessInfo(Form form) {
super(form);
}
// 获取模板类型
public int getReportType() {
return 2;
}
// 获取模板格子数
public int getCellCount() {
return 0;
}
// 获取模板悬浮元素个数
public int getFloatCount() {
return 0;
}
// 获取模板聚合块个数
public int getBlockCount() {
return 0;
}
// 获取模板控件数
public int getWidgetCount() {
int widgetCount = 0;
for (int i = 0; i < template.getContainer().getWidgetCount(); i++) {
WLayout wl = (WLayout) template.getContainer().getWidget(i);
widgetCount += wl.getWidgetCount();
}
int a = 1;
int b = 2;
return widgetCount;
}
}

57
designer_form/src/com/fr/design/mainframe/widget/accessibles/AccessibleElementCaseToolBarEditor.java

@ -0,0 +1,57 @@
package com.fr.design.mainframe.widget.accessibles;
import com.fr.design.dialog.BasicDialog;
import com.fr.design.dialog.DialogActionAdapter;
import com.fr.design.gui.core.WidgetOption;
import com.fr.design.mainframe.FormWebWidgetConstants;
import com.fr.design.mainframe.widget.editors.ElementCaseToolBarPane;
import com.fr.design.mainframe.widget.wrappers.ElementCaseToolBarWrapper;
import com.fr.form.web.FormToolBarManager;
import com.fr.stable.ArrayUtils;
import javax.swing.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* Created by harry on 2017-2-23.
*/
public class AccessibleElementCaseToolBarEditor extends UneditableAccessibleEditor {
private ElementCaseToolBarPane pane;
public AccessibleElementCaseToolBarEditor() {
super(new ElementCaseToolBarWrapper());
}
@Override
protected void showEditorPane() {
if (pane == null) {
pane = new ElementCaseToolBarPane();
pane.setDefaultToolBar(getDefaultToolBarManager(), getToolBarInstance());
}
BasicDialog dlg = pane.showToolBarWindow(SwingUtilities.getWindowAncestor(this), new DialogActionAdapter() {
@Override
public void doOk() {
setValue(pane.updateBean());
fireStateChanged();
}
});
FormToolBarManager[] managers = (FormToolBarManager[]) getValue();
pane.setCheckBoxSelected(ArrayUtils.isNotEmpty(managers));
pane.populateBean((FormToolBarManager[]) getValue());
dlg.setVisible(true);
}
private FormToolBarManager getDefaultToolBarManager() {
return FormToolBarManager.createDefaultToolBar();
}
private WidgetOption[] getToolBarInstance() {
List<WidgetOption> defaultOptions = Arrays.asList(FormWebWidgetConstants.getFormElementCaseToolBarInstance());
List<WidgetOption> options = new ArrayList<WidgetOption>();
options.addAll(defaultOptions);
return options.toArray(new WidgetOption[options.size()]);
}
}

13
designer_form/src/com/fr/design/mainframe/widget/editors/ElementCaseToolBarEditor.java

@ -0,0 +1,13 @@
package com.fr.design.mainframe.widget.editors;
import com.fr.design.mainframe.widget.accessibles.AccessibleElementCaseToolBarEditor;
import com.fr.design.mainframe.widget.accessibles.AccessiblePropertyEditor;
/**
* Created by harry on 2017-2-23.
*/
public class ElementCaseToolBarEditor extends AccessiblePropertyEditor {
public ElementCaseToolBarEditor() {
super(new AccessibleElementCaseToolBarEditor());
}
}

304
designer_form/src/com/fr/design/mainframe/widget/editors/ElementCaseToolBarPane.java

@ -0,0 +1,304 @@
package com.fr.design.mainframe.widget.editors;
import com.fr.design.beans.BasicBeanPane;
import com.fr.design.gui.core.WidgetOption;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.FormSettingToolBar;
import com.fr.design.mainframe.FormToolBarButton;
import com.fr.design.mainframe.FormToolBarPane;
import com.fr.form.ui.Widget;
import com.fr.form.web.FormToolBarManager;
import com.fr.form.web.Location;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
import com.fr.stable.ArrayUtils;
import com.fr.stable.Constants;
import com.fr.stable.StringUtils;
import javax.swing.*;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.ImageObserver;
import java.util.*;
import java.util.List;
/**
* Created by harry on 2017-2-23.
*/
public class ElementCaseToolBarPane extends BasicBeanPane<FormToolBarManager[]> {
private static final int COLUMN = 2;
private int row = 6;
private DefaultTableModel toolbarButtonTableModel;
private JTable layoutTable;
private UICheckBox isUseToolBarCheckBox = new UICheckBox(Inter.getLocText("FR-Designer_Use_ToolBar") + ":"); // 是否使用工具栏
private FormToolBarPane northToolBar;
private FormToolBarPane southToolBar;
private FormToolBarManager defaultToolBar;
public ElementCaseToolBarPane() {
toolbarButtonTableModel = new TableModel(row ,COLUMN);
this.setLayout(FRGUIPaneFactory.createBorderLayout());
JPanel north = FRGUIPaneFactory.createBorderLayout_S_Pane();
UIButton defaultButton = new UIButton(Inter.getLocText("FR-Designer_Restore_Default"));
// 恢复默认按钮
defaultButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
northToolBar.removeButtonList();
northToolBar.removeAll();
southToolBar.removeButtonList();
southToolBar.removeAll();
if (defaultToolBar == null) {
return;
}
FormToolBarManager toolBarManager = defaultToolBar;
toolBarManager.setToolBarLocation(Location.createTopEmbedLocation());
FormToolBarManager[] tbm = new FormToolBarManager[] { toolBarManager };
populateBean(tbm);
ElementCaseToolBarPane.this.repaint();
}
});
north.add(isUseToolBarCheckBox, BorderLayout.WEST);
JPanel aa = FRGUIPaneFactory.createRightFlowInnerContainer_S_Pane();
aa.add(defaultButton);
north.add(aa, BorderLayout.CENTER);
this.add(north, BorderLayout.NORTH);
northToolBar = new FormToolBarPane();
northToolBar.setPreferredSize(new Dimension(ImageObserver.WIDTH, 26));
northToolBar.setBackground(Color.lightGray);
UIButton topButton = new UIButton(IOUtils.readIcon("com/fr/design/images/arrow/arrow_up.png"));
topButton.setBorder(null);
topButton.setOpaque(false);
topButton.setContentAreaFilled(false);
topButton.setFocusPainted(false);
topButton.setRequestFocusEnabled(false);
topButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isSelectedtable()) {
WidgetOption no = (WidgetOption)layoutTable.getValueAt(layoutTable.getSelectedRow(), layoutTable.getSelectedColumn());
Widget widget = no.createWidget();
FormToolBarButton tb = new FormToolBarButton(no.optionIcon(), widget);
tb.setNameOption(no);
northToolBar.add(tb);
northToolBar.validate();
northToolBar.repaint();
} else {
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("FR-Designer_ChooseOneButton"));
}
}
});
UIButton downButton = new UIButton(IOUtils.readIcon("com/fr/design/images/arrow/arrow_down.png"));
downButton.setBorder(null);
downButton.setMargin(null);
downButton.setOpaque(false);
downButton.setContentAreaFilled(false);
downButton.setFocusPainted(false);
downButton.setRequestFocusEnabled(false);
downButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (isSelectedtable()) {
WidgetOption no = (WidgetOption)layoutTable.getValueAt(layoutTable.getSelectedRow(), layoutTable.getSelectedColumn());
Widget widget = no.createWidget();
FormToolBarButton tb = new FormToolBarButton(no.optionIcon(), widget);
tb.setNameOption(no);
southToolBar.add(tb);
southToolBar.validate();
southToolBar.repaint();
} else {
JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Inter.getLocText("FR-Designer_ChooseOneButton"));
}
}
});
initLayoutTable();
JPanel center = FRGUIPaneFactory.createBorderLayout_S_Pane();
center.setBackground(Color.white);
center.add(topButton, BorderLayout.NORTH);
JPanel small = FRGUIPaneFactory.createBorderLayout_S_Pane();
small.setBackground(Color.white);
small.add(new UILabel(StringUtils.BLANK), BorderLayout.NORTH);
small.add(layoutTable, BorderLayout.CENTER);
center.add(small, BorderLayout.CENTER);
center.add(downButton, BorderLayout.SOUTH);
southToolBar = new FormToolBarPane();
southToolBar.setPreferredSize(new Dimension(ImageObserver.WIDTH, 26));
southToolBar.setBackground(Color.lightGray);
JPanel movePane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel northContentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
FormSettingToolBar top = new FormSettingToolBar(Inter.getLocText("FR-Designer_ToolBar_Top"), northToolBar);
northContentPane.add(top, BorderLayout.EAST);
northContentPane.add(northToolBar, BorderLayout.CENTER);
northContentPane.setBackground(Color.lightGray);
JPanel southContentPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
FormSettingToolBar bottom = new FormSettingToolBar(Inter.getLocText("FR-Designer_ToolBar_Bottom"), southToolBar);
southContentPane.add(bottom, BorderLayout.EAST);
southContentPane.add(southToolBar, BorderLayout.CENTER);
southContentPane.setBackground(Color.lightGray);
movePane.add(northContentPane, BorderLayout.NORTH);
movePane.add(center, BorderLayout.CENTER);
movePane.add(southContentPane, BorderLayout.SOUTH);
this.add(new JScrollPane(movePane), BorderLayout.CENTER);
isUseToolBarCheckBox.setSelected(false);
}
private void initLayoutTable() {
layoutTable = new JTable(toolbarButtonTableModel);
layoutTable.setDefaultRenderer(Object.class, tableRenderer);
layoutTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
layoutTable.setColumnSelectionAllowed(false);
layoutTable.setRowSelectionAllowed(false);
layoutTable.setBackground(Color.white);
int columnWidth = Integer.parseInt(Inter.getLocText("FR-Designer_LayoutTable_Column_Width"));
for (int i = 0; i < layoutTable.getColumnModel().getColumnCount(); i++) {
layoutTable.getColumnModel().getColumn(i).setPreferredWidth(columnWidth);
}
layoutTable.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() > 1 && !SwingUtilities.isRightMouseButton(e)) {
WidgetOption no = (WidgetOption)layoutTable.getValueAt(layoutTable.getSelectedRow(), layoutTable.getSelectedColumn());
Widget widget = no.createWidget();
FormToolBarButton tb = new FormToolBarButton(no.optionIcon(), widget);
tb.setNameOption(no);
northToolBar.add(tb);
northToolBar.validate();
northToolBar.repaint();
}
}
});
}
private boolean isSelectedtable() {
for (int i = 0; i < layoutTable.getColumnCount(); i++) {
if (layoutTable.isColumnSelected(i)) {
return true;
}
}
return false;
}
/**
* 是否被选中
* @return 同上
*/
public boolean isUseToolbar() {
return this.isUseToolBarCheckBox.isSelected();
}
public void setDefaultToolBar(FormToolBarManager defaultToolBar, WidgetOption[] buttonArray) {
this.defaultToolBar = defaultToolBar;
if (buttonArray != null) {
for (int i = 0; i < buttonArray.length; i++) {
toolbarButtonTableModel.setValueAt(buttonArray[i], i % row, i / row);
}
}
}
DefaultTableCellRenderer tableRenderer = new DefaultTableCellRenderer() {
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (value instanceof WidgetOption) {
WidgetOption nameOption = (WidgetOption)value;
this.setText(nameOption.optionName());
Icon icon = nameOption.optionIcon();
if (icon != null) {
this.setIcon(icon);
}
}
if (value == null) {
this.setText(StringUtils.EMPTY);
this.setIcon(null);
}
return this;
}
};
@Override
protected String title4PopupWindow() {
return Inter.getLocText(new String[]{"Form-EC_toolbar", "Set"});
}
public void setCheckBoxSelected(boolean b) {
this.isUseToolBarCheckBox.setSelected(b);
}
@Override
public void populateBean(FormToolBarManager[] toolBarManager) {
if (ArrayUtils.isEmpty(toolBarManager)) {
defaultToolBar.setToolBarLocation(Location.createTopEmbedLocation());
toolBarManager = new FormToolBarManager[] { defaultToolBar };
}
if (ArrayUtils.isEmpty(toolBarManager)) {
return;
}
for (int i = 0; i < toolBarManager.length; i++) {
Location location = toolBarManager[i].getToolBarLocation();
if (location instanceof Location.Embed) {
if (((Location.Embed)location).getPosition() == Constants.TOP) {
northToolBar.populateBean(toolBarManager[i].getToolBar());
} else if (((Location.Embed)location).getPosition() == Constants.BOTTOM) {
southToolBar.populateBean(toolBarManager[i].getToolBar());
}
}
}
}
@Override
public FormToolBarManager[] updateBean() {
if(!isUseToolbar()){
return new FormToolBarManager[0];
}
List<FormToolBarManager> toolBarManagerList = new ArrayList<FormToolBarManager>();
if (!northToolBar.isEmpty()) {
FormToolBarManager north = new FormToolBarManager();
north.setToolBar(northToolBar.updateBean());
north.setToolBarLocation(Location.createTopEmbedLocation());
toolBarManagerList.add(north);
}
if (!southToolBar.isEmpty()) {
FormToolBarManager south = new FormToolBarManager();
south.setToolBar(southToolBar.updateBean());
south.setToolBarLocation(Location.createBottomEmbedLocation());
toolBarManagerList.add(south);
}
return toolBarManagerList.toArray(new FormToolBarManager[toolBarManagerList.size()]);
}
private class TableModel extends DefaultTableModel {
public TableModel(int i, int j) {
super(i, j);
}
// 禁止jtable的双击编辑功能
public boolean isCellEditable(int row, int column) {
return false;
}
}
}

34
designer_form/src/com/fr/design/mainframe/widget/wrappers/ElementCaseToolBarWrapper.java

@ -0,0 +1,34 @@
package com.fr.design.mainframe.widget.wrappers;
import com.fr.design.Exception.ValidationException;
import com.fr.design.designer.properties.Decoder;
import com.fr.design.designer.properties.Encoder;
import com.fr.form.web.FormToolBarManager;
import com.fr.general.Inter;
/**
* Created by harry on 2017-3-1.
*/
public class ElementCaseToolBarWrapper implements Encoder, Decoder {
@Override
public Object decode(String txt) {
return null;
}
@Override
public void validate(String txt) throws ValidationException {
}
@Override
public String encode(Object v) {
if (v == null) {
return null;
}
FormToolBarManager[] toolBarManager = (FormToolBarManager[])v;
if (toolBarManager.length != 0) {
return Inter.getLocText("FR-Designer_Open");
}
return Inter.getLocText("FR-Designer_Close");
}
}
Loading…
Cancel
Save