Browse Source

设计器方面实现了控件顺序属性表

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
fanglei 8 years ago
parent
commit
cba9fa9a4d
  1. 61
      designer_base/src/com/fr/design/gui/itable/AbstractPropertyTable.java
  2. 22
      designer_base/src/com/fr/design/gui/itable/PropertyGroup.java
  3. 3
      designer_base/src/com/fr/design/locale/designer.properties
  4. 3
      designer_base/src/com/fr/design/locale/designer_en_US.properties
  5. 3
      designer_base/src/com/fr/design/locale/designer_zh_CN.properties
  6. 3
      designer_base/src/com/fr/design/locale/designer_zh_TW.properties
  7. 3
      designer_form/src/com/fr/design/designer/beans/ConnectorCreator.java
  8. 4
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java
  9. 2
      designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java
  10. 2
      designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java
  11. 3
      designer_form/src/com/fr/design/designer/beans/location/Inner.java
  12. 16
      designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java
  13. 2
      designer_form/src/com/fr/design/designer/creator/XWFitLayout.java
  14. 2
      designer_form/src/com/fr/design/designer/creator/XWScaleLayout.java
  15. 2
      designer_form/src/com/fr/design/designer/creator/XWTitleLayout.java
  16. 2
      designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java
  17. 2
      designer_form/src/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java
  18. 16
      designer_form/src/com/fr/design/designer/properties/mobile/BodyAppRelayoutTable.java
  19. 1
      designer_form/src/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java
  20. 2
      designer_form/src/com/fr/design/mainframe/ConnectorHelper.java
  21. 267
      designer_form/src/com/fr/design/mainframe/MobileBodyWidgetTable.java
  22. 431
      designer_form/src/com/fr/design/mainframe/MobileParaWidgetTable.java
  23. 460
      designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java
  24. 269
      designer_form/src/com/fr/design/mainframe/WidgetPropertyPane.java

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

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

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

