diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java index 06d086aef..739cbdeee 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java @@ -31,7 +31,8 @@ import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.fun.TableDataPaneProcessor; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.gui.icontainer.UIScrollPane; -import com.fr.design.gui.ilist.CheckBoxList; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.ilist.CheckBoxListWithPartialSelect; import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itoolbar.UIToolbar; @@ -53,7 +54,6 @@ import com.fr.esd.event.StrategyEventsNotifier; import com.fr.esd.query.StrategicTableData; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralContext; -import com.fr.general.IOUtils; import com.fr.general.NameObject; import com.fr.log.FineLoggerFactory; import com.fr.plugin.context.PluginContext; @@ -115,6 +115,20 @@ public class TableDataTreePane extends BasicTableDataTreePane { return singleton; } + /** + * 获取不必每次都refreshDockingView的数据集树面板 + * 不会主动替换DesignModelAdapter,需要保证使用时没有跨模板动作,谨慎使用 + * @param tc + * @return + */ + public synchronized static BasicTableDataTreePane getInstanceWithoutRefreshEverytime(DesignModelAdapter tc) { + TableDataPaneProcessor treePaneProcessor = ExtraDesignClassManager.getInstance().getSingle(TableDataPaneProcessor.XML_TAG); + if (treePaneProcessor != null) { + return treePaneProcessor.createTableDataTreePane(tc); + } + return singleton.tc == null ? getInstance(tc) : singleton; + } + private TableDataSourceOP op; private TableDataTree tableDataTree; private UIPopupMenu popupMenu; @@ -210,7 +224,7 @@ public class TableDataTreePane extends BasicTableDataTreePane { private TreeSearchToolbarPane initToolBarPane() { // toolbar addMenuDef = new MenuDef(Toolkit.i18nText("Fine-Design_Basic_Action_Add")); - addMenuDef.setIconPath(IconPathConstants.ADD_POPMENU_ICON_PATH); + addMenuDef.setIconPath("/com/fr/design/images/control/addPopup"); createAddMenuDef(); // 创建插件监听 createPluginListener(); @@ -842,8 +856,8 @@ public class TableDataTreePane extends BasicTableDataTreePane { } @Override - public Icon getIcon() { - return IOUtils.readIcon("/com/fr/design/images/control/batch_esd_on.png"); + public String getIconResource() { + return "/com/fr/design/images/control/batch_esd_on"; } @Override @@ -889,8 +903,8 @@ public class TableDataTreePane extends BasicTableDataTreePane { } @Override - public Icon getIcon() { - return IOUtils.readIcon("/com/fr/design/images/control/batch_esd_off.png"); + public String getIconResource() { + return "/com/fr/design/images/control/batch_esd_off"; } @Override @@ -911,14 +925,14 @@ public class TableDataTreePane extends BasicTableDataTreePane { public abstract String getName(); - public abstract Icon getIcon(); + public abstract String getIconResource(); public abstract void doWithTableDataWrapper(TableDataWrapper tableDataWrapper); public AbstractESDAction() { this.setName(getName()); this.setMnemonic('R'); - this.setSmallIcon(getIcon()); + this.setSmallIcon(getIconResource()); } @Override @@ -984,7 +998,7 @@ public class TableDataTreePane extends BasicTableDataTreePane { public EditAction() { this.setName(Toolkit.i18nText("Fine-Design_Basic_Edit")); this.setMnemonic('E'); - this.setSmallIcon(IOUtils.readIcon(IconPathConstants.TD_EDIT_ICON_PATH)); + this.setSmallIcon("/com/fr/design/images/control/edit"); } @Override @@ -1011,7 +1025,7 @@ public class TableDataTreePane extends BasicTableDataTreePane { public RemoveAction() { this.setName(Toolkit.i18nText("Fine-Design_Basic_Remove")); this.setMnemonic('R'); - this.setSmallIcon(IOUtils.readIcon(IconPathConstants.TD_REMOVE_ICON_PATH)); + this.setSmallIcon("/com/fr/design/images/control/remove"); } @Override @@ -1021,8 +1035,10 @@ public class TableDataTreePane extends BasicTableDataTreePane { FineLoggerFactory.getLogger().error("Table Data to remove is null or not selected"); return; } - CheckBoxList checkBoxList = new CheckBoxList(selectedNameObjects, CheckBoxList.SelectedState.ALL, Toolkit.i18nText("Fine-Design_Basic_Remove_All_Selected")); - UIScrollPane scrollPane = new UIScrollPane(checkBoxList); + // 可以半选的CheckBoxList + CheckBoxListWithPartialSelect tableDataCheckBoxPane = new CheckBoxListWithPartialSelect(selectedNameObjects); + UIScrollPane scrollPane = new UIScrollPane(tableDataCheckBoxPane); + UILabel tips = new UILabel("Fine-Design_Basic_Select_Source_To_Remove"); BasicPane basicPane = new BasicPane() { @Override protected String title4PopupWindow() { @@ -1030,11 +1046,12 @@ public class TableDataTreePane extends BasicTableDataTreePane { } }; basicPane.setLayout(new BorderLayout()); + basicPane.add(tips, BorderLayout.NORTH); basicPane.add(scrollPane, BorderLayout.CENTER); BasicDialog basicDialog = basicPane.showSmallWindow(SwingUtilities.getWindowAncestor(TableDataTreePane.this), new DialogActionAdapter() { @Override public void doOk() { - Object[] selectedValues = checkBoxList.getSelectedValues(); + List selectedValues = tableDataCheckBoxPane.getSelectedObjects(); // 删除时如果正在搜索,跳回原树 if (TableDataTreeSearchManager.getInstance().isInSearchMode()) { TableDataTreeSearchManager.getInstance().outOfSearchMode(); diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TableDataSearchRemindPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TableDataSearchRemindPane.java index 23738338b..01b767623 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TableDataSearchRemindPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TableDataSearchRemindPane.java @@ -190,7 +190,7 @@ public class TableDataSearchRemindPane extends JPanel implements TreeSearchStatu @Override public void onInSearching() { - this.textLabel.setText(IN_SEARCHING); + this.textLabel.setVisible(false); this.stopLabel.setText(STOP_SEARCHING); this.stopLabel.setVisible(true); this.setVisible(true); @@ -199,6 +199,7 @@ public class TableDataSearchRemindPane extends JPanel implements TreeSearchStatu @Override public void onStoppedSearching() { this.textLabel.setText(SEARCHING_STOPPED); + this.textLabel.setVisible(true); this.stopLabel.setVisible(false); this.setVisible(true); } @@ -206,6 +207,7 @@ public class TableDataSearchRemindPane extends JPanel implements TreeSearchStatu @Override public void onDoneSearching(boolean matchSetsEmpty) { this.textLabel.setText(DONE_SEARCHING); + this.textLabel.setVisible(true); this.stopLabel.setVisible(false); this.setVisible(true); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TreeSearchToolbarPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TreeSearchToolbarPane.java index ecabc02b3..ea51e1a82 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TreeSearchToolbarPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/pane/TreeSearchToolbarPane.java @@ -16,6 +16,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.stable.StringUtils; import javax.swing.BorderFactory; +import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; @@ -23,6 +24,7 @@ import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; +import java.awt.Insets; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.KeyAdapter; @@ -103,7 +105,7 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha searchPane.setBackground(Color.WHITE); // 左侧搜索图标 UILabel searchLabel = new UILabel(IconUtils.readIcon("/com/fr/design/images/data/search")); - searchLabel.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + searchLabel.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0)); searchLabel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { @@ -111,7 +113,12 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha } }); // 中间输入框 - searchTextField = new UITextField(); + searchTextField = new UITextField(){ + @Override + public Insets getInsets() { + return new Insets(2, 4, 0, 4); + } + }; searchTextField.setBorderPainted(false); searchTextField.setPlaceholder(Toolkit.i18nText("Fine-Design_Tree_Search_Press_Enter_For_Search")); searchTextField.addFocusListener(new FocusListener() { @@ -145,7 +152,7 @@ public class TreeSearchToolbarPane extends JPanel implements TreeSearchStatusCha // 右侧返回图标 UILabel returnLabel = new UILabel(IconUtils.readIcon("/com/fr/design/images/data/clear")); returnLabel.setToolTipText(Toolkit.i18nText("Fine-Design_Tree_Search_Return")); - returnLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + returnLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 11)); returnLabel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/view/TreeSearchRendererHelper.java b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/view/TreeSearchRendererHelper.java index cf348f128..fa445b7fb 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/management/search/view/TreeSearchRendererHelper.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/management/search/view/TreeSearchRendererHelper.java @@ -67,7 +67,7 @@ public class TreeSearchRendererHelper { } private String getHighlightText(String text, String textToHighlight) { - String highLightTemplate = "$1"; + String highLightTemplate = "$1"; if (textToHighlight.length() == 0) { return text; } diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java b/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java index 5884bcbbc..f69312d47 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/paste/TableDataFollowingPasteUtils.java @@ -54,7 +54,7 @@ public class TableDataFollowingPasteUtils { } // 获取当前的TableDataTreePane DesignModelAdapter currentModelAdapter = DesignModelAdapter.getCurrentModelAdapter(); - TableDataTreePane tableDataTreePane = (TableDataTreePane) TableDataTreePane.getInstance(currentModelAdapter); + TableDataTreePane tableDataTreePane = (TableDataTreePane) TableDataTreePane.getInstanceWithoutRefreshEverytime(currentModelAdapter); // 粘贴(添加)数据集 for (Map.Entry dataWrapperEntry : tableDataWrapperMap.entrySet()) { String dsName = dataWrapperEntry.getKey(); diff --git a/designer-base/src/main/java/com/fr/design/gui/ilist/CheckBoxListWithPartialSelect.java b/designer-base/src/main/java/com/fr/design/gui/ilist/CheckBoxListWithPartialSelect.java new file mode 100644 index 000000000..3304073df --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/ilist/CheckBoxListWithPartialSelect.java @@ -0,0 +1,162 @@ +package com.fr.design.gui.ilist; + +import com.fr.design.event.StateChangeListener; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.itree.checkboxtree.TristateCheckBox; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.AbstractListModel; +import javax.swing.DefaultListCellRenderer; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.List; + +/** + * 支持全选、全不选、半选的CheckBoxList面板 + * @author Yvan + */ +public class CheckBoxListWithPartialSelect extends JPanel { + + private UICheckBox[] dataCheckBoxes; + + private TristateCheckBox chooseAllCheckBox; + + private UIList dataList; + + public CheckBoxListWithPartialSelect (Object[] data) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + init(data); + this.add(chooseAllCheckBox, BorderLayout.NORTH); + this.add(dataList, BorderLayout.CENTER); + } + + private void init(Object[] data) { + // 复选框组 + dataCheckBoxes = new UICheckBox[data.length]; + for (int i = 0; i < dataCheckBoxes.length; i++) { + dataCheckBoxes[i] = new UICheckBox(transferDataValue2Show(data[i])); + dataCheckBoxes[i].setSelected(true); + } + + // UIList + dataList = new UIList(dataCheckBoxes); + dataList.setModel(getListModel()); + dataList.setCellRenderer(getListCellRenderer()); + + // 全选框 + chooseAllCheckBox = new TristateCheckBox(Toolkit.i18nText("Fine-Design_Basic_Remove_All_Selected")); + chooseAllCheckBox.setState(TristateCheckBox.SELECTED); + chooseAllCheckBox.setFocusable(false); + chooseAllCheckBox.addStateChangeListener(getChooseAllCheckBoxStateChangeListener()); + dataList.addMouseListener(getDataListMouseListener()); + } + + public List getSelectedObjects() { + return dataList.getSelectedValuesList(); + } + + protected MouseListener getDataListMouseListener() { + return new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + super.mousePressed(e); + int index = dataList.getSelectedIndex(); + if (index < 0) { + return; + } + UICheckBox checkBox = (UICheckBox) dataList.getModel().getElementAt(index); + checkBox.setSelected(!checkBox.isSelected()); + //根据CheckBoxes中的选择情况来更新全选框的状态 + int selectedCount = calculateSelectedNum(); + if (selectedCount == 0) { + chooseAllCheckBox.setState(TristateCheckBox.NOT_SELECTED); + } else if (selectedCount == dataCheckBoxes.length) { + chooseAllCheckBox.setState(TristateCheckBox.SELECTED); + } else { + chooseAllCheckBox.setState(TristateCheckBox.DO_NOT_CARE); + } + dataList.repaint(); + } + }; + } + + /** + * 获取全选框状态改变监听 + * @return + */ + protected StateChangeListener getChooseAllCheckBoxStateChangeListener() { + return () -> { + if (chooseAllCheckBox.getState() == TristateCheckBox.DO_NOT_CARE) { + return; + } + boolean isSelected = chooseAllCheckBox.isSelected(); + for (int i = 0; i < dataList.getModel().getSize(); i++) { + UICheckBox checkBox = (UICheckBox) dataList.getModel().getElementAt(i); + checkBox.setSelected(isSelected); + } + dataList.repaint(); + }; + } + + /** + * 计算CheckBox的选中情况,用来更新全选框的状态 + * @return + */ + protected int calculateSelectedNum() { + int count = 0; + for (UICheckBox dataCheckBox : dataCheckBoxes) { + if (dataCheckBox.isSelected()) { + count++; + } + } + return count; + } + + /** + * 将传入的Object转化为字符串展示,默认调用toString方法 + * @param object + * @return + */ + protected String transferDataValue2Show(Object object) { + return object.toString(); + } + + protected AbstractListModel getListModel() { + return new SelectedListDataModel(); + } + + protected ListCellRenderer getListCellRenderer() { + return new SelectedListCellRender(); + } + + private class SelectedListCellRender extends DefaultListCellRenderer { + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, final boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + dataCheckBoxes[index] = (UICheckBox) value; + dataCheckBoxes[index].setBackground(list.getBackground()); + return dataCheckBoxes[index]; + } + + } + + private class SelectedListDataModel extends AbstractListModel { + @Override + public int getSize() { + return dataCheckBoxes.length; + } + + @Override + public Object getElementAt(int index) { + return (index > getSize() - 1 || index < 0) ? null : dataCheckBoxes[index]; + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java b/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java index 0384b5c29..23a712508 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java @@ -32,23 +32,14 @@ public class UpmShowPane extends BasicPane { UpmShowPane() { setLayout(new BorderLayout()); - modernUIPane = ModernUIPaneFactory.modernUIPaneBuilder() - .prepareForV6(new ScriptContextAdapter() { + modernUIPane = new ModernUIPane.Builder<>() + .prepare(new ScriptContextAdapter() { @Override public void onScriptContextCreated(ScriptContextEvent event) { - // 6.x JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser())); } }) - .prepareForV7(params -> { - // 7.x - JsObject window = params.frame().executeJavaScript("window"); - if (window != null) { - window.putProperty("PluginHelper", NewUpmBridge.getBridge(window)); - } - return InjectJsCallback.Response.proceed(); - }) .withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()) .build(); EventDispatcher.listen(DownloadEvent.UPDATE, new Listener() { @@ -57,6 +48,12 @@ public class UpmShowPane extends BasicPane { modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()); } }); + EventDispatcher.listen(DownloadEvent.UPDATE, new Listener() { + @Override + public void on(Event event, String param) { + modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()); + } + }); add(modernUIPane, BorderLayout.CENTER); } } diff --git a/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_off_disabled.svg b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_off_disabled.svg new file mode 100644 index 000000000..ed225a99b --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_off_disabled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_off_normal.svg b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_off_normal.svg new file mode 100644 index 000000000..c81b5419a --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_off_normal.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_on_disabled.svg b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_on_disabled.svg new file mode 100644 index 000000000..23d8c5da5 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_on_disabled.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_on_normal.svg b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_on_normal.svg new file mode 100644 index 000000000..13f924d88 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/images/control/batch_esd_on_normal.svg @@ -0,0 +1,3 @@ + + +