Browse Source

Merge pull request #717 in BA/design from ~FANGLEI/design:dev to dev

* commit 'f91cec5562e296c8450ca3c2c712ea0efb2b13c7':
  修改代码规范。
  修正一个小错误
  修正几个不规范的地方
  消除PMD错误
  消除PMD错误
  解决冲突
  设计器方面实现了控件顺序属性表 1.将MobileBodyWidgetTable更名为MobileWidgetTable 2.重写MobieWidgetTable和MobileParaWidgetTable的拖动逻辑 3.将BodyAppRelayout从designer_form\src\com\fr\design\designer\properties移动到designer_form\src\com\fr\design\designer\properties\mobile 4.修改国际化文件 5.整理WidgetPropertyPane的代码结构并且加以修改删除冗余代码 6.由于引擎代码中BoundsWidget位置变动,删除冗余的import代码,修改import BoundsWidget新位置的代码
master
superman 8 years ago
parent
commit
2a14757dd4
  1. 4
      designer/src/com/fr/poly/hanlder/BottomCornerMouseHanlder.java
  2. 13
      designer_base/src/com/fr/design/beans/location/MoveUtils.java
  3. 54
      designer_base/src/com/fr/design/gui/itable/AbstractPropertyTable.java
  4. 10
      designer_base/src/com/fr/design/gui/itable/PropertyGroup.java
  5. 1
      designer_base/src/com/fr/design/locale/designer.properties
  6. 1
      designer_base/src/com/fr/design/locale/designer_en_US.properties
  7. 1
      designer_base/src/com/fr/design/locale/designer_zh_CN.properties
  8. 1
      designer_base/src/com/fr/design/locale/designer_zh_TW.properties
  9. 13
      designer_form/src/com/fr/design/designer/beans/ConnectorCreator.java
  10. 4
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java
  11. 2
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java
  12. 8
      designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java
  13. 23
      designer_form/src/com/fr/design/designer/beans/location/Inner.java
  14. 16
      designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java
  15. 2
      designer_form/src/com/fr/design/designer/creator/XWFitLayout.java
  16. 2
      designer_form/src/com/fr/design/designer/creator/XWScaleLayout.java
  17. 2
      designer_form/src/com/fr/design/designer/creator/XWTitleLayout.java
  18. 4
      designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java
  19. 2
      designer_form/src/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java
  20. 16
      designer_form/src/com/fr/design/designer/properties/mobile/BodyAppRelayoutTable.java
  21. 1
      designer_form/src/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java
  22. 6
      designer_form/src/com/fr/design/mainframe/ConnectorHelper.java
  23. 267
      designer_form/src/com/fr/design/mainframe/MobileBodyWidgetTable.java
  24. 428
      designer_form/src/com/fr/design/mainframe/MobileParaWidgetTable.java
  25. 420
      designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java
  26. 269
      designer_form/src/com/fr/design/mainframe/WidgetPropertyPane.java

4
designer/src/com/fr/poly/hanlder/BottomCornerMouseHanlder.java

