diff --git a/designer_base/src/com/fr/design/gui/itable/AbstractPropertyTable.java b/designer_base/src/com/fr/design/gui/itable/AbstractPropertyTable.java index 02a6f547b8..6d36c31bdc 100644 --- a/designer_base/src/com/fr/design/gui/itable/AbstractPropertyTable.java +++ b/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 { - // 属性分组 + // // 所有数据组, 把数据分组,一个可折叠的项里面的所有行 为一组 protected ArrayList groups; 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 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(); 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,24 +75,26 @@ 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(); - } else { - return group.getSecondRenderer(); - } + //采用group中定义好的标题行渲染器 + return group.getRenderer(); } 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 +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) { int count = 0; for (int i = 0; i < groups.size(); i++) { @@ -135,6 +154,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,6 +171,11 @@ public abstract class AbstractPropertyTable extends JTable { } } + /** + * 这个mousePressed和上面的mouseClicked唯一不同的地方是单双击和e.getX() < 10 的判断 + * 这个意思应该就是说点到图标(加号减号),立即触发折叠效果,否则点其他处要双击才能触发 + * @param e + */ @Override public void mousePressed(MouseEvent e) { if (!e.isPopupTrigger() && groups != null) { @@ -163,16 +191,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 diff --git a/designer_base/src/com/fr/design/gui/itable/PropertyGroup.java b/designer_base/src/com/fr/design/gui/itable/PropertyGroup.java index f66288e391..0e6426ac17 100644 --- a/designer_base/src/com/fr/design/gui/itable/PropertyGroup.java +++ b/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; +/** + * PropertyGroup类描述了属性表中一个属性分组 + */ public class PropertyGroup { - private GroupModel model; - private String name; - private boolean collapsed; - private GroupRenderer renderer1; - private GroupRenderer renderer2; + private GroupModel model; // 描述这个属性组中的数据model + private String name; // 这组属性的标题名称 + private boolean collapsed; // 这组属性是否折叠 + private GroupRenderer renderer; // 属性标题渲染器 public PropertyGroup(GroupModel model) { this(model.getGroupName(), model, false); - renderer1 = new GroupRenderer(); - renderer2 = new GroupRenderer(); + renderer = new GroupRenderer(); } public PropertyGroup(String name, GroupModel model, boolean collapsed) { @@ -48,11 +49,8 @@ public class PropertyGroup { this.collapsed = collapsed; } - public TableCellRenderer getFirstRenderer() { - return renderer1; + public TableCellRenderer getRenderer() { + return renderer; } - public TableCellRenderer getSecondRenderer() { - return renderer2; - } } \ No newline at end of file diff --git a/designer_base/src/com/fr/design/locale/designer.properties b/designer_base/src/com/fr/design/locale/designer.properties index 41f3c8cdd8..2140d85182 100644 --- a/designer_base/src/com/fr/design/locale/designer.properties +++ b/designer_base/src/com/fr/design/locale/designer.properties @@ -520,4 +520,5 @@ FR-Designer_Background_Clear= FR-Designer_Background_Image_Select= FR-Designer_Tab_carousel= FR-Designer_setCarousel= -FR-Designer_carouselInterval= \ No newline at end of file +FR-Designer_carouselInterval= +FR-Designer_WidgetOrder= \ No newline at end of file diff --git a/designer_base/src/com/fr/design/locale/designer_en_US.properties b/designer_base/src/com/fr/design/locale/designer_en_US.properties index 334e01ca8c..7067d99320 100644 --- a/designer_base/src/com/fr/design/locale/designer_en_US.properties +++ b/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_Tab_carousel= FR-Designer_setCarousel= -FR-Designer_carouselInterval= \ No newline at end of file +FR-Designer_carouselInterval= +FR-Designer_WidgetOrder=Widget Order \ No newline at end of file diff --git a/designer_base/src/com/fr/design/locale/designer_zh_CN.properties b/designer_base/src/com/fr/design/locale/designer_zh_CN.properties index 10c53380d0..b86e381ba7 100644 --- a/designer_base/src/com/fr/design/locale/designer_zh_CN.properties +++ b/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_Tab_carousel=tab\u8F6E\u64AD FR-Designer_setCarousel=\u5F00\u542F\u8F6E\u64AD -FR-Designer_carouselInterval=\u8F6E\u64AD\u95F4\u9694 \ No newline at end of file +FR-Designer_carouselInterval=\u8F6E\u64AD\u95F4\u9694 +FR-Designer_WidgetOrder=\u63A7\u4EF6\u987A\u5E8F \ No newline at end of file diff --git a/designer_base/src/com/fr/design/locale/designer_zh_TW.properties b/designer_base/src/com/fr/design/locale/designer_zh_TW.properties index 96cb4260a9..795ae69876 100644 --- a/designer_base/src/com/fr/design/locale/designer_zh_TW.properties +++ b/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_Tab_carousel= FR-Designer_setCarousel= -FR-Designer_carouselInterval= \ No newline at end of file +FR-Designer_carouselInterval= +FR-Designer_WidgetOrder=\u63A7\u4EF6\u9806\u5E8F \ No newline at end of file diff --git a/designer_form/src/com/fr/design/designer/beans/ConnectorCreator.java b/designer_form/src/com/fr/design/designer/beans/ConnectorCreator.java index 2bfc0bf3f6..70a5d71f2c 100644 --- a/designer_form/src/com/fr/design/designer/beans/ConnectorCreator.java +++ b/designer_form/src/com/fr/design/designer/beans/ConnectorCreator.java @@ -6,8 +6,7 @@ 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 { diff --git a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java index 3d53eab015..140204e75c 100644 --- a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java +++ b/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; diff --git a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java index 25b079caf0..0cfd0c7143 100644 --- a/designer_form/src/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java +++ b/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; /** diff --git a/designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java b/designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java index a9d7007703..aa9125e5df 100644 --- a/designer_form/src/com/fr/design/designer/beans/location/AccessDirection.java +++ b/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.utils.ComponentUtils; 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 diff --git a/designer_form/src/com/fr/design/designer/beans/location/Inner.java b/designer_form/src/com/fr/design/designer/beans/location/Inner.java index c54796a0ab..3abe94730d 100644 --- a/designer_form/src/com/fr/design/designer/beans/location/Inner.java +++ b/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; diff --git a/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java index 06ae6fa785..4ed1b6549b 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/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 diff --git a/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java b/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java index 483b08fe59..340ec9cd1e 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWFitLayout.java +++ b/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; diff --git a/designer_form/src/com/fr/design/designer/creator/XWScaleLayout.java b/designer_form/src/com/fr/design/designer/creator/XWScaleLayout.java index 46683401b8..8dad2c7f07 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWScaleLayout.java +++ b/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, 用此容器来实现 diff --git a/designer_form/src/com/fr/design/designer/creator/XWTitleLayout.java b/designer_form/src/com/fr/design/designer/creator/XWTitleLayout.java index c0f45c8889..0e1a293bdf 100644 --- a/designer_form/src/com/fr/design/designer/creator/XWTitleLayout.java +++ b/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.*; diff --git a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java b/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java index 42a45c53c3..08f5765b99 100644 --- a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java +++ b/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; diff --git a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java b/designer_form/src/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java index d772e3b453..a1fafb0075 100644 --- a/designer_form/src/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java +++ b/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.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.Inter; diff --git a/designer_form/src/com/fr/design/designer/properties/BodyAppRelayoutTable.java b/designer_form/src/com/fr/design/designer/properties/mobile/BodyAppRelayoutTable.java similarity index 89% rename from designer_form/src/com/fr/design/designer/properties/BodyAppRelayoutTable.java rename to designer_form/src/com/fr/design/designer/properties/mobile/BodyAppRelayoutTable.java index 36bde25d82..fb0cc93b49 100644 --- a/designer_form/src/com/fr/design/designer/properties/BodyAppRelayoutTable.java +++ b/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(); 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); } diff --git a/designer_form/src/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java b/designer_form/src/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java index 70b80bc990..a3a1e5086a 100644 --- a/designer_form/src/com/fr/design/designer/properties/mobile/BodyMobilePropertyUI.java +++ b/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; diff --git a/designer_form/src/com/fr/design/mainframe/ConnectorHelper.java b/designer_form/src/com/fr/design/mainframe/ConnectorHelper.java index e592a48c9b..f2b68043d1 100644 --- a/designer_form/src/com/fr/design/mainframe/ConnectorHelper.java +++ b/designer_form/src/com/fr/design/mainframe/ConnectorHelper.java @@ -7,12 +7,12 @@ 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 { //这个类是用来画连接线的,暂时用不到 diff --git a/designer_form/src/com/fr/design/mainframe/MobileBodyWidgetTable.java b/designer_form/src/com/fr/design/mainframe/MobileBodyWidgetTable.java deleted file mode 100644 index 90e2316a67..0000000000 --- a/designer_form/src/com/fr/design/mainframe/MobileBodyWidgetTable.java +++ /dev/null @@ -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 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; - } - - } - -} \ No newline at end of file diff --git a/designer_form/src/com/fr/design/mainframe/MobileParaWidgetTable.java b/designer_form/src/com/fr/design/mainframe/MobileParaWidgetTable.java new file mode 100644 index 0000000000..9d670db2ca --- /dev/null +++ b/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)); + } + } + + /** + * 鼠标拖动事件(如果鼠标当前是MOVE_CURSOR状态则执行开始拖动的代码, + * 绘制一个moveComponent来跟随鼠标移动) + * @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); + } + + } +} \ No newline at end of file diff --git a/designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java b/designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java index fb8f5fc861..a692e37667 100644 --- a/designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java +++ b/designer_form/src/com/fr/design/mainframe/MobileWidgetTable.java @@ -1,167 +1,208 @@ 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类主要显示各种容器的控件列表(body,tab,绝对布局快,不包括参数面板) * 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[][] cellData; + private String[] headers = {Inter.getLocText("Form-Widget_Name")}; + private static final int WIDGET_TABLE_ROW_HEIGHT = 22; + private UILabel moveComponent = new UILabel(); // 作为拖动时候随鼠标移动的那个半透明控件 private int selectedRow = -1; - private int GAP = 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() < 10){ // 如果是点击在第一行 + 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)); } } - @Override + /** + * 鼠标拖动事件(如果鼠标当前是MOVE_CURSOR状态则执行开始拖动的代码, + * 绘制一个moveComponent来跟随鼠标移动) + * @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){ - 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.setSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT)); - moveComponent.setVisible(true); - moveComponent.setForeground(Color.lightGray); - moveComponent.setBorder(BorderFactory.createLineBorder(Color.lightGray)); - } + int width = getColumnModel().getColumn(0).getWidth(); + //如果当前选中的行的范围是合理的话,就可以拖动 + if (selectedRow < getRowCount() && selectedRow > 0){ + setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); + draging = true; + moveComponent.setText(getValueAt(selectedRow,0).toString()); + moveComponent.setLocation(0, e.getY() - GAP); + moveComponent.setSize(new Dimension(width, WIDGET_TABLE_ROW_HEIGHT)); + moveComponent.setVisible(true); + moveComponent.setForeground(Color.lightGray); + moveComponent.setBorder(BorderFactory.createLineBorder(Color.lightGray)); + } } + + /** + * 设置鼠标单击时处理的事件(单击控件列表进入控件属性表) + * @param e + */ @Override - public void 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)); } }; @@ -170,130 +211,90 @@ public class MobileWidgetTable extends JTable { } public FormDesigner getEditingDesigner(){ - return designer; + return designer; } /** - * 刷新 + * 设置当前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; - } - } - selectedRow = row; - changeSelection(row,column,false,false); - if(row == -1){ - this.clearSelection(); - } + private void setCellSelected() { + selectedRow = getSelectedRow(); + if (selectedRow != -1) { + this.setRowSelectionInterval(selectedRow, selectedRow); + this.setColumnSelectionInterval(0, 0); } } - 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(); - } - - 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; + /** + * 切换属性组折叠属性true/false + */ + private void toggleCollapse() { + this.setCollapsed(!this.isCollapsed()); + //这里获取表格的父控件是为了当表格被折叠了后,装表格的父控件也要相应的重新布局一下 + //比如折叠之后表格行数应该比原来的少,占用父容器空间应该小点,不重新布局父容器,表格大小不会改变 + Container parent = MobileWidgetTable.this.getParent(); + if (parent != null) { + parent.revalidate(); } - + 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) { - firePropertyChange(); - } + /** + * 重新get排序后的数据 + */ + 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改变 - */ - public void firePropertyChange(){ - ((WParameterLayout) designer.getParaComponent().toData()).add2NameTagMap(uiTableTextField.getText(), - cellData[getSelectedRow()][1]); - } + //选择的控件 + Widget selectedModel = designer.getSelectionModel().getSelection().getSelectedCreator().toData(); - public Object getCellEditorValue(){ - return uiTableTextField.getText(); + if(selectedModel == null){ + return new String[0][0]; } - /* - * 双击以编辑 - */ - public boolean isCellEditable(EventObject anEvent) { - if (anEvent instanceof MouseEvent) { - return ((MouseEvent)anEvent).getClickCount() >= 2; + // 选择的控件有两种类型,一种是WLayout,代表容器,一种是Widget,代表控件 + if (selectedModel.acceptType(WLayout.class)) { + //WCardLayout里面并不是控件,而仍然是容器TabFitLayout,故要向下获取控件 + //WCardTitlelLayout是XWCardLayout的标题容器,里面同样不是控件,不能获取MobileList + //WTitleLayout是标题容器,比如图表的标题,里面是图表控件和Label标题控件,但是不需要获取MobileList + if (selectedModel.acceptType(WCardLayout.class) || selectedModel.acceptType(WCardTitleLayout.class) + || selectedModel.acceptType(WTitleLayout.class) || selectedModel.acceptType(WCardMainBorderLayout.class)) { + return new String[0][0]; + } + ArrayList 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, - boolean isSelected,int row,int column){ - uiTableTextField.setText(value.toString()); - return uiTableTextField; - } + public boolean isCollapsed() { + return collapsed; } + public void setCollapsed(boolean collapsed) { + this.collapsed = collapsed; + } + + /** + * 自定义的tableEditor类 + */ public class BeanTableModel extends DefaultTableModel { public BeanTableModel() { super(cellData,headers); @@ -301,12 +302,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 +319,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]; - } + return headers[0]; } @@ -338,10 +338,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 +351,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); - } - - } } \ No newline at end of file diff --git a/designer_form/src/com/fr/design/mainframe/WidgetPropertyPane.java b/designer_form/src/com/fr/design/mainframe/WidgetPropertyPane.java index a5ec304718..23242e399e 100644 --- a/designer_form/src/com/fr/design/mainframe/WidgetPropertyPane.java +++ b/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 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 WidgetPropertyTable propertyTable; // 控件的属性表 + private EventPropertyTable eventTable; // 控件的事件表 + private List 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出来作为一个组件 + private static final String PARA = "para"; + private static final String BODY = "body"; 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(); + + //依次创建属性表、事件表、移动端表,再将它们整合到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); + } + + /** + * 获取当前控件扩展的属性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 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 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;