@ -4,18 +4,19 @@ import javax.swing.table.TableCellRenderer;
import com.fr.design.beans.GroupModel; import com.fr.design.beans.GroupModel;
/**
* PropertyGroup类描述了属性表中一个属性分组
*/
public class PropertyGroup { public class PropertyGroup {
private GroupModel model; private GroupModel model; // 描述这个属性组中的数据model
private String name; private String name; // 这组属性的标题名称
private boolean collapsed; private boolean collapsed; // 这组属性是否折叠
private GroupRenderer renderer1; private GroupRenderer renderer; // 属性标题渲染器
private GroupRenderer renderer2;
public PropertyGroup(GroupModel model) { public PropertyGroup(GroupModel model) {
this(model.getGroupName(), model, false); this(model.getGroupName(), model, false);
renderer1 = new GroupRenderer(); renderer = new GroupRenderer();
renderer2 = new GroupRenderer();
} }
public PropertyGroup(String name, GroupModel model, boolean collapsed) { public PropertyGroup(String name, GroupModel model, boolean collapsed) {
@ -48,11 +49,8 @@ public class PropertyGroup {
this.collapsed = collapsed; this.collapsed = collapsed;
} }
public TableCellRenderer getFirstRenderer() { public TableCellRenderer getRenderer() {
return renderer1; return renderer;
} }
public TableCellRenderer getSecondRenderer() {
return renderer2;
}
} }

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

@ -520,4 +520,5 @@ FR-Designer_Background_Clear=
FR-Designer_Background_Image_Select= FR-Designer_Background_Image_Select=
FR-Designer_Tab_carousel= FR-Designer_Tab_carousel=
FR-Designer_setCarousel= FR-Designer_setCarousel=
FR-Designer_carouselInterval= FR-Designer_carouselInterval=
FR-Designer_WidgetOrder=

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

@ -520,4 +520,5 @@ FR-Designer_Background_Clear=Clear
FR-Designer_Background_Image_Select=Select Picture FR-Designer_Background_Image_Select=Select Picture
FR-Designer_Tab_carousel= FR-Designer_Tab_carousel=
FR-Designer_setCarousel= FR-Designer_setCarousel=
FR-Designer_carouselInterval= FR-Designer_carouselInterval=
FR-Designer_WidgetOrder=Widget Order

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

@ -524,4 +524,5 @@ FR-Designer_Background_Clear=\u6E05\u9664
FR-Designer_Background_Image_Select=\u9009\u62E9\u56FE\u7247 FR-Designer_Background_Image_Select=\u9009\u62E9\u56FE\u7247
FR-Designer_Tab_carousel=tab\u8F6E\u64AD FR-Designer_Tab_carousel=tab\u8F6E\u64AD
FR-Designer_setCarousel=\u5F00\u542F\u8F6E\u64AD FR-Designer_setCarousel=\u5F00\u542F\u8F6E\u64AD
FR-Designer_carouselInterval=\u8F6E\u64AD\u95F4\u9694 FR-Designer_carouselInterval=\u8F6E\u64AD\u95F4\u9694
FR-Designer_WidgetOrder=\u63A7\u4EF6\u987A\u5E8F

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

@ -512,4 +512,5 @@ FR-Designer_Background_Clear=
FR-Designer_Background_Image_Select= FR-Designer_Background_Image_Select=
FR-Designer_Tab_carousel= FR-Designer_Tab_carousel=
FR-Designer_setCarousel= FR-Designer_setCarousel=
FR-Designer_carouselInterval= FR-Designer_carouselInterval=
FR-Designer_WidgetOrder=\u63A7\u4EF6\u9806\u5E8F

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

@ -6,8 +6,7 @@ import java.util.ArrayList;
import java.util.PriorityQueue; import java.util.PriorityQueue;
import com.fr.form.ui.container.WLayout; 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 class ConnectorCreator {

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.form.ui.container.WAbsoluteLayout;
import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.ComponentUtils;
import com.fr.design.utils.gui.LayoutUtils; 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.ComparatorUtils;
import com.fr.general.FRLogger; import com.fr.general.FRLogger;
@ -111,7 +111,7 @@ public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter {
Rectangle curRec = new Rectangle(creatorX, creatorY, creator.getWidth(), creator.getHeight()); Rectangle curRec = new Rectangle(creatorX, creatorY, creator.getWidth(), creator.getHeight());
WAbsoluteLayout wAbsoluteLayout = (WAbsoluteLayout)topLayout.toData(); WAbsoluteLayout wAbsoluteLayout = (WAbsoluteLayout)topLayout.toData();
for (int i = 0, count = wAbsoluteLayout.getWidgetCount(); i < count; i++) { 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(); Rectangle rectangle = temp.getBounds();
if (curRec.intersects(rectangle)){ if (curRec.intersects(rectangle)){
return false; 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.mainframe.JForm;
import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.LayoutBorderStyle; 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.WLayout;
import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout; import com.fr.form.ui.container.cardlayout.WCardMainBorderLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
/** /**

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

@ -12,8 +12,8 @@ import com.fr.design.mainframe.FormDesigner;
import com.fr.design.mainframe.FormSelection; import com.fr.design.mainframe.FormSelection;
import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.container.WAbsoluteLayout; 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.container.WParameterLayout;
import com.fr.form.ui.widget.BoundsWidget;
/** /**
* @author richer * @author richer

3
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.mainframe.FormSelection;
import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.ComponentUtils;
import com.fr.form.ui.container.WAbsoluteLayout; 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.stable.ArrayUtils;
import com.fr.third.com.lowagie.text.*;
import java.awt.*; import java.awt.*;
import java.awt.Rectangle; import java.awt.Rectangle;

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.event.MouseEvent;
import java.awt.image.BufferedImage; import java.awt.image.BufferedImage;
import java.beans.IntrospectionException; import java.beans.IntrospectionException;
import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.AdapterBus;
import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.ComponentAdapter;
import com.fr.design.designer.beans.LayoutAdapter; 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.adapters.layout.FRAbsoluteLayoutAdapter;
import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.beans.location.Direction;
import com.fr.design.designer.beans.models.SelectionModel; 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.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.icon.IconPathConstants;
import com.fr.design.mainframe.*; 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.Connector;
import com.fr.form.ui.Widget; import com.fr.form.ui.Widget;
import com.fr.form.ui.container.WAbsoluteLayout; 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.container.WLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.FRScreen; import com.fr.general.FRScreen;
import com.fr.general.IOUtils; import com.fr.general.IOUtils;
import com.fr.general.Inter; import com.fr.general.Inter;
import com.fr.stable.core.PropertyChangeAdapter;
import org.eclipse.swt.internal.gdip.Rect;
import javax.swing.*;
/** /**
* @author richer * @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.design.utils.gui.LayoutUtils;
import com.fr.form.ui.PaddingMargin; import com.fr.form.ui.PaddingMargin;
import com.fr.form.ui.Widget; 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.WBodyLayoutType;
import com.fr.form.ui.container.WFitLayout; import com.fr.form.ui.container.WFitLayout;
import com.fr.form.ui.container.WLayout; import com.fr.form.ui.container.WLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.FRScreen; import com.fr.general.FRScreen;
import com.fr.general.Inter; import com.fr.general.Inter;
import com.fr.stable.ArrayUtils; 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.designer.beans.adapters.layout.FRScaleLayoutAdapter;
import com.fr.design.form.layout.FRScaleLayout; import com.fr.design.form.layout.FRScaleLayout;
import com.fr.form.ui.Widget; 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.container.WScaleLayout;
import com.fr.form.ui.widget.BoundsWidget;
/** /**
* 自适应布局中添加组件时部分控件如数字文本下拉等需要保持控件默认高度21 用此容器来实现 * 自适应布局中添加组件时部分控件如数字文本下拉等需要保持控件默认高度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.Label;
import com.fr.form.ui.Widget; import com.fr.form.ui.Widget;
import com.fr.form.ui.WidgetTitle; 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.container.WTitleLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.ComparatorUtils; import com.fr.general.ComparatorUtils;
import java.awt.*; import java.awt.*;

2
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.EditingMouseListener;
import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormDesigner;
import com.fr.form.ui.container.WBorderLayout; 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.container.cardlayout.WCardMainBorderLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.IOUtils; import com.fr.general.IOUtils;
import com.fr.general.Inter; import com.fr.general.Inter;

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

@ -23,9 +23,9 @@ import com.fr.design.mainframe.widget.editors.ImgBackgroundEditor;
import com.fr.design.mainframe.widget.renderer.FontCellRenderer; import com.fr.design.mainframe.widget.renderer.FontCellRenderer;
import com.fr.design.utils.gui.LayoutUtils; import com.fr.design.utils.gui.LayoutUtils;
import com.fr.form.ui.CardSwitchButton; 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.WCardTagLayout;
import com.fr.form.ui.container.cardlayout.WTabFitLayout; import com.fr.form.ui.container.cardlayout.WTabFitLayout;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.general.Background; import com.fr.general.Background;
import com.fr.general.FRFont; import com.fr.general.FRFont;
import com.fr.general.Inter; import com.fr.general.Inter;

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

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

@ -7,12 +7,12 @@ import java.awt.Rectangle;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.util.ArrayList; import java.util.ArrayList;
import com.fr.form.ui.widget.BoundsWidget;
import com.fr.stable.Constants; import com.fr.stable.Constants;
import com.fr.base.GraphHelper; import com.fr.base.GraphHelper;
import com.fr.design.designer.beans.ConnectorCreator; import com.fr.design.designer.beans.ConnectorCreator;
import com.fr.design.designer.creator.XWAbsoluteLayout; import com.fr.design.designer.creator.XWAbsoluteLayout;
import com.fr.form.ui.Connector; import com.fr.form.ui.Connector;
import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget;
public class ConnectorHelper { public class ConnectorHelper {
//这个类是用来画连接线的,暂时用不到 //这个类是用来画连接线的,暂时用不到

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;
}
}
}

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

@ -0,0 +1,431 @@
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);
}
}
}

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

@ -1,167 +1,208 @@
package com.fr.design.mainframe; package com.fr.design.mainframe;
import java.awt.*;
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.MouseAdapter;
import java.awt.event.MouseEvent; import java.awt.event.MouseEvent;
import java.awt.geom.RoundRectangle2D; import java.util.ArrayList;
import java.util.EventObject;
import javax.swing.AbstractCellEditor;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.JLabel;
import javax.swing.JTable; import javax.swing.JTable;
import javax.swing.ListSelectionModel; import javax.swing.ListSelectionModel;
import javax.swing.event.DocumentEvent; import javax.swing.table.*;
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.designer.creator.XCreator;
import com.fr.design.gui.ilable.UILabel; 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.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.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.ComparatorUtils;
import com.fr.general.Inter; import com.fr.general.Inter;
import com.fr.stable.StringUtils; import com.fr.stable.StringUtils;
/** /**
* MobileWidgetTable类主要显示各种容器的控件列表bodytab绝对布局快不包括参数面板
* Created with IntelliJ IDEA. * Created with IntelliJ IDEA.
* User: zx * User: zx
* Date: 14-7-9 * Date: 14-9-15
* Time: 上午11:26 * Time: 下午4:52
* Modified by fanglei at 2017/01/23
*/ */
public class MobileWidgetTable extends JTable { public class MobileWidgetTable extends JTable {
private FormDesigner designer; private FormDesigner designer;
protected TableModel defaultmodel; private String[][] cellData;
private String[][] cellData ; private String[] headers = {Inter.getLocText("Form-Widget_Name")};
private String[] headers = {Inter.getLocText("FR-Utils_Label"),Inter.getLocText("Form-Widget_Name")}; private static final int WIDGET_TABLE_ROW_HEIGHT = 22;
public static final int WIDGET_TABLE_ROW_HEIGHT = 22; private UILabel moveComponent = new UILabel(); // 作为拖动时候随鼠标移动的那个半透明控件
private UILabel moveComponent = new UILabel();
private int selectedRow = -1; private int selectedRow = -1;
private int GAP = 10; private int GAP = 11;
private boolean draging = false; 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) { public MobileWidgetTable(FormDesigner designer) {
this.designer = designer; this.designer = designer;
this.cellData = getData(); cellData = getData();
this.setRowHeight(WIDGET_TABLE_ROW_HEIGHT); 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(); JTableHeader header = getTableHeader();
header.setReorderingAllowed(false); header.setReorderingAllowed(false);
header.setPreferredSize(new Dimension(0, WIDGET_TABLE_ROW_HEIGHT)); header.setPreferredSize(new Dimension(0, 0)); // 隐藏表头
header.setDefaultRenderer(new HeaderRenderer()); 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.setGridColor(new Color(212, 208, 200));
this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); this.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
this.setColumnSelectionAllowed(false); this.setColumnSelectionAllowed(false);
this.setRowSelectionAllowed(false); this.setRowSelectionAllowed(false);
this.setFillsViewportHeight(true); this.setFillsViewportHeight(false);
this.setDefaultEditor(Object.class,new MobileCellEditor());
defaultmodel = new BeanTableModel();
this.setModel(defaultmodel);
this.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS); 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() { private MouseAdapter mouseAdapter = new MouseAdapter() {
/**
* 鼠标按下时处理的事件设置当前选中的行列
* @param e
*/
@Override @Override
public void mouseClicked(MouseEvent e) { public void mousePressed(MouseEvent e) {
if(getSelectedRow() != -1 && getSelectedColumn() == 1){ getInstance().setCellSelected();
String widgetName = cellData[getSelectedRow()][getSelectedColumn()]; if (selectedRow == 0 && !e.isPopupTrigger() && e.getClickCount() == 1 && e.getX() < 10){ // 如果是点击在第一行
if (StringUtils.isNotEmpty(widgetName)){ toggleCollapse();
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)); * @param e
selectedRow = getSelectedRow(); */
} @Override
} public void mouseReleased(MouseEvent e) {
} if(!draging){
} return;
} }
public void mouseExited(MouseEvent e) {
draging = false; draging = false;
moveComponent.setVisible(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 @Override
public void mouseMoved(MouseEvent e) { public void mouseMoved(MouseEvent e) {
int overColumn = e.getX() < getColumnModel().getColumn(0).getWidth() ? 0 : 1; int overRow = 0;
int overRow = -1;
for (int i = 0;i < getRowCount();i++) { for (int i = 0;i < getRowCount();i++) {
if (e.getY() > i * WIDGET_TABLE_ROW_HEIGHT && e.getY() <= (i + 1) * WIDGET_TABLE_ROW_HEIGHT){ 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)); setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
} else { } else {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
} }
} }
@Override /**
* 鼠标拖动事件如果鼠标当前是<code>MOVE_CURSOR</code>状态则执行开始拖动的代码
* 绘制一个<code>moveComponent</code>来跟随鼠标移动
* @param e
*/
@Override
public void mouseDragged(MouseEvent e) { public void mouseDragged(MouseEvent e) {
if (e.getX() < getColumnModel().getColumn(0).getWidth()) { int width = getColumnModel().getColumn(0).getWidth();
draging = false; //如果当前选中的行的范围是合理的话,就可以拖动
moveComponent.setVisible(false); if (selectedRow < getRowCount() && selectedRow > 0){
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
} draging = true;
int width = getColumnModel().getColumn(1).getWidth(); moveComponent.setText(getValueAt(selectedRow,0).toString());
if (getCursor().getType() == Cursor.MOVE_CURSOR){ moveComponent.setLocation(0, e.getY() - GAP);
draging = true; moveComponent.setSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT));
//下面这句话太重要了,拖拽过程中选中的不变 moveComponent.setVisible(true);
getInstance().setRowSelectionInterval(selectedRow,selectedRow); moveComponent.setForeground(Color.lightGray);
moveComponent.setText(getValueAt(getSelectedRow(), getSelectedColumn()).toString()); moveComponent.setBorder(BorderFactory.createLineBorder(Color.lightGray));
moveComponent.setLocation(getColumnModel().getColumn(0).getWidth(), 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));
}
} }
/**
* 设置鼠标单击时处理的事件单击控件列表进入控件属性表
* @param e
*/
@Override @Override
public void mouseReleased(MouseEvent e) { public void mouseClicked(MouseEvent e) {
if(!draging){ if(selectedRow > 0){
return; //当前点击的控件的名字
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; draging = false;
moveComponent.setVisible(false); moveComponent.setVisible(false);
int toIndex = e.getY() < GAP ? 0 : (int)Math.rint((e.getY() - GAP)/WIDGET_TABLE_ROW_HEIGHT) + 1; setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
((WParameterLayout) designer.getParaComponent().toData()).adjustOrder(getSelectedRow(), toIndex);
getInstance().setRowSelectionInterval(0,getRowCount() - 1);
refresh();
getInstance().repaint();
designer.fireTargetModified();
} }
}; };
@ -170,130 +211,90 @@ public class MobileWidgetTable extends JTable {
} }
public FormDesigner getEditingDesigner(){ public FormDesigner getEditingDesigner(){
return designer; return designer;
} }
/** /**
* 刷新 * 设置当前get到的行列的单元格为选中状态
*/ */
public void refresh(){ private void setCellSelected() {
XCreator creator = designer.getSelectionModel().getSelection().getSelectedCreator(); selectedRow = getSelectedRow();
cellData = getData(); if (selectedRow != -1) {
if(creator != null){ this.setRowSelectionInterval(selectedRow, selectedRow);
String widgetName =creator.toData().getWidgetName(); this.setColumnSelectionInterval(0, 0);
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;
}
}
selectedRow = row;
changeSelection(row,column,false,false);
if(row == -1){
this.clearSelection();
}
} }
} }
private String[][] getData(){ /**
XLayoutContainer paraContainer = designer.getParaComponent(); * 切换属性组折叠属性true/false
if(paraContainer == null || !paraContainer.acceptType(XWParameterLayout.class)){ */
return new String[0][0]; private void toggleCollapse() {
} this.setCollapsed(!this.isCollapsed());
//这里获取表格的父控件是为了当表格被折叠了后,装表格的父控件也要相应的重新布局一下
WParameterLayout para = (WParameterLayout) (paraContainer.toData()); //比如折叠之后表格行数应该比原来的少,占用父容器空间应该小点,不重新布局父容器,表格大小不会改变
return para.getWidgetNameTag(); Container parent = MobileWidgetTable.this.getParent();
} if (parent != null) {
parent.revalidate();
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;
} }
repaint();
} }
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) { * 重新get排序后的数据
firePropertyChange(); */
} public void refreshData(){
cellData = getData();
}
@Override /**
public void changedUpdate(DocumentEvent e) { * 获取选中控件的控件列表
firePropertyChange(); *
} * @return String[][] 二维数组[0][0]widgetName
}); */
private String[][] getData(){
if(designer.isFormParaDesigner()){
return new String[0][0];
} }
/** //选择的控件
* cell改变相应的nametag改变 Widget selectedModel = designer.getSelectionModel().getSelection().getSelectedCreator().toData();
*/
public void firePropertyChange(){
((WParameterLayout) designer.getParaComponent().toData()).add2NameTagMap(uiTableTextField.getText(),
cellData[getSelectedRow()][1]);
}
public Object getCellEditorValue(){ if(selectedModel == null){
return uiTableTextField.getText(); return new String[0][0];
} }
/* // 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件
* 双击以编辑 if (selectedModel.acceptType(WLayout.class)) {
*/ //WCardLayout里面并不是控件,而仍然是容器TabFitLayout,故要向下获取控件
public boolean isCellEditable(EventObject anEvent) { //WCardTitlelLayout是XWCardLayout的标题容器,里面同样不是控件,不能获取MobileList
if (anEvent instanceof MouseEvent) { //WTitleLayout是标题容器,比如图表的标题,里面是图表控件和Label标题控件,但是不需要获取MobileList
return ((MouseEvent)anEvent).getClickCount() >= 2; if (selectedModel.acceptType(WCardLayout.class) || selectedModel.acceptType(WCardTitleLayout.class)
|| selectedModel.acceptType(WTitleLayout.class) || selectedModel.acceptType(WCardMainBorderLayout.class)) {
return new String[0][0];
}
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);
} }
return true; return widgetName;
} else {
return new String[0][0];
} }
}
public Component getTableCellEditorComponent( JTable table,Object value, public boolean isCollapsed() {
boolean isSelected,int row,int column){ return collapsed;
uiTableTextField.setText(value.toString());
return uiTableTextField;
}
} }
public void setCollapsed(boolean collapsed) {
this.collapsed = collapsed;
}
/**
* 自定义的tableEditor类
*/
public class BeanTableModel extends DefaultTableModel { public class BeanTableModel extends DefaultTableModel {
public BeanTableModel() { public BeanTableModel() {
super(cellData,headers); super(cellData,headers);
@ -301,12 +302,15 @@ public class MobileWidgetTable extends JTable {
@Override @Override
public int getRowCount() { public int getRowCount() {
if (isCollapsed()) {
return 1;
}
return cellData.length; return cellData.length;
} }
@Override @Override
public int getColumnCount() { public int getColumnCount() {
return 2; return 1;
} }
@ -315,20 +319,16 @@ public class MobileWidgetTable extends JTable {
if (row >= getRowCount() || column >= getColumnCount()) { if (row >= getRowCount() || column >= getColumnCount()) {
return null; return null;
} }
Object[] rowValue = cellData[row]; if (row == 0) {
if (column > -1 && column < rowValue.length) { return (isCollapsed()? "+" : "-") + cellData[row][0];
return cellData[row][column];
} }
return null;
return cellData[row][0];
} }
@Override @Override
public String getColumnName(int column) { public String getColumnName(int column) {
if (column == 0) { return headers[0];
return headers[0];
} else {
return headers[1];
}
} }
@ -338,10 +338,10 @@ public class MobileWidgetTable extends JTable {
return; return;
} }
if (aValue == null) { if (aValue == null) {
cellData[row][column] = null; cellData[row] = null;
return; return;
} }
cellData[row][column] = aValue.toString(); cellData[row][0] = aValue.toString();
} }
/** /**
@ -351,35 +351,9 @@ public class MobileWidgetTable extends JTable {
* @return 是否可编辑 * @return 是否可编辑
*/ */
public boolean isCellEditable(int row, int column) { public boolean isCellEditable(int row, int column) {
if(column ==1){
return false; 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.fun.WidgetPropertyUIProvider;
import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.frpane.UITabbedPane;
import com.fr.design.gui.icontainer.UIScrollPane; 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.gui.itable.AbstractPropertyTable;
import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.form.ui.Widget;
import com.fr.general.Inter; import com.fr.general.Inter;
import com.fr.stable.ArrayUtils; import com.fr.stable.ArrayUtils;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.LineBorder; import javax.swing.border.LineBorder;
import javax.swing.table.JTableHeader;
import java.awt.*; import java.awt.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
/** /**
* 控件属性表Docking * 控件属性表绘制
* Modified by fanglei
*/ */
public class WidgetPropertyPane extends FormDockView implements BaseWidgetPropertyPane { public class WidgetPropertyPane extends FormDockView implements BaseWidgetPropertyPane {
private WidgetPropertyTable propertyTable; private WidgetPropertyTable propertyTable; // 控件的属性表
private EventPropertyTable eventTable; private EventPropertyTable eventTable; // 控件的事件表
private List<AbstractPropertyTable> widgetPropertyTables; private List<AbstractPropertyTable> widgetPropertyTables; // 这个变量应该是保存控件拓展的属性tab
private FormDesigner designer; private FormDesigner designer; // 当前designer
private JPanel wsp; private UIScrollPane psp; // 用来装载属性表table的容器
private MobileWidgetTable mobileWidgetTable; private UIScrollPane esp; //用来装载事件table的容器
private MobileBodyWidgetTable mobileBodyWidgetTable; private JPanel wsp; // 装载移动端tab的容器,包括移动端属性表和控件拓展的移动端属性表
private UIScrollPane downPanel; private MobileParaWidgetTable mobileParaWidgetTable; // 参数面板的移动端属性tab(和body的移动端属性tab区别是没有标签名column)
private JPanel centerPane; private MobileWidgetTable mobileWidgetTable; // body的移动端属性tab
private CardLayout cardLayout; private UIScrollPane downPanel; // 这个滚动容器是用于装载centerPane的
public static final String PARA = "para"; private JPanel centerPane; // 此centerPane采用的是cardLayout布局,装载着mobileWidgetTable和mobileBodyWidgetTable
public static final String BODY = "body"; private CardLayout cardLayout; // 卡片布局,选中参数面板时显示mobileWidgetTable,选中body时显示mobileBodyWidgetTable
public static final int NODE_LENGTH = 2; private JTableHeader header;//把表头单独get出来作为一个组件
public boolean isrefresh = true; private static final String PARA = "para";
private static final String BODY = "body";
public static WidgetPropertyPane getInstance() { public static WidgetPropertyPane getInstance() {
if (HOLDER.singleton == null) { if (HOLDER.singleton == null) {
@ -68,37 +70,6 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
setLayout(FRGUIPaneFactory.createBorderLayout()); 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 @Override
public String getViewTitle() { public String getViewTitle() {
return Inter.getLocText("Form-Widget_Property_Table"); return Inter.getLocText("Form-Widget_Property_Table");
@ -110,6 +81,9 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
} }
@Override @Override
/**
* 绘制属性表tab
*/
public void refreshDockingView() { public void refreshDockingView() {
designer = this.getEditingFormDesigner(); designer = this.getEditingFormDesigner();
removeAll(); removeAll();
@ -118,66 +92,149 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
return; return;
} }
widgetPropertyTables = new ArrayList<AbstractPropertyTable>(); 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); propertyTable = new WidgetPropertyTable(designer);
designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable)); designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable));
propertyTable.setBorder(null); propertyTable.setBorder(null);
UIScrollPane psp = new UIScrollPane(propertyTable); psp = new UIScrollPane(propertyTable); // 用来装载属性表table
psp.setBorder(null); psp.setBorder(null);
}
/**
* 创建事件表事件选项卡不是JTable
*/
private void createEventTable() {
eventTable = new EventPropertyTable(designer); eventTable = new EventPropertyTable(designer);
designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable)); designer.addDesignerEditListener(new EventPropertyDesignerAdapter(eventTable));
eventTable.setBorder(null); eventTable.setBorder(null);
UIScrollPane esp = new UIScrollPane(eventTable); esp = new UIScrollPane(eventTable); //用来装载事件table
esp.setBorder(null); esp.setBorder(null);
wsp = FRGUIPaneFactory.createBorderLayout_S_Pane(); }
/**
* 创建移动端控件列表
*/
private void createMobileWidgetTable() {
//加上表头后,这里不再使用borderLayout布局,而采用BoxLayout布局
wsp = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane();
wsp.setBorder(null); wsp.setBorder(null);
mobileParaWidgetTable = new MobileParaWidgetTable(designer);
mobileWidgetTable = new MobileWidgetTable(designer); mobileWidgetTable = new MobileWidgetTable(designer);
mobileBodyWidgetTable = new MobileBodyWidgetTable(designer);
designer.addDesignerEditListener(new mobileWidgetDesignerAdapter()); designer.addDesignerEditListener(new mobileWidgetDesignerAdapter());
centerPane = FRGUIPaneFactory.createCardLayout_S_Pane(); centerPane = FRGUIPaneFactory.createCardLayout_S_Pane();
cardLayout = (CardLayout) centerPane.getLayout(); cardLayout = (CardLayout) centerPane.getLayout();
centerPane.add(mobileWidgetTable,PARA); centerPane.add(mobileParaWidgetTable, PARA);// 采用卡片布局的容器必须指定卡片名字,如果没有卡片名字
centerPane.add(mobileBodyWidgetTable,BODY); // 就会出现: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)){ if(hasSelectParaPane(designer)){
cardLayout.show(centerPane,PARA); cardLayout.show(centerPane,PARA);
header = mobileParaWidgetTable.getTableHeader();
} else { } else {
cardLayout.show(centerPane,BODY); cardLayout.show(centerPane,BODY);
header = mobileWidgetTable.getTableHeader();
} }
downPanel = new UIScrollPane(centerPane); downPanel = new UIScrollPane(centerPane);
downPanel.setBorder(new LineBorder(Color.gray)); downPanel.setBorder(new LineBorder(Color.GRAY));
wsp.add(downPanel,BorderLayout.CENTER);
UITabbedPane tabbedPane = new UITabbedPane(); //获取拓展移动端属性tab
initTabPane(psp, esp, tabbedPane);
WidgetPropertyUIProvider[] widgetAttrProviders = getExtraPropertyUIProviders(); WidgetPropertyUIProvider[] widgetAttrProviders = getExtraPropertyUIProviders();
addWidgetAttr(widgetAttrProviders); addWidgetAttr(widgetAttrProviders);
}
/**
* 将属性表事件表移动端控件列表整合到TabPane里面去
*/
private void createTabPane() {
UITabbedPane tabbedPane = new UITabbedPane(); // tab选项卡容器
initTabPane(tabbedPane);
add(tabbedPane, BorderLayout.CENTER); add(tabbedPane, BorderLayout.CENTER);
propertyTable.initPropertyGroups(null); }
eventTable.refresh();
for (AbstractPropertyTable propertyTable : widgetPropertyTables) { /**
propertyTable.initPropertyGroups(designer); * 获取当前控件扩展的属性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();
} }
isrefresh = false; 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) { private void addWidgetAttr(WidgetPropertyUIProvider[] widgetAttrProviders) {
if (widgetAttrProviders.length == 0) { if (widgetAttrProviders.length == 0) { // 判断有没有拓展的tab,没有就使用原来的
UILabel upLabel = new UILabel(Inter.getLocText("FR-Widget_Mobile_Table"), SwingConstants.CENTER); wsp.add(header);
upLabel.setBorder(BorderFactory.createEmptyBorder(6,0,6,0)); wsp.add(downPanel);
wsp.add(upLabel, BorderLayout.NORTH);
} else { } else {
for (WidgetPropertyUIProvider widgetAttrProvider : widgetAttrProviders) { for (WidgetPropertyUIProvider widgetAttrProvider : widgetAttrProviders) {
AbstractPropertyTable propertyTable = widgetAttrProvider.createWidgetAttrTable(); AbstractPropertyTable propertyTable = widgetAttrProvider.createWidgetAttrTable();
widgetPropertyTables.add(propertyTable); widgetPropertyTables.add(propertyTable);
designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable)); designer.addDesignerEditListener(new WidgetPropertyDesignerAdapter(propertyTable));
UIScrollPane uiScrollPane = new UIScrollPane(propertyTable); UIScrollPane uiScrollPane = new UIScrollPane(getExtraBodyTable(propertyTable));
uiScrollPane.setBorder(null);
wsp.add(uiScrollPane); 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.setOpaque(true);
tabbedPane.setBorder(null); tabbedPane.setBorder(null);
tabbedPane.setTabPlacement(SwingConstants.BOTTOM); tabbedPane.setTabPlacement(SwingConstants.BOTTOM);
@ -201,31 +258,12 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
return xCreator.acceptType(XWParameterLayout.class) || container.acceptType(XWParameterLayout.class); 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) { public void setEditingFormDesigner(BaseFormDesigner editor) {
FormDesigner fd = (FormDesigner) editor; FormDesigner fd = (FormDesigner) editor;
super.setEditingFormDesigner(fd); super.setEditingFormDesigner(fd);
} }
public void clearDockingView() { private void clearDockingView() {
propertyTable = null; propertyTable = null;
eventTable = null; eventTable = null;
if (widgetPropertyTables != null) { if (widgetPropertyTables != null) {
@ -236,10 +274,13 @@ public class WidgetPropertyPane extends FormDockView implements BaseWidgetProper
this.add(psp, BorderLayout.CENTER); this.add(psp, BorderLayout.CENTER);
} }
public class WidgetPropertyDesignerAdapter implements DesignerEditListener { /**
* 属性表监听界面事件(编辑删除选中改变大小)
*/
private class WidgetPropertyDesignerAdapter implements DesignerEditListener {
AbstractPropertyTable propertyTable; AbstractPropertyTable propertyTable;
public WidgetPropertyDesignerAdapter(AbstractPropertyTable propertyTable) { WidgetPropertyDesignerAdapter(AbstractPropertyTable propertyTable) {
this.propertyTable = 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; EventPropertyTable propertyTable;
public EventPropertyDesignerAdapter(EventPropertyTable eventTable) { EventPropertyDesignerAdapter(EventPropertyTable eventTable) {
this.propertyTable = eventTable; this.propertyTable = eventTable;
} }
@Override @Override
public void fireCreatorModified(DesignerEvent evt) { public void fireCreatorModified(DesignerEvent evt) {
if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED if (evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_EDITED
|| evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) { || evt.getCreatorEventID() == DesignerEvent.CREATOR_SELECTED) {
propertyTable.refresh(); 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 @Override
public Location preferredLocation() { public Location preferredLocation() {
return Location.WEST_BELOW; return Location.WEST_BELOW;

Loading…
Cancel
Save