@ -161,7 +161,7 @@ public class BottomCornerMouseHanlder extends MouseInputAdapter {
* @param isIntersects 是否重叠
*/
@Override
public void setWidgetsIntersects(boolean isIntersects) {
public void setWidgetsIntersected(boolean isIntersects) {
}
/**
@ -170,7 +170,7 @@ public class BottomCornerMouseHanlder extends MouseInputAdapter {
* @return 重叠
*/
@Override
public boolean getWidgetsIntersects() {
public boolean isWidgetsIntersected() {
return false;
}

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

@ -16,6 +16,7 @@ import java.util.ArrayList;
public class MoveUtils {
public static final int SORPTION_UNIT = 5;
private static final int EQUIDISTANTLINE_UNIT = 4;
public static WidgetForbidWindow widgetForbidWindow = new WidgetForbidWindow();
@ -77,13 +78,13 @@ public class MoveUtils {
* 设置designer内部组件是否重叠的标志位
* @param isIntersects 是否重叠
*/
void setWidgetsIntersects(boolean isIntersects);
void setWidgetsIntersected(boolean isIntersects);
/**
* 获取designer内部组件是否重叠的标志位
* @return 重叠
*/
boolean getWidgetsIntersects();
boolean isWidgetsIntersected();
/**
* 获取designer相对屏幕的位置
@ -357,10 +358,10 @@ public class MoveUtils {
if(designer.getDesignerLocationOnScreen() != null) {
displayForbidWindow(x + designer.getDesignerLocationOnScreen().x, y + designer.getDesignerLocationOnScreen().y);
}
designer.setWidgetsIntersects(true);
designer.setWidgetsIntersected(true);
}
else{
designer.setWidgetsIntersects(false);
designer.setWidgetsIntersected(false);
hideForbidWindow();
}
}
@ -479,10 +480,10 @@ public class MoveUtils {
}
private static void processEquidistantLinesList(PlacePointing pEquidistantX, PlacePointing pEquidistantY, Rectangle operatingRectangle){
EquidistantLine[] equidistantLines1 = new EquidistantLine[4];
EquidistantLine[] equidistantLines1 = new EquidistantLine[EQUIDISTANTLINE_UNIT];
//先按方向处理,只保留四个方向上距离最近
for(int count = 0; count < equidistantLines.size(); count++){
for (int direction = 0; direction < 4; direction++){
for (int direction = 0; direction < EQUIDISTANTLINE_UNIT; direction++){
if(equidistantLines.get(count).getDirection() == (direction + 1)){//direction 1,2,3,4 分别对应top,left,bottom,right
if(equidistantLines1[direction] != null
&& equidistantLines1[direction].getDistance() > equidistantLines.get(count).getDistance()

54
designer_base/src/com/fr/design/gui/itable/AbstractPropertyTable.java

@ -26,32 +26,39 @@ import com.fr.general.Inter;
*/
public abstract class AbstractPropertyTable extends JTable {
// 属性分
// // 所有数据组, 把数据分组,一个可折叠的项里面的所有行 为一
protected ArrayList<PropertyGroup> groups;
protected TableModel default_table_model;
// 属性表被选中的行加一个浅蓝色的背景
public static final Color PROPERTY_SELECTION_BACKGROUND = new Color(153, 204, 255);
// 属性表的行高
public static final int PROPERTY_TABLE_ROW_HEIGHT = 22;
private static final int PROPERTY_ICON_WIDTH = 10;
public AbstractPropertyTable() {
this.setRowHeight(PROPERTY_TABLE_ROW_HEIGHT);
this.setTableProperties();
this.initPopup();
this.setModel(new DefaultTableModel());
}
private void setTableProperties() {
JTableHeader header = getTableHeader();
header.setReorderingAllowed(false);
header.setPreferredSize(new Dimension(0, PROPERTY_TABLE_ROW_HEIGHT));
header.setDefaultRenderer(new HeaderRenderer());
this.setRowHeight(PROPERTY_TABLE_ROW_HEIGHT);
this.setGridColor(new Color(212, 208, 200));
this.setSelectionBackground(PROPERTY_SELECTION_BACKGROUND);
this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setColumnSelectionAllowed(false);
this.setRowSelectionAllowed(true);
this.setFillsViewportHeight(true);
this.initPopup();
default_table_model = new DefaultTableModel();
this.setModel(default_table_model);
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
}
/**
* 在这个函数里面初始化表格数据再repaint
* @param source
*/
public abstract void initPropertyGroups(Object source);
public void fireValueChanged(Object old_value, boolean success, Object newValue) {
@ -64,12 +71,15 @@ public abstract class AbstractPropertyTable extends JTable {
@Override
public TableCellRenderer getCellRenderer(int row, int column) {
//如果数据组不为空
if (groups != null) {
Point pIndex = getGroupIndex(row);
if (pIndex == null){
return super.getCellRenderer(row, column);
}
//拿出当前行所在的那个属性组
PropertyGroup group = groups.get(pIndex.x);
//如果是标题行
if (pIndex.y == 0) {
if (column == 0) {
return group.getFirstRenderer();
@ -77,11 +87,13 @@ public abstract class AbstractPropertyTable extends JTable {
return group.getSecondRenderer();
}
} else {
//如果是非标题行第一列,采用默认渲染器
if (column == 0) {
return super.getCellRenderer(row, column);
} else {
TableCellRenderer renderer = group.getModel().getRenderer(pIndex.y - 1);
if (renderer instanceof Component) {
//如果这个渲染器是继承自Component,根据当前行列是否可编辑决定该控件是否可用
((Component) renderer).setEnabled(isCellEditable(row, column));
}
return renderer;
@ -115,6 +127,12 @@ public abstract class AbstractPropertyTable extends JTable {
}
}
/**
* 看懂了写个注释先
* 获取当前row行的Point(x, y), x代表当前row行是属于groups中的第x个组y代表当前row行所在的第x组里面的第y行
* @param row
* @return
*/
private Point getGroupIndex(int row) {
int count = 0;
for (int i = 0; i < groups.size(); i++) {
@ -135,6 +153,10 @@ public abstract class AbstractPropertyTable extends JTable {
this.addMouseListener(new MouseAdapter() {
/**
* 如果点到标题行就要触发折叠事件
* @param e
*/
@Override
public void mouseClicked(MouseEvent e) {
if (!e.isPopupTrigger() && groups != null) {
@ -148,13 +170,18 @@ public abstract class AbstractPropertyTable extends JTable {
}
}
/**
* 这个mousePressed和上面的mouseClicked唯一不同的地方是单双击和e.getX() < 10 的判断
* 这个意思应该就是说点到图标加号减号立即触发折叠效果否则点其他处要双击才能触发
* @param e
*/
@Override
public void mousePressed(MouseEvent e) {
if (!e.isPopupTrigger() && groups != null) {
int row = AbstractPropertyTable.super.rowAtPoint(e.getPoint());
if (row != -1) {
Point pIndex = getGroupIndex(row);
if (pIndex.y == 0 && e.getClickCount() == 1 && e.getX() < 10) {
if (pIndex.y == 0 && e.getClickCount() == 1 && e.getX() < PROPERTY_ICON_WIDTH) {
toggleCollapse(pIndex.x);
}
}
@ -163,16 +190,27 @@ public abstract class AbstractPropertyTable extends JTable {
});
}
/**
* 切换属性组折叠属性true/false
* @param groupIndex
*/
private void toggleCollapse(int groupIndex) {
PropertyGroup group = groups.get(groupIndex);
group.setCollapsed(!group.isCollapsed());
//这里获取表格的父控件是为了当表格被折叠了后,装表格的父控件也要相应的重新布局一下
//比如折叠之后表格行数应该比原来的少,占用父容器空间应该小点,不重新布局父容器,表格大小不会改变
Container parent = AbstractPropertyTable.this.getParent();
if (parent != null) {
parent.doLayout();
// parent.doLayout(); // 这里还是用revalidate吧。。daLayout有时候会失效不知道为什么
parent.revalidate();
}
repaint();
}
/**
* BeanTableModel类提供表格数据
* 它的所有数据来源均来自PropertyGroup中的AbstractPropertyGroupModel中的descriptor
*/
public class BeanTableModel extends AbstractTableModel {
@Override

10
designer_base/src/com/fr/design/gui/itable/PropertyGroup.java

@ -4,11 +4,14 @@ import javax.swing.table.TableCellRenderer;
import com.fr.design.beans.GroupModel;
/**
* PropertyGroup类描述了属性表中一个属性分组
*/
public class PropertyGroup {
private GroupModel model;
private String name;
private boolean collapsed;
private GroupModel model; // 描述这个属性组中的数据model
private String name; // 这组属性的标题名称
private boolean collapsed; // 这组属性是否折叠
private GroupRenderer renderer1;
private GroupRenderer renderer2;
@ -55,4 +58,5 @@ public class PropertyGroup {
public TableCellRenderer getSecondRenderer() {
return renderer2;
}
}

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

@ -562,3 +562,4 @@ FR-Designer-Move_Tab_Prev=move to previous
FR-Designer_DS_TableData=Data Set
FR-Designer_Parameter-Formula=Formula
FR-Designer_Plugin_Should_Update_Please_Contact_Developer=Plugin version is too low, and is not compatible with current API. Please contact the developer to update.
FR-Designer_WidgetOrder=Widget Order

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

@ -562,3 +562,4 @@ FR-Designer_Role=Role
FR-Designer_DS_TableData=Data Set
FR-Designer_Parameter-Formula=Formula
FR-Designer_Plugin_Should_Update_Please_Contact_Developer=Plugin version is too low, and is not compatible with current API. Please contact the developer to update.
FR-Designer_WidgetOrder=Widget Order

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

@ -566,3 +566,4 @@ FR-Designer_Role=\u89D2\u8272
FR-Designer_DS_TableData=\u6570\u636E\u96C6
FR-Designer_Parameter-Formula=\u516C\u5F0F
FR-Designer_Plugin_Should_Update_Please_Contact_Developer=\u63D2\u4EF6\u7248\u672C\u8FC7\u4F4E, \u5B58\u5728API\u4E0D\u517C\u5BB9, \u8BF7\u8054\u7CFB\u5F00\u53D1\u8005\u5347\u7EA7\u63D2\u4EF6
FR-Designer_WidgetOrder=\u63A7\u4EF6\u987A\u5E8F

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

@ -554,3 +554,4 @@ FR-Designer_Role=
FR-Designer_DS_TableData=\u8CC7\u6599\u96C6
FR-Designer_Parameter-Formula=\u516C\u5F0F
FR-Designer_Plugin_Should_Update_Please_Contact_Developer=\u633F\u4EF6\u7248\u672C\u904E\u4F4E\uFF0C\u5B58\u5728API\u4E0D\u76F8\u5BB9\uFF0C\u8ACB\u806F\u7CFB\u958B\u767C\u8005\u965E\u7D1A\u633F\u4EF6
FR-Designer_WidgetOrder=\u63A7\u4EF6\u9806\u5E8F

13
designer_form/src/com/fr/design/designer/beans/ConnectorCreator.java

@ -6,15 +6,14 @@ import java.util.ArrayList;
import java.util.PriorityQueue;
import com.fr.form.ui.container.WLayout;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.widget.BoundsWidget;
public class ConnectorCreator {
public static final int UNIT = 10;
public static final int SIDE = 2;
public static final int CORNER_LOSS = 20;
public static final int vector[][] = { { UNIT, 0 }, { -UNIT, 0 }, { 0, UNIT }, { 0, -UNIT } };
public static final int VECTOR[][] = { { UNIT, 0 }, { -UNIT, 0 }, { 0, UNIT }, { 0, -UNIT } };
private long timeOut = 200;
private boolean beyond;
@ -179,8 +178,8 @@ public class ConnectorCreator {
}
void pushInto() {
for (int i = 0; i < vector.length; i++) {
Point temp = new Point(p.x + vector[i][0], p.y + vector[i][1]);
for (int i = 0; i < VECTOR.length; i++) {
Point temp = new Point(p.x + VECTOR[i][0], p.y + VECTOR[i][1]);
if (parent != null && parent.x == temp.x && parent.y == temp.y) {
continue;
}
@ -192,8 +191,8 @@ public class ConnectorCreator {
}
boolean reCheck() {
for (int i = 0; i < vector.length; i++) {
Point temp = new Point(p.x + SIDE * vector[i][0], p.y + SIDE * vector[i][1]);
for (int i = 0; i < VECTOR.length; i++) {
Point temp = new Point(p.x + SIDE * VECTOR[i][0], p.y + SIDE * VECTOR[i][1]);
AssessedPoint ap = new AssessedPoint(temp, this, loss(temp));
if (check(temp)) {
open.add(ap);

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

@ -12,7 +12,7 @@ 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.container.WBodyLayoutType;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogger;
@ -111,7 +111,7 @@ public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter {
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++) {
WAbsoluteLayout.BoundsWidget temp = (WAbsoluteLayout.BoundsWidget) wAbsoluteLayout.getWidget(i);
BoundsWidget temp = (BoundsWidget) wAbsoluteLayout.getWidget(i);
Rectangle rectangle = temp.getBounds();
if (curRec.intersects(rectangle)){
return false;

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

@ -26,9 +26,9 @@ import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.mainframe.JForm;
import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.LayoutBorderStyle;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.WLayout;
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.ComparatorUtils;
/**

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

@ -11,9 +11,10 @@ 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.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.WParameterLayout;
import com.fr.form.ui.widget.BoundsWidget;
/**
* @author richer
@ -66,10 +67,8 @@ public abstract class AccessDirection implements Direction {
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);
@ -111,7 +110,10 @@ public abstract class AccessDirection implements Direction {
}
}
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);

23
designer_form/src/com/fr/design/designer/beans/location/Inner.java

@ -9,9 +9,8 @@ import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelection;
import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.stable.ArrayUtils;
import com.fr.third.com.lowagie.text.*;
import java.awt.*;
import java.awt.Rectangle;
@ -47,9 +46,13 @@ public class Inner extends AccessDirection {
return new Point(x, y);
}
@Override
protected void sorptionPoint(Point point, Rectangle current_bounds, final FormDesigner designer) {
RectangleDesigner rd = new RectangleDesigner() {
private class RectDesigner implements RectangleDesigner {
private FormDesigner designer = null;
public RectDesigner(FormDesigner designer) {
this.designer = designer;
}
public void setXAbsorptionline(Absorptionline line) {
designer.getStateModel().setXAbsorptionline(line);
}
@ -86,7 +89,7 @@ public class Inner extends AccessDirection {
* @param isIntersects 是否重叠
*/
@Override
public void setWidgetsIntersects(boolean isIntersects) {
public void setWidgetsIntersected(boolean isIntersects) {
designer.setWidgetsIntersect(isIntersects);
}
@ -96,7 +99,7 @@ public class Inner extends AccessDirection {
* @return 重叠
*/
@Override
public boolean getWidgetsIntersects() {
public boolean isWidgetsIntersected() {
return designer.isWidgetsIntersect();
}
@ -129,7 +132,11 @@ public class Inner extends AccessDirection {
public int getDesignerScrollVerticalValue() {
return designer.getArea().getVerticalValue();
}
};
}
@Override
protected void sorptionPoint(Point point, Rectangle current_bounds, final FormDesigner designer) {
RectDesigner rd = new RectDesigner(designer);
//判断当前操作的是不是参数面板,要特殊处理
boolean isParameterLayout = ((XCreator)(designer.getSelectionModel().getSelection().getSelectedCreator().getParent())).acceptType(XWParameterLayout.class);
point.setLocation(MoveUtils.sorption(point.x, point.y, current_bounds.width, current_bounds.height, rd, isParameterLayout));

16
designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java

@ -8,39 +8,25 @@ import java.awt.event.ContainerEvent;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.beans.IntrospectionException;
import java.util.ArrayList;
import java.util.HashMap;
import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.ComponentAdapter;
import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.AbsoluteLayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.FRAbsoluteLayoutAdapter;
import com.fr.design.designer.beans.location.Direction;
import com.fr.design.designer.beans.models.SelectionModel;
import com.fr.design.designer.creator.cardlayout.XWTabFitLayout;
import com.fr.design.form.layout.FRAbsoluteLayout;
import com.fr.design.form.util.XCreatorConstants;
import com.fr.design.gui.icheckbox.UICheckBox;
import com.fr.design.icon.IconPathConstants;
import com.fr.design.mainframe.*;
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.ui.Connector;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WAbsoluteLayout;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.WFitLayout;
import com.fr.form.ui.container.WLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.FRScreen;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
import com.fr.stable.core.PropertyChangeAdapter;
import org.eclipse.swt.internal.gdip.Rect;
import javax.swing.*;
/**
* @author richer

2
designer_form/src/com/fr/design/designer/creator/XWFitLayout.java

@ -20,10 +20,10 @@ import com.fr.design.mainframe.FormArea;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.PaddingMargin;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.WBodyLayoutType;
import com.fr.form.ui.container.WFitLayout;
import com.fr.form.ui.container.WLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.FRScreen;
import com.fr.general.Inter;
import com.fr.stable.ArrayUtils;

2
designer_form/src/com/fr/design/designer/creator/XWScaleLayout.java

@ -11,8 +11,8 @@ import com.fr.design.designer.beans.LayoutAdapter;
import com.fr.design.designer.beans.adapters.layout.FRScaleLayoutAdapter;
import com.fr.design.form.layout.FRScaleLayout;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.WScaleLayout;
import com.fr.form.ui.widget.BoundsWidget;
/**
* 自适应布局中添加组件时部分控件如数字文本下拉等需要保持控件默认高度21 用此容器来实现

2
designer_form/src/com/fr/design/designer/creator/XWTitleLayout.java

@ -10,8 +10,8 @@ import com.fr.design.fun.WidgetPropertyUIProvider;
import com.fr.form.ui.Label;
import com.fr.form.ui.Widget;
import com.fr.form.ui.WidgetTitle;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.WTitleLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.ComparatorUtils;
import java.awt.*;

4
designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java

@ -18,8 +18,8 @@ import com.fr.design.icon.IconPathConstants;
import com.fr.design.mainframe.EditingMouseListener;
import com.fr.design.mainframe.FormDesigner;
import com.fr.form.ui.container.WBorderLayout;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.IOUtils;
import com.fr.general.Inter;
@ -231,7 +231,7 @@ public class XWCardMainBorderLayout extends XWBorderLayout{
);
g2d.setColor(Color.BLACK);
//画编辑文字
g2d.drawString(Inter.getLocText("Edit"), x + w / 2 - 2, y + h / 2 + 5);
g2d.drawString(Inter.getLocText("FR-Designer_Edit"), x + w / 2 - 2, y + h / 2 + 5);
}
}

2
designer_form/src/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java

@ -25,9 +25,9 @@ import com.fr.design.mainframe.widget.editors.ImgBackgroundEditor;
import com.fr.design.mainframe.widget.renderer.FontCellRenderer;
import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.CardSwitchButton;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
import com.fr.form.ui.container.cardlayout.WCardTagLayout;
import com.fr.form.ui.container.cardlayout.WTabFitLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.Background;
import com.fr.general.FRFont;
import com.fr.general.FRLogger;

16
designer_form/src/com/fr/design/designer/properties/BodyAppRelayoutTable.java → designer_form/src/com/fr/design/designer/properties/mobile/BodyAppRelayoutTable.java

@ -1,9 +1,9 @@
package com.fr.design.designer.properties;
package com.fr.design.designer.properties.mobile;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.beans.IntrospectionException;
import java.util.ArrayList;
import javax.swing.table.TableModel;
import com.fr.base.FRContext;
import com.fr.design.designer.beans.events.DesignerEvent;
@ -17,7 +17,9 @@ import com.fr.design.mainframe.WidgetPropertyPane;
import com.fr.design.mainframe.widget.editors.InChangeBooleanEditor;
import com.fr.general.Inter;
/**
* 将body的控件列表中再加入手机重布局选项
*/
public class BodyAppRelayoutTable extends AbstractPropertyTable {
private XCreator xCreator;
@ -31,7 +33,6 @@ public class BodyAppRelayoutTable extends AbstractPropertyTable {
CRPropertyDescriptor[] propertyTableEditor = {
new CRPropertyDescriptor("appRelayout", this.xCreator.toData().getClass()).setEditorClass(InChangeBooleanEditor.class)
.setI18NName(Inter.getLocText("FR-Designer-App_ReLayout"))
.putKeyValue(XCreatorConstants.PROPERTY_CATEGORY, Inter.getLocText("FR-Designer-Layout_Adaptive_Layout"))
};
return propertyTableEditor;
}
@ -43,6 +44,7 @@ public class BodyAppRelayoutTable extends AbstractPropertyTable {
public void initPropertyGroups(Object source) {
this.designer = WidgetPropertyPane.getInstance().getEditingFormDesigner();
this.setFillsViewportHeight(false);
groups = new ArrayList<PropertyGroup>();
CRPropertyDescriptor[] propertyTableEditor = null;
@ -55,8 +57,7 @@ public class BodyAppRelayoutTable extends AbstractPropertyTable {
groups.add(new PropertyGroup(new ReportAppPropertyGroupModel(Inter.getLocText("FR-Designer_Properties_Mobile"), xCreator, propertyTableEditor, designer)));
TableModel model = new BeanTableModel();
setModel(model);
setModel(new BeanTableModel());
this.repaint();
}
@ -78,8 +79,9 @@ public class BodyAppRelayoutTable extends AbstractPropertyTable {
}
/**
* 待说明
* 触发控件编辑事件
*/
@Override
public void firePropertyEdit() {
designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED);
}

1
designer_form/src/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java

@ -3,7 +3,6 @@ package com.fr.design.designer.properties.mobile;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XWAbsoluteBodyLayout;
import com.fr.design.designer.creator.XWFitLayout;
import com.fr.design.designer.properties.BodyAppRelayoutTable;
import com.fr.design.fun.impl.AbstractWidgetPropertyUIProvider;
import com.fr.design.gui.itable.AbstractPropertyTable;
import com.fr.general.Inter;

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

@ -7,18 +7,19 @@ import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.stable.Constants;
import com.fr.base.GraphHelper;
import com.fr.design.designer.beans.ConnectorCreator;
import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.form.ui.Connector;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
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;
@ -67,7 +68,6 @@ public class ConnectorHelper {
ConnectorCreator cc = new ConnectorCreator(designer.getTarget().getContainer(), new Point(startPoint), new Point(endPoint));
ArrayList<Point> p = cc.createPointList();
long e = System.currentTimeMillis();
System.out.println("useTime:" + (e - s));
return p;
}
@ -87,7 +87,7 @@ public class ConnectorHelper {
public void createDefalutLine() {
if (drawingPoint != null
&& drawingPoint.size() > 1
&& ConnectorCreator.getMinimumDistance(drawingPoint.get(0), drawingPoint.get(drawingPoint.size() - 1)) > 15) {
&& ConnectorCreator.getMinimumDistance(drawingPoint.get(0), drawingPoint.get(drawingPoint.size() - 1)) > ADSORPTION) {
((XWAbsoluteLayout) designer.getRootComponent()).addConnector(new Connector().addAll(drawingPoint));
}
drawingPoint = null;

267
designer_form/src/com/fr/design/mainframe/MobileBodyWidgetTable.java

@ -1,267 +0,0 @@
package com.fr.design.mainframe;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itable.HeaderRenderer;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WFitLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.stable.StringUtils;
/**
* Created with IntelliJ IDEA.
* User: zx
* Date: 14-9-15
* Time: 下午4:52
*/
public class MobileBodyWidgetTable extends JTable {
private FormDesigner designer;
protected TableModel defaultmodel;
private String[][] cellData;
private String[] headers = {Inter.getLocText("Form-Widget_Name")};
public static final int WIDGET_TABLE_ROW_HEIGHT = 22;
private UILabel moveComponent = new UILabel();
private int selectedRow = -1;
private int GAP = 10;
private boolean draging = false;
public MobileBodyWidgetTable(FormDesigner designer) {
this.designer = designer;
cellData = getData();
this.setRowHeight(WIDGET_TABLE_ROW_HEIGHT);
JTableHeader header = getTableHeader();
header.setReorderingAllowed(false);
header.setPreferredSize(new Dimension(0, WIDGET_TABLE_ROW_HEIGHT));
HeaderRenderer headerRenderer = new HeaderRenderer();
headerRenderer.setHorizontalAlignment(JLabel.CENTER);
header.setDefaultRenderer(headerRenderer);
this.setGridColor(new Color(212, 208, 200));
this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setColumnSelectionAllowed(false);
this.setRowSelectionAllowed(false);
this.setFillsViewportHeight(true);
defaultmodel = new BeanTableModel();
this.setModel(defaultmodel);
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
this.repaint();
this.setDefaultRenderer(Object.class,new MobileWidgetTableCellRenderer());
refresh();
this.addMouseListener(mouseAdapter);
this.addMouseMotionListener(mouseAdapter);
add(moveComponent);
}
private MouseAdapter mouseAdapter = new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if(getSelectedRow() != -1){
String widgetName = cellData[getSelectedRow()][0];
if (StringUtils.isNotEmpty(widgetName)){
XLayoutContainer root = getEditingDesigner().getRootComponent();
int count = root.getXCreatorCount();
for (int i = 0;i < count ;i++){
XCreator xCreator = root.getXCreator(i).getEditingChildCreator();
Widget widget = xCreator.toData();
if (ComparatorUtils.equals(widgetName, widget.getWidgetName())) {
getEditingDesigner().getSelectionModel().setSelectedCreator(xCreator);
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
selectedRow = getSelectedRow();
}
}
}
}
}
public void mouseExited(MouseEvent e) {
draging = false;
moveComponent.setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
@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 == getSelectedRow()) {
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
} else {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
}
@Override
public void mouseDragged(MouseEvent e) {
int width = getColumnModel().getColumn(0).getWidth();
if (getCursor().getType() == Cursor.MOVE_CURSOR){
draging = true;
//下面这句话太重要了,拖拽过程中选中的不变
getInstance().setRowSelectionInterval(selectedRow,selectedRow);
moveComponent.setText(getValueAt(getSelectedRow(), getSelectedColumn()).toString());
moveComponent.setLocation(0, e.getY() - GAP);
moveComponent.setPreferredSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT));
moveComponent.setSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT));
moveComponent.setVisible(true);
moveComponent.setForeground(Color.lightGray);
moveComponent.setBorder(BorderFactory.createLineBorder(Color.lightGray));
}
}
@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;
((WFitLayout) designer.getRootComponent().toData()).adjustOrder(getSelectedRow(), toIndex);
getInstance().setRowSelectionInterval(0,getRowCount() - 1);
refresh();
getInstance().repaint();
designer.fireTargetModified();
}
};
public MobileBodyWidgetTable getInstance(){
return this;
}
public FormDesigner getEditingDesigner(){
return designer;
}
/**
* 刷新
*/
public void refresh(){
XCreator creator = designer.getSelectionModel().getSelection().getSelectedCreator();
cellData = getData();
if(creator != null){
String widgetName =creator.toData().getWidgetName();
int row = -1;
for (int i =0; i < cellData.length;i++){
if(ComparatorUtils.equals(widgetName, cellData[i][0])){
row = i;
break;
}
}
selectedRow = row;
changeSelection(row,0,false,false);
if(row == -1){
this.clearSelection();
}
}
}
private String[][] getData(){
if(designer.isFormParaDesigner()){
return new String[0][0];
}
XLayoutContainer paraContainer = designer.getRootComponent();
if(paraContainer == null || !paraContainer.acceptType(WFitLayout.class)){
return new String[0][0];
}
WFitLayout fitLayout = (WFitLayout) (paraContainer.toData());
ArrayList<String> strings = fitLayout.getMobileWidgetList();
String[][] widgetName = new String[strings.size()][2];
for(int i = 0;i < strings.size();i++){
widgetName[i][0] = strings.get(i);
}
return widgetName;
}
private class MobileWidgetTableCellRenderer extends DefaultTableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
if (getCursor().getType() == Cursor.MOVE_CURSOR){
if(selectedRow > -1 && selectedRow < getRowCount()){
//拖拽过程中选中的不变
getInstance().setRowSelectionInterval(selectedRow,selectedRow);
}
}
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
return this;
}
}
public class BeanTableModel extends DefaultTableModel {
public BeanTableModel() {
super(cellData,headers);
}
@Override
public int getRowCount() {
return cellData.length;
}
@Override
public int getColumnCount() {
return 1;
}
@Override
public Object getValueAt(int row, int column) {
if (row >= getRowCount() || column >= getColumnCount()) {
return null;
}
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;
}
}
}

428
designer_form/src/com/fr/design/mainframe/MobileParaWidgetTable.java

@ -0,0 +1,428 @@
package com.fr.design.mainframe;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itable.GroupRenderer;
import com.fr.design.gui.itable.HeaderRenderer;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.form.ui.Label;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WParameterLayout;
import com.fr.general.ComparatorUtils;
import com.fr.general.Inter;
import com.fr.stable.StringUtils;
/**
* MobileParaWidgetTable主要显示参数面板容器的控件列表与MobileWidgetTable的区别就是该表多了UITextField这一列
* Created with IntelliJ IDEA.
* User: zx
* Date: 14-7-9
* Time: 上午11:26
* Modified by fanglei during 2017/1/22 - 2017/2/
*/
class MobileParaWidgetTable extends JTable {
private FormDesigner designer;
private String[][] cellData ;
private String[] headers = {Inter.getLocText("FR-Utils_Label"), Inter.getLocText("Form-Widget_Name")};
private static final int WIDGET_TABLE_ROW_HEIGHT = 22;
private static final int UITEXTFIELD_WIDTH = 40;
private UILabel moveComponent = new UILabel(); // 作为拖动时候随鼠标移动的那个半透明控件
private int selectedRow = -1;
private int selectedColumn = -1;
private int GAP = 11;
private boolean draging = false;
MobileParaWidgetTable(FormDesigner designer) {
this.designer = designer;
this.cellData = getData();
this.setTableProperties();
this.setDefaultEditor(Object.class, new MobileCellEditor());
TableModel defaultModel = new BeanTableModel();
this.setModel(defaultModel);
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
TableColumn tc = this.getColumn(this.getColumnName(0));
tc.setPreferredWidth(UITEXTFIELD_WIDTH);
this.repaint();
this.setDefaultRenderer(Object.class,new MobileWidgetTableCellRenderer());
refreshData();
this.addMouseListener(mouseAdapter);
this.addMouseMotionListener(mouseAdapter);
add(moveComponent);
}
private void setTableProperties() {
JTableHeader header = getTableHeader();
header.setReorderingAllowed(false);
header.setPreferredSize(new Dimension(0, WIDGET_TABLE_ROW_HEIGHT));
header.setDefaultRenderer(new 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(true);
}
private MouseAdapter mouseAdapter = new MouseAdapter() {
/**
* 鼠标按下时处理的事件设置当前选中的行列
* @param e
*/
@Override
public void mousePressed(MouseEvent e) {
getInstance().setCellSelected();
}
/**
* 鼠标放开时处理的事件如果是正在拖动则执行换位操作重新绘制属性表如果不是则什么也不做
* @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;
//当鼠标放开时,将选中的容器调整至新的顺序
((WParameterLayout) designer.getParaComponent().toData()).adjustOrder(selectedRow, toIndex);
//拿取排序后表格数据,然后重绘表格
getInstance().refreshData();
getInstance().repaint();
designer.fireTargetModified();
getInstance().setCellSelected();
}
/**
* 设置鼠标在属性表区域移动时候的事件
* @param e
*/
@Override
public void mouseMoved(MouseEvent e) {
int overColumn = e.getX() < getColumnModel().getColumn(0).getWidth() ? 0 : 1; // 判断当前鼠标在哪一列
int overRow = -1;
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 && overColumn == selectedColumn && overColumn !=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(1).getWidth();
//如果点击选中的是第二列,就可以拖动
if (selectedColumn == 1){
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
draging = true;
moveComponent.setText(getValueAt(selectedRow, selectedColumn).toString());
moveComponent.setLocation(getColumnModel().getColumn(0).getWidth(), 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(getSelectedRow() != -1 && getSelectedColumn() == 1){
String widgetName = cellData[getSelectedRow()][getSelectedColumn()];
if (StringUtils.isNotEmpty(widgetName)){
int count = getEditingDesigner().getParaComponent().getComponentCount();
for (int i = 0; i < count; i++){
XCreator xCreator = (XCreator)getEditingDesigner().getParaComponent().getComponent(i);
Widget widget = xCreator.toData();
if (!widget.acceptType(Label.class) && ComparatorUtils.equals(widgetName,widget.getWidgetName())) {
//设置选中的component,这句代码控制点击之后跳转到相应component属性表
getEditingDesigner().getSelectionModel().setSelectedCreator(xCreator);
}
}
}
}
}
/**
* 鼠标离开属性表区域事件
* @param e
*/
@Override
public void mouseExited(MouseEvent e) {
draging = false;
moveComponent.setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
};
public MobileParaWidgetTable getInstance(){
return this;
}
private FormDesigner getEditingDesigner(){
return designer;
}
/**
* 设置当前get到的行列的单元格为选中状态
*/
private void setCellSelected() {
selectedRow = getSelectedRow();
selectedColumn = getSelectedColumn();
if (selectedRow != -1) {
this.setRowSelectionInterval(selectedRow, selectedRow);
}
if (selectedColumn != -1) {
this.setColumnSelectionInterval(selectedColumn, selectedColumn);
}
}
/**
* 重新get排序后的数据
*/
public void refreshData(){
cellData = getData();
}
/**
* 获取参数面板的控件列表
*
* @return String[][] 二维数组[0][0]widgetTag, [0][1]widgetName
*/
private String[][] getData(){
XLayoutContainer paraContainer = designer.getParaComponent();
if(paraContainer == null || !paraContainer.acceptType(XWParameterLayout.class)){
return new String[0][0];
}
WParameterLayout para = (WParameterLayout) (paraContainer.toData());
return para.getWidgetNameTag(); // TODO 从这个函数开始看,可以看到后台如何决定拖动后的控件顺序的
}
/**
* 自定义的tableRender类
*/
private class MobileWidgetTableCellRenderer extends 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 (column == 0){
UITextField uiTableTextField;
if (getSelectedColumn() == column && getSelectedRow() == row){
uiTableTextField = new UITableTextField(value.toString());
} else {
uiTableTextField = new UITextField(value.toString());
}
return uiTableTextField;
}
return this;
}
}
/**
* 自定义的tableEditor类
*/
private class MobileCellEditor extends AbstractCellEditor implements TableCellEditor {
UITableTextField uiTableTextField;
MobileCellEditor(){
uiTableTextField = new UITableTextField();
uiTableTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent evt) {
stopCellEditing();
designer.fireTargetModified();
}
});
uiTableTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange();
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange();
}
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange();
}
});
}
/**
* cell改变相应的nametag改变
*/
private void firePropertyChange(){
((WParameterLayout) designer.getParaComponent().toData()).add2NameTagMap(uiTableTextField.getText(),
cellData[getSelectedRow()][1]);
}
@Override
public Object getCellEditorValue(){
return uiTableTextField.getText();
}
/**
* 双击以编辑, 表示只有双击的情况下才可以编辑
*/
@Override
public boolean isCellEditable(EventObject anEvent) {
return !(anEvent instanceof MouseEvent) || ((MouseEvent) anEvent).getClickCount() >= 2;
}
@Override
public Component getTableCellEditorComponent( JTable table,Object value,
boolean isSelected,int row,int column){
uiTableTextField.setText(value.toString());
return uiTableTextField;
}
}
/**
* BeanTableModel类继承DefaultTableModel类指定了表格的表头和内容
*/
private class BeanTableModel extends DefaultTableModel {
BeanTableModel() {
super(cellData, headers);
}
@Override
public int getRowCount() {
return cellData.length;
}
@Override
public int getColumnCount() {
return headers.length;
}
@Override
public Object getValueAt(int row, int column) {
if (row >= getRowCount() || column >= getColumnCount()) {
return null;
}
Object[] rowValue = cellData[row];
if (column > -1 && column < rowValue.length) {
return cellData[row][column];
}
return null;
}
@Override
public String getColumnName(int column) {
if (column == 0) {
return headers[0];
} else {
return headers[1];
}
}
@Override
public void setValueAt(Object aValue, int row, int column) {
if (row >= getRowCount() || column >= getColumnCount()) {
return;
}
if (aValue == null) {
cellData[row][column] = null;
return;
}
cellData[row][column] = aValue.toString();
}
/**
* 是否可编辑 控件标签列可以编辑控件名不可编辑
* @param row 行号
* @param column 列号
* @return 是否可编辑
*/
public boolean isCellEditable(int row, int column) {
if(column ==1){
return false;
}
return true;
}
}
/**
* 继承自JTextField类重写了编辑框的样式
*/
private class UITableTextField extends UITextField {
public UITableTextField(){
super();
}
public UITableTextField(String string){
super(string);
}
protected void paintBorder(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (this.isFocusOwner()) {
g2d.setStroke(new BasicStroke(1.5f));
} else {
g2d.setStroke(new BasicStroke(1f));
}
RoundRectangle2D.Double rect = new RoundRectangle2D.Double(0, 0, this.getWidth() - 2, this.getHeight() - 2, 4, 4);
g2d.setColor(Color.orange);
g2d.draw(rect);
}
}
}

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

@ -1,167 +1,205 @@
package com.fr.design.mainframe;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D;
import java.util.EventObject;
import java.util.ArrayList;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
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.design.gui.itable.HeaderRenderer;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.designer.creator.XCreator;
import com.fr.design.designer.creator.XLayoutContainer;
import com.fr.design.designer.creator.XWParameterLayout;
import com.fr.form.ui.Label;
import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WParameterLayout;
import com.fr.form.ui.container.*;
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import com.fr.form.ui.container.cardlayout.WCardTitleLayout;
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-7-9
* Time: 上午11:26
* Date: 14-9-15
* Time: 下午4:52
* Modified by fanglei at 2017/01/23
*/
public class MobileWidgetTable extends JTable {
private FormDesigner designer;
protected TableModel defaultmodel;
private String[][] cellData;
private String[] headers = {Inter.getLocText("FR-Utils_Label"),Inter.getLocText("Form-Widget_Name")};
public static final int WIDGET_TABLE_ROW_HEIGHT = 22;
private UILabel moveComponent = new UILabel();
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 = 10;
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;
this.cellData = getData();
this.setRowHeight(WIDGET_TABLE_ROW_HEIGHT);
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, WIDGET_TABLE_ROW_HEIGHT));
header.setDefaultRenderer(new HeaderRenderer());
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(true);
this.setDefaultEditor(Object.class,new MobileCellEditor());
defaultmodel = new BeanTableModel();
this.setModel(defaultmodel);
this.setFillsViewportHeight(false);
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
TableColumn tc = this.getColumn(this.getColumnName(0));
tc.setPreferredWidth(30);
this.repaint();
this.setDefaultRenderer(Object.class,new MobileWidgetTableCellRenderer());
refresh();
this.addMouseListener(mouseAdapter);
this.addMouseMotionListener(mouseAdapter);
add(moveComponent);
}
private MouseAdapter mouseAdapter = new MouseAdapter() {
/**
* 鼠标按下时处理的事件设置当前选中的行列
* @param e
*/
@Override
public void mouseClicked(MouseEvent e) {
if(getSelectedRow() != -1 && getSelectedColumn() == 1){
String widgetName = cellData[getSelectedRow()][getSelectedColumn()];
if (StringUtils.isNotEmpty(widgetName)){
int count = getEditingDesigner().getParaComponent().getComponentCount();
for (int i = 0;i < count ;i++){
XCreator xCreator = (XCreator)getEditingDesigner().getParaComponent().getComponent(i);
Widget widget = xCreator.toData();
if (!widget.acceptType(Label.class) && ComparatorUtils.equals(widgetName,widget.getWidgetName())) {
getEditingDesigner().getSelectionModel().setSelectedCreator(xCreator);
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
selectedRow = getSelectedRow();
}
}
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;
}
public void mouseExited(MouseEvent e) {
draging = false;
moveComponent.setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
int toIndex = e.getY() < GAP ? 0 : (int)Math.rint((e.getY() - GAP)/WIDGET_TABLE_ROW_HEIGHT) + 1;
//当鼠标放开时,将选中的容器调整至新的顺序
((WLayout)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 overColumn = e.getX() < getColumnModel().getColumn(0).getWidth() ? 0 : 1;
int overRow = -1;
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;
overRow = i; //判断鼠标在哪一行
}
}
if (overRow == getSelectedRow() && overColumn == getSelectedColumn() && overColumn !=0) {
//如果鼠标移动到当前选中的行上面的时候
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) {
if (e.getX() < getColumnModel().getColumn(0).getWidth()) {
draging = false;
moveComponent.setVisible(false);
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
int width = getColumnModel().getColumn(1).getWidth();
if (getCursor().getType() == Cursor.MOVE_CURSOR){
int width = getColumnModel().getColumn(0).getWidth();
//如果当前选中的行的范围是合理的话,就可以拖动
if (selectedRow < getRowCount() && selectedRow > 0){
setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
draging = true;
//下面这句话太重要了,拖拽过程中选中的不变
getInstance().setRowSelectionInterval(selectedRow,selectedRow);
moveComponent.setText(getValueAt(getSelectedRow(), getSelectedColumn()).toString());
moveComponent.setLocation(getColumnModel().getColumn(0).getWidth(), e.getY() - GAP);
moveComponent.setPreferredSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT));
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 mouseReleased(MouseEvent e) {
if(!draging){
return;
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);
int toIndex = e.getY() < GAP ? 0 : (int)Math.rint((e.getY() - GAP)/WIDGET_TABLE_ROW_HEIGHT) + 1;
((WParameterLayout) designer.getParaComponent().toData()).adjustOrder(getSelectedRow(), toIndex);
getInstance().setRowSelectionInterval(0,getRowCount() - 1);
refresh();
getInstance().repaint();
designer.fireTargetModified();
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
};
@ -174,126 +212,87 @@ public class MobileWidgetTable extends JTable {
}
/**
* 刷新
* 设置当前get到的行列的单元格为选中状态
*/
public void refresh(){
XCreator creator = designer.getSelectionModel().getSelection().getSelectedCreator();
cellData = getData();
if(creator != null){
String widgetName =creator.toData().getWidgetName();
int row = -1;
int column = -1;
for (int i =0; i < cellData.length;i++){
if(ComparatorUtils.equals(widgetName, cellData[i][0])){
row = i;
column = 0;
break;
}
if(ComparatorUtils.equals(widgetName, cellData[i][1])){
row = i;
column = 1;
break;
private void setCellSelected() {
selectedRow = getSelectedRow();
if (selectedRow != -1) {
this.setRowSelectionInterval(selectedRow, selectedRow);
this.setColumnSelectionInterval(0, 0);
}
}
selectedRow = row;
changeSelection(row,column,false,false);
if(row == -1){
this.clearSelection();
/**
* 切换属性组折叠属性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(){
XLayoutContainer paraContainer = designer.getParaComponent();
if(paraContainer == null || !paraContainer.acceptType(XWParameterLayout.class)){
if(designer.isFormParaDesigner()){
return new String[0][0];
}
WParameterLayout para = (WParameterLayout) (paraContainer.toData());
return para.getWidgetNameTag();
}
//选择的控件
Widget selectedModel = designer.getSelectionModel().getSelection().getSelectedCreator().toData();
private class MobileWidgetTableCellRenderer extends DefaultTableCellRenderer{
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
if (getCursor().getType() == Cursor.MOVE_CURSOR){
if(selectedRow > -1 && selectedRow < getRowCount()){
//拖拽过程中选中的不变
getInstance().setRowSelectionInterval(selectedRow,selectedRow);
}
}
super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (column == 0){
UITextField uiTableTextField;
if (getSelectedColumn() == column && getSelectedRow() == row){
uiTableTextField = new UITableTextField(value.toString());
} else {
uiTableTextField = new UITextField(value.toString());
}
return uiTableTextField;
}
return this;
if(selectedModel == null){
return new String[0][0];
}
// 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件
if (selectedModel.acceptType(WLayout.class)) {
//WCardLayout里面并不是控件,而仍然是容器TabFitLayout,故要向下获取控件
//WCardTitlelLayout是XWCardLayout的标题容器,里面同样不是控件,不能获取MobileList
//WTitleLayout是标题容器,比如图表的标题,里面是图表控件和Label标题控件,但是不需要获取MobileList
if (selectedModel.acceptType(WCardLayout.class) || selectedModel.acceptType(WCardTitleLayout.class)) {
if (selectedModel.acceptType(WTitleLayout.class) || selectedModel.acceptType(WCardMainBorderLayout.class)) {
return new String[0][0];
}
private class MobileCellEditor extends AbstractCellEditor implements TableCellEditor {
UITableTextField uiTableTextField;
MobileCellEditor(){
uiTableTextField = new UITableTextField();
uiTableTextField.addFocusListener(new FocusAdapter() {
@Override
public void focusLost(FocusEvent evt) {
stopCellEditing();
designer.fireTargetModified();
}
});
uiTableTextField.getDocument().addDocumentListener(new DocumentListener() {
@Override
public void insertUpdate(DocumentEvent e) {
firePropertyChange();
}
@Override
public void removeUpdate(DocumentEvent e) {
firePropertyChange();
ArrayList<String> strings = ((WLayout)selectedModel).getMobileWidgetList();
String[][] widgetName = new String[strings.size() + 1][1];
widgetName[0][0] = Inter.getLocText("FR-Designer_WidgetOrder");
for (int i = 0; i < strings.size(); i++) {
widgetName[i + 1][0] = strings.get(i);
}
@Override
public void changedUpdate(DocumentEvent e) {
firePropertyChange();
return widgetName;
} else {
return new String[0][0];
}
});
}
/**
* cell改变相应的nametag改变
*/
public void firePropertyChange(){
((WParameterLayout) designer.getParaComponent().toData()).add2NameTagMap(uiTableTextField.getText(),
cellData[getSelectedRow()][1]);
public boolean isCollapsed() {
return collapsed;
}
public Object getCellEditorValue(){
return uiTableTextField.getText();
public void setCollapsed(boolean collapsed) {
this.collapsed = collapsed;
}
/*
* 双击以编辑
/**
* 自定义的tableEditor类
*/
public boolean isCellEditable(EventObject anEvent) {
if (anEvent instanceof MouseEvent) {
return ((MouseEvent)anEvent).getClickCount() >= 2;
}
return true;
}
public Component getTableCellEditorComponent( JTable table,Object value,
boolean isSelected,int row,int column){
uiTableTextField.setText(value.toString());
return uiTableTextField;
}
}
public class BeanTableModel extends DefaultTableModel {
public BeanTableModel() {
super(cellData,headers);
@ -301,12 +300,15 @@ public class MobileWidgetTable extends JTable {
@Override
public int getRowCount() {
if (isCollapsed()) {
return 1;
}
return cellData.length;
}
@Override
public int getColumnCount() {
return 2;
return 1;
}
@ -315,20 +317,16 @@ public class MobileWidgetTable extends JTable {
if (row >= getRowCount() || column >= getColumnCount()) {
return null;
}
Object[] rowValue = cellData[row];
if (column > -1 && column < rowValue.length) {
return cellData[row][column];
if (row == 0) {
return (isCollapsed()? "+" : "-") + cellData[row][0];
}
return null;
return cellData[row][0];
}
@Override
public String getColumnName(int column) {
if (column == 0) {
return headers[0];
} else {
return headers[1];
}
}
@ -338,10 +336,10 @@ public class MobileWidgetTable extends JTable {
return;
}
if (aValue == null) {
cellData[row][column] = null;
cellData[row] = null;
return;
}
cellData[row][column] = aValue.toString();
cellData[row][0] = aValue.toString();
}
/**
@ -351,35 +349,9 @@ public class MobileWidgetTable extends JTable {
* @return 是否可编辑
*/
public boolean isCellEditable(int row, int column) {
if(column ==1){
return false;
}
return true;
}
}
private class UITableTextField extends UITextField {
public UITableTextField(){
super();
}
public UITableTextField(String string){
super(string);
}
protected void paintBorder(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (this.isFocusOwner()) {
g2d.setStroke(new BasicStroke(1.5f));
} else {
g2d.setStroke(new BasicStroke(1f));
}
RoundRectangle2D.Double rect = new RoundRectangle2D.Double(0, 0, this.getWidth() - 2, this.getHeight() - 2, 4, 4);
g2d.setColor(Color.orange);
g2d.draw(rect);
}
}
}

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

@ -13,39 +13,41 @@ 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.ilable.UILabel;
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;
/**
* 控件属性表Docking
* 控件属性表绘制
* Modified by fanglei
*/
public class WidgetPropertyPane extends FormDockView implements BaseWidgetPropertyPane {
private WidgetPropertyTable propertyTable;
private EventPropertyTable eventTable;
private List<AbstractPropertyTable> widgetPropertyTables;
private FormDesigner designer;
private JPanel wsp;
private MobileWidgetTable mobileWidgetTable;
private MobileBodyWidgetTable mobileBodyWidgetTable;
private UIScrollPane downPanel;
private JPanel centerPane;
private CardLayout cardLayout;
public static final String PARA = "para";
public static final String BODY = "body";
public static final int NODE_LENGTH = 2;
public boolean isrefresh = true;
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) {
@ -68,37 +70,6 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
setLayout(FRGUIPaneFactory.createBorderLayout());
}
public class mobileWidgetDesignerAdapter implements DesignerEditListener {
public 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);
mobileWidgetTable.refresh();
} else {
cardLayout.show(centerPane,BODY);
mobileBodyWidgetTable.refresh();
}
//出现滚动条
downPanel.doLayout();
//控件列表选中某组件,触发表单中选中控件,选中事件又触发列表刷新,滚动条回到0
//此处设置滚动条值为刷新前
downPanel.getVerticalScrollBar().setValue(value);
}
}
}
@Override
public String getViewTitle() {
return Inter.getLocText("Form-Widget_Property_Table");
@ -110,6 +81,9 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
}
@Override
/**
* 绘制属性表tab
*/
public void refreshDockingView() {
designer = this.getEditingFormDesigner();
removeAll();
@ -118,66 +92,149 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
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);
UIScrollPane psp = new UIScrollPane(propertyTable);
psp = new UIScrollPane(propertyTable); // 用来装载属性表table
psp.setBorder(null);
}
/**
* 创建事件表事件选项卡不是JTable
*/
private void createEventTable() {
eventTable = new EventPropertyTable(designer);
designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable));
eventTable.setBorder(null);
UIScrollPane esp = new UIScrollPane(eventTable);
esp = new UIScrollPane(eventTable); //用来装载事件table
esp.setBorder(null);
wsp = FRGUIPaneFactory.createBorderLayout_S_Pane();
}
/**
* 创建移动端控件列表
*/
private void createMobileWidgetTable() {
//加上表头后,这里不再使用borderLayout布局,而采用BoxLayout布局
wsp = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
wsp.setBorder(null);
mobileParaWidgetTable = new MobileParaWidgetTable(designer);
mobileWidgetTable = new MobileWidgetTable(designer);
mobileBodyWidgetTable = new MobileBodyWidgetTable(designer);
designer.addDesignerEditListener(new mobileWidgetDesignerAdapter());
centerPane = FRGUIPaneFactory.createCardLayout_S_Pane();
cardLayout = (CardLayout) centerPane.getLayout();
centerPane.add(mobileWidgetTable,PARA);
centerPane.add(mobileBodyWidgetTable,BODY);
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));
wsp.add(downPanel,BorderLayout.CENTER);
downPanel.setBorder(new LineBorder(Color.GRAY));
UITabbedPane tabbedPane = new UITabbedPane();
initTabPane(psp, esp, tabbedPane);
//获取拓展移动端属性tab
WidgetPropertyUIProvider[] widgetAttrProviders = getExtraPropertyUIProviders();
addWidgetAttr(widgetAttrProviders);
}
/**
* 将属性表事件表移动端控件列表整合到TabPane里面去
*/
private void createTabPane() {
UITabbedPane tabbedPane = new UITabbedPane(); // tab选项卡容器
initTabPane(tabbedPane);
add(tabbedPane, BorderLayout.CENTER);
propertyTable.initPropertyGroups(null);
eventTable.refresh();
for (AbstractPropertyTable propertyTable : widgetPropertyTables) {
propertyTable.initPropertyGroups(designer);
}
isrefresh = false;
/**
* 获取当前控件扩展的属性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) {
UILabel upLabel = new UILabel(Inter.getLocText("FR-Widget_Mobile_Table"), SwingConstants.CENTER);
upLabel.setBorder(BorderFactory.createEmptyBorder(6,0,6,0));
wsp.add(upLabel, BorderLayout.NORTH);
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(propertyTable);
uiScrollPane.setBorder(null);
UIScrollPane uiScrollPane = new UIScrollPane(getExtraBodyTable(propertyTable));
wsp.add(uiScrollPane);
}
}
}
private void initTabPane(UIScrollPane psp, UIScrollPane esp, UITabbedPane tabbedPane) {
/**
* 如果是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);
@ -201,31 +258,12 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
return xCreator.acceptType(XWParameterLayout.class) || container.acceptType(XWParameterLayout.class);
}
/**
* 获取当前控件扩展的属性tab
* 来源有两个:
* 1, 各个控件从各自的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);
WidgetPropertyUIProvider[] widgetAttrProviders = ArrayUtils.addAll(embeddedPropertyUIProviders, set.toArray(new WidgetPropertyUIProvider[set.size()]));
return widgetAttrProviders;
}
public void setEditingFormDesigner(BaseFormDesigner editor) {
FormDesigner fd = (FormDesigner) editor;
super.setEditingFormDesigner(fd);
}
public void clearDockingView() {
private void clearDockingView() {
propertyTable = null;
eventTable = null;
if (widgetPropertyTables != null) {
@ -236,10 +274,13 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
this.add(psp, BorderLayout.CENTER);
}
public class WidgetPropertyDesignerAdapter implements DesignerEditListener {
/**
* 属性表监听界面事件(编辑删除选中改变大小)
*/
private class WidgetPropertyDesignerAdapter implements DesignerEditListener {
AbstractPropertyTable propertyTable;
public WidgetPropertyDesignerAdapter(AbstractPropertyTable propertyTable) {
WidgetPropertyDesignerAdapter(AbstractPropertyTable propertyTable) {
this.propertyTable = propertyTable;
}
@ -260,17 +301,19 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
}
}
public class EventPropertyDesignerAdapter implements DesignerEditListener {
/**
* 事件表监听界面事件编辑选中
*/
private class EventPropertyDesignerAdapter implements DesignerEditListener {
EventPropertyTable propertyTable;
public EventPropertyDesignerAdapter(EventPropertyTable eventTable) {
EventPropertyDesignerAdapter(EventPropertyTable eventTable) {
this.propertyTable = eventTable;
}
@Override
public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) {
propertyTable.refresh();
}
@ -282,6 +325,40 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
}
}
/**
* 移动端属性表监听界面事件改变大小编辑选中增加控件
*/
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;

Loading…
Cancel
Save