diff --git a/build.gradle b/build.gradle index d58f83f44b..ee9bc62782 100644 --- a/build.gradle +++ b/build.gradle @@ -36,7 +36,7 @@ allprojects { group 'com.fr.design' version frDevVersion sourceCompatibility = languageLevelSetting - targetCompatibility = languageLevelSetting + targetCompatibility = languageLevelSetting tasks.withType(JavaCompile) { options.encoding = "UTF-8" @@ -49,8 +49,8 @@ allprojects { idea { module { inheritOutputDirs = false - outputDir = file(outputPath +"/classes") - testOutputDir = file(outputPath +"/test-classes") + outputDir = file(outputPath + "/classes") + testOutputDir = file(outputPath + "/test-classes") languageLevel = new IdeaLanguageLevel(sourceCompatibility) targetBytecodeVersion = targetCompatibility } @@ -68,7 +68,7 @@ allprojects { implementation 'org.swingexplorer:swexpl:2.0.1' implementation 'org.swingexplorer:swag:1.0' implementation 'net.java.dev.jna:jna:5.4.0' - implementation 'org.apache.tomcat:tomcat-catalina:8.5.57' + implementation 'org.apache.tomcat:tomcat-catalina:8.5.69' implementation 'io.socket:socket.io-client:0.7.0' implementation 'com.fr.third:fine-third:' + frVersion implementation 'com.fr.core:fine-core:' + frDevVersion diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java index 717faebe15..48f05f7e2c 100644 --- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java +++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java @@ -91,6 +91,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private static final String VERSION100 = "100"; private static final int CACHINGTEMPLATE_LIMIT = 5; private static final String WEB_NAME = "webapps"; + public static final int LAYOUT_TEMPLATE_SIMPLE_STYLE = 0; + public static final int LAYOUT_TEMPLATE_REAL_STYLE = 1; /** * 指定默认工作空间 */ @@ -195,6 +197,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private static List mapWorkerList = new ArrayList(); private boolean imageCompress = false;//图片压缩 private boolean showImageCompressMoveTip = true; + private boolean showServerDatasetAuthTip = true; // 开启内嵌web页面的调试窗口 private boolean openDebug = false; @@ -204,6 +207,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { private boolean showTemplateMissingPlugin = true; + private int layoutTemplateStyle = LAYOUT_TEMPLATE_SIMPLE_STYLE; + /** * DesignerEnvManager. */ @@ -1674,6 +1679,13 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { this.showImageCompressMoveTip = showImageCompressMoveTip; } + public boolean isShowServerDatasetAuthTip() { + return showServerDatasetAuthTip; + } + + public void setShowServerDatasetAuthTip(boolean showServerDatasetAuthTip) { + this.showServerDatasetAuthTip = showServerDatasetAuthTip; + } public boolean isOpenDebug() { return openDebug; @@ -1683,6 +1695,14 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { this.openDebug = openDebug; } + public int getLayoutTemplateStyle() { + return layoutTemplateStyle; + } + + public void setLayoutTemplateStyle(int layoutTemplateStyle) { + this.layoutTemplateStyle = layoutTemplateStyle; + } + /** * Read XML.
* The method will be invoked when read data from XML file.
@@ -1852,6 +1872,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { } this.setEmbedServerLazyStartup(reader.getAttrAsBoolean("embedServerLazyStartup", false)); this.setShowTemplateMissingPlugin(reader.getAttrAsBoolean("showTemplateMissingPlugin", true)); + this.setShowServerDatasetAuthTip(reader.getAttrAsBoolean("showServerDatasetAuthTip", true)); + this.setLayoutTemplateStyle(reader.getAttrAsInt("layoutTemplateStyle", LAYOUT_TEMPLATE_SIMPLE_STYLE)); } private void readReportPaneAttributions(XMLableReader reader) { @@ -2125,6 +2147,8 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter { if (!this.isShowTemplateMissingPlugin()) { writer.attr("showTemplateMissingPlugin", this.isShowTemplateMissingPlugin()); } + writer.attr("layoutTemplateStyle", this.getLayoutTemplateStyle()); + writer.attr("showServerDatasetAuthTip", this.isShowServerDatasetAuthTip()); writer.end(); } diff --git a/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java b/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java index 5c12ff29c3..048f233373 100644 --- a/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/UpdateAction.java @@ -345,6 +345,17 @@ public abstract class UpdateAction extends ShortCut implements Action { return (JComponent) object; } + public JComponent createToolBarComponentByName(String componentName) { + Object object = this.getValue(componentName); + if (!(object instanceof AbstractButton)) { + UIButton button = null; + button = new UIButton(); + object = initButton(button, componentName); + } + + return (JComponent) object; + } + protected JComponent initButton(UIButton button, String name) { // 添加一个名字作为自动化测试用 button.setName(getName()); diff --git a/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java b/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java index 3e08b13991..51a390c82d 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/TutorialAction.java @@ -28,7 +28,7 @@ public class TutorialAction extends AbstractDesignerSSO { @Override public String getJumpUrl() { - return CloudCenter.getInstance().acquireUrlByKind(createDocKey()); + return CloudCenter.getInstance().acquireUrlByKind(createDocKey(), "http://help.finereport.com"); } // 生成帮助文档 sitecenter key, help.zh_CN.10 diff --git a/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java b/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java index bc1445718a..1457f0d111 100644 --- a/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java +++ b/designer-base/src/main/java/com/fr/design/actions/server/GlobalTableDataAction.java @@ -25,9 +25,6 @@ import com.fr.esd.event.DsNameTarget; import com.fr.esd.event.StrategyEventsNotifier; import com.fr.file.TableDataConfig; -import com.fr.transaction.CallBackAdaptor; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; import com.fr.report.LockItem; import javax.swing.KeyStroke; @@ -91,7 +88,6 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS } protected void renameConnection(final String oldName, final String newName) { - tableDataConfig.renameTableData(oldName, newName); StrategyEventsNotifier.modifyDataSet(DSMapping.ofServerDS(new DsNameTarget(oldName))); } }; @@ -106,33 +102,17 @@ public class GlobalTableDataAction extends UpdateAction implements ResponseDataS globalTableDataDialog.setDoOKSucceed(false); return; } + globalTableDataPane.update(tableDataConfig); DesignTableDataManager.clearGlobalDs(); // 保存时 移除服务器数据集列名缓存 for (String name : tableDataConfig.getTableDatas().keySet()) { DesignTableDataManager.removeSelectedColumnNames(name); } - - Configurations.modify(new WorkerFacade(TableDataConfig.class) { - @Override - public void run() { - globalTableDataPane.update(tableDataConfig); - } - }.addCallBack(new CallBackAdaptor() { - @Override - public boolean beforeCommit() { - //如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面 - return doWithDatasourceManager(tableDataConfig, globalTableDataPane, globalTableDataDialog); - } - - @Override - public void afterCommit() { - // 刷新共有数据集 - TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); - fireDSChanged(globalTableDataPane.getDsChangedNameMap()); - // 关闭服务器数据集页面,为其解锁 - EditLockUtils.unlock(LockItem.SERVER_TABLE_DATA); - } - })); + // 刷新共有数据集 + TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()); + fireDSChanged(globalTableDataPane.getDsChangedNameMap()); + // 关闭服务器数据集页面,为其解锁 + EditLockUtils.unlock(LockItem.SERVER_TABLE_DATA); } @Override diff --git a/designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java b/designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java new file mode 100644 index 0000000000..e2444a4eca --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/beans/ErrorMsgTextFieldAdapter.java @@ -0,0 +1,11 @@ +package com.fr.design.beans; + +import javax.swing.JComponent; + +public interface ErrorMsgTextFieldAdapter { + void setText(String str); + + String getText(); + + JComponent getErrorMsgTextField(); +} diff --git a/designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java b/designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java new file mode 100644 index 0000000000..48fa6944fc --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/beans/UITextFieldAdapter.java @@ -0,0 +1,46 @@ +package com.fr.design.beans; + +import com.fr.design.gui.itextfield.UITextField; + +import javax.swing.JComponent; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +public class UITextFieldAdapter implements ErrorMsgTextFieldAdapter { + private final UITextField uiTextField = new UITextField(); + + public UITextFieldAdapter(){ + addDocumentListener(); + } + @Override + public void setText(String str) { + uiTextField.setText(str); + } + + @Override + public String getText() { + return uiTextField.getText(); + } + + public void addDocumentListener() { + uiTextField.getDocument().addDocumentListener(new DocumentListener() { + + public void changedUpdate(DocumentEvent e) { + uiTextField.setToolTipText(uiTextField.getText()); + } + + public void insertUpdate(DocumentEvent e) { + uiTextField.setToolTipText(uiTextField.getText()); + } + + public void removeUpdate(DocumentEvent e) { + uiTextField.setToolTipText(uiTextField.getText()); + } + }); + } + + @Override + public JComponent getErrorMsgTextField() { + return uiTextField; + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java b/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java index 3987844cf8..875ef00833 100644 --- a/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java +++ b/designer-base/src/main/java/com/fr/design/border/UITitledBorder.java @@ -22,24 +22,7 @@ public class UITitledBorder extends TitledBorder { } private UITitledBorder(String title) { - super( - BorderFactory.createCompoundBorder( - BorderFactory.createEmptyBorder( - 0, - 0, - 5, - 0), - new UIRoundedBorder( - UIConstants.TITLED_BORDER_COLOR, - 1, - 10) - ), - title, - TitledBorder.LEADING, - TitledBorder.TOP, - null, - new Color(1, 159, 222) - ); + this(title, 10); } /** diff --git a/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java b/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java new file mode 100644 index 0000000000..c46143e1e5 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/border/UITitledMatteBorder.java @@ -0,0 +1,32 @@ +package com.fr.design.border; + +import com.fr.design.constants.UIConstants; + +import javax.swing.BorderFactory; +import javax.swing.border.TitledBorder; +import java.awt.Color; + +public class UITitledMatteBorder extends TitledBorder { + public static UITitledMatteBorder createTitledTopBorder(String title, Color color) { + return new UITitledMatteBorder(title, 1, 0, 0, 0, color); + } + + public static UITitledMatteBorder createTitledBorder(String title, Color color) { + return new UITitledMatteBorder(title, 1, 1, 1, 1, color); + } + + public static UITitledMatteBorder createTitledBorder(String title, int top, int left, int bottom, int right, Color color) { + return new UITitledMatteBorder(title, top, left, bottom, right, color); + } + + private UITitledMatteBorder(String title, int top, int left, int bottom, int right, Color color) { + super( + BorderFactory.createMatteBorder(top, left, bottom, right, UIConstants.TITLED_BORDER_COLOR), + title, + TitledBorder.LEADING, + TitledBorder.TOP, + null, + color + ); + } +} diff --git a/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java b/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java index 393f217ce7..355dca62de 100644 --- a/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/cell/CellStylePreviewPane.java @@ -6,6 +6,9 @@ import com.fr.base.Style; import com.fr.general.IOUtils; import javax.swing.JPanel; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; @@ -40,10 +43,22 @@ public class CellStylePreviewPane extends JPanel { @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; - int resolution = ScreenResolution.getScreenResolution(); + g.clearRect(0, 0, getWidth(), getHeight()); - int width = getWidth(); - int height = getHeight(); + paintTransparentBackground(g2d, style); + + paintCellStyle(g2d, style); + } + + private void paintTransparentBackground(Graphics2D g2d, Style style) { + Color fontColor = style.getFRFont().getForeground(); + float g = fontColor.getRed() * 0.299F + fontColor.getGreen() * 0.587F * fontColor.getBlue() * 0.114F; + float alpha = 1.0F; + if (g < 50) { + alpha = 0.2F; + } else if (g < 160){ + alpha = 0.5F; + } float scaleWidth = 1.0F * getWidth() / transparentBackgroundWidth; float scaleHeight = 1.0F * getHeight() / transparentBackgroundHeight; @@ -54,7 +69,18 @@ public class CellStylePreviewPane extends JPanel { } else { scaleHeight = scaleWidth = maxScale; } + + Composite oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, alpha)); g2d.drawImage(transparentBackgroundImage, 0, 0, (int) (transparentBackgroundWidth * scaleWidth), (int) (transparentBackgroundHeight * scaleHeight), null); + g2d.setComposite(oldComposite); + } + + private void paintCellStyle(Graphics2D g2d, Style style) { + int resolution = ScreenResolution.getScreenResolution(); + + int width = getWidth(); + int height = getHeight(); if (style == Style.DEFAULT_STYLE) { // 如果是默认的style,就只写"Report"上去 diff --git a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java b/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java index ab86a0d6f2..f7eb9bacc4 100644 --- a/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java +++ b/designer-base/src/main/java/com/fr/design/data/DesignTableDataManager.java @@ -47,9 +47,11 @@ import java.util.Collections; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; import java.util.Map; import java.util.Map.Entry; +import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -71,8 +73,8 @@ public abstract class DesignTableDataManager { * 其实globalDsCache没有绝对的必要,只是为了操作方便。如果没有它,那么每次清空服务器数据集或者存储过程的时候,还要去遍历找一下, * 这个操作可能比较复杂 。 从减少代码复杂度的角度看,还是很有必要的 */ - private static java.util.Map globalDsCache = new java.util.HashMap(); - private static java.util.Map dsNameChangedMap = new HashMap(); + private static Map globalDsCache = new java.util.HashMap(); + private static Set dsNameChangedSet = new LinkedHashSet<>(); private static List globalDsListeners = new ArrayList<>(); private static Map> dsListenersMap = new ConcurrentHashMap<>(); @@ -123,7 +125,7 @@ public abstract class DesignTableDataManager { public static void envChange() { columnCache.clear(); dsListenersMap.clear(); - dsNameChangedMap.clear(); + dsNameChangedSet.clear(); clearGlobalDs(); } @@ -136,17 +138,17 @@ public abstract class DesignTableDataManager { public static void fireDSChanged(Map dsNameChangedMap) { clearGlobalDs(); if (!dsNameChangedMap.isEmpty()) { - setDsNameChangedMap(dsNameChangedMap); + setDsNameChangedSet(dsNameChangedMap); } fireDsChanged(); dsNameChangedMap.clear(); } - private static void setDsNameChangedMap(Map map) { + private static void setDsNameChangedSet(Map map) { Iterator iterator = map.keySet().iterator(); while (iterator.hasNext()) { String key = (String) iterator.next(); - dsNameChangedMap.put(key, map.get(key)); + dsNameChangedSet.add(new NameChangeBean(key, map.get(key))); } } @@ -157,23 +159,21 @@ public abstract class DesignTableDataManager { * @return 是则返回true */ public static boolean isDsNameChanged(String oldDsName) { - return dsNameChangedMap.containsKey(oldDsName); - } - - public static String getChangedDsNameByOldDsName(String oldDsName) { - String changeName; - - if (isDsNameChanged(oldDsName)) { - changeName = dsNameChangedMap.get(oldDsName); - } else { - changeName = StringUtils.EMPTY; + for (NameChangeBean bean : dsNameChangedSet) { + if (ComparatorUtils.equals(oldDsName, bean.getOldName())) { + return true; + } } + return false; + } - if (StringUtils.isNotEmpty(changeName)) { - return getChangedDsNameByOldDsName(changeName); - } else { - return oldDsName; + public static String getChangedDsNameByOldDsName(String dsName) { + for (NameChangeBean bean : dsNameChangedSet) { + if (ComparatorUtils.equals(dsName, bean.getOldName())) { + dsName = bean.getChangedName(); + } } + return dsName; } public static void addGlobalDsChangeListener(ChangeListener l) { diff --git a/designer-base/src/main/java/com/fr/design/data/NameChangeBean.java b/designer-base/src/main/java/com/fr/design/data/NameChangeBean.java new file mode 100644 index 0000000000..2d4caf44e3 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/NameChangeBean.java @@ -0,0 +1,27 @@ +package com.fr.design.data; + +public class NameChangeBean { + private String oldName; + private String changedName; + + public NameChangeBean(String oldName, String changedName) { + this.oldName = oldName; + this.changedName = changedName; + } + + public String getOldName() { + return oldName; + } + + public void setOldName(String oldName) { + this.oldName = oldName; + } + + public String getChangedName() { + return changedName; + } + + public void setChangedName(String changedName) { + this.changedName = changedName; + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index b5bc39e4eb..f656105265 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -25,6 +25,7 @@ import com.fr.design.gui.icombobox.UIComboBoxEditor; import com.fr.design.gui.icombobox.UIComboBoxRenderer; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; @@ -39,7 +40,16 @@ import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; import com.fr.workspace.server.connection.DBConnectAuth; -import javax.swing.*; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import java.util.Collections; +import java.util.concurrent.CancellationException; +import javax.swing.JList; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.JTree; +import javax.swing.SwingWorker; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.PopupMenuEvent; @@ -50,7 +60,6 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; -import java.awt.*; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; @@ -70,6 +79,9 @@ import java.util.concurrent.FutureTask; * @since 2012-7-11下午4:49:39 */ public class ChoosePane extends BasicBeanPane implements Refreshable, Previewable, Prepare4DataSourceChange { + + private static final List PENDING_CONTENT = new ArrayList<>(Collections.singletonList(Toolkit.i18nText("Fine-Design_Basic_Loading") + "...")); + private static final double COLUMN_SIZE = 24; /** @@ -91,6 +103,8 @@ public class ChoosePane extends BasicBeanPane implements Refresha private SwingWorker populateWorker; + private SwingWorker, Void> initWorker; + private PopupMenuListener popupMenuListener = new PopupMenuListener() { @Override @@ -213,10 +227,34 @@ public class ChoosePane extends BasicBeanPane implements Refresha @SuppressWarnings("unchecked") protected void initDsNameComboBox() { + if (initWorker != null && !initWorker.isDone()) { + initWorker.cancel(true); + } dsNameComboBox.setRefreshingModel(true); - FilterableComboBoxModel dsNameComboBoxModel = new FilterableComboBoxModel(getHasAuthConnections()); - dsNameComboBox.setModel(dsNameComboBoxModel); - dsNameComboBox.setRefreshingModel(false); + dsNameComboBox.setModel(new FilterableComboBoxModel(PENDING_CONTENT)); + initWorker = new SwingWorker, Void>() { + + @Override + protected List doInBackground() throws Exception { + return getHasAuthConnections(); + } + + @Override + protected void done() { + try { + FilterableComboBoxModel dsNameComboBoxModel = new FilterableComboBoxModel(get()); + String selected = dsNameComboBox.getSelectedItem(); + dsNameComboBox.setModel(dsNameComboBoxModel); + dsNameComboBox.setSelectedItem(selected); + dsNameComboBox.setRefreshingModel(false); + } catch (Exception e) { + if (!(e instanceof CancellationException)) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + }; + initWorker.execute(); } protected void initComponentsLayout(PreviewLabel previewLabel, int labelSize) { diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java index 8972821b43..a16c16e24d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataPaneListPane.java @@ -1,6 +1,8 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; +import com.fr.base.TableDataBean; +import com.fr.config.RemoteConfigEvent; import com.fr.data.TableDataSource; import com.fr.data.api.StoreProcedureAssist; import com.fr.data.impl.storeproc.StoreProcedure; @@ -12,22 +14,26 @@ import com.fr.design.gui.controlpane.JListControlPane; import com.fr.design.gui.controlpane.NameableCreator; import com.fr.design.gui.ilist.ListModelElement; import com.fr.design.i18n.Toolkit; +import com.fr.event.EventDispatcher; import com.fr.file.ProcedureConfig; import com.fr.file.TableDataConfig; +import com.fr.file.TableDataOperator; import com.fr.general.ComparatorUtils; import com.fr.general.NameObject; +import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; +import com.fr.third.org.apache.commons.collections4.MapUtils; +import com.fr.workspace.WorkContext; import javax.swing.*; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.Iterator; -import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.Set; @@ -231,15 +237,25 @@ public class TableDataPaneListPane extends JListControlPane implements TableData @Override public void update(TableDataConfig tableDataConfig) { - tableDataConfig.removeAllTableData(); - ProcedureConfig.getInstance().removeAllProcedure(); Nameable[] tableDataArray = this.update(); - Map tableDataMap = new LinkedHashMap(); + List tableDataBeans = new ArrayList<>(); + Map map = MapUtils.invertMap(getDsNameChangedMap()); for (int i = 0; i < tableDataArray.length; i++) { NameObject nameObject = (NameObject) tableDataArray[i]; - tableDataMap.put(nameObject.getName(), (TableData) nameObject.getObject()); + String oldName = map.get(nameObject.getName()); + if (oldName == null) { + oldName = StringUtils.EMPTY; + } + tableDataBeans.add(new TableDataBean(nameObject.getName(), oldName, (TableData) nameObject.getObject())); + } + try { + WorkContext.getCurrent().get(TableDataOperator.class).saveTableData(tableDataBeans); + if (!WorkContext.getCurrent().isLocal()) { + EventDispatcher.fire(RemoteConfigEvent.EDIT, TableDataConfig.getInstance().getNameSpace()); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); } - tableDataConfig.setTableDatas(tableDataMap); } @Override 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 493d40d796..6a9c2d1edb 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 @@ -5,6 +5,7 @@ import com.fr.data.TableDataSource; import com.fr.data.impl.DBTableData; import com.fr.data.impl.TableDataSourceDependent; import com.fr.design.DesignModelAdapter; +import com.fr.design.DesignerEnvManager; import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.UpdateAction; import com.fr.design.constants.UIConstants; @@ -53,10 +54,12 @@ import com.fr.plugin.manage.PluginFilter; import com.fr.plugin.observer.PluginEvent; import com.fr.plugin.observer.PluginEventListener; import com.fr.stable.core.PropertyChangeAdapter; +import com.fr.workspace.WorkContext; import org.jetbrains.annotations.NotNull; import javax.swing.BorderFactory; import javax.swing.Icon; +import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; @@ -64,6 +67,7 @@ import javax.swing.SwingWorker; import javax.swing.ToolTipManager; import javax.swing.tree.TreePath; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.GridLayout; import java.awt.dnd.DnDConstants; import java.awt.event.ActionEvent; @@ -106,6 +110,7 @@ public class TableDataTreePane extends BasicTableDataTreePane { private EsdOnAction esdAction; private EsdOffAction esdOffAction; private PreviewTableDataAction previewTableDataAction; + private JPanel serverDatasetAuthTipJPanel = new JPanel(); private TableDataTreePane() { initPane(); @@ -149,10 +154,12 @@ public class TableDataTreePane extends BasicTableDataTreePane { UIScrollPane scrollPane = new UIScrollPane(tableDataTree); scrollPane.setBorder(null); + initServerDatasetAuthTipJPanel(); initButtonGroup(); JPanel jPanel = new JPanel(new BorderLayout(0, 0)); - JPanel buttonPane = new JPanel(new GridLayout()); + JPanel buttonPane = new JPanel(FRGUIPaneFactory.createBorderLayout()); buttonPane.add(buttonGroup, BorderLayout.CENTER); + buttonPane.add(serverDatasetAuthTipJPanel, BorderLayout.SOUTH); jPanel.add(buttonPane, BorderLayout.NORTH); jPanel.add(scrollPane, BorderLayout.CENTER); this.add(jPanel, BorderLayout.CENTER); @@ -172,6 +179,40 @@ public class TableDataTreePane extends BasicTableDataTreePane { checkButtonEnabled(); } + private void initServerDatasetAuthTipJPanel() { + String[] lineTips = Toolkit.i18nText("Fine-Design_Server_Dataset_Auth_Tip").split("\n"); + serverDatasetAuthTipJPanel = new JPanel(); + serverDatasetAuthTipJPanel.setLayout(new GridLayout(lineTips.length, 1)); + for (int i = 0; i < lineTips.length; i++) { + String lineTip = lineTips[i]; + List jLabels = new ArrayList<>(); + JLabel lineJLabel = new JLabel(lineTip); + lineJLabel.setForeground(Color.lightGray); + jLabels.add(lineJLabel); + if (i == (lineTips.length - 1)) { + JLabel jLabel = new JLabel(Toolkit.i18nText("Fine-Design_Basic_Alphafine_No_Remind")); + jLabel.setForeground(Color.blue); + jLabel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + DesignerEnvManager.getEnvManager().setShowServerDatasetAuthTip(false); + serverDatasetAuthTipJPanel.setVisible(false); + } + }); + jLabels.add(jLabel); + } + serverDatasetAuthTipJPanel.add(getLineTipJPanel(jLabels)); + } + } + + private JPanel getLineTipJPanel(List jLabels) { + JPanel jPanel = new JPanel(FRGUIPaneFactory.createLabelFlowLayout()); + for (JLabel jLabel : jLabels) { + jPanel.add(jLabel); + } + return jPanel; + } + private void createPluginListener() { //菜单栏监听 GeneralContext.listenPluginRunningChanged(new PluginEventListener(PLUGIN_LISTENER_PRIORITY) { @@ -532,6 +573,11 @@ public class TableDataTreePane extends BasicTableDataTreePane { String[] textArray = {Toolkit.i18nText("Fine-Design_Basic_Tabledata_Source_Type_Template"), Toolkit.i18nText("Fine-Design_Basic_DS_Server_TableData")}; buttonGroup = new UIHeadGroup(textArray) { public void tabChanged(int index) { + if (isShowServerDatasetAuthTipJPanel(textArray[index])) { + serverDatasetAuthTipJPanel.setVisible(true); + } else { + serverDatasetAuthTipJPanel.setVisible(false); + } if (op != null) { op.setDataMode(modeArray[buttonGroup.getSelectedIndex()]); addMenuDef.setEnabled(modeArray[buttonGroup.getSelectedIndex()] == TEMPLATE_TABLE_DATA); @@ -539,6 +585,15 @@ public class TableDataTreePane extends BasicTableDataTreePane { } } + + private boolean isShowServerDatasetAuthTipJPanel(String name) { + if (ComparatorUtils.equals(name, Toolkit.i18nText("Fine-Design_Basic_DS_Server_TableData")) + && DesignerEnvManager.getEnvManager().isShowServerDatasetAuthTip() + && !WorkContext.getCurrent().isLocal()) { + return true; + } + return false; + } }; buttonGroup.setNeedLeftRightOutLine(false); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java index 1ce37b4c51..3b5aebed9e 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java @@ -5,20 +5,13 @@ import com.fr.data.impl.AbstractDatabaseConnection; import com.fr.data.impl.Connection; import com.fr.data.impl.NameDatabaseConnection; import com.fr.design.DesignerEnvManager; -import com.fr.design.actions.server.ConnectionListAction; -import com.fr.design.dialog.BasicDialog; -import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.editlock.ConnectionLockChangeChecker; import com.fr.design.editlock.EditLockUtils; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UILockButton; -import com.fr.design.mainframe.DesignerContext; import com.fr.file.ConnectionConfig; import com.fr.general.ComparatorUtils; import com.fr.stable.StringUtils; -import com.fr.transaction.CallBackAdaptor; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; import com.fr.workspace.WorkContext; import com.fr.workspace.server.connection.DBConnectAuth; import com.fr.report.LockItem; @@ -87,12 +80,13 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { * 刷新ComboBox.items */ protected Iterator items() { - nameList = new ArrayList(); - ConnectionConfig mgr = ConnectionConfig.getInstance(); Iterator nameIt = mgr.getConnections().keySet().iterator(); Collection noAuthConnections = WorkContext.getCurrent().get(DBConnectAuth.class).getNoAuthConnections(); + + nameList = new ArrayList<>(); + if (noAuthConnections == null) { return nameList.iterator(); } @@ -132,48 +126,7 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { return; } // 锁定成功,执行后续操作 - final ConnectionListPane connectionListPane = new ConnectionListPane(); - final ConnectionConfig connectionConfig = ConnectionConfig.getInstance(); - ConnectionConfig cloned = connectionConfig.mirror(); - connectionListPane.populate(cloned); - final BasicDialog connectionListDialog = connectionListPane.showLargeWindow( - SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this), null); - connectionListDialog.addDialogActionListener(new DialogActionAdapter() { - public void doOk() { - if (!connectionListPane.isNamePermitted()) { - connectionListDialog.setDoOKSucceed(false); - return; - } - Configurations.modify(new WorkerFacade(ConnectionConfig.class) { - @Override - public void run() { - connectionListPane.update(connectionConfig); - } - }.addCallBack(new CallBackAdaptor() { - @Override - public boolean beforeCommit() { - //如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面 - return ConnectionListAction.doWithDatasourceManager(connectionConfig, connectionListPane, connectionListDialog); - } - - @Override - public void afterCommit() { - DesignerContext.getDesignerBean("databasename").refreshBeanElement(); - // 关闭定义数据连接页面,为其解锁 - EditLockUtils.unlock(LockItem.CONNECTION); - } - })); - - } - - @Override - public void doCancel() { - // 关闭定义数据连接页面,为其解锁 - super.doCancel(); - EditLockUtils.unlock(LockItem.CONNECTION); - } - }); - connectionListDialog.setVisible(true); + ConnectionListPane.showDialog(SwingUtilities.getWindowAncestor(ConnectionComboBoxPanel.this)); refreshItems(); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java new file mode 100644 index 0000000000..2428c9a005 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListDialogActionAdapter.java @@ -0,0 +1,48 @@ +package com.fr.design.data.datapane.connect; + +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.editlock.EditLockUtils; +import com.fr.design.mainframe.DesignerContext; +import com.fr.file.ConnectionConfig; +import com.fr.report.LockItem; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2021/9/8 + */ +public class ConnectionListDialogActionAdapter extends DialogActionAdapter { + + private final ConnectionManagerPane connectionManagerPane; + private final BasicDialog connectionListDialog; + private final ConnectionConfig connectionConfig; + + public ConnectionListDialogActionAdapter(ConnectionManagerPane connectionManagerPane, + BasicDialog connectionListDialog, + ConnectionConfig connectionConfig) { + this.connectionManagerPane = connectionManagerPane; + this.connectionListDialog = connectionListDialog; + this.connectionConfig = connectionConfig; + } + + @Override + public void doOk() { + if (!connectionManagerPane.isNamePermitted()) { + connectionListDialog.setDoOKSucceed(false); + return; + } + connectionManagerPane.update(connectionConfig); + DesignerContext.getDesignerBean("databasename").refreshBeanElement(); + // 关闭定义数据连接页面,为其解锁 + EditLockUtils.unlock(LockItem.CONNECTION); + + } + + @Override + public void doCancel() { + // 关闭定义数据连接页面,为其解锁 + super.doCancel(); + EditLockUtils.unlock(LockItem.CONNECTION); + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 1e3f96a986..4ce851295d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -1,23 +1,32 @@ package com.fr.design.data.datapane.connect; +import com.fr.config.RemoteConfigEvent; import com.fr.data.impl.Connection; +import com.fr.data.impl.ConnectionBean; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; import com.fr.design.ExtraDesignClassManager; +import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.fun.ConnectionProvider; import com.fr.design.gui.controlpane.JListControlPane; import com.fr.design.gui.controlpane.NameObjectCreator; import com.fr.design.gui.controlpane.NameableCreator; import com.fr.design.i18n.Toolkit; +import com.fr.event.EventDispatcher; import com.fr.file.ConnectionConfig; import com.fr.general.ComparatorUtils; import com.fr.general.NameObject; +import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; +import com.fr.third.org.apache.commons.collections4.MapUtils; +import com.fr.workspace.WorkContext; +import com.fr.file.ConnectionOperator; +import java.awt.Window; import javax.swing.*; import java.util.ArrayList; import java.util.Arrays; @@ -67,8 +76,19 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh protected void rename(String oldName, String newName) { - renameMap.remove(selectedName); - renameMap.put(selectedName, newName); + //如果a改成了b,b又被改成了c,就认为是a改成了c + for (Map.Entry entry : renameMap.entrySet()) { + if (StringUtils.equals(oldName, entry.getValue())) { + oldName = entry.getKey(); + break; + } + } + if (StringUtils.equals(oldName, newName)) { + //a -> b;b -> a,说明没改 + renameMap.remove(oldName); + } else { + renameMap.put(oldName, newName); + } } /** @@ -149,14 +169,37 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh public void update(ConnectionConfig connectionConfig) { // Nameable[]居然不能强转成NameObject[],一定要这么写... Nameable[] res = this.update(); - NameObject[] res_array = new NameObject[res.length]; - java.util.Arrays.asList(res).toArray(res_array); - - connectionConfig.removeAllConnection(); - - for (int i = 0; i < res_array.length; i++) { - NameObject nameObject = res_array[i]; - connectionConfig.addConnection(nameObject.getName(), (Connection) nameObject.getObject()); + List connectionBeans = new ArrayList<>(); + Map map = MapUtils.invertMap(getRenameMap()); + for (int i = 0; i < res.length; i++) { + NameObject nameObject = (NameObject) res[i]; + String oldName = map.get(nameObject.getName()); + if (oldName == null) { + oldName = StringUtils.EMPTY; + } + connectionBeans.add(new ConnectionBean(nameObject.getName(), oldName, (Connection) nameObject.getObject())); } + try { + WorkContext.getCurrent().get(ConnectionOperator.class).saveConnection(connectionBeans); + if (!WorkContext.getCurrent().isLocal()) { + EventDispatcher.fire(RemoteConfigEvent.EDIT, ConnectionConfig.getInstance().getNameSpace()); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + public static void showDialog(Window parent) { + final ConnectionConfig connectionConfig = ConnectionConfig.getInstance(); + final ConnectionManagerPane connectionManagerPane = new ConnectionManagerPane() { + @Override + public void complete() { + ConnectionConfig cloned = connectionConfig.mirror(); + populate(cloned); + } + }; + final BasicDialog connectionListDialog = connectionManagerPane.showLargeWindow(parent, null); + connectionListDialog.addDialogActionListener(new ConnectionListDialogActionAdapter(connectionManagerPane, connectionListDialog, connectionConfig)); + connectionListDialog.setVisible(true); } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java index f06d1405b8..d0738e57b8 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java @@ -3,12 +3,19 @@ package com.fr.design.data.datapane.connect; import com.fr.base.BaseUtils; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; -import javax.swing.*; -import java.awt.*; +import com.fr.log.FineLoggerFactory; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.util.Iterator; +import java.util.concurrent.CancellationException; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JPanel; +import javax.swing.SwingWorker; public abstract class ItemEditableComboBoxPanel extends JPanel { /** @@ -16,6 +23,8 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { */ private static final long serialVersionUID = 1L; + private static final String PENDING = Toolkit.i18nText("Fine-Design_Basic_Loading") + "..."; + protected static final Object EMPTY = new Object() { public String toString() { return ""; @@ -26,6 +35,8 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { protected UIButton editButton; protected UIButton refreshButton; + private SwingWorker, Void> refreshWorker; + public ItemEditableComboBoxPanel() { super(); @@ -75,6 +86,11 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { * 刷新itemComboBox的内容 */ protected void refreshItems() { + + if (refreshWorker != null && !refreshWorker.isDone()) { + refreshWorker.cancel(true); + } + // 记录原来选中的Item,重新加载后需要再次选中 Object lastSelectedItem = itemComboBox.getSelectedItem(); @@ -83,18 +99,43 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { // 先加EMPTY,再加items model.addElement(EMPTY); + model.addElement(PENDING); - java.util.Iterator itemIt = items(); - while(itemIt.hasNext()) { - model.addElement(itemIt.next()); + // 存在两种场景之前只考虑了填充场景 有populate会填充下 把这边的填充逻辑删了 所以没有问题 + // 如果是纯通过刷新按钮 没有populate 需要手动设置下上次选中的内容 + if (lastSelectedItem != null) { + model.setSelectedItem(lastSelectedItem); } - // 再次选中之前选中的Item - int idx = model.getIndexOf(lastSelectedItem); - if(idx < 0) { - idx = 0; - } - itemComboBox.setSelectedIndex(idx); + refreshWorker = new SwingWorker, Void>() { + @Override + protected Iterator doInBackground() throws Exception { + return items(); + } + + @Override + protected void done() { + try { + Iterator itemIt = get(); + model.removeElement(PENDING); + while(itemIt.hasNext()) { + model.addElement(itemIt.next()); + } + // 如果加载成功 但是下拉框是可见的 下拉框高度是会固定为原始高度 不会因为填充了更多下拉项而变化 + // 需要重新设置下拉框高度 但值一样时相关事件不会生效 所以先加再减下 + if (itemComboBox.isPopupVisible()) { + itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() + 1); + itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() - 1); + } + } catch (Exception e) { + if (!(e instanceof CancellationException)) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + } + }; + refreshWorker.execute(); } /* diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java index adce85f3b6..6bc9e21ed6 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/TableDataFactory.java @@ -26,6 +26,8 @@ import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.authority.user.UserAuthority; import java.lang.reflect.Constructor; import java.util.ArrayList; @@ -175,7 +177,8 @@ public abstract class TableDataFactory { public static String[] getSortOfChineseNameOfServerData(TableDataConfig tableDataConfig) { clearAll(); try { - java.util.Iterator nameIt = tableDataConfig.getTableDatas().keySet().iterator(); + UserAuthority userAuthority = WorkContext.getCurrent().get(UserAuthority.class); + Iterator nameIt = userAuthority.getAuthServerDataSetNames().iterator(); while (nameIt.hasNext()) { String name = nameIt.next(); addName(name, tableDataConfig.getTableData(name)); diff --git a/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java b/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java index dd3ddab3b9..c158123574 100644 --- a/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java +++ b/designer-base/src/main/java/com/fr/design/dialog/UIDialog.java @@ -175,7 +175,11 @@ public abstract class UIDialog extends JDialog { try { checkValid(); } catch (Exception exp) { - FineJOptionPane.showMessageDialog(this, exp.getMessage()); + FineJOptionPane.showMessageDialog( + this, + exp.getMessage(), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.WARNING_MESSAGE); return; } diff --git a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java index 6c3323600c..b7a564713b 100644 --- a/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java +++ b/designer-base/src/main/java/com/fr/design/file/MutilTempalteTabPane.java @@ -4,6 +4,7 @@ package com.fr.design.file; import com.fr.base.BaseUtils; import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.constants.UIConstants; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.imenu.UIMenuItem; @@ -763,7 +764,7 @@ public class MutilTempalteTabPane extends JComponent { /** * 关闭掉一个模板之后激活新的待显示模板 */ - private void activePrevTemplateAfterClose() { + public void activePrevTemplateAfterClose() { if (openedTemplate.isEmpty()) { //新建并激活模板 DesignerContext.getDesignerFrame().addAndActivateJTemplate(); diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaChecker.java b/designer-base/src/main/java/com/fr/design/formula/FormulaChecker.java new file mode 100644 index 0000000000..59446169d3 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/formula/FormulaChecker.java @@ -0,0 +1,91 @@ +package com.fr.design.formula; + +import com.fr.design.i18n.Toolkit; +import com.fr.log.FineLoggerFactory; +import com.fr.parser.FRLexer; +import com.fr.parser.FRParser; +import com.fr.script.checker.FunctionCheckerDispatcher; +import com.fr.script.checker.exception.ConditionCheckWrongException; +import com.fr.script.checker.exception.FunctionCheckWrongException; +import com.fr.script.rules.FunctionParameterType; +import com.fr.script.rules.FunctionRule; +import com.fr.stable.StringUtils; +import com.fr.stable.script.Expression; +import com.fr.stable.script.Node; + +import java.io.StringReader; +import java.util.List; + +/** + * @author Hoky + * @date 2021/9/28 + */ +public class FormulaChecker { + private static final String VALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Valid_Formula"); + private static final String INVALID_FORMULA = Toolkit.i18nText("Fine-Design_Basic_FormulaD_Invalid_Formula"); + public static final String COLON = ":"; + + public static String check(String formulaText) throws FormulaCheckerException { + StringReader in = new StringReader(formulaText); + + FRLexer lexer = new FRLexer(in); + FRParser parser = new FRParser(lexer); + + try { + Expression expression = parser.parse(); + Node node = expression.getConditionalExpression(); + boolean valid = FunctionCheckerDispatcher.getInstance().getFunctionChecker(node).checkFunction(node); + if (valid) { + return VALID_FORMULA; + } else { + throw new FormulaCheckerException(INVALID_FORMULA); + } + } catch (ConditionCheckWrongException cce) { + String functionName = cce.getFunctionName(); + throw new FormulaCheckerException(functionName + Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Condition_Tips") + COLON); + } catch (FunctionCheckWrongException ce) { + List rules = ce.getRules(); + String functionName = ce.getFunctionName(); + StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + COLON); + for (int i = 0; i < rules.size(); i++) { + errorMsg.append("("); + if (rules.get(i).getParameterList().isEmpty()) { + errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param")); + } + for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) { + errorMsg.append(getTypeString(functionParameterType)).append(","); + } + if (",".equals(errorMsg.charAt(errorMsg.length() - 1) + "")) { + errorMsg.deleteCharAt(errorMsg.length() - 1); + } + errorMsg.append(")"); + if (i != rules.size() - 1) { + errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or")); + } + } + throw new FormulaCheckerException(errorMsg.toString()); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + throw new FormulaCheckerException(INVALID_FORMULA); + // alex:继续往下面走,expression为null时告知不合法公式 + } + } + + private static String getTypeString(FunctionParameterType type) { + switch (type) { + case NUMBER: + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number"); + case STRING: + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String"); + case ANY: + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any"); + case DATE: + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date"); + case BOOLEAN: + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean"); + case ARRAY: + return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array"); + } + return StringUtils.EMPTY; + } +} diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaCheckerException.java b/designer-base/src/main/java/com/fr/design/formula/FormulaCheckerException.java new file mode 100644 index 0000000000..42fc585cbb --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/formula/FormulaCheckerException.java @@ -0,0 +1,11 @@ +package com.fr.design.formula; + +public class FormulaCheckerException extends Exception { + public FormulaCheckerException() { + + } + + public FormulaCheckerException(String message) { + super(message); + } +} diff --git a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java index 52807a6cb4..6012bba195 100644 --- a/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java +++ b/designer-base/src/main/java/com/fr/design/formula/FormulaPane.java @@ -38,18 +38,11 @@ import com.fr.log.FineLoggerFactory; import com.fr.parser.ArrayExpression; import com.fr.parser.BlockIntervalLiteral; import com.fr.parser.ColumnRowRangeInPage; -import com.fr.parser.FRLexer; -import com.fr.parser.FRParser; import com.fr.parser.NumberLiteral; import com.fr.parser.SheetIntervalLiteral; import com.fr.report.core.namespace.SimpleCellValueNameSpace; import com.fr.script.Calculator; import com.fr.script.ScriptConstants; -import com.fr.script.checker.FunctionCheckerDispatcher; -import com.fr.script.checker.exception.ConditionCheckWrongException; -import com.fr.script.checker.exception.FunctionCheckWrongException; -import com.fr.script.rules.FunctionParameterType; -import com.fr.script.rules.FunctionRule; import com.fr.stable.EncodeConstants; import com.fr.stable.EssentialUtils; import com.fr.stable.ParameterProvider; @@ -657,96 +650,41 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { public void actionPerformed(ActionEvent evt) { // Execute Formula default cell element. String formulaText = formulaTextArea.getText().trim(); - String formulaValidMessage = getFormulaValidMessage(formulaText); - FineJOptionPane.showMessageDialog( - FormulaPane.this, - formulaValidMessage + ".", - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), - JOptionPane.INFORMATION_MESSAGE); - } - }; - - private static String getFormulaValidMessage(String formulaText) { - StringReader in = new StringReader(formulaText); - - FRLexer lexer = new FRLexer(in); - FRParser parser = new FRParser(lexer); - - try { - Expression expression = parser.parse(); - Node node = expression.getConditionalExpression(); - return FunctionCheckerDispatcher.getInstance() - .getFunctionChecker(node) - .checkFunction(node) ? VALID_FORMULA : INVALID_FORMULA; - } catch (ConditionCheckWrongException cce) { - String functionName = cce.getFunctionName(); - StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Condition_Tips") + ":"); - return errorMsg.toString(); - } catch (FunctionCheckWrongException ce) { - List rules = ce.getRules(); - String functionName = ce.getFunctionName(); - StringBuilder errorMsg = new StringBuilder(functionName + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Error_Tips") + ":"); - for (int i = 0; i < rules.size(); i++) { - errorMsg.append("("); - if (rules.get(i).getParameterList().isEmpty()) { - errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_No_Param")); - } - for (FunctionParameterType functionParameterType : rules.get(i).getParameterList()) { - errorMsg.append(getTypeString(functionParameterType)).append(","); - } - if (",".equals(errorMsg.charAt(errorMsg.length() - 1) + "")) { - errorMsg.deleteCharAt(errorMsg.length() - 1); - } - errorMsg.append(")"); - if (i != rules.size() - 1) { - errorMsg.append(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_Or")); - } + String formulaValidMessage; + try { + formulaValidMessage = FormulaChecker.check(formulaText); + showMessageDialog(formulaValidMessage + "."); + } catch (FormulaCheckerException e) { + formulaValidMessage = e.getMessage(); + showMessageDialog(formulaValidMessage + ".", false); } - return errorMsg.toString(); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - return INVALID_FORMULA; - // alex:继续往下面走,expression为null时告知不合法公式 - } - } - - private static String getTypeString(FunctionParameterType type) { - switch (type) { - case NUMBER: - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Number"); - case STRING: - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_String"); - case ANY: - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Any"); - case DATE: - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Date"); - case BOOLEAN: - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Boolean"); - case ARRAY: - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Check_ParamType_Array"); } - return ""; - } + }; private final ActionListener calculateActionListener = new ActionListener() { @Override public void actionPerformed(ActionEvent e) { String formulaText = formulaTextArea.getText().trim(); - String formulaValidMessage = getFormulaValidMessage(formulaText); String unSupportFormula = containsUnsupportedSimulationFormulas(formulaText); if (unSupportFormula != null) { - FineJOptionPane.showMessageDialog( - FormulaPane.this, - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula, - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), - JOptionPane.INFORMATION_MESSAGE); + showMessageDialog(Toolkit.i18nText("Fine-Design_Basic_Formula_Unsupported_Formulas") + ":" + unSupportFormula, false); return; } + + String formulaValidMessage; + boolean formulaValid; + try { + formulaValidMessage = FormulaChecker.check(formulaText); + formulaValid = true; + } catch (FormulaCheckerException formulaCheckerException) { + formulaValidMessage = formulaCheckerException.getMessage(); + formulaValid = false; + } String messageTips; - if (formulaValidMessage.equals(INVALID_FORMULA)) { + if (ComparatorUtils.equals(formulaValidMessage, INVALID_FORMULA)) { messageTips = INVALID_FORMULA; } else { - messageTips = formulaValidMessage.equals(VALID_FORMULA) ? "" : formulaValidMessage + "\n"; + messageTips = ComparatorUtils.equals(formulaValidMessage, VALID_FORMULA) ? "" : formulaValidMessage + "\n"; Map paramsMap = setParamsIfExist(formulaText); Calculator calculator = Calculator.createCalculator(); ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(paramsMap); @@ -767,19 +705,33 @@ public class FormulaPane extends BasicPane implements KeyListener, UIFormula { String result = objectToString.length() > DEFUAL_FOMULA_LENGTH ? objectToString.substring(0, DEFUAL_FOMULA_LENGTH - ELLIPSIS.length()) + ELLIPSIS : objectToString; messageTips = messageTips + - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + result; + Toolkit.i18nText("Fine-Design_Basic_Formula_Cal_Result") + ":" + result; FineLoggerFactory.getLogger().info("value:{}", value); } catch (UtilEvalError utilEvalError) { FineLoggerFactory.getLogger().error("", utilEvalError); } } + showMessageDialog(messageTips, formulaValid); + } + }; + + private void showMessageDialog(String message) { + showMessageDialog(message, true); + } + + private void showMessageDialog(String message, boolean formulaValid) { + if (formulaValid) { FineJOptionPane.showMessageDialog( FormulaPane.this, - messageTips, - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), - JOptionPane.INFORMATION_MESSAGE); + message); + } else { + FineJOptionPane.showMessageDialog( + FormulaPane.this, + message, + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.WARNING_MESSAGE); } - }; + } private String containsUnsupportedSimulationFormulas(String formulaText) { try { diff --git a/designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java b/designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java new file mode 100644 index 0000000000..26fe62b5e6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/RegPaneProvider.java @@ -0,0 +1,11 @@ +package com.fr.design.fun; + +import com.fr.design.gui.frpane.RegFieldPane; +import com.fr.stable.fun.mark.Immutable; + +public interface RegPaneProvider extends Immutable { + int CURRENT_LEVEL = 1; + String XML_TAG = "RegPaneProvider"; + + RegFieldPane createRegPane(); +} diff --git a/designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java b/designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java new file mode 100644 index 0000000000..7ab8c782b4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/TextFieldAdapterProvider.java @@ -0,0 +1,11 @@ +package com.fr.design.fun; + +import com.fr.design.beans.ErrorMsgTextFieldAdapter; +import com.fr.stable.fun.mark.Immutable; + +public interface TextFieldAdapterProvider extends Immutable { + String XML_TAG = "TextFieldAdapterProvider"; + int CURRENT_LEVEL = 1; + + ErrorMsgTextFieldAdapter createTextFieldAdapter(); +} diff --git a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java new file mode 100644 index 0000000000..98185f2a5a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractRegPaneProvider.java @@ -0,0 +1,22 @@ +package com.fr.design.fun.impl; + +import com.fr.design.fun.RegPaneProvider; +import com.fr.stable.fun.mark.API; + +/** + * @author Joe + * 2021/10/8 15:19 + */ +@API(level = RegPaneProvider.CURRENT_LEVEL) +public abstract class AbstractRegPaneProvider implements RegPaneProvider { + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} diff --git a/designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java new file mode 100644 index 0000000000..bc0836eb40 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/fun/impl/AbstractTextFieldAdapterProvider.java @@ -0,0 +1,22 @@ +package com.fr.design.fun.impl; + +import com.fr.design.fun.TextFieldAdapterProvider; +import com.fr.stable.fun.mark.API; + +/** + * @author Joe + * 2021/10/8 15:17 + */ +@API(level = TextFieldAdapterProvider.CURRENT_LEVEL) +public abstract class AbstractTextFieldAdapterProvider implements TextFieldAdapterProvider { + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public int layerIndex() { + return DEFAULT_LAYER_INDEX; + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java b/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java index 3003800364..0a3684ba30 100644 --- a/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java +++ b/designer-base/src/main/java/com/fr/design/gui/chart/ChartEditPaneProvider.java @@ -16,4 +16,7 @@ public interface ChartEditPaneProvider { default void removeChartEditPaneActionListener(ChartEditPaneActionListener l) { } + default void resetLastChartCollection() { + } + } diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java index 2955801f76..82cba758b7 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/JListControlPane.java @@ -335,7 +335,7 @@ public abstract class JListControlPane extends JControlPane implements ListContr getHelper().checkButtonEnabled(); } - private class NameableListCellRenderer extends + protected class NameableListCellRenderer extends DefaultListCellRenderer { @Override public Component getListCellRendererComponent(JList list, Object value, diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java index 648cb03f33..f7229136f5 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIControlPane.java @@ -387,8 +387,6 @@ public abstract class UIControlPane extends JControlPane { contentPane.setBackground(originColor); contentPane.setLayout(new BorderLayout()); titleLabel = new UILabel(title); - Font font = new Font("SimSun", Font.PLAIN, 12); - titleLabel.setFont(font); contentPane.add(titleLabel, BorderLayout.WEST); contentPane.setBorder(new EmptyBorder(5, 14, 6, 0)); diff --git a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java index 6ec5f496a6..7c40235304 100644 --- a/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/controlpane/UIListGroupControlPane.java @@ -329,7 +329,7 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li width = Math.max(width, calculateUIListMaxCellWidth(uiList.getModel(), uiList.getFontMetrics(uiList.getFont()))); } iterator = nameEdListMap.entrySet().iterator(); - width += 40; + width += 30; while (iterator.hasNext()) { Map.Entry entry = iterator.next(); ListWrapperPane wrapperPane = entry.getValue(); @@ -349,7 +349,8 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li } else { text = element.toString(); } - width = Math.max(width, fontMetrics.stringWidth(text)); + //增加 10px 的左右间隔 + width = Math.max(width, fontMetrics.stringWidth(text) + 10); } } return width; @@ -539,7 +540,8 @@ public abstract class UIListGroupControlPane extends UIControlPane implements Li label.setBackground(Color.WHITE); label.setForeground(Color.decode("#333334")); label.setFont(label.getFont().deriveFont(11F)); - label.setPreferredSize(new Dimension(224, 26)); + //预留 10px 的纵向滚动条的宽度 + label.setPreferredSize(new Dimension(214, 26)); this.nameEdList = nameEdList; this.add(label, BorderLayout.NORTH); this.add(this.nameEdList, BorderLayout.CENTER); diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java index 381a9cd761..a9321879c8 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/AbstractAttrNoScrollPane.java @@ -24,6 +24,16 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane { private AttributeChangeListener listener; private String globalName = ""; + private boolean autoFireAttributesChanged = true; + + public boolean isAutoFireAttributesChanged() { + return this.autoFireAttributesChanged; + } + + public void setAutoFireAttributesChanged(boolean autoFireAttributesChanged) { + this.autoFireAttributesChanged = autoFireAttributesChanged; + } + protected AbstractAttrNoScrollPane() { initAll(); } @@ -127,7 +137,9 @@ public abstract class AbstractAttrNoScrollPane extends BasicPane { public void attributeChanged() { synchronized (this) { if (listener != null) { - listener.attributeChange(); + if (autoFireAttributesChanged) { + listener.attributeChange(); + } } } } diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java b/designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java new file mode 100644 index 0000000000..bfc1ff9d45 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/AttributeChangeUtils.java @@ -0,0 +1,47 @@ +package com.fr.design.gui.frpane; + +import java.awt.Component; +import java.awt.Container; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/17 + */ +public class AttributeChangeUtils { + private static AbstractAttrNoScrollPane findNearestAttrNoScrollPaneAncestor(Component c) { + for(Container p = c.getParent(); p != null; p = p.getParent()) { + if (p instanceof AbstractAttrNoScrollPane) { + return (AbstractAttrNoScrollPane) p; + } + } + return null; + } + + public static void changeComposedUI(Component composedComponent, boolean fireMiddleStateChanged, UIChangeAction action) { + AbstractAttrNoScrollPane attrPane = findNearestAttrNoScrollPaneAncestor(composedComponent); + boolean oldAutoFire = true; + + if (!fireMiddleStateChanged) { + // 禁止属性面板自动处理属性更新 + if (attrPane != null) { + oldAutoFire = attrPane.isAutoFireAttributesChanged(); + attrPane.setAutoFireAttributesChanged(false); + } + } + + // 更新UI + action.changeComposedUI(); + + if (!fireMiddleStateChanged) { + // 恢复属性面板自动处理属性更新 + if (attrPane != null) { + attrPane.setAutoFireAttributesChanged(oldAutoFire); + } + } + } + + public interface UIChangeAction { + void changeComposedUI(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java index 5d37fb4a96..38e33514bc 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/RegFieldPane.java @@ -1,21 +1,25 @@ package com.fr.design.gui.frpane; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.beans.ErrorMsgTextFieldAdapter; +import com.fr.design.beans.UITextFieldAdapter; import com.fr.design.constants.LayoutConstants; import com.fr.design.designer.IntervalConstants; import com.fr.design.dialog.BasicPane; +import com.fr.design.fun.TextFieldAdapterProvider; import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itextfield.UITextField; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; import com.fr.form.ui.TextEditor; import com.fr.form.ui.reg.NoneReg; import com.fr.form.ui.reg.RegExp; +import com.fr.log.FineLoggerFactory; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; /** * Created by kerry on 2017/9/4. @@ -23,7 +27,7 @@ import java.awt.*; public class RegFieldPane extends RegPane { protected RegErrorMsgPane regErrorMsgPane; - public RegFieldPane(){ + public RegFieldPane() { this(ALL_REG_TYPE); } @@ -39,8 +43,8 @@ public class RegFieldPane extends RegPane { @Override public void regChangeAction() { - RegExp regExp = (RegExp)getRegComboBox().getSelectedItem(); - if(regExp instanceof NoneReg){ + RegExp regExp = (RegExp) getRegComboBox().getSelectedItem(); + if (regExp instanceof NoneReg) { regErrorMsgPane.setVisible(false); return; } @@ -67,33 +71,35 @@ public class RegFieldPane extends RegPane { } private static class RegErrorMsgPane extends BasicPane { - private UITextField regErrorMsgField; + private ErrorMsgTextFieldAdapter errorMsgTextFieldAdapter; public RegErrorMsgPane() { + initRegErrorMsgField(); + setStyle(); + } + + private void setStyle() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); this.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L5, 0, 0)); - initRegErrorMsgField(); UILabel tipLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Error_Tip")); tipLabel.setPreferredSize(new Dimension(60, 20)); - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{tipLabel, regErrorMsgField}}, TableLayoutHelper.FILL_LASTCOLUMN, 10, LayoutConstants.VGAP_MEDIUM); + JPanel panel = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{tipLabel, errorMsgTextFieldAdapter.getErrorMsgTextField()}}, TableLayoutHelper.FILL_LASTCOLUMN, 10, LayoutConstants.VGAP_MEDIUM); this.add(panel); } private void initRegErrorMsgField() { - regErrorMsgField = new UITextField(); - regErrorMsgField.getDocument().addDocumentListener(new DocumentListener() { - public void changedUpdate(DocumentEvent e) { - regErrorMsgField.setToolTipText(regErrorMsgField.getText()); - } - - public void insertUpdate(DocumentEvent e) { - regErrorMsgField.setToolTipText(regErrorMsgField.getText()); - } + TextFieldAdapterProvider provider = ExtraDesignClassManager.getInstance().getSingle(TextFieldAdapterProvider.XML_TAG); + if (provider == null) { + errorMsgTextFieldAdapter = new UITextFieldAdapter(); + return; + } + try { + errorMsgTextFieldAdapter = provider.createTextFieldAdapter(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + errorMsgTextFieldAdapter = new UITextFieldAdapter(); - public void removeUpdate(DocumentEvent e) { - regErrorMsgField.setToolTipText(regErrorMsgField.getText()); - } - }); + } } @Override @@ -102,11 +108,11 @@ public class RegFieldPane extends RegPane { } public void populate(TextEditor textEditor) { - regErrorMsgField.setText(textEditor.getRegErrorMessage()); + errorMsgTextFieldAdapter.setText(textEditor.getRegErrorMessage()); } public void update(TextEditor textEditor) { - textEditor.setRegErrorMessage(regErrorMsgField.getText()); + textEditor.setRegErrorMessage(errorMsgTextFieldAdapter.getText()); } } diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPane.java index c1021321b9..fd2fcc3755 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPane.java @@ -21,6 +21,8 @@ public class UITabbedPane extends JTabbedPane{ private String classPath; //panel对象的类名 private String tabName; //Tab名称 private int tabSize = 0; + private Color tabBorderColor; + public UITabbedPane() { super(); } @@ -93,6 +95,16 @@ public class UITabbedPane extends JTabbedPane{ public int getTabSize(){ return tabSize; } + + public Color getTabBorderColor() { + return tabBorderColor; + } + + public void setTabBorderColor(Color tabBorderColor) { + this.tabBorderColor = tabBorderColor; + repaint(); + } + @Override /** * 获取UI对象 diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPaneUI.java b/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPaneUI.java index 5798a864b0..d31107c2ce 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPaneUI.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/UITabbedPaneUI.java @@ -31,9 +31,20 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI { private int addX = -1; private int addY = -1; private int rollover = -1; - private Color tabBorderColor = new Color(143, 160, 183); + private final Color DEFAULT_TAB_BORDER_COLOR = new Color(143, 160, 183); private Color[] tabSelectedColor = {UIConstants.NORMAL_BLUE, UIConstants.NORMAL_BLUE, UIConstants.NORMAL_BLUE}; + public Color getTabBorderColor() { + Color color = null; + if (tabPane instanceof UITabbedPane) { + color = ((UITabbedPane) tabPane).getTabBorderColor(); + } + if (color == null) { + color = DEFAULT_TAB_BORDER_COLOR; + } + return color; + } + /** * 创建UI对象 * @@ -252,9 +263,9 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI { private void drawUITabBorder(Graphics g, int tabPlacement, int x, int y, int w, int h, boolean isSelected, boolean isEnabled, boolean isRollover) { if (!isEnabled) { - drawUITabBorder(g, tabBorderColor, x, y, w, h, tabPlacement); + drawUITabBorder(g, getTabBorderColor(), x, y, w, h, tabPlacement); } else if (isSelected || isRollover) { - drawSelectedUITabBorder(g, tabBorderColor, x, y, w, h, tabPlacement); + drawSelectedUITabBorder(g, getTabBorderColor(), x, y, w, h, tabPlacement); if (isRollover && canClose()) { closeX = x + w - closeIcon.getIconWidth() - 3; closeY = 0; @@ -269,7 +280,7 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI { closeIcon.paintIcon(tabPane, g, closeX, closeY); } } else { - drawUITabBorder(g, tabBorderColor, x, y, w, h, tabPlacement); + drawUITabBorder(g, getTabBorderColor(), x, y, w, h, tabPlacement); } } @@ -322,7 +333,7 @@ public class UITabbedPaneUI extends BasicTabbedPaneUI { } private void drawUIContentBorder(Graphics g, int x, int y, int w, int h) { - g.setColor(tabBorderColor); + g.setColor(getTabBorderColor()); g.drawRect(x, y, w - 3, h - 3); // Shadow g.setColor(new Color(204, 204, 204)); diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java index 624e2e8ee8..34a7a0012b 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIButtonGroup.java @@ -37,6 +37,8 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver { private boolean isToolBarComponent = false; private boolean isClick; + private boolean autoFireStateChanged = true; + public UIButtonGroup(String[] textArray) { this(textArray, null); } @@ -72,7 +74,7 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver { if (globalNameListener != null) { globalNameListener.setGlobalName(buttonGroupName); } - setSelectedWithFireChanged(index); + setSelectedIndex(index, autoFireStateChanged); } }; } @@ -108,7 +110,7 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver { if (globalNameListener != null) { globalNameListener.setGlobalName(buttonGroupName); } - setSelectedWithFireChanged(index); + setSelectedIndex(index, autoFireStateChanged); } }; } @@ -175,7 +177,7 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver { if (globalNameListener != null) { globalNameListener.setGlobalName(buttonGroupName); } - setSelectedWithFireChanged(index); + setSelectedIndex(index, autoFireStateChanged); } }; } @@ -253,6 +255,10 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver { g2d.setClip(oldClip); } + public void setAutoFireStateChanged(boolean autoFireStateChanged) { + this.autoFireStateChanged = autoFireStateChanged; + } + /** * setSelectedItem * @@ -287,13 +293,14 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver { return selectedIndex; } - protected void setSelectedWithFireChanged(int newSelectedIndex) { - selectedIndex = newSelectedIndex; - for (int i = 0; i < labelButtonList.size(); i++) { - if (i == selectedIndex) { - labelButtonList.get(i).setSelectedWithFireListener(true); - } else { - labelButtonList.get(i).setSelected(false); + protected void setSelectedIndex(int newSelectedIndex, boolean fireChanged) { + if (selectedIndex != newSelectedIndex) { + selectedIndex = newSelectedIndex; + for (int i = 0; i < labelButtonList.size(); i++) { + labelButtonList.get(i).setSelected(i == selectedIndex, false); + } + if (fireChanged) { + fireStateChanged(); } } } @@ -304,10 +311,7 @@ public class UIButtonGroup extends JPanel implements GlobalNameObserver { * @param newSelectedIndex */ public void setSelectedIndex(int newSelectedIndex) { - selectedIndex = newSelectedIndex; - for (int i = 0; i < labelButtonList.size(); i++) { - labelButtonList.get(i).setSelected(i == selectedIndex); - } + setSelectedIndex(newSelectedIndex, true); } private void fireStateChanged() { diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java index 69f5845f1d..1d74d2e1d3 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UITabGroup.java @@ -63,13 +63,8 @@ public class UITabGroup extends UIButtonGroup { } @Override - protected void setSelectedWithFireChanged(int newSelectedIndex) { - if (selectedIndex != newSelectedIndex) { - selectedIndex = newSelectedIndex; - for (int i = 0; i < labelButtonList.size(); i++) { - labelButtonList.get(i).setSelected(i == selectedIndex); - } - } + protected void setSelectedIndex(int newSelectedIndex, boolean fireChanged) { + super.setSelectedIndex(newSelectedIndex, fireChanged); tabChanged(newSelectedIndex); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIToggleButton.java b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIToggleButton.java index dc380c0c94..18764e9119 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ibutton/UIToggleButton.java +++ b/designer-base/src/main/java/com/fr/design/gui/ibutton/UIToggleButton.java @@ -142,10 +142,12 @@ public class UIToggleButton extends UIButton implements GlobalNameObserver{ } } - public void setSelectedWithFireListener(boolean isSelected) { + public void setSelected(boolean isSelected, boolean fireChanged) { if (this.isSelected != isSelected) { this.isSelected = isSelected; - fireSelectedChanged(); + if (fireChanged) { + fireSelectedChanged(); + } refresh(isSelected); } } @@ -175,7 +177,7 @@ public class UIToggleButton extends UIButton implements GlobalNameObserver{ @Override public void mouseClicked(MouseEvent e) { if (isEnabled() && !isEventBannded) { - setSelectedWithFireListener(!isSelected()); + setSelected(!isSelected(), true); } } }; diff --git a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java index 22f6cb246e..4a722fc50d 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java @@ -73,6 +73,12 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver textField.setValue(defaultValue); } + public UISpinner(double minValue, double maxValue, double dierta, double defaultValue, boolean fillNegativeNumber) { + init(minValue, maxValue, dierta); + textField.setValue(defaultValue); + textField.canFillNegativeNumber(fillNegativeNumber); + } + protected void init(double minValue, double maxValue, double dierta) { this.minValue = minValue; this.maxValue = maxValue; diff --git a/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java b/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java index 9ed9068273..85474ca3ce 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java +++ b/designer-base/src/main/java/com/fr/design/gui/itextfield/EditTextField.java @@ -1,12 +1,11 @@ package com.fr.design.gui.itextfield; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Toolkit; - import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Toolkit; /** diff --git a/designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java b/designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java index fe6318ad3f..0b814f284a 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/AbstractTranslucentBackgroundSpecialPane.java @@ -2,13 +2,13 @@ package com.fr.design.gui.style; import com.fr.design.designer.IntervalConstants; import com.fr.design.dialog.BasicPane; -import com.fr.design.dialog.BasicScrollPane; import com.fr.design.gui.frpane.UIPercentDragPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.backgroundpane.GradientBackgroundQuickPane; +import com.fr.design.widget.FRWidgetFactory; import com.fr.general.Background; import com.fr.general.act.BackgroundPacker; @@ -51,8 +51,8 @@ public abstract class AbstractTranslucentBackgroundSpecialPane(hAlignmentIconArray, hAlignment); - hAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Left"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Right"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Distributed"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_DEFAULT")}); + hAlignmentPane.setAllToolTips(new String[]{Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Left"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Right"), + Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Distributed"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_DEFAULT")}); hPaneContainer = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); vPaneContainer = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); @@ -113,7 +114,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO {IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/v_down_normal.png"), IOUtils.readIcon("/com/fr/design/images/m_format/cellstyle/v_down_normal_white.png")}}; Integer[] vAlignment = new Integer[]{Constants.TOP, Constants.CENTER, Constants.BOTTOM}; vAlignmentPane = new UIButtonGroup<>(vAlignmentIconArray, vAlignment); - vAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Top"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Bottom")}); + vAlignmentPane.setAllToolTips(new String[]{Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Top"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Center"), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Tooltips_Bottom")}); initOtherComponent(); initAllNames(); @@ -175,7 +176,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private void initTextRotationCombox() { ArrayList selectOption = new ArrayList<>(); - selectOption.add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Custom_Angle")); + selectOption.add(Toolkit.i18nText("Fine-Design_Basic_Custom_Angle")); VerticalTextProcessor processor = ExtraClassManager.getInstance().getSingle(VerticalTextProcessor.XML_TAG, DefaultVerticalTextProcessor.class); selectOption.addAll(Arrays.asList(processor.getComboxOption())); @@ -183,25 +184,25 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO } private void initAllNames() { - hAlignmentPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal")); - vAlignmentPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical")); - imageLayoutComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout")); - textComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style")); - textRotationComboBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); - rotationPane.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); - leftIndentSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent")); - rightIndentSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent")); - spaceBeforeSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before")); - spaceAfterSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After")); - lineSpaceSpinner.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")); + hAlignmentPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal")); + vAlignmentPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical")); + imageLayoutComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Image_Layout")); + textComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style")); + textRotationComboBox.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); + rotationPane.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation")); + leftIndentSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent")); + rightIndentSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent")); + spaceBeforeSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before")); + spaceAfterSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After")); + lineSpaceSpinner.setGlobalName(Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")); } private JPanel createPane() { JPanel jp1 = new JPanel(new BorderLayout()); basicPane = new JPanel(); seniorPane = new JPanel(); - basicPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic"), 290, 24, basicPane()); - seniorPane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Advanced"), 290, 24, seniorPane()); + basicPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Report_Basic"), 290, 24, basicPane()); + seniorPane = new UIExpandablePane(Toolkit.i18nText("Fine-Design_Basic_Advanced"), 290, 24, seniorPane()); jp1.add(basicPane, BorderLayout.NORTH); jp1.add(seniorPane, BorderLayout.CENTER); @@ -212,13 +213,13 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private JPanel basicPane() { double f = TableLayout.FILL; double p = TableLayout.PREFERRED; - UILabel horizontalLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal") + " ", SwingConstants.LEFT); + UILabel horizontalLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal") + " ", SwingConstants.LEFT); UIComponentUtils.setLineWrap(horizontalLabel); Component[][] components = new Component[][]{ new Component[]{null, null}, new Component[]{horizontalLabel, hPaneContainer}, new Component[]{null, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical") + " ", SwingConstants.RIGHT), vPaneContainer}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical") + " ", SwingConstants.RIGHT), vPaneContainer}, new Component[]{null, null} }; double[] rowSize = {p, p, p, p, p, p}; @@ -233,11 +234,11 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO double p = TableLayout.PREFERRED; Component[][] components = new Component[][]{ new Component[]{null, null}, - new Component[]{new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout")) + " ", SwingConstants.LEFT), imageLayoutComboBox}, + new Component[]{new UILabel((Toolkit.i18nText("Fine-Design_Basic_Image_Layout")) + " ", SwingConstants.LEFT), imageLayoutComboBox}, new Component[]{null, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style") + " ", SwingConstants.LEFT), textComboBox}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style") + " ", SwingConstants.LEFT), textComboBox}, new Component[]{null, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation") + " ", SwingConstants.LEFT), textRotationComboBox}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation") + " ", SwingConstants.LEFT), textRotationComboBox}, new Component[]{null, rotationBarCC}, new Component[]{null, null}, }; @@ -261,23 +262,23 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO lineSpaceSpinner.setPreferredSize(SPINNER_DIMENSION); JPanel indentationPane = new JPanel(new BorderLayout()); - indentationPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Indentation")), SwingConstants.LEFT)); + indentationPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Indentation")), SwingConstants.LEFT)); indentationPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP)); JPanel partSpacingPane = new JPanel(new BorderLayout()); - partSpacingPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Part_Spacing")), SwingConstants.LEFT)); + partSpacingPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Part_Spacing")), SwingConstants.LEFT)); partSpacingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP)); JPanel spacingPane = new JPanel(new BorderLayout()); - spacingPane.add(new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Spacing")), SwingConstants.LEFT)); + spacingPane.add(new UILabel((Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing")), SwingConstants.LEFT)); spacingPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, GAP)); Component[][] components = new Component[][]{ new Component[]{null, null, null}, new Component[]{indentationPane, creatSpinnerPane(leftIndentSpinner), creatSpinnerPane(rightIndentSpinner)}, - new Component[]{null, new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Left")), SwingConstants.CENTER), new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Right")), SwingConstants.CENTER)}, + new Component[]{null, new UILabel((Toolkit.i18nText("Fine-Design_Report_Left")), SwingConstants.CENTER), new UILabel((Toolkit.i18nText("Fine-Design_Basic_Right")), SwingConstants.CENTER)}, new Component[]{null, null, null}, new Component[]{null, null, null}, new Component[]{partSpacingPane, creatSpinnerPane(spaceBeforeSpinner), creatSpinnerPane(spaceAfterSpinner)}, - new Component[]{null, new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Front")), SwingConstants.CENTER), new UILabel((com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Behind")), SwingConstants.CENTER)}, + new Component[]{null, new UILabel((Toolkit.i18nText("Fine-Design_Basic_Front")), SwingConstants.CENTER), new UILabel((Toolkit.i18nText("Fine-Design_Basic_Behind")), SwingConstants.CENTER)}, new Component[]{null, null, null}, new Component[]{null, null, null}, new Component[]{spacingPane, creatSpinnerPane(lineSpaceSpinner), null}, @@ -300,7 +301,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO * @return 标题 */ public String title4PopupWindow() { - return com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Alignment"); + return Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Style_Alignment"); } /** @@ -363,18 +364,18 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO return null; } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Horizontal"))) { Integer h = this.hAlignmentPane.getSelectedItem(); style = style.deriveHorizontalAlignment(h == null ? -1 : h); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Pane_Vertical"))) { Integer vAlign = this.vAlignmentPane.getSelectedItem(); if (vAlign != null) { style = style.deriveVerticalAlignment(vAlign); } } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Alignment_Text_Style"))) { if (ComparatorUtils.equals(this.textComboBox.getSelectedItem(), TEXT[0])) { style = style.deriveTextStyle(Style.TEXTSTYLE_WRAPTEXT); } else if (ComparatorUtils.equals(this.textComboBox.getSelectedItem(), TEXT[1])) { @@ -394,7 +395,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private Style updateImageLayout(Style style) { - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Image_Layout"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Image_Layout"))) { if (ComparatorUtils.equals(this.imageLayoutComboBox.getSelectedItem(), LAYOUT[1])) { style = style.deriveImageLayout(Constants.IMAGE_TILED); } else if (ComparatorUtils.equals(this.imageLayoutComboBox.getSelectedItem(), LAYOUT[2])) { @@ -410,7 +411,7 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO private Style updateTextRotation(Style style) { - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_StyleAlignment_Text_Rotation"))) { if (this.textRotationComboBox.getSelectedIndex() != 0) { style = style.deriveVerticalText(Style.VERTICALTEXT); style = style.deriveRotation(0); @@ -424,21 +425,21 @@ public class AlignmentPane extends AbstractBasicStylePane implements GlobalNameO } private Style updateOther(Style style) { - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Left_Indent"))) { style = style.derivePaddingLeft(indentationUnitProcessor.paddingUnitGainFromSpinner((int) (this.leftIndentSpinner.getValue()))); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Right_Indent"))) { style = style.derivePaddingRight(indentationUnitProcessor.paddingUnitGainFromSpinner((int) (this.rightIndentSpinner.getValue()))); } //间距 - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_Before"))) { style = style.deriveSpacingBefore((int) (this.spaceBeforeSpinner.getValue())); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Spacing_After"))) { style = style.deriveSpacingAfter((int) (this.spaceAfterSpinner.getValue())); } - if (ComparatorUtils.equals(globalNameListener.getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"))) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), Toolkit.i18nText("Fine-Design_Basic_Style_Line_Spacing"))) { style = style.deriveLineSpacing((int) (this.lineSpaceSpinner.getValue())); } return style; diff --git a/designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java b/designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java index ef47a148b1..0fe9c14891 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/ComponentIntegralStylePane.java @@ -2,11 +2,11 @@ package com.fr.design.gui.style; import com.fr.design.designer.IntervalConstants; import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ispinner.UISpinner; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.widget.FRWidgetFactory; import com.fr.general.act.BorderPacker; import javax.swing.JComponent; @@ -72,9 +72,9 @@ public class ComponentIntegralStylePane extends AbstractBorderPackerPane { double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f}; JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Render_Style")), borderStyleCombo}, + {FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Render_Style")), FRGUIPaneFactory.createBorderLayoutNorthPaneWithComponent(borderStyleCombo)}, {this.borderPane, null}, - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Radius")), cornerSpinner}, + {FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Radius")), cornerSpinner}, }, rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); diff --git a/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java b/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java index 8f9a8503da..33af029ad6 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/ComponentTitleStylePane.java @@ -9,10 +9,10 @@ import com.fr.design.gui.ibutton.UIColorButton; import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.ilable.UILabel; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.widget.FRWidgetFactory; import com.fr.form.ui.LayoutBorderStyle; import com.fr.form.ui.WidgetTitle; import com.fr.general.FRFont; @@ -168,7 +168,7 @@ public class ComponentTitleStylePane extends AbstractBorderPackerPane { visibleCheckbox.setSelected(false); container.add(visibleCheckbox, BorderLayout.WEST); - container.add(new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Visible")), BorderLayout.CENTER); + container.add(FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Visible")), BorderLayout.CENTER); visibleCheckbox.addChangeListener(new ChangeListener() { @Override @@ -192,7 +192,7 @@ public class ComponentTitleStylePane extends AbstractBorderPackerPane { double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f}; return TableLayoutHelper.createCommonTableLayoutPane( - new JComponent[][]{{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Content")), textContentPane}}, + new JComponent[][]{{FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Content")), textContentPane}}, rowSize, columnSize, IntervalConstants.INTERVAL_L1); } @@ -203,10 +203,10 @@ public class ComponentTitleStylePane extends AbstractBorderPackerPane { double[] columnSize = {this.uiLabelWidth, this.uiSettingWidth > 0 ? this.uiSettingWidth : f}; JComponent[][] components = new JComponent[][]{ - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Format")), fontFamilyComboBox}, + {FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Format")), FRGUIPaneFactory.createBorderLayoutNorthPaneWithComponent(fontFamilyComboBox)}, {null, createTitleFontButtonPane()}, {insetImagePane, null}, - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Text_Align")), alignPane}, + {FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Title_Text_Align")), alignPane}, {backgroundPane, null} }; diff --git a/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java b/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java index 55f4612a2b..bf06aa2fd7 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/FollowingThemePane.java @@ -1,13 +1,11 @@ package com.fr.design.gui.style; -import com.fr.base.theme.FormTheme; import com.fr.base.theme.TemplateTheme; import com.fr.design.dialog.BasicPane; -import com.fr.design.event.GlobalNameListener; -import com.fr.design.event.GlobalNameObserver; import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.frpane.AttributeChangeUtils; import com.fr.design.gui.ibutton.UIButtonGroup; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; @@ -15,12 +13,12 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.JTemplate; +import com.fr.design.widget.FRWidgetFactory; import javax.swing.BorderFactory; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; -import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; @@ -50,28 +48,32 @@ public class FollowingThemePane extends BasicPane implements UIObserver { this.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); followingThemeButtonGroup = new UIButtonGroup<>(FOLLOWING_THEME_STRING_ARRAYS); + followingThemeButtonGroup.setAutoFireStateChanged(false); followingThemeButtonGroup.setSelectedIndex(1); followingThemeButtonGroup.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - for (FollowingThemeActionChangeListener changeListener : changeListeners) { - changeListener.onFollowingTheme(isFollowingTheme()); - } - invalidate(); - - // 与主题相关的属性面板更新完毕后,再通知外层更新数据 + AttributeChangeUtils.changeComposedUI(FollowingThemePane.this, false, new AttributeChangeUtils.UIChangeAction() { + @Override + public void changeComposedUI() { + for (FollowingThemeActionChangeListener changeListener : changeListeners) { + changeListener.onFollowingTheme(isFollowingTheme()); + } + invalidate(); + } + }); if (uiObserverListener != null) { uiObserverListener.doChange(); } } }); - UILabel followingThemeLabel = new UILabel(name); + UILabel followingThemeLabel = FRWidgetFactory.createLineWrapLabel(name); double p = TableLayout.PREFERRED; double f = TableLayout.FILL; JPanel followingThemePane = - TableLayoutHelper.createGapTableLayoutPane( new Component[][]{new Component[] { followingThemeLabel, followingThemeButtonGroup}}, + TableLayoutHelper.createGapTableLayoutPane( new Component[][]{new Component[] { followingThemeLabel, FRGUIPaneFactory.createBorderLayoutNorthPaneWithComponent(followingThemeButtonGroup)}}, new double[] { p }, new double[] { SETTING_LABEL_WIDTH, f }, 10, 0); followingThemePane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); followingThemePane.setVisible(false); diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java new file mode 100644 index 0000000000..7f11b0d4bf --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/style/TextFontTippedPane.java @@ -0,0 +1,86 @@ +package com.fr.design.gui.style; + +import com.fr.base.Style; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.theme.edit.ui.LabelUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.JTextArea; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; + + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/29 + */ +public class TextFontTippedPane extends AbstractBasicStylePane { + + private FRFontPane fontPane; + + public TextFontTippedPane(boolean showFormatTip) { + this.initializePane(showFormatTip); + } + + private void initializePane(boolean showFormatTip) { + setLayout(new BorderLayout()); + setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); + + fontPane = new FRFontPane(); + this.add(createLabeledPane(Toolkit.i18nText("Fine-Design_Form_FR_Font"), fontPane), BorderLayout.NORTH); + + if (showFormatTip) { + JPanel formatTipPane = createFormatTipPane(); + this.add(formatTipPane, BorderLayout.CENTER); + } + } + + private JPanel createLabeledPane(String text, JPanel panel) { + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = { p }; + double[] columnSize = {p, f}; + + UILabel uiLabel = new UILabel(text); + JPanel uiLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + uiLabelPane.add(uiLabel, BorderLayout.NORTH); + + return TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ + new Component[] { uiLabelPane, panel }, + }, rowSize, columnSize, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); + } + + private JPanel createFormatTipPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, 0, 0)); + JTextArea formatMigratedTip = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Report_Format_Style_Migrated_Tip"), new Color(153, 153, 153)); + + container.add(formatMigratedTip, BorderLayout.NORTH); + return container; + } + + @Override + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Report_Text"); + } + + @Override + public void populateBean(Style style) { + this.fontPane.populateBean(style); + } + + @Override + public Style update(Style style) { + return this.fontPane.update(style); + } +} + diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java new file mode 100644 index 0000000000..ae0a947992 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/style/TextFormatPane.java @@ -0,0 +1,483 @@ +package com.fr.design.gui.style; + +import com.fr.base.CoreDecimalFormat; +import com.fr.base.GraphHelper; +import com.fr.base.Style; +import com.fr.base.TextFormat; +import com.fr.data.core.FormatField; +import com.fr.data.core.FormatField.FormatContents; +import com.fr.design.border.UIRoundedBorder; +import com.fr.design.constants.LayoutConstants; +import com.fr.design.constants.UIConstants; +import com.fr.design.event.GlobalNameListener; +import com.fr.design.event.GlobalNameObserver; +import com.fr.design.event.UIObserverListener; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.icombobox.TextFontComboBox; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.icombobox.UIComboBoxRenderer; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JLabel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.UIManager; +import javax.swing.border.Border; +import javax.swing.border.TitledBorder; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.math.RoundingMode; +import java.text.Format; +import java.text.SimpleDateFormat; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/29 + * 包含格式相关的设置 + */ +public class TextFormatPane extends AbstractBasicStylePane implements GlobalNameObserver { + private static final long serialVersionUID = 724330854437726751L; + + private static final int LABEL_X = 4; + private static final int LABEL_Y = 18; + private static final int LABEL_DELTA_WIDTH = 8; + private static final int LABEL_HEIGHT = 15; //标签背景的范围 + private static final int CURRENCY_FLAG_POINT = 6; + + private static final Integer[] TYPES = new Integer[]{ + FormatContents.NULL, FormatContents.NUMBER, + FormatContents.CURRENCY, FormatContents.PERCENT, + FormatContents.SCIENTIFIC, FormatContents.DATE, + FormatContents.TIME, FormatContents.TEXT}; + + private static final Integer[] DATE_TYPES = new Integer[]{FormatContents.NULL, FormatContents.DATE, FormatContents.TIME}; + + private Format format; + + private UIComboBox typeComboBox; + private TextFontComboBox textField; + private UILabel sampleLabel; + private JPanel contentPane; + private JPanel txtCenterPane; + private JPanel centerPane; + private JPanel optionPane; + private UICheckBox roundingBox; + private JPanel formatFontPane; + private boolean isRightFormat; + private boolean isDate = false; + private GlobalNameListener globalNameListener = null; + + /** + * Constructor. + */ + public TextFormatPane() { + this.initComponents(TYPES); + } + + protected UIComboBox getTypeComboBox() { + return typeComboBox; + } + + protected void initComponents(Integer[] types) { + this.setLayout(new BorderLayout(0, 4)); + initSampleLabel(); + contentPane = new JPanel(new BorderLayout(0, 4)) { + @Override + public Dimension getPreferredSize() { + return new Dimension(super.getPreferredSize().width, 65); + } + }; + typeComboBox = new UIComboBox(types); + UIComboBoxRenderer render = createComBoxRender(); + typeComboBox.setRenderer(render); + typeComboBox.addItemListener(itemListener); + typeComboBox.setGlobalName("typeComboBox"); + contentPane.add(sampleLabel, BorderLayout.NORTH); + + txtCenterPane = new JPanel(new BorderLayout()); + textField = new TextFontComboBox(); + textField.addItemListener(textFieldItemListener); + textField.setEditable(true); + textField.setGlobalName("textField"); + txtCenterPane.add(textField, BorderLayout.NORTH); + + contentPane.add(txtCenterPane, BorderLayout.CENTER); + + centerPane = new JPanel(new CardLayout()); + centerPane.add(new JPanel(), "hide"); + centerPane.setPreferredSize(new Dimension(0, 0)); + centerPane.add(contentPane, "show"); + + typeComboBox.setPreferredSize(new Dimension(155,20)); + JPanel typePane = new JPanel(new BorderLayout()); + typePane.add(typeComboBox, BorderLayout.CENTER); + typePane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + + JPanel option = new JPanel(new BorderLayout()); + option.add(new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Option"), SwingConstants.LEFT), BorderLayout.WEST); + roundingBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Base_Option_Half_Up")); + roundingBox.setBorder(BorderFactory.createEmptyBorder(0, 30, 0, 0)); + roundingBox.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + } + }); + roundingBox.setGlobalName("roundingBox"); + option.add(roundingBox, BorderLayout.CENTER); + optionPane = new JPanel(new CardLayout()); + optionPane.add(new JPanel(), "hide"); + optionPane.setPreferredSize(new Dimension(0, 0)); + optionPane.add(option, "show"); + + Component[][] components = getComponent(centerPane, typePane); + this.add(createContentPane(components), BorderLayout.CENTER); + } + + protected JPanel createContentPane (Component[][] components) { + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p, p, p, p, p}; + double[] columnSize = {p, f}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; + return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_LARGE, LayoutConstants.VGAP_MEDIUM); + } + + + protected Component[][] getComponent (JPanel centerPane, JPanel typePane) { + return new Component[][]{ + new Component[]{null, null}, + new Component[]{new UILabel(Toolkit.i18nText("Fine-Design_Report_Base_Format"), SwingConstants.LEFT), typePane}, + new Component[]{centerPane, null}, + new Component[]{optionPane, null}, + }; + } + + protected UIComboBoxRenderer createComBoxRender() { + return new UIComboBoxRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof Integer) { + label.setText(" " + FormatField.getInstance().getName((Integer) value)); + } + return label; + } + }; + } + + private void initSampleLabel() { + Border interBorder = new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 4); + String title = Toolkit.i18nText("Fine-Design_Report_Base_StyleFormat_Sample"); + Border border = BorderFactory.createTitledBorder(interBorder, title, TitledBorder.LEFT, 0, null, UIConstants.LINE_COLOR); + sampleLabel = new UILabel(FormatField.getInstance().getFormatValue()) { + + @Override + public void paint(Graphics g) { + super.paint(g); + int width = getWidth(); + Color original = g.getColor(); + g.setColor(getBackground()); + g.fillRect(LABEL_X, LABEL_Y, width - LABEL_DELTA_WIDTH, LABEL_HEIGHT); + g.setColor(UIConstants.LINE_COLOR); + FontMetrics cellFM = g.getFontMetrics(); + int textWidth = cellFM.stringWidth(getText()); + GraphHelper.drawString(g, getText(), (width - textWidth) / 2, 26); + g.setColor(original); + } + }; + sampleLabel.setHorizontalAlignment(UILabel.CENTER); + sampleLabel.setBorder(border); + } + + + @Override + /** + * 得到合适的大小 + */ + public Dimension getPreferredSize() { + if (this.typeComboBox.getSelectedIndex() == FormatContents.NULL) { + return typeComboBox.getPreferredSize(); + } + return super.getPreferredSize(); + } + + /** + * 弹出框标题 + * + * @return 标题 + */ + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Report_Text"); + } + + /** + * Populate + */ + public void populateBean(Format format) { + this.format = format; + + if (format == null) { + this.typeComboBox.setSelectedIndex(FormatContents.NULL); + } else { + if (format instanceof CoreDecimalFormat) { + // check all value + String pattern = ((CoreDecimalFormat) format).toPattern(); + if (isCurrencyFormatStyle(pattern)) { + setPatternComboBoxAndList(FormatContents.CURRENCY, pattern); + } else if (pattern.indexOf("%") > 0) { + setPatternComboBoxAndList(FormatContents.PERCENT, pattern); + this.roundingBox.setSelected(((CoreDecimalFormat) format).getRoundingMode().equals(RoundingMode.HALF_UP)); + } else if (pattern.indexOf("E") > 0) { + setPatternComboBoxAndList(FormatContents.SCIENTIFIC, pattern); + } else { + setPatternComboBoxAndList(FormatContents.NUMBER, pattern); + } + } else if (format instanceof SimpleDateFormat) { // date and time + String pattern = ((SimpleDateFormat) format).toPattern(); + if (!isTimeType(pattern)) { + setPatternComboBoxAndList(FormatContents.DATE, pattern); + } else { + setPatternComboBoxAndList(FormatContents.TIME, pattern); + } + } else if (format instanceof TextFormat) { // Text + this.typeComboBox.setSelectedItem(FormatContents.TEXT); + } + } + } + + private boolean isCurrencyFormatStyle(String pattern) { + if (pattern.length() == 0) { + return false; + } + + if (pattern.charAt(0) == '¤' || pattern.charAt(0) == '$') { + return true; + } + + return pattern.length() > CURRENCY_FLAG_POINT && pattern.startsWith("#,##0;"); + } + + /** + * 判断是否是数组有模式 + * + * @param stringArray 字符串数组 + * @param pattern 格式 + * @return 是否是数组有模式 + */ + public static int isArrayContainPattern(String[] stringArray, String pattern) { + for (int i = 0; i < stringArray.length; i++) { + if (ComparatorUtils.equals(stringArray[i], pattern)) { + return i; + } + } + + return -1; + } + + private void setPatternComboBoxAndList(int formatStyle, String pattern) { + this.typeComboBox.setSelectedItem(formatStyle); + this.textField.setSelectedItem(pattern); + } + + private boolean isTimeType(String pattern) { + return pattern.matches(".*[Hhmsa].*"); + } + + /** + * update + */ + public Format update() { + String patternString = String.valueOf(textField.getSelectedItem()); + if (getFormatContents() == FormatContents.TEXT) { + return FormatField.getInstance().getFormat(getFormatContents(), patternString); + } + if (isRightFormat) { + if (StringUtils.isNotEmpty(patternString)) { + RoundingMode roundingMode = roundingBox.isSelected() ? RoundingMode.HALF_UP : RoundingMode.HALF_EVEN; + return FormatField.getInstance().getFormat(getFormatContents(), patternString, roundingMode); + } + } + return null; + } + + private int getFormatContents() { + return (Integer) typeComboBox.getSelectedItem(); + } + + /** + * Refresh preview label. + */ + private void refreshPreviewLabel() { + this.sampleLabel.setText(FormatField.getInstance().getFormatValue()); + this.sampleLabel.setForeground(UIManager.getColor("Label.foreground")); + try { + isRightFormat = true; + if (StringUtils.isEmpty(String.valueOf(textField.getSelectedItem()))) { + return; + } + this.sampleLabel.setText(FormatField.getInstance().getFormatValue(getFormatContents(), String.valueOf(textField.getSelectedItem()))); + } catch (Exception e) { + this.sampleLabel.setForeground(Color.red); + this.sampleLabel.setText(e.getMessage()); + isRightFormat = false; + } + } + + private boolean isTextOrNull() { + int contents = getFormatContents(); + return contents == FormatContents.TEXT || contents == FormatContents.NULL; + } + + /** + * Radio selection listener. + */ + ItemListener itemListener = new ItemListener() { + + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + int contents = getFormatContents(); + String[] items = FormatField.getInstance().getFormatArray(contents, false); + CardLayout cardLayout = (CardLayout) centerPane.getLayout(); + + if (isTextOrNull()) { + centerPane.setPreferredSize(new Dimension(0, 0)); + cardLayout.show(centerPane, "hide"); + } else { + textField.removeAllItems(); + textField.setItemArray(items); + textField.setSelectedIndex(0); + centerPane.setPreferredSize(new Dimension(270, 65)); + cardLayout.show(centerPane, "show"); + } + CardLayout optionLayout = ((CardLayout) optionPane.getLayout()); + if (getFormatContents() == FormatContents.PERCENT) { + optionPane.setPreferredSize(new Dimension(100, 20)); + optionLayout.show(optionPane, "show"); + } else { + optionPane.setPreferredSize(new Dimension(0, 0)); + optionLayout.show(optionPane, "hide"); + roundingBox.setSelected(false); + } + } + + } + }; + + ItemListener textFieldItemListener = new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + refreshPreviewLabel(); + } + } + }; + + @Override + /** + * populate + */ + public void populateBean(Style style) { + this.populateBean(style.getFormat()); + } + + @Override + /** + * update + */ + public Style update(Style style) { + if (ComparatorUtils.equals(globalNameListener.getGlobalName(), "textField") + || ComparatorUtils.equals(globalNameListener.getGlobalName(), "typeComboBox") + || ComparatorUtils.equals(globalNameListener.getGlobalName(), "roundingBox")) { + return style.deriveFormat(this.update()); + } + return style; + } + + /** + * 默认只显示百分比的编辑下拉. + */ + public void justUsePercentFormat() { + typeComboBox.setEnabled(false); + this.typeComboBox.setSelectedItem(FormatContents.PERCENT); + } + + public void setForDataSheet() { + Integer[] otherTypes = new Integer[]{FormatContents.NULL, FormatContents.NUMBER, FormatContents.CURRENCY, FormatContents.PERCENT, FormatContents.SCIENTIFIC,}; + this.typeComboBox = new UIComboBox(otherTypes); + UIComboBoxRenderer render = new UIComboBoxRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof Integer) { + label.setText(" " + FormatField.getInstance().getName((Integer) value)); + } + return label; + } + }; + typeComboBox.setRenderer(render); + typeComboBox.addItemListener(itemListener); + setTypeComboBoxPane(typeComboBox); + } + + protected void setTypeComboBoxPane (UIComboBox typeComboBox) { + this.add(typeComboBox, BorderLayout.NORTH); + } + + public void setComboBoxModel(boolean isDate) { + if (this.isDate != isDate) { + this.isDate = isDate; + this.typeComboBox.setSelectedIndex(0); + if (isDate) { + for (int i = 0; i < DATE_TYPES.length; i++) { + this.typeComboBox.addItem(DATE_TYPES[i]); + } + for (int i = 0; i < TYPES.length; i++) { + this.typeComboBox.removeItemAt(1); + } + } else { + for (int i = 0; i < TYPES.length; i++) { + this.typeComboBox.addItem(TYPES[i]); + } + for (int i = 0; i < DATE_TYPES.length; i++) { + this.typeComboBox.removeItemAt(1); + } + } + } + } + + @Override + public void registerNameListener(GlobalNameListener listener) { + globalNameListener = listener; + } + + public void registerChangeListener(UIObserverListener listener) { + typeComboBox.registerChangeListener(listener); + textField.registerChangeListener(listener); + } + + @Override + public boolean shouldResponseNameListener() { + return false; + } + + @Override + public void setGlobalName(String name) { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java b/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java index 237a5659a7..bb3ccf38bc 100644 --- a/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/style/TranslucentBorderSpecialPane.java @@ -299,15 +299,16 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple Background borderImage = style.getBorderImage(); if (borderImage instanceof ImageBackground) { // 图片类型边框 - Image image = ((ImageBackground) borderImage).getImage(); - int[] ninePoint = ((ImageBackground) borderImage).getNinePoint(); + ImageBackground imageBackground = (ImageBackground) borderImage; + Image image = imageBackground.getImage(); if (image != null) { this.borderLineCombo.selectBorderImage(); this.imagePreviewPane.setImageWithSuffix(((ImageBackground) borderImage).getImageWithSuffix()); this.tweakNinePointButton.setEnabled(true); this.borderImageOpacityPane.populateBean(style.getBorderImageOpacity()); - if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] > 0 && ninePoint[1] > 0 && ninePoint[2] > 0 && ninePoint[3] > 0) { + int[] ninePoint = ((ImageBackground) borderImage).getNinePoint(); + if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] >= 0 && ninePoint[1] >= 0 && ninePoint[2] >= 0 && ninePoint[3] >= 0) { this.ninePoint = Arrays.copyOf(ninePoint, 4); } else { this.ninePoint = new int[4]; @@ -487,6 +488,7 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private int ninePointBottom = -1; private static final int MIN_NINE_POINT = 0; + private static final int MIN_GAP_PARALLEL_LINES = 1; private int imgWidth; private int imgHeight; @@ -757,8 +759,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointTopChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgHeight - ninePointBottom) { - value = imgHeight - ninePointBottom - MIN_NINE_POINT; + } else if (value >= imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES) { + value = imgHeight - ninePointBottom - MIN_GAP_PARALLEL_LINES; } this.ninePointTop = value; repaint(); @@ -767,8 +769,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointBottomChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgHeight - ninePointTop) { - value = imgHeight - ninePointTop - MIN_NINE_POINT; + } else if (value >= imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES) { + value = imgHeight - ninePointTop - MIN_GAP_PARALLEL_LINES; } this.ninePointBottom = value; repaint(); @@ -777,8 +779,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointLeftChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgWidth - ninePointRight) { - value = imgWidth - ninePointRight - MIN_NINE_POINT; + } else if (value >= imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES) { + value = imgWidth - ninePointRight - MIN_GAP_PARALLEL_LINES; } this.ninePointLeft = value; repaint(); @@ -787,8 +789,8 @@ public class TranslucentBorderSpecialPane extends AbstractBorderPackerPane imple private void onNinePointRightChanged(int value) { if (value < MIN_NINE_POINT) { value = MIN_NINE_POINT; - } else if (value >= imgWidth - ninePointLeft) { - value = imgWidth - ninePointLeft - MIN_NINE_POINT; + } else if (value >= imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES) { + value = imgWidth - ninePointLeft - MIN_GAP_PARALLEL_LINES; } this.ninePointRight = value; repaint(); diff --git a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java index f3367206f5..48c18eb699 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java @@ -2,6 +2,8 @@ package com.fr.design.javascript; import com.fr.base.BaseFormula; import com.fr.base.Parameter; +import com.fr.base.extension.FileExtension; +import com.fr.design.border.UITitledBorder; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; @@ -14,6 +16,10 @@ import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIComboBoxRenderer; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itableeditorpane.ParameterTableModel; +import com.fr.design.gui.itableeditorpane.UITableEditAction; +import com.fr.design.gui.itableeditorpane.UITableEditorPane; +import com.fr.design.gui.itableeditorpane.UITableModelAdapter; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itree.filetree.TemplateFileTree; import com.fr.design.hyperlink.AbstractHyperLinkPane; @@ -22,32 +28,40 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.DesignerContext; -import com.fr.design.scrollruler.ModLineBorder; import com.fr.file.filetree.IOFileNodeFilter; import com.fr.general.GeneralUtils; import com.fr.js.ExportJavaScript; +import com.fr.js.SingleJavaScript; import com.fr.stable.ParameterProvider; import com.fr.stable.StringUtils; import javax.swing.AbstractButton; +import javax.swing.AbstractCellEditor; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.DefaultComboBoxModel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JTable; import javax.swing.SwingUtilities; +import javax.swing.event.CellEditorListener; +import javax.swing.event.ChangeEvent; import javax.swing.event.TableModelEvent; import javax.swing.event.TableModelListener; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; import java.awt.BorderLayout; import java.awt.CardLayout; import java.awt.Component; -import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.HashSet; import java.util.List; @@ -58,21 +72,21 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane EXPORT_TYPES_MAP = new HashMap<>(); - private static final String CURRENT_TEMPLATE = "current"; - private static final String DEFAULT_FILENAME = "default"; - + private static final Map FILENAME_TYPE_MAP = new HashMap<>(); + private static final Map PARAMETER_TYPE_MAP = new HashMap<>(); + private static final String DEFAULT = "default"; + private static final String CUSTOM = "custom"; + private static final String CURRENT_TEMPLATE = "cur"; + private static final String OTHER_TEMPLATE = "other"; + private static final UILabel EMPTY_LABEL = new UILabel(); static { EXPORT_TYPES_MAP.put(ExportJavaScript.EXPORT_PDF, Toolkit.i18nText("Fine-Design_Basic_Export_JS_PDF")); @@ -81,134 +95,648 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Front") + "\\/:*?\"<>|" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Back") + ""); + fileNameTipLabel.setVisible(false); + fileNameRadioGroup.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + if (defaultNameRadio.isSelected()) { + fileNameFormulaEditor.setVisible(false); + fileNameFormulaEditor.setEnabled(false); + fileNameTipLabel.setVisible(false); + } else { + fileNameFormulaEditor.setVisible(true); + fileNameFormulaEditor.setEnabled(true); + fileNameTipLabel.setVisible(true); + } + } + }); + Component[][] components = new Component[][]{{nameLabel, defaultNameRadio, customNameRadio, fileNameFormulaEditor}}; + JPanel fileNameRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p, p}); + + JPanel fileNameTipPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + fileNameTipPane.add(fileNameTipLabel); + + JPanel fileNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + fileNamePane.add(fileNameRadioPane, BorderLayout.NORTH); + fileNamePane.add(fileNameTipPane, BorderLayout.CENTER); + fileNameTipPane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); + fileNamePane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); + return fileNamePane; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting"); + } + } - private void initComponents() { - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - this.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting"))); + // 其他模板 + class OtherTemplatePane extends BasicPane { - //导出模板+导出方式+导出文件名 - JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + private UITableEditorPane editorPane; - //导出模板 - JPanel chooseTemplatePane = initChooseTemplatePane(); - northPane.add(chooseTemplatePane, BorderLayout.NORTH); + public OtherTemplatePane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_Other"))); - //导出方式 - JPanel exportTypePane = initExportTypePane(); - northPane.add(exportTypePane, BorderLayout.CENTER); + editorPane = new UITableEditorPane<>(new ExportJSTableModel()); - //导出文件名 - JPanel fileNamePane = initFileNamePane(); - northPane.add(fileNamePane, BorderLayout.SOUTH); + this.add(editorPane, BorderLayout.CENTER); + } - //参数 - JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - JPanel paramsPane = initParamsPane(); - centerPane.add(paramsPane); + public void reset() { + editorPane.populate(new SingleJavaScript[0]); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting"); + } - this.add(northPane, BorderLayout.NORTH); - this.add(centerPane, BorderLayout.CENTER); } - private JPanel initParamsPane() { - extendParametersCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Basic_Hyperlink_Extends_Report_Parameters")); - extendParametersCheckBox.setSelected(true); - parameterViewPane = new ReportletParameterViewPane(getChartParaType(), getValueEditorPane(), getValueEditorPane()); - parameterViewPane.setVisible(false); - parameterViewPane.addTableEditorListener(new TableModelListener() { - public void tableChanged(TableModelEvent e) { - List list = parameterViewPane.update(); - HashSet tempSet = new HashSet<>(); - for (int i = 0; i < list.size(); i++) { - if (StringUtils.isEmpty(list.get(i).getName())) { - continue; + class ExportJSTableModel extends UITableModelAdapter { + + private static final long serialVersionUID = -3697206557955735642L; + + public ExportJSTableModel() { + super(new String[]{ + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Template_File"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Custom"), + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Parameters_Setting"), + StringUtils.EMPTY}); + this.setColumnClass(new Class[]{ + ExportTemplateChooser.class, + ExportTypeCombobox.class, + FileNameCombobox.class, + FileNameFormulaEditor.class, + ParameterCombobox.class, + ParameterSettingButton.class + }); + this.setDefaultEditor(ExportTemplateChooser.class, new ExportTemplateChooser()); + this.setDefaultRenderer(ExportTemplateChooser.class, new ExportTemplateChooser()); + this.setDefaultEditor(ExportTypeCombobox.class, new ExportTypeCombobox()); + this.setDefaultEditor(FileNameCombobox.class, new FileNameCombobox()); + this.setDefaultEditor(FileNameFormulaEditor.class, new FileNameFormulaEditor()); + this.setDefaultEditor(ParameterCombobox.class, new ParameterCombobox()); + this.setDefaultEditor(ParameterSettingButton.class, new ParameterSettingButton()); + this.setDefaultRenderer(ParameterSettingButton.class, new ParameterSettingButton()); + this.createTable().getColumnModel().getColumn(2).setMaxWidth(60); + this.createTable().getColumnModel().getColumn(4).setMaxWidth(60); + this.createTable().getColumnModel().getColumn(5).setMaxWidth(50); + } + + @Override + public UITableEditAction[] createAction() { + return new UITableEditAction[]{new AddJSAction(), new DeleteAction()}; + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + SingleJavaScript js = this.getList().get(rowIndex); + switch (columnIndex) { + case 0: + return js.getTemplatePath(); + case 1: + return EXPORT_TYPES_MAP.get(js.getExportType()); + case 2: + return js.isDefaultFileName() ? Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default") : Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom"); + case 3: + return js.getFileName(); + case 4: + return js.isExtendParameters() ? Toolkit.i18nText("Fine-Design_Basic_Export_JS_Extend_Parameters") : Toolkit.i18nText("Fine-Design_Basic_Export_JS_Custom"); + case 5: + return js.getParameters(); + } + return null; + } + + @Override + public boolean isCellEditable(int row, int col) { + if (col == 3) { + // 命名详情 + return this.getList().get(row) != null && !this.getList().get(row).isDefaultFileName(); + } + return true; + } + + private class AddJSAction extends AddTableRowAction { + + public AddJSAction() { + + } + + @Override + public void actionPerformed(ActionEvent e) { + super.actionPerformed(e); + if (otherTemplatePane.editorPane.getTableModel().getList().size() <= 50) { + addJS(); + } else { + FineJOptionPane.showMessageDialog(otherTemplatePane, Toolkit.i18nText("Fine-Design_Basic_Export_JS_Batch_Export_Limit")); + } + } + } + + private void addJS() { + SingleJavaScript js = new SingleJavaScript(); + addRow(js); + fireTableDataChanged(); + table.getSelectionModel().setSelectionInterval(table.getRowCount() - 1, table.getRowCount() - 1); + } + + // 导出文件选择 + class ExportTemplateChooser extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { + + private static final long serialVersionUID = -9112506131272704717L; + private JPanel reportletNamePane; + private UITextField reportPathTextField; + private UIButton browserButton; + + public ExportTemplateChooser() { + // 路径输入框 + reportPathTextField = new UITextField(8); + reportPathTextField.setEnabled(false); + + // 选择路径按钮 + browserButton = new UIButton("..."); + browserButton.setVisible(true); + + Component[][] templateChooserComponent = {{reportPathTextField, browserButton}}; + double[] rowSize = {TableLayout.PREFERRED}; + double[] columnSize = {TableLayout.FILL, 22}; + reportletNamePane = TableLayoutHelper.createCommonTableLayoutPane(templateChooserComponent, rowSize, columnSize, 0); + + browserButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent evt) { + final ReportletPane reportletPane = new ReportletPane(); + reportletPane.setSelectedReportletPath(reportPathTextField.getText()); + BasicDialog reportletDialog = reportletPane.showWindow(SwingUtilities.getWindowAncestor(ExportJavaScriptPane.this)); + + reportletDialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + reportPathTextField.setText(reportletPane.getSelectedReportletPath()); + } + }); + reportletDialog.setVisible(true); } - if (tempSet.contains(list.get(i).toString())) { - list.remove(i); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Parameter_Duplicate_Name") + "!"); - return; + }); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + } - tempSet.add(list.get(i).toString()); + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1) { + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + String value = StringUtils.trimToNull(reportPathTextField.getText()); + js.setTemplatePath(value); + js.setCurrentTemplate(false); + fireTableDataChanged(); + } + }); + + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + reportPathTextField.setText((String) value); + return reportletNamePane; + } + + @Override + public Object getCellEditorValue() { + return reportPathTextField.getText(); + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + reportPathTextField.setText((String) value); + return reportletNamePane; + } + } + + // 导出方式下拉框 + class ExportTypeCombobox extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = -6564079764032351372L; + + private UIComboBox exportTypeComboBox; + + public ExportTypeCombobox() { + exportTypeComboBox = getComboBoxWithModel(new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE} + , EXPORT_TYPES_MAP); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1) { + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + Object ob = exportTypeComboBox.getSelectedItem(); + if (ob != null) { + String value = ob.toString(); + js.setExportType(value); + } + fireTableDataChanged(); + } + }); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + exportTypeComboBox.setSelectedItem(value); + return exportTypeComboBox; + } + + @Override + public Object getCellEditorValue() { + Object ob = exportTypeComboBox.getSelectedItem(); + if (ob != null) { + return ob.toString(); } + return ExportJavaScript.EXPORT_PDF; } - }); - extendParametersCheckBox.addItemListener(new ItemListener() { + } + + // 命名方式下拉框 + class FileNameCombobox extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = 1829005772744444269L; + private UIComboBox fileNameComboBox; + + public FileNameCombobox() { + fileNameComboBox = getComboBoxWithModel(new String[]{DEFAULT, CUSTOM}, FILENAME_TYPE_MAP); + fileNameComboBox.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + final int row = table.getSelectedRow(); + if (row == -1) { + return; + } + SingleJavaScript js = getList().get(row); + Object ob = fileNameComboBox.getSelectedItem(); + if (ob != null) { + String value = ob.toString(); + js.setDefaultFileName(StringUtils.equals(value, DEFAULT)); + if (js.isDefaultFileName()) { + js.setFileName(StringUtils.EMPTY); + } + } + table.repaint(); + } + }); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + fireTableDataChanged(); + } + }); + } + @Override - public void itemStateChanged(ItemEvent e) { - parameterViewPane.setVisible(e.getStateChange() == ItemEvent.DESELECTED); + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + fileNameComboBox.setSelectedItem(value); + return fileNameComboBox; } - }); - JPanel paramsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - paramsPane.setBorder(BorderFactory.createTitledBorder(new ModLineBorder(ModLineBorder.TOP), Toolkit.i18nText("Fine-Design_Basic_Parameters"))); - paramsPane.add(extendParametersCheckBox, BorderLayout.NORTH); - JPanel dynamicPaneWrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); - dynamicPaneWrapper.add(parameterViewPane); - paramsPane.add(dynamicPaneWrapper, BorderLayout.CENTER); - return paramsPane; - } - private JPanel initFileNamePane() { - UILabel nameLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename") + ":"); - fileNameRadioGroup = new ExportRadioGroup(); - defaultNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Default")); - defaultNameRadio.setSelected(true); - customNameRadio = new UIRadioButton(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Filename_Custom")); - addRadioToGroup(fileNameRadioGroup, defaultNameRadio, customNameRadio); - fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula")); - fileNameFormulaEditor.setEnabled(false); - fileNameRadioGroup.addActionListener(new ActionListener() { @Override - public void actionPerformed(ActionEvent e) { - if (defaultNameRadio.isSelected()) { - fileNameFormulaEditor.setEnabled(false); + public Object getCellEditorValue() { + return fileNameComboBox.getSelectedItem().toString(); + } + } + + // 命名方式公式框 + class FileNameFormulaEditor extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = 7120075192535645493L; + private FormulaEditor fileNameFormulaEditor; + + public FileNameFormulaEditor() { + fileNameFormulaEditor = new FormulaEditor(Toolkit.i18nText("Fine-Design_Report_Parameter_Formula")); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1) { + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + String value = fileNameFormulaEditor.getUITextField().getText(); + js.setFileName(value); + fireTableDataChanged(); + } + }); + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + if (value != null) { + fileNameFormulaEditor.setValue(BaseFormula.createFormulaBuilder().build(value)); } else { - fileNameFormulaEditor.setEnabled(true); + fileNameFormulaEditor.setValue(BaseFormula.createFormulaBuilder().build()); } + return fileNameFormulaEditor; } - }); - Component[][] components = new Component[][]{{nameLabel, defaultNameRadio, customNameRadio, fileNameFormulaEditor}}; - JPanel fileNameRadioPane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p, p, p}); - - JPanel fileNameTipPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - UILabel fileNameTipLabel = new UILabel("" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Front") + "\\/:*?\"<>|" + Toolkit.i18nText("Fine-Design_Basic_Export_JS_Title_Tip_Back") + ""); - fileNameTipPane.add(fileNameTipLabel); - - JPanel fileNamePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - fileNamePane.add(fileNameRadioPane, BorderLayout.NORTH); - fileNamePane.add(fileNameTipPane, BorderLayout.CENTER); - fileNameTipPane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2)); - fileNamePane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2)); - return fileNamePane; - } - private JPanel initExportTypePane() { - UILabel typeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type") + ":"); - exportTypeComboBox = new UIComboBox(new DefaultComboBoxModel()); - DefaultComboBoxModel comboBoxModel = (DefaultComboBoxModel) exportTypeComboBox.getModel(); - String[] allExportTypes = new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE}; - for (int i = 0; i < allExportTypes.length; i++) { - comboBoxModel.addElement(allExportTypes[i]); + @Override + public Object getCellEditorValue() { + return fileNameFormulaEditor.getUITextField().getText(); + } + + public FormulaEditor getFileNameEditor() { + return fileNameFormulaEditor; + } } - this.exportTypeComboBox.setRenderer(new UIComboBoxRenderer() { + + //参数设置下拉框 + class ParameterCombobox extends AbstractCellEditor implements TableCellEditor { + + private static final long serialVersionUID = 2630964402770993584L; + private UIComboBox parameterSetting; + + public ParameterCombobox() { + parameterSetting = getComboBoxWithModel(new String[]{DEFAULT, CUSTOM}, PARAMETER_TYPE_MAP); + parameterSetting.addItemListener(e -> { + if (e.getStateChange() == ItemEvent.SELECTED) { + final int row = table.getSelectedRow(); + if (row == -1) { + return; + } + SingleJavaScript js = getList().get(row); + Object ob = parameterSetting.getSelectedItem(); + if (ob != null) { + String value = ob.toString(); + js.setExtendParameters(StringUtils.equals(value, DEFAULT)); + } + // 单纯为了刷新表格,使某些联动生效 + table.repaint(); + } + }); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + // 这里重新触发是为了触发某些编辑后事件 + fireTableDataChanged(); + } + }); + } @Override - public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { - super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); - if (value instanceof String) { - this.setText(EXPORT_TYPES_MAP.get(value)); + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + parameterSetting.setSelectedItem(value); + return parameterSetting; + } + + @Override + public Object getCellEditorValue() { + return parameterSetting.getSelectedItem().toString(); + } + } + + // 参数设置按钮 + class ParameterSettingButton extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { + + private static final long serialVersionUID = 4021592871993049137L; + private UIButton paraButton; + private ParameterSettingPane paraSettingPane; + ParameterProvider[] parameterArr; + + public ParameterSettingButton() { + paraSettingPane = new ParameterSettingPane(); + paraButton = new UIButton(Toolkit.i18nText("Fine-Design_Report_Set")); + paraButton.addMouseListener(new MouseAdapter() { + + @Override + public void mousePressed(MouseEvent e) { + BasicDialog dialog = paraSettingPane.showWindow(SwingUtilities.getWindowAncestor(ExportJavaScriptPane.this)); + dialog.addDialogActionListener(new DialogActionAdapter() { + @Override + public void doOk() { + List parameterList = paraSettingPane.getParameterList(); + parameterArr = parameterList.toArray(new Parameter[parameterList.size()]); + } + }); + dialog.setVisible(true); + } + + }); + this.addCellEditorListener(new CellEditorListener() { + + @Override + public void editingCanceled(ChangeEvent e) { + + } + + @Override + public void editingStopped(ChangeEvent e) { + if (table.getSelectedRow() == -1) { + return; + } + SingleJavaScript js = getList().get(table.getSelectedRow()); + js.setParameters(parameterArr); + fireTableDataChanged(); + } + }); + + } + + @Override + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { + if (getList().get(row) == null || getList().get(row).isExtendParameters()) { + return EMPTY_LABEL; } - return this; + ParameterProvider[] providers = (ParameterProvider[]) value; + if (providers != null) { + paraSettingPane.refresh(new ArrayList<>(Arrays.asList(providers))); + } + return paraButton; } - }); + + @Override + public Object getCellEditorValue() { + return paraSettingPane.getParameterList(); + } + + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + if (getList().get(row) == null || getList().get(row).isExtendParameters()) { + return EMPTY_LABEL; + } + return paraButton; + } + } + + // 参数设置弹出框 + class ParameterSettingPane extends BasicPane { + + private ReportletParameterViewPane parameterViewPane; + + public ParameterSettingPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + parameterViewPane = new ReportletParameterViewPane(ParameterTableModel.NO_CHART_USE, getValueEditorPane(), getValueEditorPane()); + addListener(parameterViewPane); + this.add(parameterViewPane); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Export_JS_Parameters_Setting"); + } + + public List getParameterList() { + return parameterViewPane.update(); + } + + public void refresh(List list) { + parameterViewPane.update(list); + } + + } + + } + + public ExportJavaScriptPane() { + initComponents(); + } + + private void initComponents() { + JPanel totalPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + totalPanel.setBorder(UITitledBorder.createBorderWithTitle(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Setting"))); + + // 导出模板 + JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + JPanel chooseTemplatePane = initChooseTemplatePane(); + northPane.add(chooseTemplatePane, BorderLayout.NORTH); + + // 默认当前模板 + currentTemplatePane = new CurrentTemplatePane(); + otherTemplatePane = new OtherTemplatePane(); + templatePanel = FRGUIPaneFactory.createCardLayout_S_Pane(); + card = new CardLayout(); + templatePanel.setLayout(card); + templatePanel.add(CURRENT_TEMPLATE, currentTemplatePane); + templatePanel.add(OTHER_TEMPLATE, otherTemplatePane); + + totalPanel.add(northPane, BorderLayout.NORTH); + totalPanel.add(templatePanel, BorderLayout.CENTER); + + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(totalPanel); + } + + private JPanel initExportTypePane() { + UILabel typeLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Export_JS_Type") + ":"); + exportTypeComboBox = getComboBoxWithModel(new String[]{ExportJavaScript.EXPORT_PDF, ExportJavaScript.EXPORT_EXCEL_PAGE, ExportJavaScript.EXPORT_EXCEL_SIMPLE, ExportJavaScript.EXPORT_EXCEL_SHEET, ExportJavaScript.EXPORT_WORD, ExportJavaScript.EXPORT_IMAGE} + , EXPORT_TYPES_MAP); Component[][] components = new Component[][]{{typeLabel, exportTypeComboBox}}; JPanel exportTypePane = TableLayoutHelper.createTableLayoutPane(components, new double[]{p}, new double[]{p, p}); - exportTypePane.setBorder(BorderFactory.createEmptyBorder(5,2,5,2)); + exportTypePane.setBorder(BorderFactory.createEmptyBorder(5, 2, 5, 2)); return exportTypePane; } @@ -219,51 +747,28 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane parameterList = this.parameterViewPane.update(); + parameterList.clear(); + ParameterProvider[] parameters = js.getParameters(); + this.parameterViewPane.populate(parameters); + } + } } else { - this.extendParametersCheckBox.setSelected(false); - List parameterList = this.parameterViewPane.update(); - parameterList.clear(); - ParameterProvider[] parameters = ob.getParameters(); - this.parameterViewPane.populate(parameters); + OtherTemplatePane pane = (OtherTemplatePane) this.templatePanel.getComponent(1); + pane.editorPane.populate(ob.getJsList().toArray(new SingleJavaScript[ob.getJsList().size()])); } } @@ -308,32 +815,80 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane parameterList = parameterViewPane.update(); + if (!parameterList.isEmpty()) { + Parameter[] parameters = new Parameter[parameterList.size()]; + parameterList.toArray(parameters); + js.setParameters(parameters); + } + } + } + exportJavaScript.addJS(js); } else { - List parameterList = this.parameterViewPane.update(); - if (!parameterList.isEmpty()) { - Parameter[] parameters = new Parameter[parameterList.size()]; - parameterList.toArray(parameters); - exportJavaScript.setParameters(parameters); + List javaScripts = otherTemplatePane.editorPane.update(); + for (SingleJavaScript js : javaScripts) { + exportJavaScript.addJS(js); } } } - private String getTemplatePath() { - return currentTemplateRadio.isSelected() ? CURRENT_TEMPLATE : reportPathTextField.getText(); + private String getFileName() { + return currentTemplatePane.defaultNameRadio.isSelected() ? DEFAULT : currentTemplatePane.fileNameFormulaEditor.getUITextField().getText(); } - private String getFileName() { - return defaultNameRadio.isSelected() ? DEFAULT_FILENAME : fileNameFormulaEditor.getUITextField().getText(); + private UIComboBox getComboBoxWithModel(String[] itemTextArr, Map itemTextDic) { + UIComboBox comboBox = new UIComboBox(new DefaultComboBoxModel()); + DefaultComboBoxModel comboBoxModel = (DefaultComboBoxModel) comboBox.getModel(); + for (int i = 0; i < itemTextArr.length; i++) { + comboBoxModel.addElement(itemTextArr[i]); + } + comboBox.setRenderer(new UIComboBoxRenderer() { + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + if (value instanceof String) { + this.setText(itemTextDic.get(value)); + } + return this; + } + }); + return comboBox; } + private void addListener(ReportletParameterViewPane paraPane) { + paraPane.addTableEditorListener(new TableModelListener() { + public void tableChanged(TableModelEvent e) { + List list = paraPane.update(); + HashSet tempSet = new HashSet<>(); + for (int i = 0; i < list.size(); i++) { + if (StringUtils.isEmpty(list.get(i).getName())) { + continue; + } + if (tempSet.contains(list.get(i).toString())) { + list.remove(i); + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Parameter_Duplicate_Name") + "!"); + return; + } + tempSet.add(list.get(i).toString()); + } + } + }); + } @Override public boolean accept(Object ob) { @@ -417,6 +972,9 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane> TEMPLATE_RENAME = new Event>() { + }; private static final String FILE = "file"; private static volatile DesignerFrameFileDealerPane THIS; @@ -690,6 +695,7 @@ public class DesignerFrameFileDealerPane extends JPanel implements FileToolbarSt boolean success = selectedOperation.rename(fnf, path, newPath); if (success) { + EventDispatcher.fire(TEMPLATE_RENAME, new TwoTuple<>(path, newPath)); HistoryTemplateListCache.getInstance().rename(fnf, path, newPath); DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(fnf.isDirectory(), path, newPath); selectedOperation.refresh(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java index 0c10ac2e12..65a9a47d68 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesktopCardPane.java @@ -92,7 +92,7 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener } else if (jt.isOpening()) { showOpenStatus(); } else if (jt.isOpenFailed()) { - showOpenFailedCover(); + showOpenFailedCover(jt.getTemplateOpenFailedTip()); } else { hideCover(); } @@ -121,7 +121,8 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener layeredPane.moveToFront(loadingPane); } - public void showOpenFailedCover() { + public void showOpenFailedCover(String text) { + failedPane.setFailedTip(text); layeredPane.moveToFront(failedPane); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java index 588b4e2563..a6734da917 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/EastRegionContainerPane.java @@ -1005,6 +1005,7 @@ public class EastRegionContainerPane extends UIEastResizableContainer { button.addActionListener(actionListener); } button.setToolTipText(title); + button.setName(name); } public void processSnapChat() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 70d1f3e0e2..c342cc3910 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -19,7 +19,6 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.TableDataSourceAction; import com.fr.design.actions.edit.RedoAction; import com.fr.design.actions.edit.UndoAction; -import com.fr.design.actions.file.BatchCompileAction; import com.fr.design.actions.file.SaveAsTemplateAction; import com.fr.design.actions.file.SaveTemplateAction; import com.fr.design.actions.file.WebPreviewUtils; @@ -43,6 +42,7 @@ import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.imenu.UIMenuItem; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.authority.JTemplateAuthorityChecker; import com.fr.design.mainframe.chart.info.ChartInfoCollector; import com.fr.design.mainframe.check.CheckButton; import com.fr.design.mainframe.template.info.TemplateProcessInfo; @@ -67,7 +67,12 @@ import com.fr.form.ui.NoneWidget; import com.fr.form.ui.Widget; import com.fr.general.ComparatorUtils; import com.fr.general.IOUtils; +import com.fr.locale.InterProviderFactory; import com.fr.log.FineLoggerFactory; +import com.fr.nx.app.designer.utils.CptAndCptxCompatibilityUtil; +import com.fr.nx.app.designer.utils.CptCompileUtil; +import com.fr.nx.cptx.entry.metadata.CptxMetadata; +import com.fr.nx.cptx.utils.CptxFileUtils; import com.fr.plugin.context.PluginContext; import com.fr.plugin.context.PluginRuntime; import com.fr.nx.app.designer.toolbar.CompileAction; @@ -129,6 +134,8 @@ public abstract class JTemplate> private JComponent centerPane; private DesignModelAdapter designModel; private PreviewProvider previewType; + private String templateOpenFailedTip; + /** * 统计模板制作耗时 * @@ -247,6 +254,7 @@ public abstract class JTemplate> } } } + private void stopListenThemeConfig() { if (themeConfigChangeListener != null) { TemplateThemeConfig config = getUsingTemplateThemeConfig(); @@ -269,7 +277,7 @@ public abstract class JTemplate> public void fireTabChange() { // do nothing } - + protected void addPane(PropertyItemPaneProvider provider) { // do nothing } @@ -949,7 +957,7 @@ public abstract class JTemplate> } protected boolean export() throws Exception { - return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE)); + return this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(getEditingFILE())); } @@ -967,7 +975,7 @@ public abstract class JTemplate> } else if (DesignerMode.isAuthorityEditing()) { return new ShortCut[]{new SaveTemplateAction(this), new UndoAction(this), new RedoAction(this)}; } else { - return new ShortCut[]{new SaveTemplateAction(this), new SaveAsTemplateAction(this), new BatchCompileAction(), new UndoAction(this), new RedoAction(this)}; + return new ShortCut[]{new SaveTemplateAction(this), new SaveAsTemplateAction(this), new UndoAction(this), new RedoAction(this)}; } } @@ -1123,35 +1131,49 @@ public abstract class JTemplate> /** * 判断是否是新版设计器 * + * @param showTipPane 是否需要展示弹窗 * @return 是返回true */ - public boolean isNewDesigner() { + public boolean isNewDesigner(boolean showTipPane) { String xmlDesignerVersion = getTarget().getXMLDesignerVersion(); if (isLowerThanHBB(xmlDesignerVersion)) { String info = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Open-New_Form_Tip"); String moreInfo = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Server_Version_Tip_More_Info"); - new InformationWarnPane(info, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + if (showTipPane) { + new InformationWarnPane(info, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + } return true; } return false; } + public boolean isNewDesigner() { + return isNewDesigner(true); + } + /** * 是否是就版本设计器 * + * @param showTipPane 是否需要展示弹窗 * @return 是就返回true */ - public boolean isOldDesigner() { + public boolean isOldDesigner(boolean showTipPane) { String xmlDesignerVersion = getTarget().getXMLDesignerVersion(); if (isHigherThanCurrent(xmlDesignerVersion)) { String infor = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Template_Version_Not_Match", DesignUtils.parseVersion(xmlDesignerVersion)); String moreInfo = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Server_Version_Tip_More_Info"); - new InformationWarnPane(infor, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + if (showTipPane) { + new InformationWarnPane(infor, moreInfo, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips")).show(); + } return true; } return false; } + public boolean isOldDesigner() { + return isOldDesigner(true); + } + /** * */ @@ -1404,9 +1426,7 @@ public abstract class JTemplate> * @return 按钮组 */ public UIButton[] createExtraButtons() { - UIButton[] uiButtons = new UIButton[] { - (UIButton) new CompileAction().createToolBarComponent() - }; + UIButton[] uiButtons = new UIButton[0]; Set providers = ExtraDesignClassManager.getInstance().getArray(DesignerFrameUpButtonProvider.XML_TAG); for (DesignerFrameUpButtonProvider provider : providers) { uiButtons = ArrayUtils.addAll(uiButtons, provider.getUpButtons(getMenuState())); @@ -1432,6 +1452,7 @@ public abstract class JTemplate> }; button.setToolTipText(getTemplateTheme().getName()); button.setText(getTemplateTheme().getName()); + button.setName(getTemplateTheme().getName()); button.setAlignmentX(SwingConstants.LEFT); button.set4ToolbarButton(); button.setEnabled(true); @@ -1458,7 +1479,27 @@ public abstract class JTemplate> public abstract String route(); public String getTemplateName() { - return getEditingFILE().getName(); + return getEditingFILE().getName() + compatibilityTip(); + } + + /** + * 设置新引擎后,有不支持的功能时,设计器中模板的标题需要加上“兼容模式”或者“不支持分页引擎”来提示用户 + * */ + private String compatibilityTip() { + if (!CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())){ + return StringUtils.EMPTY; + } + String path = this.getEditingFILE().getPath(); + CptxMetadata metadata = CptxFileUtils.getMetadata(path); + //是否是兼容模式,兼容模式下,设置了新引擎的cpt和cptx的后缀不同 + if (metadata != null && metadata.isForceCpt()) { + if (path.endsWith(".cptx")){ + return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Compatibility_Mode"); + } else if (path.endsWith(".cpt")){ + return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Paging_Engine_Not_Work"); + } + } + return StringUtils.EMPTY; } public String getTemplatePredefinedStyle() { @@ -1527,6 +1568,8 @@ public abstract class JTemplate> @Override public void run() { callBackForSave(); + //在保存后的回调中执行预编译流程 + CptCompileUtil.compile(JTemplate.this); } }); @@ -1549,13 +1592,19 @@ public abstract class JTemplate> } private boolean saveRealFile() throws Exception { - FILE editingFILE = this.getEditingFILE(); - if (editingFILE == null || editingFILE instanceof MemFILE) { + JTemplateAuthorityChecker jTemplateAuthorityChecker = new JTemplateAuthorityChecker(this); + if (jTemplateAuthorityChecker.isAuthority()) { + FILE editingFILE = this.getEditingFILE(); + if (editingFILE == null || editingFILE instanceof MemFILE) { + return false; + } + export(); + this.editingFILE = editingFILE; + return true; + } else { + jTemplateAuthorityChecker.showAuthorityFailPromptDialog(); return false; } - this.getTarget().export(TemplateResourceManager.getResource().saveTemplate(editingFILE)); - this.editingFILE = editingFILE; - return true; } private CallbackSaveWorker saveAs(boolean showLoc) { @@ -1591,6 +1640,10 @@ public abstract class JTemplate> worker.addSuccessCallback(new Runnable() { @Override public void run() { + boolean isChangedFile = !JTemplate.this.saved; + if (isChangedFile){ + CptCompileUtil.compile(JTemplate.this); + } callBackForSave(); // 当前打开的是正在保存的模板才刷新 if (ComparatorUtils.equals(JTemplate.this.template.getTemplateID(), @@ -1600,7 +1653,6 @@ public abstract class JTemplate> DesignerFrameFileDealerPane.getInstance().refresh(); } }); - return worker; } @@ -1651,6 +1703,14 @@ public abstract class JTemplate> result = result || provider.saveToNewFile(this.editingFILE.getPath(), this); } if (!result) { + /* + * 1.在CptCompileUtil::haveChanged改变报表引擎属性 + * 2.在这三种情况下:1.cptx文件另存为cpt文件 2.cptx另存为cptx文件 3.设置了新引擎的cpt文件另存为cpt文件, + * 因为文件的编译目录改变了,需要重新预编译,因此设置jTemplate的保存状态为false + * */ + if (CptAndCptxCompatibilityUtil.needRecompile(oldName, this)){ + this.saved = false; + } result = this.saveRealFile(); // 更换最近打开 DesignerEnvManager.getEnvManager().replaceRecentOpenedFilePath(oldName, this.getPath()); @@ -1733,6 +1793,14 @@ public abstract class JTemplate> themeAttrMark.setDark(theme.isDark()); } + public String getTemplateOpenFailedTip() { + return templateOpenFailedTip; + } + + public void setTemplateOpenFailedTip(String templateOpenFailedTip) { + this.templateOpenFailedTip = templateOpenFailedTip; + } + @Override public void setTemplateTheme(TemplateTheme newTheme, TemplateThemeCompatible compatible) { ThemedTemplate.super.setTemplateTheme(newTheme, compatible); @@ -1740,4 +1808,4 @@ public abstract class JTemplate> templateThemeButton.setText(name); templateThemeButton.setToolTipText(name); } -} +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java index b070710579..f15b3517f0 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java @@ -116,6 +116,7 @@ public class NorthRegionContainerPane extends JPanel { if (!DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) { ad.createAlphaFinePane().setVisible(false); } + northEastPane.add(ad.createGuideEntryPane()); northEastPane.add(ad.createNotificationCenterPane()); OSSupportCenter.buildAction(new OSBasedAction() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java index 132569c236..63ab984da6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/OpenFailedPane.java @@ -24,6 +24,7 @@ public class OpenFailedPane extends JPanel { private UILabel label; private MessageWithLink link; + private String defaultFailedText; public OpenFailedPane() { this.setLayout(new LayoutManager() { @@ -83,11 +84,18 @@ public class OpenFailedPane extends JPanel { }); } }; + this.defaultFailedText = link.getText(); link.setBackground(Color.WHITE); this.add(label); this.add(link); } - + public void setFailedTip(String text) { + if (StringUtils.isEmpty(text)) { + this.link.setText(defaultFailedText); + } else { + this.link.setText(text); + } + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/DSColumnAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/DSColumnAuthorityChecker.java new file mode 100644 index 0000000000..fdab6ea2a2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/DSColumnAuthorityChecker.java @@ -0,0 +1,20 @@ +package com.fr.design.mainframe.authority; + +import com.fr.report.cell.cellattr.core.group.DSColumn; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class DSColumnAuthorityChecker extends ElementAuthorityChecker { + + @Override + @Nullable + Set getNoAuthDatasetNames(DSColumn dsColumn, Set authDatasetNames) { + if (!authDatasetNames.contains(dsColumn.getDSName())) { + return new HashSet<>(Arrays.asList(dsColumn.getDSName())); + } + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java new file mode 100644 index 0000000000..67d0f1da36 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/ElementAuthorityChecker.java @@ -0,0 +1,45 @@ +package com.fr.design.mainframe.authority; + +import org.jetbrains.annotations.Nullable; +import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl; + +import java.lang.reflect.Type; +import java.util.Set; + + +public abstract class ElementAuthorityChecker { + + + /** + * @Description 获取越权的数据连接 + * @param: t 待检查的对象 + * @param: authConnectionNames 有权限的数据连接名 + * @return 如果有返回名称,没有返回null + */ + @Nullable + Set getNoAuthConnectionNames(T t, Set authConnectionNames) { + return null; + } + + + /** + * @Description 获取越权的服务器数据集 + * @param: t 待检查的对象 + * @param: authDatasetNames 有权限的服务器数据集名 + * @return 如果有返回名称,没有返回null + */ + @Nullable + Set getNoAuthDatasetNames(T t, Set authDatasetNames) { + return null; + } + + /** + * @Description 要检查对象的className + * @return className + */ + String getCheckClassName() { + ParameterizedTypeImpl parameterizedType = (ParameterizedTypeImpl) this.getClass().getGenericSuperclass(); + Type type = parameterizedType.getActualTypeArguments()[0]; + return type.getTypeName(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java new file mode 100644 index 0000000000..15a7f4853f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/FormulaAuthorityChecker.java @@ -0,0 +1,97 @@ +package com.fr.design.mainframe.authority; + +import com.fr.base.Formula; +import com.fr.general.ComparatorUtils; +import com.fr.parser.FunctionCall; +import com.fr.parser.StringLiteral; +import com.fr.script.Calculator; +import com.fr.stable.script.Node; +import org.jetbrains.annotations.Nullable; + +import java.util.HashSet; +import java.util.Set; + +public class FormulaAuthorityChecker extends ElementAuthorityChecker { + private static final Set CONNECTION_NAME_FORMULA_PARSER = new HashSet<>(); + private static final Set DATASET_NAME_FORMULA_PARSER = new HashSet<>(); + + static { + CONNECTION_NAME_FORMULA_PARSER.add(new FormulaParser("SQL", 0)); + DATASET_NAME_FORMULA_PARSER.add(new FormulaParser("VALUE", 0)); + } + + @Override + @Nullable + public Set getNoAuthConnectionNames(Formula formula, Set authConnectionNames) { + return getNoAuthNames(formula, CONNECTION_NAME_FORMULA_PARSER, authConnectionNames); + } + + + @Override + @Nullable + Set getNoAuthDatasetNames(Formula formula, Set authDatasetNames) { + return getNoAuthNames(formula, DATASET_NAME_FORMULA_PARSER, authDatasetNames); + } + + private Set getNoAuthNames(Formula formula, Set formulaParsers, Set authNames) { + Set noAuthNames = new HashSet<>(); + try { + FunctionCall functionCall = (FunctionCall) Calculator.createCalculator().parse(formula.getContent()).getConditionalExpression(); + handleNoAuthNames(functionCall, formulaParsers, authNames, noAuthNames); + } catch (Exception ignore) { + + } finally { + return noAuthNames; + } + } + + private void handleNoAuthNames(FunctionCall functionCall, Set formulaParsers, Set authNames, Set noAuthNames) { + for (FormulaParser formulaPattern : formulaParsers) { + String noAuthName = formulaPattern.getNoAuthName(functionCall, authNames); + if (noAuthName != null) { + noAuthNames.add(noAuthName); + } + } + Node[] nodes = functionCall.getArguments(); + if (nodes != null) { + for (int i = 0; i < nodes.length; i++) { + Node node = nodes[i]; + if (node instanceof FunctionCall) { + handleNoAuthNames((FunctionCall) node, formulaParsers, authNames, noAuthNames); + } + } + } + + } + + + static class FormulaParser { + //函数的名称 + public String name; + //要检测的位置 + public int index; + + + FormulaParser(String name, int index) { + this.name = name; + this.index = index; + } + + String getNoAuthName(FunctionCall functionCall, Set authNames) { + if (functionCall.getName() != null && ComparatorUtils.equals(functionCall.getName().toUpperCase(), name)) { + Node node = functionCall.getArguments()[index]; + if (node instanceof StringLiteral) { + String stringLiteral = node.toString(); + if (stringLiteral.length() > 2) { + String value = stringLiteral.substring(1, stringLiteral.length() - 1); + if (!authNames.contains(value)) { + return value; + } + } + } + } + return null; + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java new file mode 100644 index 0000000000..d76031f654 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/JTemplateAuthorityChecker.java @@ -0,0 +1,188 @@ +package com.fr.design.mainframe.authority; + + +import com.fr.design.dialog.FineJOptionPane; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mod.ModClassFilter; +import com.fr.file.ConnectionConfig; +import com.fr.file.TableDataConfig; +import com.fr.invoke.ClassHelper; + +import com.fr.log.FineLoggerFactory; +import com.fr.stable.Filter; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.authority.user.UserAuthority; + +import java.util.Collection; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + + +import static javax.swing.JOptionPane.WARNING_MESSAGE; + + +public class JTemplateAuthorityChecker { + JTemplate jTemplate; + Set allConnectionNames; + Set authConnectionNames; + Set allDatasetNames; + Set authDatasetNames; + Map checkerMap = new HashMap<>(); + Set authFailConnectionNames = new HashSet<>(); + Set authFailDatasetNames = new HashSet<>(); + + + public JTemplateAuthorityChecker(JTemplate jTemplate) { + long s = System.currentTimeMillis(); + this.jTemplate = jTemplate; + this.initAuthNames(); + this.initChecker(); + FineLoggerFactory.getLogger().info("JTemplateAuthorityChecker init time consume:" + (System.currentTimeMillis() - s)); + } + + private void initAuthNames() { + allDatasetNames = new HashSet<>(); + for (String authServerDataSetName : TableDataConfig.getInstance().getTableDatas().keySet()) { + allDatasetNames.add(authServerDataSetName); + } + + allConnectionNames = ConnectionConfig.getInstance().getConnections().keySet(); + + UserAuthority templateAuthority = WorkContext.getCurrent().get(UserAuthority.class); + Map> authNamesMap = templateAuthority.getAuthServerDataSetAndConnectionNames(); + if (authNamesMap != null) { + //有权限的数据连接名称 + authConnectionNames = authNamesMap.get(UserAuthority.AUTH_CONNECTION_NAMES); + //有权限的数据集名称 + authDatasetNames = authNamesMap.get(UserAuthority.AUTH_SERVER_DATASET_NAMES); + } + } + + private void initChecker() { + registerChecker(new NameDatabaseConnectionAuthorityChecker()); + registerChecker(new DSColumnAuthorityChecker()); + registerChecker(new FormulaAuthorityChecker()); + registerChecker(new NameTableDataAuthorityChecker()); + } + + private void registerChecker(ElementAuthorityChecker checker) { + checkerMap.put(checker.getCheckClassName(), checker); + } + + + public boolean isAuthority() { + long s = System.currentTimeMillis(); + //遍历模板对象,根据checkerMap.keySet()把感兴趣的对象找出来 + Map> targetObjects = ClassHelper.searchObject(jTemplate.getTarget(), checkerMap.keySet(), ClassFilter.getInstance()); + + //找到对应的checker,对对象进行检查 + for (String name : targetObjects.keySet()) { + ElementAuthorityChecker checker = checkerMap.get(name); + for (Object object : targetObjects.get(name)) { + if (authConnectionNames != null) { + Set noAuthName = checker.getNoAuthConnectionNames(object, authConnectionNames); + if (noAuthName != null) { + authFailConnectionNames.addAll(noAuthName); + } + } + if (authDatasetNames != null) { + Set noAuthName = checker.getNoAuthDatasetNames(object, authDatasetNames); + if (noAuthName != null) { + authFailDatasetNames.addAll(noAuthName); + } + } + } + } + authFailConnectionNames.retainAll(allConnectionNames); + authFailDatasetNames.retainAll(allDatasetNames); + FineLoggerFactory.getLogger().info("JTemplateAuthorityChecker check time consume:" + (System.currentTimeMillis() - s)); + return authFailConnectionNames.size() == 0 && authFailDatasetNames.size() == 0; + } + + public void showAuthorityFailPromptDialog() { + StringBuffer stringBuffer = new StringBuffer(); + stringBuffer.append(Toolkit.i18nText("Fine-Design-Basic_Save_Failure")); + stringBuffer.append("\n"); + stringBuffer.append(getPromptInfo(authFailDatasetNames, + Toolkit.i18nText("Fine-Design_Template_Authority_Check_Server_Dataset_Authority"))); + stringBuffer.append(getPromptInfo(authFailConnectionNames, + Toolkit.i18nText("Fine-Design_Template_Authority_Check_Data_Connection_Authority"))); + FineJOptionPane.showMessageDialog( + DesignerContext.getDesignerFrame(), + stringBuffer.toString(), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + WARNING_MESSAGE); + } + + private String getPromptInfo(Set authFailNames, String message) { + StringBuffer stringBuffer = new StringBuffer(); + if (authFailNames.size() > 0) { + stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Current_Operator_Miss")); + stringBuffer.append(authFailNames.size()); + stringBuffer.append(Toolkit.i18nText("Fine-Design_Report_Ge")); + stringBuffer.append(message); + stringBuffer.append("\n"); + stringBuffer.append(getNoAuthNameSequence(authFailNames)); + } + return stringBuffer.toString(); + } + + private String getNoAuthNameSequence(Set names) { + StringBuffer stringBuffer = new StringBuffer(); + int showMaxCount = 3; + int count = 0; + for (String name : names) { + if (count == showMaxCount) { + stringBuffer.append(Toolkit.i18nText("Fine-Design_Template_Authority_Check_Etc")); + break; + } + stringBuffer.append(name); + if (count != names.size() - 1 && count != showMaxCount - 1) { + stringBuffer.append(";"); + } + count++; + } + stringBuffer.append("\n"); + return stringBuffer.toString(); + } + + static class ClassFilter implements Filter { + + private static final Set FILTER_SET = new HashSet<>(); + private static final Set START_WITH_SET = new HashSet<>(); + private static final Filter INSTANCE = new ModClassFilter(); + + public static Filter getInstance() { + return INSTANCE; + } + + static { + FILTER_SET.add("java.awt.image.BufferedImage"); + FILTER_SET.add("sun.awt.AppContext"); + FILTER_SET.add("com.fr.poly.creator.ECBlockCreator"); + FILTER_SET.add("io.netty.channel.nio.SelectedSelectionKeySet"); + FILTER_SET.add("com.fr.form.ui.ElementCaseImage"); + FILTER_SET.add("this$0"); + START_WITH_SET.add("com.fr.design"); + } + + @Override + public boolean accept(String s) { + if (FILTER_SET.contains(s)) { + return true; + } + for (String start : START_WITH_SET) { + if (s.startsWith(start)) { + return true; + } + } + return false; + } + } +} + diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java new file mode 100644 index 0000000000..96bc0b8c5d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameDatabaseConnectionAuthorityChecker.java @@ -0,0 +1,22 @@ +package com.fr.design.mainframe.authority; + +import com.fr.data.impl.NameDatabaseConnection; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; +import java.util.stream.Collectors; + +public class NameDatabaseConnectionAuthorityChecker extends ElementAuthorityChecker { + @Override + @Nullable + Set getNoAuthConnectionNames(NameDatabaseConnection nameDatabaseConnection, Set authConnectionNames) { + String name = nameDatabaseConnection.getName(); + if (!authConnectionNames.contains(name)) { + return new HashSet<>(Arrays.asList(name)); + } + return null; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java new file mode 100644 index 0000000000..13e7300856 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/authority/NameTableDataAuthorityChecker.java @@ -0,0 +1,19 @@ +package com.fr.design.mainframe.authority; + +import com.fr.data.impl.NameTableData; +import org.jetbrains.annotations.Nullable; + +import java.util.Arrays; +import java.util.HashSet; +import java.util.Set; + +public class NameTableDataAuthorityChecker extends ElementAuthorityChecker { + @Override + @Nullable + Set getNoAuthDatasetNames(NameTableData nameTableData, Set authDatasetNames) { + if (!authDatasetNames.contains(nameTableData.getName())) { + return new HashSet<>(Arrays.asList(nameTableData.getName())); + } + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java new file mode 100644 index 0000000000..9469f931a1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/Guide.java @@ -0,0 +1,189 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.guide.collect.GuideCollector; +import com.fr.design.mainframe.guide.scene.GuideScene; +import com.fr.design.mainframe.guide.ui.GuideCompleteDialog; +import com.fr.design.mainframe.guide.ui.GuideManageDialog; +import com.fr.stable.StringUtils; + +import javax.swing.JFrame; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; + +public class Guide { + private String id; + private String name; + private String description; + private String completeMessage; + private GuideView guideView; + private GuideLifecycle lifecycle; + private boolean isComplete; + private GuideScene scene; + + public Guide() { + this(null, null, null); + } + + public Guide(String id, String name, String description) { + this.id = id; + this.name = name; + this.description = description; + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public void setName(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public void setDescription(String description) { + this.description = description; + } + + public String getDescription() { + if (StringUtils.isNotEmpty(description)) { + return description; + } + return name; + } + + public String getCompleteMessage() { + return completeMessage; + } + + public void setCompleteMessage(String completeMessage) { + this.completeMessage = completeMessage; + } + + public void setGuideView(GuideView guideView) { + this.guideView = guideView; + } + + public GuideView getGuideView() { + return guideView; + } + + public void setComplete(boolean complete) { + isComplete = complete; + } + + public boolean isComplete() { + return isComplete; + } + + public void setScene(GuideScene scene) { + this.scene = scene; + } + + public GuideScene getScene() { + return scene; + } + + /** + * 开启引导流程 + */ + public void go() { + DesignerContext.getDesignerFrame().setExtendedState(JFrame.MAXIMIZED_BOTH); + // 同时只能启动一个引导 + if (GuideManager.getInstance().getCurrentGuide() != null) { + return; + } + GuideManager.getInstance().setCurrentGuide(this); + guideView.showLoading(); + + new SwingWorker() { + @Override + protected Boolean doInBackground() { + try { + if (lifecycle != null && !lifecycle.prepared()) { + return false; + } + return true; + } catch (Exception e) { + e.printStackTrace(); + guideView.hideLoading(); + terminate(); + return false; + } + } + + @Override + protected void done() { + try { + if (get()) { + start(); + } + } catch (Exception e) { + e.printStackTrace(); + guideView.hideLoading(); + terminate(); + } + } + }.execute(); + } + + public void start() { + guideView.hideLoading(); + if (scene != null) { + guideView.setScene(scene); + guideView.showGuide(); + if (lifecycle != null) { + lifecycle.onStart(); + } + } else { + complete(); + } + } + + public void complete() { + if (lifecycle != null) { + lifecycle.onComplete(); + } + setComplete(true); + GuideCollector.getInstance().saveInfo(); + guideView.dismissGuide(); + GuideCompleteDialog.getInstance().showDialog(getCompleteMessage()); + end(); + } + + public void terminate() { + if (lifecycle != null) { + lifecycle.onTerminate(); + } + end(); + } + + public void end() { + guideView.dismissGuide(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (lifecycle != null) { + lifecycle.onEnd(); + } + GuideManager.getInstance().setCurrentGuide(null); + GuideManageDialog.getInstance().showDialog(); + } + }); + + } + + public void registerLifecycle(GuideLifecycle lifecycle) { + this.lifecycle = lifecycle; + } + + public void removeGuideLifecycle() { + this.lifecycle = null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java new file mode 100644 index 0000000000..a1974bf924 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideBuilder.java @@ -0,0 +1,51 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.guide.scene.GuideScene; + +public class GuideBuilder { + private Guide guide; + + public static GuideBuilder newInstance() { + return new GuideBuilder(); + } + + public GuideBuilder() { + guide = new Guide(); + guide.setGuideView(new GuideView(DesignerContext.getDesignerFrame(), guide)); + } + + public GuideBuilder setID(String id) { + guide.setId(id); + return this; + } + + public GuideBuilder setName(String name) { + guide.setName(name); + return this; + } + + public GuideBuilder setDescription(String description) { + guide.setDescription(description); + return this; + } + + public GuideBuilder setCompleteMessage(String message) { + guide.setCompleteMessage(message); + return this; + } + + public GuideBuilder addScene(GuideScene scene) { + guide.setScene(scene); + return this; + } + + public GuideBuilder registerLifecycle(GuideLifecycle lifecycle) { + guide.registerLifecycle(lifecycle); + return this; + } + + public Guide getGuide() { + return guide; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java new file mode 100644 index 0000000000..cd5e0b5794 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideGroup.java @@ -0,0 +1,55 @@ +package com.fr.design.mainframe.guide.base; + +import java.util.ArrayList; +import java.util.List; + +public class GuideGroup { + private List guideList; + private String id; + private String name; + + public GuideGroup(String id, String name) { + this.id = id; + this.name = name; + guideList = new ArrayList<>(); + } + + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void addGuide(Guide guide) { + guideList.add(guide); + } + + public List getGuideList() { + return guideList; + } + + public List getCompleteGuideList() { + List complete = new ArrayList<>(); + for (Guide guide : getGuideList()) { + if (guide.isComplete()) { + complete.add(guide); + } + } + return complete; + } + + public boolean isCompleteAll() { + return getCompleteGuideList().size() == getGuideList().size(); + } + + public boolean isCompleteSome() { + List completeGuides = getCompleteGuideList(); + return completeGuides.size() > 0 && completeGuides.size() < getGuideList().size(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java new file mode 100644 index 0000000000..2ddfd975f1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycle.java @@ -0,0 +1,32 @@ +package com.fr.design.mainframe.guide.base; + +public interface GuideLifecycle{ + /** + * 准备环境 + * @return 返回true引导可继续执行 + */ + boolean prepared(); + + /** + * 开始引导教程 + */ + void onStart(); + + /** + * 完成引导教程 + */ + + void onComplete(); + + /** + * 终止引导教程 + */ + + void onTerminate(); + + /** + * 结束引导教程 + */ + void onEnd(); + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java new file mode 100644 index 0000000000..c67f47e35f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideLifecycleAdaptor.java @@ -0,0 +1,28 @@ +package com.fr.design.mainframe.guide.base; + +public abstract class GuideLifecycleAdaptor implements GuideLifecycle{ + @Override + public boolean prepared() { + return true; + } + + @Override + public void onStart() { + + } + + @Override + public void onComplete() { + + } + + @Override + public void onTerminate() { + + } + + @Override + public void onEnd() { + + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java new file mode 100644 index 0000000000..08c46688d8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideManager.java @@ -0,0 +1,113 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.mainframe.guide.collect.GuideCollector; +import com.fr.stable.StringUtils; + +import java.util.ArrayList; +import java.util.List; + +public class GuideManager { + private static GuideManager guideManager; + + private Guide currentGuide; + private List guideVersionList; + + public static GuideManager getInstance() { + if (guideManager == null) { + guideManager = new GuideManager(); + } + return guideManager; + } + + public GuideManager() { + guideVersionList = new ArrayList<>(); + } + + public Guide getCurrentGuide() { + return currentGuide; + } + + public void setCurrentGuide(Guide currentGuide) { + this.currentGuide = currentGuide; + } + + public void addGuideGroup(String version, GuideGroup guideGroup) { + GuideVersion guideVersion = getGuideVersion(version); + if (guideVersion == null) { + guideVersion = new GuideVersion(version); + guideVersionList.add(guideVersion); + } + guideVersion.addGuideGroup(guideGroup); + } + + public void addGuide(String groupId, Guide guide) { + GuideGroup guideGroup = getGuideGroup(groupId); + if (guideGroup != null) { + guideGroup.addGuide(guide); + } + } + + public List getGuideVersionList() { + return guideVersionList; + } + + public List getAllGuide() { + List guideList = new ArrayList<>(); + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + for (Guide guide : group.getGuideList()) { + guideList.add(guide); + } + } + } + return guideList; + } + + public GuideVersion getGuideVersion(String version) { + for (GuideVersion guideVersion : guideVersionList) { + if (StringUtils.equals(version, guideVersion.getVersion())) { + return guideVersion; + } + } + return null; + } + + public GuideGroup getGuideGroup(String groupId) { + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + if (StringUtils.equals(groupId, group.getId())) { + return group; + } + } + } + return null; + } + + public Guide getGuide(String guideId) { + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + for (Guide guide : group.getGuideList()) { + if (StringUtils.equals(guideId, guide.getId())) { + return guide; + } + } + } + } + return null; + } + + public void completeAll() { + for (GuideVersion version : guideVersionList) { + for (GuideGroup group : version.getGuideGroupList()) { + for (Guide guide : group.getGuideList()) { + guide.setComplete(true); + } + } + } + GuideCollector.getInstance().saveInfo(); + } + + public void clearAll() { + guideVersionList.clear(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java new file mode 100644 index 0000000000..3c365aa949 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideVersion.java @@ -0,0 +1,29 @@ +package com.fr.design.mainframe.guide.base; + +import java.util.ArrayList; +import java.util.List; + +public class GuideVersion { + private String version; + private List guideGroupList; + public GuideVersion(String version) { + guideGroupList = new ArrayList<>(); + this.version = version; + } + + public String getVersion() { + return version; + } + + public void setVersion(String version) { + this.version = version; + } + + public List getGuideGroupList() { + return guideGroupList; + } + + public void addGuideGroup(GuideGroup guideGroup) { + guideGroupList.add(guideGroup); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java new file mode 100644 index 0000000000..f8b93e34c3 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/base/GuideView.java @@ -0,0 +1,132 @@ +package com.fr.design.mainframe.guide.base; + +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.guide.scene.AbstractGuideScene; +import com.fr.design.mainframe.guide.scene.GuideScene; +import com.fr.design.mainframe.guide.ui.GuideLoadingGlassPane; +import com.fr.design.utils.gui.GUICoreUtils; + +import javax.swing.JDialog; +import javax.swing.SwingUtilities; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Window; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class GuideView extends JDialog { + private static GuideView guideView; + private Guide invoker; + private GuideScene scene; + private Color modalColor; + private float modalOpacity; + private Window window; + + public static GuideView getInstance(Guide guide) { + if (guideView == null) { + guideView = new GuideView(DesignerContext.getDesignerFrame(), guide); + } + return guideView; + } + + public GuideView(Window window) { + super(window); + this.setUndecorated(true); + this.window = window; + this.modalColor = Color.BLACK; + this.modalOpacity = 0.6f; + this.setPreferredSize(window.getSize()); + this.setSize(window.getSize()); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + setBg(); + DesignerContext.getDesignerFrame().addWindowListener(new WindowAdapter() { + + @Override + public void windowDeiconified(WindowEvent e) { + if (isVisible()) { + updateGuideViewLocation(); + // window 带透明的dialog在窗口最小化后再打开会不渲染,这边试了下重新设置visible可行 + setVisible(false); + setVisible(true); + } + } + }); + } + + public GuideView(Window window, Guide guide) { + this(window); + this.invoker = guide; + } + + public void setModalColor(Color color) { + modalColor = color; + setBg(); + } + + public void setModalOpacity(float opacity){ + modalOpacity = opacity; + setBg(); + } + + private void setBg() { + Color newColor = new Color(modalColor.getRed(), modalColor.getGreen(), modalColor.getBlue(), (int) (255 * modalOpacity)); + this.setBackground(newColor); + } + + public void setScene(GuideScene scene) { + if (scene instanceof AbstractGuideScene) { + ((AbstractGuideScene) scene).setContainer(this); + } + this.scene = scene; + } + + public void showGuide() { + updateGuideViewLocation(); + this.setVisible(true); + if (scene != null) { + scene.start(); + } else { + GuideManager.getInstance().getCurrentGuide().complete(); + } + } + + public void dismissGuide() { + this.getLayeredPane().removeAll(); + revalidate(); + repaint(); + setVisible(false); + dispose(); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + } + + public void showLoading() { + this.setGlassPane(GuideLoadingGlassPane.getInstance()); + GuideLoadingGlassPane.getInstance().startLoading(); + updateGuideViewLocation(); + this.setVisible(true); + this.invalidate(); + this.getGlassPane().setVisible(true); + } + + public void hideLoading() { + GuideLoadingGlassPane.getInstance().stopLoading(); + this.getGlassPane().setVisible(false); + repaint(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + setVisible(false); + } + }); + } + + private void updateGuideViewLocation() { + GUICoreUtils.centerWindow(window, this); + this.setBounds(window.getBounds()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java new file mode 100644 index 0000000000..4c4c40f768 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/collect/GuideCollector.java @@ -0,0 +1,155 @@ +package com.fr.design.mainframe.guide.collect; + +import com.fr.base.io.XMLReadHelper; +import com.fr.design.mainframe.guide.base.Guide; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLReadable; +import com.fr.stable.xml.XMLTools; +import com.fr.stable.xml.XMLable; +import com.fr.stable.xml.XMLableReader; +import com.fr.third.javax.xml.stream.XMLStreamException; +import com.fr.third.org.apache.commons.io.FileUtils; + +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileNotFoundException; +import java.io.IOException; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +public class GuideCollector implements XMLable { + private static final String ROOT_XML = "GuideCollector"; + private static final String GUIDE_XML = "Guide"; + private static final String FILE_NAME = "guide.info"; + private static GuideCollector collector; + + private boolean showHint; + private List cacheGuides; + + public static GuideCollector getInstance() { + if (collector == null) { + collector = new GuideCollector(); + } + return collector; + } + + public GuideCollector() { + cacheGuides = new ArrayList<>(); + } + + public boolean isShowHint() { + return showHint; + } + + public void setShowHint(boolean showHint) { + this.showHint = showHint; + saveInfo(); + } + + public void load() { + for(Guide cacheGuide : cacheGuides) { + Guide guide = GuideManager.getInstance().getGuide(cacheGuide.getId()); + if (guide != null) { + guide.setComplete(cacheGuide.isComplete()); + } + } + } + + public void saveInfo() { + cacheGuides = GuideManager.getInstance().getAllGuide(); + try { + ByteArrayOutputStream out = new ByteArrayOutputStream(); + XMLTools.writeOutputStreamXML(this, out); + out.flush(); + out.close(); + String fileContent = new String(out.toByteArray(), StandardCharsets.UTF_8); + FileUtils.writeStringToFile(getInfoFile(), fileContent, StandardCharsets.UTF_8); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage()); + } + } + + private File getInfoFile() { + File file = new File(StableUtils.pathJoin(ProductConstants.getEnvHome(), FILE_NAME)); + try { + if (!file.exists()) { + file.createNewFile(); + } + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + return file; + } + + public void loadFromFile() { + if (!getInfoFile().exists()) { + return; + } + XMLableReader reader = null; + try (InputStream in = new FileInputStream(getInfoFile())) { + reader = XMLReadHelper.createXMLableReader(in, XMLPrintWriter.XML_ENCODER); + if (reader == null) { + return; + } + reader.readXMLObject(this); + } catch (FileNotFoundException e) { + } catch (XMLStreamException | IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + try { + if (reader != null) { + reader.close(); + } + } catch (XMLStreamException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + + @Override + public void readXML(XMLableReader xmLableReader) { + String tagName = xmLableReader.getTagName(); + if (tagName.equals(ROOT_XML)) { + showHint = xmLableReader.getAttrAsBoolean("showHint", false); + xmLableReader.readXMLObject(new XMLReadable() { + public void readXML(XMLableReader reader) { + String tagName = reader.getTagName(); + if (tagName.equals(GUIDE_XML)) { + Guide guide = new Guide(); + guide.setId(reader.getAttrAsString("id", null)); + guide.setComplete(reader.getAttrAsBoolean("isComplete", false)); + cacheGuides.add(guide); + } + + } + }); + } + } + + @Override + public void writeXML(XMLPrintWriter writer) { + writer.startTAG(ROOT_XML); + writer.attr("showHint", showHint); + for(Guide guide : GuideManager.getInstance().getAllGuide()) { + writer.startTAG(GUIDE_XML); + writer.attr("id", guide.getId()); + writer.attr("isComplete", guide.isComplete()); + writer.end(); + } + writer.end(); + + + } + + @Override + public Object clone() throws CloneNotSupportedException { + return null; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java new file mode 100644 index 0000000000..95c7c24a4a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/AbstractGuideScene.java @@ -0,0 +1,493 @@ +package com.fr.design.mainframe.guide.scene; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.design.mainframe.guide.base.GuideView; +import com.fr.design.mainframe.guide.utils.ScreenImage; +import com.fr.design.mainframe.guide.tip.BubbleTip; +import com.fr.design.mainframe.guide.tip.GuideTip; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; +import java.awt.AWTException; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Insets; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.image.BufferedImage; +import java.util.ArrayList; +import java.util.List; + +public abstract class AbstractGuideScene extends JPanel implements GuideScene { + private static final int DEFAULT_ARROW_HEIGHT = 12; + private static final int DEFAULT_ARROW_WIDTH = 18; + public static final Insets DEFAULT_HIGHLIGHT_INSETS = new Insets(5, 5, 5, 5); + + private GuideScene nextScene; + private SceneFilter sceneFilter; + private GuideSceneLifecycle lifecycle; + private GuideView container; + private List targetList; + private List highlightList; + private Component nextButton; + private List pointsList; + + + public AbstractGuideScene() { + this.setLayout(null); + this.setOpaque(false); + targetList = new ArrayList<>(); + highlightList = new ArrayList<>(); + pointsList = new ArrayList<>(); + } + + /** + * 根据设计器上组件添加高亮区域视图, + * JComponent 采用组件绘制方式 + * Component 采用屏幕截图方式 + * @param component 设计器组件对象 + * @return + */ + public boolean addTarget(Component component) { + try { + if (component == null || container == null) { + return false; + } + + Point point = SwingUtilities.convertPoint(component,0,0, container.getRootPane()); + Rectangle rectangle = new Rectangle(point, component.getSize()); + BufferedImage image; + + if (component instanceof JComponent) { + JComponent jComponent = (JComponent) component; + image = ScreenImage.createImage(jComponent); + } else if (component instanceof Window) { + image = ScreenImage.createImage(component); + } else { + image = captureImage(component); + } + targetList.add(component); + highlightList.add(getTargetComponentWithImage(image, rectangle)); + return true; + } catch (AWTException e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + return false; + } + } + + /** + * 根据设计器上选定区域获取高亮视图,采用截屏的方式 + * @param rectangle 选定区域,相对屏幕 + * @return + */ + public boolean addTarget(Rectangle rectangle) { + try { + targetList.add(null); + BufferedImage image = captureImage(rectangle); + highlightList.add(getTargetComponentWithImage(image, rectangle)); + return true; + } catch (AWTException e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + return false; + } + } + + /** + * 根据设计器组件,选定其中某个区域,添加高亮视图 + * @param component 设计器组件 + * @param origin 相对组件的区域 + * @return + */ + public boolean addTarget(Component component, Rectangle origin) { + try { + if (component == null) { + return false; + } + Point point = SwingUtilities.convertPoint(component,0,0, container.getRootPane()); + + origin = origin.intersection(new Rectangle(0,0,component.getWidth(), component.getHeight())); + Rectangle rectangle = new Rectangle(point.x + origin.x, point.y + origin.y, origin.width, origin.height); + + BufferedImage image; + + if (component instanceof JComponent) { + JComponent jComponent = (JComponent) component; + image = ScreenImage.createImage(jComponent, origin); + } else { + image = ScreenImage.createImage(component).getSubimage(origin.x, origin.y, origin.width, origin.height); + } + targetList.add(component); + highlightList.add(getTargetComponentWithImage(image, rectangle)); + return true; + } catch (AWTException e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + return false; + } + } + + /** + * 添加自定义组件 + * @param component 自定义组件 + * @param rectangle 相对引导页的区域 + * @return + */ + public boolean addCustomTarget(Component component, Rectangle rectangle) { + if (component == null) { + return false; + } + component.setBounds(rectangle); + targetList.add(component); + highlightList.add(component); + return true; + } + + public boolean addCustomTarget(Component component, Point location) { + return addCustomTarget(component, new Rectangle(location, component.getPreferredSize())); + } + + protected List getTargetList() { + return targetList; + } + + public List getHighlightList() { + return highlightList; + } + + private UILabel getTargetComponentWithImage(BufferedImage image, Rectangle rectangle) { + ImageIcon ic = new ImageIcon(image); + UILabel label = new UILabel(ic){ + @Override + public Insets getInsets() { + return DEFAULT_HIGHLIGHT_INSETS; + } + }; + + label.setBorder(BorderFactory.createMatteBorder(DEFAULT_HIGHLIGHT_INSETS.top, DEFAULT_HIGHLIGHT_INSETS.left, DEFAULT_HIGHLIGHT_INSETS.bottom, DEFAULT_HIGHLIGHT_INSETS.right, Color.WHITE)); + + label.setOpaque(true); + label.setBounds(new Rectangle( + rectangle.x - DEFAULT_HIGHLIGHT_INSETS.left, + rectangle.y - DEFAULT_HIGHLIGHT_INSETS.top, + rectangle.width + DEFAULT_HIGHLIGHT_INSETS.left + DEFAULT_HIGHLIGHT_INSETS.right, + rectangle.height + DEFAULT_HIGHLIGHT_INSETS.top + DEFAULT_HIGHLIGHT_INSETS.bottom + )); + return label; + } + + private BufferedImage captureImage(Rectangle rectangle) throws AWTException { + container.setVisible(false); + BufferedImage image = ScreenImage.createImage(rectangle); + showContainer(); + return image; + } + + private BufferedImage captureImage(Component component) throws AWTException { + container.setVisible(false); + BufferedImage image = ScreenImage.createImage(component); + showContainer(); + return image; + } + + private void showContainer() { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + container.setVisible(true); + container.toFront(); + container.requestFocus(); + } + }); + } + + + /** + * 自定义位置添加气泡提示组件 + * @param title 提示标题 + * @param content 提示内容 + * @param direction 气泡窗口位置方向 + * @param anchor 气泡窗口箭头坐标 + * @param bubbleTailStart 气泡窗口箭头坐标相对于位置方向交叉轴的比例(从左到右,从上到下) + */ + public void addBubbleTip(String title, String content, GuideTip.Direction direction, Point anchor, float bubbleTailStart) { + BubbleTip bt = new BubbleTip(title, content, direction, bubbleTailStart); + bt.setAnchor(anchor); + this.add(bt.getTip()); + } + + /** + * 以上一个添加的引导目标窗口为基础,添加对应的气泡窗 + * @param title 提示标题 + * @param content 提示内容 + * @param direction + * @param anchorStart + * @param bubbleTailStart + */ + public void addBubbleTip(String title, String content, GuideTip.Direction direction, float anchorStart, float bubbleTailStart) { + if (highlightList.size() == 0) { + return; + } + Component lastTarget = highlightList.get(highlightList.size() - 1); + Rectangle bounds = lastTarget.getBounds(); + Point anchor = new Point(0,0); + if (direction == GuideTip.Direction.TOP) { + anchor = new Point(bounds.x + (int)(bounds.width * anchorStart), bounds.y); + } else if (direction == GuideTip.Direction.BOTTOM) { + anchor = new Point(bounds.x + (int)(bounds.width * anchorStart), bounds.y + bounds.height); + } else if (direction == GuideTip.Direction.LEFT) { + anchor = new Point(bounds.x, bounds.y + (int)(bounds.height * anchorStart)); + } else if (direction == GuideTip.Direction.RIGHT) { + anchor = new Point(bounds.x + bounds.width, bounds.y + (int) (bounds.height * anchorStart)); + } + addBubbleTip(title, content, direction, anchor, bubbleTailStart); + } + + public void addBubbleTip(String title, String content, GuideTip.Direction direction) { + addBubbleTip(title, content, direction, 0.5f, 0.5f); + } + + public void addBubbleTip(String title, GuideTip.Direction direction) { + addBubbleTip(title, StringUtils.EMPTY, direction); + } + + public void addTip(GuideTip tip) { + this.add(tip.getTip()); + } + + public void addLineArrow(Point... points) { + pointsList.add(points); + } + + public void setContainer(GuideView container) { + this.container = container; + } + + public GuideView getContainer() { + return container; + } + + @Override + public GuideScene nextScene(GuideScene scene) { + nextScene = scene; + return nextScene; + } + + @Override + public void addSceneFilter(SceneFilter filter) { + sceneFilter = filter; + } + + @Override + public void start() { + clear(); + if (lifecycle != null && !lifecycle.prepared()) { + return; + } + + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + showScene(); + } + }); + } + + @Override + public void showScene() { + if (container != null) { + container.setContentPane(AbstractGuideScene.this); + setBounds(0, 0 , getSceneWidth(), getSceneWidth()); + + // show target + for (int index = highlightList.size() - 1; index >= 0; index--) { + add(highlightList.get(index)); + } + // show next button + if (nextButton != null) { + nextButton.setBounds((getSceneWidth() - 60) / 2, getSceneHeight() - 100, 60, 30); + add(nextButton); + } + } + showContainer(); + if (lifecycle != null) { + lifecycle.onShow(); + } + } + + @Override + public void complete() { + clear(); + if (lifecycle != null && !lifecycle.onComplete()) { + return; + } + if (sceneFilter != null) { + nextScene = sceneFilter.getFilterScene(); + } + if (nextScene != null) { + if (nextScene instanceof AbstractGuideScene) { + ((AbstractGuideScene) nextScene).setContainer(container); + } + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + nextScene.start(); + } + }); + } else { + GuideManager.getInstance().getCurrentGuide().complete(); + } + } + + @Override + public void registerLifecycle(GuideSceneLifecycle lifecycle) { + this.lifecycle = lifecycle; + } + + @Override + public void removeLifecycle() { + this.lifecycle = null; + } + + public void showNextButton() { + UIButton nextButton = new UIButton("Next"); + nextButton.setPreferredSize(new Dimension(60, 30)); + nextButton.setOpaque(false); + nextButton.setFont(nextButton.getFont().deriveFont(20)); + nextButton.setRoundBorder(true, 8); + nextButton.setForeground(Color.WHITE); + nextButton.setNormalPainted(false); + nextButton.setPressedPainted(false); + nextButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + complete(); + } + }); + this.nextButton = nextButton; + } + + private int getSceneWidth() { + if (container == null) { + return 0; + } + return container.getLayeredPane().getWidth(); + + } + + private int getSceneHeight() { + if (container == null) { + return 0; + } + return container.getLayeredPane().getHeight(); + } + + public void clear() { + targetList = new ArrayList<>(); + highlightList = new ArrayList<>(); + this.nextButton = null; + if (this.getComponentCount() > 0) { + this.removeAll(); + invalidate(); + repaint(); + } + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (pointsList.isEmpty()) { + return; + } + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); + g2d.setColor(Color.WHITE); + for (Point[] points : pointsList) { + if (points.length <= 1) { + continue; + } + Point startPoint = points[0]; + Point endPoint = startPoint; + for (int index = 1; index < points.length; index++) { + startPoint = endPoint; + endPoint = points[index]; + g2d.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y); + } + + drawArrow(g2d, startPoint, endPoint); + } + g2d.setComposite(oldComposite); + } + + /** + * 根据最后两点坐标计算出三角箭头的三个点坐标,绘制箭头 + * 这里实现以终点坐标为坐标轴圆点计算 + * @param start 起始点坐标 + * @param end 重点坐标 + */ + private void drawArrow(Graphics2D g2d, Point start, Point end) { + try{ + double dealtPointX = start.x - end.x; + double dealtPointY = -(start.y - end.y); + + double pointDistance = calDistance(dealtPointX, dealtPointY); + double triangleHeight = Math.min(DEFAULT_ARROW_HEIGHT, pointDistance); + double triangleWidth = triangleHeight * (DEFAULT_ARROW_WIDTH / 2) / DEFAULT_ARROW_WIDTH; + if (triangleHeight < 1 || triangleWidth < 1 || pointDistance < 1) { + return; + } + + double pointAngle; + double abs = 1; + if (dealtPointX == 0) { + pointAngle = Math.PI / 2; + } else { + pointAngle = Math.atan(dealtPointY / dealtPointX); + } + if (dealtPointY < 0) { + pointAngle += Math.PI; + abs = -1; + } + + double deltaAngle = Math.atan(triangleWidth / triangleHeight); + double triangleDistance = calDistance(triangleWidth, triangleHeight); + + Point p1 =calPoint(end, triangleDistance, pointAngle - deltaAngle, abs); + Point p2 = calPoint(end, triangleDistance, pointAngle + deltaAngle, abs); + + int xPoints[] = {end.x, p1.x, p2.x}; + int yPoints[] = {end.y, p1.y, p2.y}; + + g2d.fillPolygon(xPoints, yPoints, 3); + } catch (Exception e) { + e.printStackTrace(); + GuideManager.getInstance().getCurrentGuide().terminate(); + } + } + + private double calDistance(double x, double y) { + return Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2)); + } + + private Point calPoint(Point relativePoint, double distance, double angle, double abs) { + int x = (int)(relativePoint.x + abs * distance * Math.cos(angle)); + int y = (int)(relativePoint.y - abs * distance * Math.sin(angle)); + return new Point(x, y); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java new file mode 100644 index 0000000000..0d8b5711b0 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/ClickScene.java @@ -0,0 +1,136 @@ +package com.fr.design.mainframe.guide.scene; + +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.mainframe.guide.base.GuideManager; + +import javax.swing.AbstractButton; +import javax.swing.SwingUtilities; +import java.awt.Component; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ClickScene extends AbstractGuideScene{ + public enum ClickType { + LEFT, LEFT_DOUBLE, RIGHT + } + + public void addClickTarget(Component component, ClickType clickType) { + addClickTarget(component, clickType, false); + } + + public void addClickTarget(Component component, ClickType clickType, boolean isDispatch) { + if (super.addTarget(component)) { + addTargetClickListener(clickType, isDispatch); + } + } + + public void addClickTarget(Rectangle rectangle, ClickType clickType) { + if (super.addTarget(rectangle)) { + addTargetClickListener(clickType,false); + } + } + + public void addClickTarget(Component component, Rectangle rectangle, ClickType clickType) { + if (super.addTarget(component, rectangle)) { + addTargetClickListener(clickType, false); + } + } + + public void addCustomClickTarget(Component component, Rectangle rectangle, ClickType clickType) { + if (super.addCustomTarget(component, rectangle)) { + addTargetClickListener(clickType, false); + } + } + + public void addCustomClickTarget(Component component, Point location, ClickType clickType) { + if (super.addCustomTarget(component, location)) { + addTargetClickListener(clickType, false); + } + } + + private void addTargetClickListener(ClickType clickType, boolean isDispatch) { + Component highlight = getHighlightList().get(getHighlightList().size() - 1); + Component target = getTargetList().get(getTargetList().size() - 1); + highlight.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1) { + if ((e.getClickCount() == 1 && clickType == ClickType.LEFT) || (e.getClickCount() == 2 && clickType == ClickType.LEFT_DOUBLE)) { + dealWithDispatchLeftClick(target, e, isDispatch); + } + } else if (e.getButton() == MouseEvent.BUTTON3 && clickType == ClickType.RIGHT) { + clear(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (isDispatch) { + redispatchMouseEvent(e, target); + } + complete(); + } + }); + } + + } + + + @Override + public void mousePressed(MouseEvent e) { + if ((target instanceof AbstractButton) && (target.getParent() instanceof UIButtonGroup)) { + if (isDispatch) { + redispatchMouseEvent(e, target); + } + } + + } + }); + } + + private void dealWithDispatchLeftClick(Component target, MouseEvent e, boolean isDispatch) { + clear(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + if (isDispatch) { + if (target instanceof AbstractButton) { + AbstractButton button = (AbstractButton) target; + ActionListener[] actionListeners= button.getActionListeners(); + for(int i = 0; i < actionListeners.length; i++) { + ActionListener actionListener = actionListeners[i]; + actionListener.actionPerformed(new ActionEvent( + button, + ActionEvent.ACTION_PERFORMED, + button.getActionCommand(), + e.getWhen(), + e.getModifiers() + )); + } + } else { + redispatchMouseEvent(e, target); + } + } + complete(); + } + }); + } + + private void redispatchMouseEvent(MouseEvent e, Component component) { + component.dispatchEvent(new MouseEvent(component, e.getID(), e + .getWhen(), e.getModifiers(), e.getX(), + e.getY(), e.getClickCount(), e.isPopupTrigger())); + } + + @Override + public void showScene() { + // 交互类的 scene 如果没有高亮内容块载,需要及时终止Guide,否则就没法去掉模态框影响到设计器主功能的使用了 + if (this.getComponentCount() == 0 && getHighlightList().isEmpty()) { + GuideManager.getInstance().getCurrentGuide().terminate(); + } else { + super.showScene(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java new file mode 100644 index 0000000000..21ebe972de --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DisplayScene.java @@ -0,0 +1,37 @@ +package com.fr.design.mainframe.guide.scene; + +import java.util.Timer; +import java.util.TimerTask; + +public class DisplayScene extends AbstractGuideScene { + private long delay; + private static final long DEFAULT_DELAY = 1000; + private static Timer displayTimer = new Timer(); + + public DisplayScene() { + this(DEFAULT_DELAY); + } + + public DisplayScene(long delay) { + super(); + this.delay = delay; + } + + public void setDelay(long delay) { + this.delay = delay; + } + + @Override + public void showScene() { + super.showScene(); + // 实例化Timer类 + displayTimer.schedule(new TimerTask() { + @Override + public void run() { + complete(); + displayTimer.purge(); + } + }, delay); + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java new file mode 100644 index 0000000000..fdf8b2d4db --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/DragScene.java @@ -0,0 +1,64 @@ +package com.fr.design.mainframe.guide.scene; + +import com.fr.design.mainframe.guide.scene.drag.DragAndDropDragGestureListener; + +import java.awt.Component; +import java.awt.Rectangle; +import java.awt.dnd.DnDConstants; +import java.awt.dnd.DragSourceDropEvent; +import java.awt.dnd.DropTarget; +import java.awt.dnd.DropTargetDropEvent; + +public class DragScene extends AbstractGuideScene{ + public enum DragType{ + NONE, FROM, TO + } + + public void addDragTarget(Component component, DragType type) { + if (super.addTarget(component)) { + addDragTargetListener(type); + } + } + + public void addDragTarget(Rectangle rectangle, DragType type) { + if (super.addTarget(rectangle)) { + addDragTargetListener(type); + } + } + + public void addDragTarget(Component component, Rectangle rectangle, DragType type) { + if (super.addTarget(component, rectangle)) { + addDragTargetListener(type); + } + } + + public void addCustomDragTarget(Component component, Rectangle rectangle, DragType type) { + if (super.addCustomTarget(component, rectangle)) { + addDragTargetListener(type); + } + } + + private void addDragTargetListener(DragType dragType) { + Component target = getHighlightList().get(getHighlightList().size() - 1); + + if (dragType == DragType.FROM) { + new DragAndDropDragGestureListener(target, DnDConstants.ACTION_COPY_OR_MOVE){ + @Override + public void dragDropEnd(DragSourceDropEvent dsde) { + if (dsde.getDropSuccess()) { + complete(); + } + } + }; + } else if (dragType == DragType.TO) { + target.setDropTarget(new DropSceneTarget()); + } + } + + private class DropSceneTarget extends DropTarget { + @Override + public synchronized void drop(DropTargetDropEvent dtde) { + dtde.dropComplete(true); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java new file mode 100644 index 0000000000..e62ca4d9a9 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideScene.java @@ -0,0 +1,18 @@ +package com.fr.design.mainframe.guide.scene; + + +public interface GuideScene { + GuideScene nextScene(GuideScene scene); + + void addSceneFilter(SceneFilter filter); + + void start(); + + void showScene(); + + void complete(); + + void registerLifecycle(GuideSceneLifecycle lifecycle); + + void removeLifecycle(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java new file mode 100644 index 0000000000..36734a619f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycle.java @@ -0,0 +1,21 @@ +package com.fr.design.mainframe.guide.scene; + +public interface GuideSceneLifecycle { + /** + * 引导场景准备工作 + * 给 scene 添加 target 应该在这个阶段处理 + * @return 返回true自动执行scene, 返回false需要手动触发 + */ + boolean prepared(); + + /** + * scene 显示后 + */ + void onShow(); + + /** + * scene 交互完成后处理 + * @return 返回true自动进入下一个scene,返回false需要手动触发 + */ + boolean onComplete(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java new file mode 100644 index 0000000000..1ed99dca6f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/GuideSceneLifecycleAdaptor.java @@ -0,0 +1,18 @@ +package com.fr.design.mainframe.guide.scene; + +public abstract class GuideSceneLifecycleAdaptor implements GuideSceneLifecycle { + @Override + public boolean prepared() { + return true; + } + + @Override + public void onShow() { + + } + + @Override + public boolean onComplete() { + return true; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java new file mode 100644 index 0000000000..ea4ccf28fa --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/SceneFilter.java @@ -0,0 +1,5 @@ +package com.fr.design.mainframe.guide.scene; + +public interface SceneFilter { + GuideScene getFilterScene(); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java new file mode 100644 index 0000000000..25979925d4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/scene/drag/DragAndDropDragGestureListener.java @@ -0,0 +1,60 @@ +package com.fr.design.mainframe.guide.scene.drag; + +import com.fr.general.ComparatorUtils; +import org.jetbrains.annotations.NotNull; + +import java.awt.Component; +import java.awt.datatransfer.DataFlavor; +import java.awt.datatransfer.Transferable; +import java.awt.dnd.DragGestureEvent; +import java.awt.dnd.DragGestureListener; +import java.awt.dnd.DragSource; +import java.awt.dnd.DragSourceAdapter; + +public class DragAndDropDragGestureListener extends DragSourceAdapter implements DragGestureListener { + private Component component; + + public DragAndDropDragGestureListener(Component component, int actions) { + this.component = component; + DragSource source = new DragSource(); + source.createDefaultDragGestureRecognizer(component, actions, this); + } + + public void dragGestureRecognized(DragGestureEvent dge) { + if (component != null) { + try { + DragAndDropTransferable dragAndDropTransferable = new DragAndDropTransferable(component); + dge.startDrag(DragSource.DefaultCopyDrop, dragAndDropTransferable, this); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + + private static class DragAndDropTransferable implements Transferable { + private Component component; + + public DragAndDropTransferable(Component component) { + this.component = component; + } + + DataFlavor[] flavors = {new DataFlavor(Component.class, "Component")}; + + public DataFlavor[] getTransferDataFlavors() { + return flavors; + } + + public boolean isDataFlavorSupported(DataFlavor flavor) { + for (DataFlavor df : flavors) { + if (ComparatorUtils.equals(df, flavor)) { + return true; + } + } + return false; + } + @NotNull + public Object getTransferData(DataFlavor df) { + return component; + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java new file mode 100644 index 0000000000..13e5dc28f0 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/BubbleTip.java @@ -0,0 +1,97 @@ +package com.fr.design.mainframe.guide.tip; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.guide.base.Guide; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.design.mainframe.guide.ui.bubble.Bubble; +import com.fr.design.mainframe.guide.ui.bubble.BubbleWithClose; + +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import java.awt.Point; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class BubbleTip implements GuideTip { + private static final int GAP = 5; + private BubbleWithClose bubbleBox; + private Point anchor; + + + /** + * + * @param title 标题 + * @param content 内容 + * @param direction 气泡提示相对anchor的方向,这里方向会和气泡组件箭头方向相反 + * @param tailStart 气泡尾巴相对当前边垂直方向偏移位置比例,值在0-1范围 + */ + public BubbleTip(String title, String content, Direction direction, float tailStart) { + bubbleBox = new BubbleWithClose(title, content, getBubbleBoxTailDirection(direction), tailStart); + bubbleBox.addCloseActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Guide currentGuide = GuideManager.getInstance().getCurrentGuide(); + if (currentGuide != null) { + + int returnVal = FineJOptionPane.showConfirmDialog( + currentGuide.getGuideView(), + Toolkit.i18nText("Fine-Design_Guide_Option_Warning_Terminal"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), + JOptionPane.YES_NO_OPTION, + JOptionPane.QUESTION_MESSAGE); + if (returnVal == JOptionPane.YES_OPTION) { + currentGuide.terminate(); + } + } + } + }); + } + @Override + public JComponent getTip() { + if(anchor == null) { + return new BubbleWithClose(bubbleBox.getTitle(), bubbleBox.getContent(), Bubble.TailDirection.TOP, 0); + } else { + setBubbleBoxBound(); + return bubbleBox; + } + } + + /** + * 设置锚点坐标 + * 这里可以指定气泡组件箭头坐标的箭头坐标 + * @param anchor + */ + public void setAnchor(Point anchor) { + this.anchor = anchor; + } + + private void setBubbleBoxBound() { + int bubbleW = bubbleBox.getPreferredSize().width; + int bubbleH = bubbleBox.getPreferredSize().height; + if (bubbleBox.isTailHorizontal()) { + int x = bubbleBox.isTailLeft() ? anchor.x + GAP : anchor.x - bubbleW - GAP; + int y = anchor.y - (int) (bubbleH * bubbleBox.getTailStart()); + bubbleBox.setBounds(x, y, bubbleW, bubbleH); + } else if (bubbleBox.isTailVertical()) { + int x = anchor.x - (int) (bubbleW * bubbleBox.getTailStart()); + int y = bubbleBox.isTailTop() ? anchor.y + GAP : anchor.y - bubbleH - GAP; + bubbleBox.setBounds(x, y, bubbleW, bubbleH); + } + } + + private Bubble.TailDirection getBubbleBoxTailDirection(Direction direction) { + switch (direction) { + case TOP: + return Bubble.TailDirection.BOTTOM; + case BOTTOM: + return Bubble.TailDirection.TOP; + case LEFT: + return Bubble.TailDirection.RIGHT; + case RIGHT: + default: + return Bubble.TailDirection.LEFT; + } + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java new file mode 100644 index 0000000000..e1573601f8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/tip/GuideTip.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.guide.tip; + +import javax.swing.JComponent; +import java.awt.Point; + +public interface GuideTip { + enum Direction { + TOP, BOTTOM, LEFT, RIGHT + } + + JComponent getTip(); + + void setAnchor(Point anchor); +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java new file mode 100644 index 0000000000..79d49d1925 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/BubbleHint.java @@ -0,0 +1,84 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.guide.ui.bubble.Bubble; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.ActionListener; + +public class BubbleHint extends Bubble { + private UIButton confirmButton; + private static final Color CONTENT_TEXT_COLOR = new Color(51, 51, 52); + + public BubbleHint() { + super(TailDirection.TOP, 0.9f); + initComponent(); + } + + private void initComponent() { + this.setLayout(new BorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(10 + Bubble.TAIL_HEIGHT, 15, 10, 15)); + this.setPreferredSize(new Dimension(220, 140)); + + JPanel contentPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, VerticalFlowLayout.CENTER, 0, 0); + contentPane.setOpaque(false); + + UILabel title = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Title")); + title.setFont(title.getFont().deriveFont(16.0f)); + title.setForeground(new Color(62, 155, 249)); + title.setPreferredSize(new Dimension(190, 30)); + title.setHorizontalAlignment(SwingConstants.CENTER); + title.setBorder(BorderFactory.createEmptyBorder(0,0,5,0)); + + UILabel content1 = createContentLabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Content1")); + + UILabel content2 = createContentLabel(Toolkit.i18nText("Fine-Design_Guide_Tips_Content2")); + + JPanel buttonContainer= FRGUIPaneFactory.createCenterFlowZeroGapBorderPane(); + buttonContainer.setBorder(BorderFactory.createEmptyBorder(15, 0, 0, 0)); + buttonContainer.setPreferredSize(new Dimension(190,40)); + buttonContainer.setOpaque(false); + + confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Guide_Tips_Know")) { + public Dimension getPreferredSize() { + return new Dimension(78, 24); + } + }; + + buttonContainer.add(confirmButton); + + contentPane.add(title); + contentPane.add(content1); + contentPane.add(content2); + contentPane.add(buttonContainer); + + this.add(contentPane, BorderLayout.CENTER); + } + + public void addConfirmAction(ActionListener listener) { + confirmButton.addActionListener(listener); + } + + public void removeConfirmAction(ActionListener listener) { + confirmButton.removeActionListener(listener); + } + + private UILabel createContentLabel(String text) { + UILabel content = new UILabel(text); + content.setPreferredSize(new Dimension(190,20)); + content.setHorizontalAlignment(SwingConstants.CENTER); + content.setFont(content.getFont().deriveFont(14.0f)); + content.setForeground(CONTENT_TEXT_COLOR); + return content; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java new file mode 100644 index 0000000000..c4e6e01601 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/ExpandPane.java @@ -0,0 +1,78 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class ExpandPane extends JPanel { + private static final Icon downIcon = IOUtils.readIcon("/com/fr/design/mainframe/guide/arrow_down.png"); + private static final Icon rightIcon = IOUtils.readIcon("/com/fr/design/mainframe/guide/arrow_right.png"); + private String title; + private boolean expand; + private UILabel arrow; + private JPanel headerPane; + private JPanel contentPane; + + public ExpandPane(String title, JPanel contentPane) { + this.title = title; + this.expand = true; + this.contentPane = contentPane; + initComponent(); + } + + private void initComponent() { + VerticalFlowLayout layout = new VerticalFlowLayout(VerticalFlowLayout.TOP, 10, 0); + layout.setAlignLeft(true); + this.setLayout(layout); + + JPanel headerPane = createHeader(); + this.add(headerPane); + this.add(contentPane); + headerPane.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setExpand(!expand); + } + }); + } + + private JPanel createHeader() { + headerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + headerPane.setPreferredSize(new Dimension(200, 16)); + UILabel headerTitle = new UILabel(this.title); + headerTitle.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); + arrow = new UILabel(downIcon); + arrow.setOpaque(false); + arrow.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + headerPane.add(headerTitle, BorderLayout.CENTER); + headerPane.add(arrow, BorderLayout.WEST); + return headerPane; + } + + @Override + public void setPreferredSize(Dimension preferredSize) { + super.setPreferredSize(preferredSize); + headerPane.setPreferredSize(new Dimension(preferredSize.width, headerPane.getPreferredSize().height)); + contentPane.setPreferredSize(new Dimension(preferredSize.width, contentPane.getPreferredSize().height)); + } + + public void setExpand(boolean isExpand) { + this.expand = isExpand; + arrow.setIcon(isExpand ? downIcon : rightIcon); + contentPane.setVisible(isExpand); + } + + public boolean isExpand() { + return expand; + } +} + diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java new file mode 100644 index 0000000000..b90c5718c6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideCompleteDialog.java @@ -0,0 +1,151 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.frpane.UITextPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonUI; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.JTextPane; +import javax.swing.SwingConstants; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics2D; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class GuideCompleteDialog extends JDialog { + private static final int DIALOG_WIDTH = 340; + private static final int DIALOG_HEIGHT = 367; + private static final Icon SUCCESS_ICON = IOUtils.readIcon("/com/fr/design/mainframe/guide/success.png"); + private static final int ICON_HEIGHT = 182; + private static final Color FONT_COLOR = new Color(51, 51, 52); + private static final Color BUTTON_BG_COLOR = new Color(65, 155,249); + private static final Font TITLE_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 22); + private static final Font CONTENT_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 18); + private static final Font BUTTON_FONT = new Font(Font.SANS_SERIF, Font.BOLD, 14); + private static GuideCompleteDialog dialog; + + public static GuideCompleteDialog getInstance() { + if (dialog == null) { + dialog = new GuideCompleteDialog(DesignerContext.getDesignerFrame()); + } + dialog = new GuideCompleteDialog(DesignerContext.getDesignerFrame()); + return dialog; + } + + private UITextPane textArea; + + public GuideCompleteDialog(Window window) { + super(window); + setSize(DIALOG_WIDTH, DIALOG_HEIGHT); + setUndecorated(true); + setModal(true); + setLocationRelativeTo(window); + this.setContentPane(getContentPane()); + } + + @Override + public Container getContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + + UILabel completeImage = new UILabel(SUCCESS_ICON); + completeImage.setPreferredSize(new Dimension(DIALOG_WIDTH, ICON_HEIGHT)); + + JPanel container = new JPanel(new BorderLayout(0, 10)); + container.setBorder(BorderFactory.createEmptyBorder(15, 52, 25, 52)); + + UILabel title = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Complete_Confirm")); + title.setFont(TITLE_FONT); + title.setPreferredSize(new Dimension(190, 30)); + title.setHorizontalAlignment(SwingConstants.CENTER); + title.setForeground(FONT_COLOR); + + textArea = new UITextPane(); + changeLineSpacing(textArea, 0.15f,false); + textArea.setEnabled(false); + textArea.setOpaque(false); + textArea.setFont(CONTENT_FONT); + textArea.setPreferredSize(new Dimension(236, 52)); + textArea.setBorder(null); + textArea.setDisabledTextColor(FONT_COLOR); + StyledDocument doc = textArea.getStyledDocument(); + SimpleAttributeSet center = new SimpleAttributeSet(); + StyleConstants.setAlignment(center, StyleConstants.ALIGN_CENTER); + doc.setParagraphAttributes(0, doc.getLength(), center, false); + + JPanel buttonContainer= FRGUIPaneFactory.createCenterFlowZeroGapBorderPane(); + buttonContainer.setPreferredSize(new Dimension(190,43)); + buttonContainer.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + buttonContainer.setOpaque(false); + + UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Guide_Complete_End")){ + @Override + public Dimension getPreferredSize() { + return new Dimension(122, 38); + } + }; + button.setFont(BUTTON_FONT); + button.setUI(confirmButtonUI); + button.setRoundBorder(true); + button.setForeground(Color.WHITE); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + dispose(); + } + }); + + buttonContainer.add(button); + container.add(title, BorderLayout.NORTH); + container.add(textArea, BorderLayout.CENTER); + container.add(buttonContainer,BorderLayout.SOUTH); + + contentPane.add(completeImage, BorderLayout.NORTH); + contentPane.add(container, BorderLayout.CENTER); + + return contentPane; + } + + public void showDialog(String str) { + textArea.setText(str); + repaint(); + this.setVisible(true); + } + + private UIButtonUI confirmButtonUI = new UIButtonUI() { + protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { + if (isPressed(b) && b.isPressedPainted()) { + GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), BUTTON_BG_COLOR); + } else if (isRollOver(b)) { + GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), BUTTON_BG_COLOR); + } else if (b.isNormalPainted()) { + GUIPaintUtils.fillNormal(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted(), BUTTON_BG_COLOR); + } + } + }; + + private void changeLineSpacing(JTextPane pane, float factor, boolean replace) { + pane.selectAll(); + MutableAttributeSet set = new SimpleAttributeSet(pane.getParagraphAttributes()); + StyleConstants.setLineSpacing(set, factor); + pane.setParagraphAttributes(set, replace); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java new file mode 100644 index 0000000000..47a10d0be8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingGlassPane.java @@ -0,0 +1,60 @@ +package com.fr.design.mainframe.guide.ui; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; + +public class GuideLoadingGlassPane extends JPanel { + private static GuideLoadingGlassPane loadingPane; + + public static GuideLoadingGlassPane getInstance() { + if (loadingPane == null) { + loadingPane = new GuideLoadingGlassPane(); + } + return loadingPane; + } + + public GuideLoadingGlassPane() { + this.setLayout(new GridBagLayout()); + this.setOpaque(false); + initComponent(); + } + + public void initComponent() { + JPanel loadingView = FRGUIPaneFactory.createBorderLayout_S_Pane(); + loadingView.setOpaque(false); + loadingView.setPreferredSize(new Dimension(150, 90)); + + JPanel imageContainer = FRGUIPaneFactory.createCenterFlowInnerContainer_S_Pane(); + imageContainer.setOpaque(false); + + imageContainer.add(GuideLoadingPane.getInstance()); + + UILabel hintLabel = new UILabel(Toolkit.i18nText("Fine-Design_Guide_Loading_Wait")); + hintLabel.setFont(new Font(Font.SANS_SERIF, Font.PLAIN, 14)); + hintLabel.setHorizontalAlignment(SwingConstants.CENTER); + hintLabel.setForeground(Color.WHITE); + + loadingView.add(imageContainer, BorderLayout.NORTH); + loadingView.add(hintLabel, BorderLayout.SOUTH); + + this.add(loadingView, new GridBagConstraints()); + } + + public void startLoading() { + GuideLoadingPane.getInstance().start(); + } + + public void stopLoading() { + GuideLoadingPane.getInstance().stop(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingPane.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingPane.java new file mode 100644 index 0000000000..0a290c784c --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideLoadingPane.java @@ -0,0 +1,98 @@ +package com.fr.design.mainframe.guide.ui; + +import javax.swing.JPanel; +import javax.swing.Timer; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * Created by kerry on 2020-10-23 + */ +public class GuideLoadingPane extends JPanel { + private static final BasicStroke STROKE = new BasicStroke(4); + private static final int FPS = 30; + private static final int START_ANGLE = 90; + private static GuideLoadingPane imagePanel; + private Image image; + private int angle; + private Timer timer; + + public static GuideLoadingPane getInstance() { + if (imagePanel == null) { + imagePanel = new GuideLoadingPane(); + } + return imagePanel; + } + + public GuideLoadingPane() { + this.setOpaque(false); + this.setPreferredSize(new Dimension(50, 50)); + timer = new Timer(1000 / FPS, new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + repaint(); + angle -= 180 / FPS; // 5 degrees per 100 ms = 50 degrees/second + if (angle > -270) { + angle += 2 * 360; + } + } + }); + } + + public void start() { + angle = START_ANGLE; + timer.start(); + } + + public void stop() { + timer.stop(); + } + + @Override + public void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + Composite oldComposite = g2.getComposite(); + Stroke oldStroke = g2.getStroke(); + + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); + + int d = Math.min(getWidth(), getHeight()); + int r = d / 2; + Point circlePoint = new Point(getWidth() / 2, getHeight() / 2); + + g2.setColor(Color.WHITE); + g2.fillOval(circlePoint.x - r, circlePoint.y - r, d, d); + + g2.setColor(Color.BLACK); + int waitCircleD = d / 10; + int waitCircleR = waitCircleD / 2; + + g2.fillOval(circlePoint.x - r / 3 - waitCircleR, circlePoint.y - waitCircleR, waitCircleD, waitCircleD); + g2.fillOval(circlePoint.x - waitCircleR, circlePoint.y - waitCircleR, waitCircleD, waitCircleD); + g2.fillOval(circlePoint.x + r / 3 - waitCircleR, circlePoint.y - waitCircleR, waitCircleD, waitCircleD); + + + g2.setStroke(STROKE); + g2.setColor(Color.decode("#419BF9")); + + int lineWidth = (int) STROKE.getLineWidth(); + g2.drawArc(circlePoint.x - r + lineWidth / 2 , circlePoint.y - r + lineWidth / 2, d - lineWidth, d - lineWidth, angle, -90); + + g2.setStroke(oldStroke); + g2.setComposite(oldComposite); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java new file mode 100644 index 0000000000..ca53613c46 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/GuideManageDialog.java @@ -0,0 +1,233 @@ +package com.fr.design.mainframe.guide.ui; + + +import com.fr.base.svg.IconUtils; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.guide.base.Guide; +import com.fr.design.mainframe.guide.base.GuideGroup; +import com.fr.design.mainframe.guide.base.GuideManager; +import com.fr.design.mainframe.guide.base.GuideVersion; +import com.fr.design.mainframe.guide.collect.GuideCollector; +import com.fr.design.utils.gui.GUICoreUtils; + +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.border.Border; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class GuideManageDialog extends JDialog { + private static final int DEFAULT_HEIGHT = 400; + private static final int DEFAULT_WIDTH = 600; + private static final Icon GROUP_COMPLETE_NONE = IconUtils.readIcon("/com/fr/design/mainframe/guide/complete_none.svg"); + private static final Icon GROUP_COMPLETE_SOME = IconUtils.readIcon("/com/fr/design/mainframe/guide/complete_some.svg"); + private static final Icon GROUP_COMPLETE_ALL = IconUtils.readIcon("/com/fr/design/mainframe/guide/complete_all.svg"); + private static final Color BORDER_COLOR = new Color(224, 224, 225); + private static final Color UNCOMPLETE_FONT_COLOR = new Color(51, 51, 52); + private static final Color COMPLETE_FONT_COLOR = new Color(51,51,52,128); + private static GuideManageDialog dialog; + + private JPanel scrollContent; + + public static GuideManageDialog getInstance() { + if (dialog == null) { + dialog = new GuideManageDialog(DesignerContext.getDesignerFrame()); + } + return dialog; + } + + public GuideManageDialog(Window parent) { + super(parent); + GuideCollector.getInstance().load(); + initComponent(); + } + + private void initComponent() { + this.setTitle(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Title")); + setResizable(false); + setModal(true); + setLayout(FRGUIPaneFactory.createBorderLayout()); + setSize(DEFAULT_WIDTH, DEFAULT_HEIGHT); + GUICoreUtils.centerWindow(this); + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentPane.add(createContentPanel(), BorderLayout.CENTER); + contentPane.add(createActionsPane(), BorderLayout.SOUTH); + setContentPane(contentPane); + } + + private UIScrollPane createContentPanel() { + scrollContent = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 5); + UIScrollPane scrollPane = new UIScrollPane(scrollContent); + return scrollPane; + } + + private JPanel createGuideVersionPane(GuideVersion guideVersion) { + JPanel expandContent = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 10); + for (GuideGroup guideGroup : guideVersion.getGuideGroupList()) { + JPanel guideGroupCard = createGuideGroupCard(guideGroup); + expandContent.add(guideGroupCard); + } + ExpandPane expandPane = new ExpandPane(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Version_Title", guideVersion.getVersion()), expandContent); + return expandPane; + } + + + private JPanel createGuideGroupCard(GuideGroup guideGroup) { + JPanel card = FRGUIPaneFactory.createBorderLayout_S_Pane(); + card.setBorder(BorderFactory.createLineBorder(BORDER_COLOR)); + card.setBackground(Color.WHITE); + + JPanel cardContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + cardContainer.setOpaque(false); + cardContainer.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + card.add(cardContainer, BorderLayout.CENTER); + + cardContainer.add(createGroupTitlePane(guideGroup), BorderLayout.NORTH); + cardContainer.add(createGroupContentPane(guideGroup), BorderLayout.CENTER); + return card; + } + + private JPanel createGroupTitlePane(GuideGroup guideGroup) { + JPanel titleContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.CENTER, 0, 0); + titleContainer.setBorder(getBottomBorder()); + titleContainer.setOpaque(false); + + titleContainer.setPreferredSize(new Dimension(500, 40)); + JPanel titlePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 8,0 ); + titlePane.setOpaque(false); + + UILabel iconLabel = new UILabel(getGroupStateIcon(guideGroup)); + iconLabel.setPreferredSize(new Dimension(16, 16)); + iconLabel.setOpaque(false); + + UILabel titleLabel = new UILabel(guideGroup.getName()); + titleLabel.setPreferredSize(new Dimension(200, 16)); + titleLabel.setForeground(new Color(65, 155, 249)); + titleLabel.setOpaque(false); + + titlePane.add(iconLabel); + titlePane.add(titleLabel); + titleContainer.add(titlePane); + return titleContainer; + } + + private JPanel createGroupContentPane(GuideGroup guideGroup) { + JPanel groupContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.TOP, 0, 0); + groupContainer.setBorder(BorderFactory.createEmptyBorder(0,10,0,0)); + groupContainer.setOpaque(false); + for (int index = 0; index < guideGroup.getGuideList().size(); index++) { + JPanel guidePane = createGuidePane(guideGroup.getGuideList().get(index), index); + if (index != guideGroup.getGuideList().size() - 1) { + guidePane.setBorder(getBottomBorder()); + } + groupContainer.add(guidePane); + } + return groupContainer; + } + + + + private JPanel createGuidePane(Guide guide, int index) { + JPanel guidePaneContainer = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, VerticalFlowLayout.CENTER, 0, 0); + guidePaneContainer.setPreferredSize(new Dimension(540, 40)); + guidePaneContainer.setOpaque(false); + + JPanel guidePane = FRGUIPaneFactory.createBoxFlowInnerContainer_S_Pane(0, 50,0 ); + guidePane.setOpaque(false); + + UILabel title = new UILabel((index + 1) + "、" + guide.getDescription()); + title.setPreferredSize(new Dimension(440, 20)); + title.setForeground(guide.isComplete() ? COMPLETE_FONT_COLOR : UNCOMPLETE_FONT_COLOR); + title.setOpaque(false); + + + UIButton button = new UIButton(guide.isComplete() ? Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Retry") : Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Show")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + guide.go(); + } + }); + + button.setPreferredSize(new Dimension(48, 20)); + guidePane.add(title); + guidePane.add(button); + + guidePaneContainer.add(guidePane); + return guidePaneContainer; + } + + private Border getBottomBorder() { + return BorderFactory.createMatteBorder( + 0,0,1, 0, BORDER_COLOR + ); + } + + public void showDialog() { + resetScrollContent(); + this.setVisible(true); + } + + private Icon getGroupStateIcon(GuideGroup guideGroup) { + if (guideGroup.isCompleteAll()) { + return GROUP_COMPLETE_ALL; + } else if (guideGroup.isCompleteSome()) { + return GROUP_COMPLETE_SOME; + } else { + return GROUP_COMPLETE_NONE; + } + } + + private UIButton createCompleteAllButton() { + UIButton button = new UIButton(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Complete_All"))); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + GuideManager.getInstance().completeAll(); + resetScrollContent(); + } + }); + return button; + } + + private UIButton createCloseButton() { + UIButton button = new UIButton(Toolkit.i18nText(Toolkit.i18nText("Fine-Design_Guide_Manager_Dialog_Close"))); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + setVisible(false); + } + }); + return button; + } + + private JPanel createActionsPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(BorderFactory.createEmptyBorder(7, 10, 7, 10)); + container.add(createCompleteAllButton(), BorderLayout.WEST); + container.add(createCloseButton(), BorderLayout.EAST); + return container; + } + + private void resetScrollContent() { + scrollContent.removeAll(); + for (GuideVersion guideVersion : GuideManager.getInstance().getGuideVersionList()) { + scrollContent.add(createGuideVersionPane(guideVersion)); + } + revalidate(); + repaint(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java new file mode 100644 index 0000000000..10b04362e1 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/Bubble.java @@ -0,0 +1,152 @@ +package com.fr.design.mainframe.guide.ui.bubble; + +import javax.swing.JComponent; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Composite; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; + +public class Bubble extends JComponent { + public enum TailDirection { + TOP, BOTTOM, LEFT, RIGHT + } + protected static final int TAIL_HEIGHT = 7; + protected static final int TAIL_WIDTH = 14; + protected static final int BUBBLE_WIDTH = 170; + protected static final Color BG_COLOR = new Color(240,240,241); + protected static final int BORDER_RADIUS = 10; + + + private TailDirection tailDirection; + private float tailStart; + + public Bubble() { + this(TailDirection.LEFT, 0.5f); + } + + public Bubble(TailDirection tailDirection, float tailStart) { + this.tailDirection = tailDirection; + this.tailStart = tailStart; + this.setOpaque(false); + } + + public void setTailDirection(TailDirection tailDirection) { + this.tailDirection = tailDirection; + } + + public TailDirection getTailDirection() { + return tailDirection; + } + + public void setTailStart(float tailStart) { + this.tailStart = tailStart; + } + + public float getTailStart() { + return tailStart; + } + + + @Override + public Dimension getPreferredSize() { + if (isPreferredSizeSet()) { + return super.getPreferredSize(); + } + return new Dimension(getDefaultWidth(), getDefaultHeight()); + + } + + protected int getDefaultWidth() { + return (isTailHorizontal() ? TAIL_HEIGHT : 0) + BUBBLE_WIDTH; + } + + protected int getDefaultHeight() { + return (isTailVertical() ? TAIL_HEIGHT : 0); + } + + @Override + protected void paintComponent(Graphics g) { + Graphics2D g2 = (Graphics2D) g; + Composite oldComposite = g2.getComposite(); + paintBubbleBg(g2); + g2.setComposite(oldComposite); + super.paintComponent(g); + } + + protected void paintBubbleBg(Graphics2D g2) { + g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); + paintRectBg(g2); + paintTailBg(g2); + } + + protected void paintRectBg(Graphics2D g2) { + g2.setColor(BG_COLOR); + Rectangle bounds = getRectBounds(); + g2.fillRoundRect(bounds.x, bounds.y, bounds.width, bounds.height, BORDER_RADIUS, BORDER_RADIUS); + } + + protected void paintTailBg(Graphics2D g2) { + int width = getWidth(); + int height = getHeight(); + if (isTailVertical()) { + int tailX = (int) (width * tailStart); + int startX = Math.max(tailX - TAIL_WIDTH / 2, 0); + int endX = startX + TAIL_WIDTH; + int[] xPoints = {startX, endX, tailX}; + int[] yPoints = isTailTop() ? new int[]{TAIL_HEIGHT, TAIL_HEIGHT, 0} : new int[]{height - TAIL_HEIGHT, height - TAIL_HEIGHT, height}; + g2.fillPolygon(xPoints, yPoints, 3); + } else if (isTailHorizontal()) { + int tailY = (int) (height * tailStart); + int startY = Math.max(tailY - TAIL_WIDTH / 2, 0); + int endY = startY + TAIL_WIDTH; + int[] xPoints = isTailLeft() ? new int[]{TAIL_HEIGHT, TAIL_HEIGHT, 0} : new int[]{width - TAIL_HEIGHT, width - TAIL_HEIGHT, width}; + int[] yPoints = {startY, endY, tailY}; + g2.fillPolygon(xPoints, yPoints, 3); + } + } + + public Rectangle getRectBounds() { + int width = getWidth(); + int height = getHeight(); + switch (tailDirection) { + case TOP: + return new Rectangle(0, TAIL_HEIGHT, width, height - TAIL_HEIGHT); + case LEFT: + return new Rectangle(TAIL_HEIGHT, 0, width - TAIL_HEIGHT, height); + case RIGHT: + return new Rectangle(0, 0 , width - TAIL_HEIGHT, height); + case BOTTOM: + return new Rectangle(0, 0, width, height - TAIL_HEIGHT); + default: + return new Rectangle(0,0,0,0); + } + } + + public boolean isTailHorizontal() { + return isTailLeft() || isTailRight(); + } + + public boolean isTailVertical() { + return isTailTop() || isTailBottom(); + } + + public boolean isTailLeft() { + return tailDirection == TailDirection.LEFT; + } + + public boolean isTailRight() { + return tailDirection == TailDirection.RIGHT; + } + + public boolean isTailTop() { + return tailDirection == TailDirection.TOP; + } + + public boolean isTailBottom() { + return tailDirection == TailDirection.BOTTOM; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java new file mode 100644 index 0000000000..62e0ed65d0 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/ui/bubble/BubbleWithClose.java @@ -0,0 +1,297 @@ +package com.fr.design.mainframe.guide.ui.bubble; + + +import com.fr.base.GraphHelper; +import com.fr.design.gui.frpane.UITextPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.Icon; +import javax.swing.JTextPane; +import javax.swing.text.MutableAttributeSet; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.FontMetrics; +import java.awt.Insets; +import java.awt.LayoutManager; +import java.awt.Rectangle; +import java.awt.event.ActionListener; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.awt.font.FontRenderContext; +import java.awt.font.LineBreakMeasurer; +import java.awt.font.TextAttribute; +import java.text.AttributedCharacterIterator; +import java.text.AttributedString; + +public class BubbleWithClose extends Bubble { + private static final Font TITLE_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 14); + private static final Font CONTENT_FONT = new Font(Font.SANS_SERIF, Font.PLAIN, 12); + private static final int TITLE_LINE_HEIGHT = 22; + private static final int CONTENT_LINE_HEIGHT = 18; + + private static final Icon ICON = IOUtils.readIcon("/com/fr/design/mainframe/guide/close.png"); + private static final Color TITLE_COLOR = new Color(51, 51, 52); + private static final Color CONTENT_COLOR = new Color(51,51,52,128); + private static final Color HIGHLIGHT_COLOR = new Color(65, 155, 249); + private static final Insets DEFAULT_INSET = new Insets(15, 15, 15, 15); + private static final int MIN_WIDTH = 140; + private static final int MAX_WIDTH = 275; + private static final int ICON_GAP = 10; + private static final int ICON_SIZE = 10; + private static final int TEXT_GAP = 5; + + + private String title; + private String content; + private UITextPane titleTextArea; + private UITextPane contentTextArea; + private UIButton closeButton; + private Dimension titleSize; + private Dimension contentSize; + + public BubbleWithClose(String title, String content) { + this(title, content, TailDirection.LEFT, 0.5f); + } + + public BubbleWithClose(String title, String content, TailDirection tailDirection, float tailStart) { + super(tailDirection, tailStart); + this.title = title; + this.content = content; + this.initComponent(); + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getContent() { + return content; + } + + public void setContent(String content) { + this.content = content; + } + + protected void initComponent() { + this.setLayout(getLayoutManager()); + createCloseButton(); + createContentPane(); + this.addComponentListener(new ComponentAdapter() { + @Override + public void componentShown(ComponentEvent e) { + super.componentShown(e); + } + + @Override + public void componentResized(ComponentEvent e) { + Rectangle rectBounds = getRectBounds(); + + closeButton.setBounds(rectBounds.x + rectBounds.width - DEFAULT_INSET.right - ICON_SIZE, rectBounds.y + 21, ICON_SIZE, ICON_SIZE); + if (titleTextArea != null) { + int x = rectBounds.x + DEFAULT_INSET.left; + int y = rectBounds.y + DEFAULT_INSET.top; + titleTextArea.setBounds(x, y, titleSize.width, titleSize.height); + } + + if (contentTextArea != null) { + int x = rectBounds.x + DEFAULT_INSET.left; + int y = rectBounds.y + DEFAULT_INSET.top + (titleSize.height == 0 ? 0 : titleSize.height + getTextGap()); + contentTextArea.setBounds(x,y, contentSize.width, contentSize.height); + } + setSize(getPreferredSize().width, getPreferredSize().height); + repaint(); + } + }); + } + + private void createCloseButton() { + closeButton = new UIButton(); + closeButton.setIcon(ICON); + closeButton.set4ToolbarButton(); + closeButton.setPreferredSize(new Dimension(ICON_SIZE, ICON_SIZE)); + closeButton.setRolloverEnabled(false); + closeButton.setPressedPainted(false); + this.add(closeButton); + } + + public void addCloseActionListener(ActionListener actionListener) { + closeButton.addActionListener(actionListener); + + } + + public void removeCloseActionListener(ActionListener actionListener){ + closeButton.removeActionListener(actionListener); + } + + private void createContentPane() { + createTitleTextArea(); + createContentTextArea(); + } + + private void createTitleTextArea() { + if (StringUtils.isNotEmpty(title)) { + titleTextArea = createTextArea(title, TITLE_FONT, TITLE_LINE_HEIGHT, TITLE_COLOR); + this.add(titleTextArea); + } + titleSize = calTextSize(titleTextArea, TITLE_LINE_HEIGHT, getTextAreaWidth(MAX_WIDTH), getTextAreaWidth(MIN_WIDTH)); + } + + private void createContentTextArea() { + if (StringUtils.isNotEmpty(content)) { + contentTextArea = createTextArea(content, CONTENT_FONT, CONTENT_LINE_HEIGHT, CONTENT_COLOR); + this.add(contentTextArea); + } + contentSize = calTextSize(contentTextArea, CONTENT_LINE_HEIGHT, getTextAreaWidth(MAX_WIDTH), getTextAreaWidth(MIN_WIDTH)); + } + + private UITextPane createTextArea(String str, Font font, int lineHeight, Color foreground) { + int lineSpace = lineHeight - font.getSize(); + UITextPane textArea= new UITextPane(){ + @Override + public Insets getInsets() { + return new Insets(lineSpace / 2 - 1, 0, lineSpace / 2, 0); + } + }; + textArea.setFont(font); + changeLineSpacing(textArea, lineHeight, true); + textArea.setEditable(false); + textArea.setForeground(foreground); + textArea.setDisabledTextColor(foreground); + textArea.setBorder(null); + textArea.setOpaque(false); + textArea.setText(str); + highlightText(textArea); + return textArea; + } + + private void changeLineSpacing(JTextPane pane, int lineHeight, boolean replace) { + pane.selectAll(); + MutableAttributeSet set = new SimpleAttributeSet(pane.getParagraphAttributes()); + FontMetrics fontMetrics = GraphHelper.getFontMetrics(pane.getFont()); + StyleConstants.setLineSpacing(set, (float)(lineHeight - fontMetrics.getHeight()) / fontMetrics.getHeight()); + pane.setParagraphAttributes(set, replace); + } + + private void highlightText(JTextPane textArea) { + SimpleAttributeSet sas = new SimpleAttributeSet(); + StyleConstants.setForeground(sas, HIGHLIGHT_COLOR); + StyledDocument doc = textArea.getStyledDocument(); + String text = textArea.getText(); + int startPos = -1; + for (int i = 0; i < text.length(); i ++) { + char ch = text.charAt(i); + if (ch == '【') { + startPos = i; + } + if (ch == '】') { + if (startPos > 0) { + try { + doc.setCharacterAttributes(startPos, (i - startPos + 1), sas, false); + startPos = -1; + } catch (Exception e) { + } + } + } + } + + } + + @Override + protected int getDefaultWidth() { + return Math.max(titleSize.width, contentSize.width) + getHorizontalInsets() + ICON_GAP + ICON_SIZE + (isTailHorizontal() ? TAIL_HEIGHT : 0) ; + } + + @Override + protected int getDefaultHeight() { + return titleSize.height + contentSize.height + getTextGap() + getVerticalInsets() + (isTailVertical() ? TAIL_HEIGHT : 0); + } + + private int getTextGap() { + return (titleSize.height != 0 && contentSize.height != 0) ? TEXT_GAP : 0; + } + + private LayoutManager getLayoutManager() { + return new LayoutManager() { + @Override + public void addLayoutComponent(String name, Component comp) { + } + + @Override + public void removeLayoutComponent(Component comp) { + + } + + @Override + public Dimension preferredLayoutSize(Container parent) { + return parent.getPreferredSize(); + } + + @Override + public Dimension minimumLayoutSize(Container parent) { + return null; + } + + @Override + public void layoutContainer(Container parent) { + + } + }; + } + + private int countLines(JTextPane textArea, int max_width) { + AttributedString text = new AttributedString(textArea.getText()); + text.addAttribute(TextAttribute.FONT, textArea.getFont()); + FontRenderContext frc = textArea.getFontMetrics(textArea.getFont()) + .getFontRenderContext(); + AttributedCharacterIterator charIt = text.getIterator(); + LineBreakMeasurer lineMeasurer = new LineBreakMeasurer(charIt, frc); + lineMeasurer.setPosition(charIt.getBeginIndex()); + int lines = 0; + while (lineMeasurer.getPosition() < charIt.getEndIndex()) { + lineMeasurer.nextLayout(max_width); + lines++; + } + return lines; + } + + private Dimension calTextSize(JTextPane textArea, int lineHeight, int maxWidth, int minWidth) { + if (textArea == null) { + return new Dimension(minWidth, 0); + } + FontMetrics fontMetrics = GraphHelper.getFontMetrics(textArea.getFont()); + int line = countLines(textArea, maxWidth); + int width = maxWidth; + if (line == 1) { + width = Math.max(fontMetrics.stringWidth(textArea.getText()), minWidth); + } + int height = lineHeight * line; + return new Dimension(width, height); + } + + + private int getTextAreaWidth(int bubbleWidth) { + return bubbleWidth - getHorizontalInsets() - ICON_SIZE - ICON_GAP; + } + + + private int getHorizontalInsets() { + return DEFAULT_INSET.left + DEFAULT_INSET.right; + } + + private int getVerticalInsets() { + return DEFAULT_INSET.top + DEFAULT_INSET.bottom; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java b/designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java new file mode 100644 index 0000000000..8705d0e8a4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/guide/utils/ScreenImage.java @@ -0,0 +1,98 @@ +package com.fr.design.mainframe.guide.utils; + +import javax.swing.JComponent; +import javax.swing.SwingUtilities; +import java.awt.AWTException; +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Dimension; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Robot; +import java.awt.image.BufferedImage; + +public class ScreenImage { + + public static BufferedImage createImage(JComponent component) { + return ScreenImage.createImage(component, getRegion(component)); + } + + public static BufferedImage createImage(JComponent component, Rectangle region) { + if (! component.isDisplayable()) { + Dimension d = component.getSize(); + + if (d.width == 0 || d.height == 0) { + d = component.getPreferredSize(); + component.setSize( d ); + } + + layoutComponent( component ); + } + + BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = image.createGraphics(); + + if (! component.isOpaque()) { + g2d.setColor( component.getBackground() ); + g2d.fillRect(region.x, region.y, region.width, region.height); + } + + g2d.translate(-region.x, -region.y); + component.print( g2d ); + g2d.dispose(); + return image; + } + + public static BufferedImage createImage(Component component) + throws AWTException { + Point p = new Point(0, 0); + SwingUtilities.convertPointToScreen(p, component); + Rectangle region = component.getBounds(); + region.x = p.x; + region.y = p.y; + return ScreenImage.createImage(region); + } + + public static BufferedImage createImageWithModal(JComponent component) { + Rectangle region = getRegion(component); + BufferedImage image = new BufferedImage(region.width, region.height, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = image.createGraphics(); + g2d.drawImage(createImage(component), 0, 0, null); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.6f)); + g2d.setColor(Color.BLACK); + g2d.fillRect(0, 0, region.width, region.height); + g2d.dispose(); + return image; + } + + public static BufferedImage createImage(Rectangle region) + throws AWTException { + BufferedImage image = new Robot().createScreenCapture( region ); + return image; + } + + private static Rectangle getRegion(Component component) { + Dimension d = component.getSize(); + if (d.width == 0 || d.height == 0) { + d = component.getPreferredSize(); + component.setSize( d ); + } + return new Rectangle(0, 0, d.width, d.height); + } + + static void layoutComponent(Component component) { + synchronized (component.getTreeLock()) { + component.doLayout(); + + if (component instanceof Container) { + for (Component child : ((Container)component).getComponents()) { + layoutComponent(child); + } + } + } + } + +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java index f34f8a27f0..798bb73c59 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/FormThemeProfilePane.java @@ -36,46 +36,56 @@ public class FormThemeProfilePane extends TemplateThemeProfilePane { } @Override - protected JPanel createCustomEditorsPane() { - JPanel container = super.createCustomEditorsPane(); - formBodyStyleSettingPane = new FormBodyStyleEditPane(); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane); - - addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); - - - componentStyleSettingPane = new ComponentStyleEditPane(); - addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane); - return container; + public TemplateThemeEditorPane createThemeEditorPane() { + return new FormThemeEditorPane(config); } @Override - protected JPanel createChartStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - chartStyleSettingPane = new ChartStyleFormEditPane(); - container.add(chartStyleSettingPane); - return container; + public String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title"); } - @Override - public void populateBean4CustomEditors(FormTheme theme) { - super.populateBean4CustomEditors(theme); - formBodyStyleSettingPane.populateBean(theme.getBodyStyle()); - componentStyleSettingPane.populateBean(theme.getComponentStyle()); - } + private static class FormThemeEditorPane extends TemplateThemeEditorPane { - @Override - public void updateBean(FormTheme theme) { - ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean(); - theme.setBodyStyle(formBodyStyle); + private final FormBodyStyleEditPane formBodyStyleSettingPane; + private final ComponentStyleEditPane componentStyleSettingPane; - ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean(); - theme.setComponentStyle(componentStyle); - } + public FormThemeEditorPane(TemplateThemeConfig config) { + super(config); + formBodyStyleSettingPane = new FormBodyStyleEditPane(); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Template_Background"), formBodyStyleSettingPane); - @Override - public String title4PopupWindow() { - return Toolkit.i18nText("Fine-Design_Basic_Form_Theme_Profile_Dialog_Title"); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); + + + componentStyleSettingPane = new ComponentStyleEditPane(); + addCustomEditorPane(i18nText("Fine-Design_Predefined_Component_Style"), componentStyleSettingPane); + } + + @Override + protected JPanel createChartStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + chartStyleSettingPane = new ChartStyleFormEditPane(); + container.add(chartStyleSettingPane); + return container; + } + + @Override + protected void populateBean4CustomEditors(FormTheme theme) { + super.populateBean4CustomEditors(theme); + formBodyStyleSettingPane.populateBean(theme.getBodyStyle()); + componentStyleSettingPane.populateBean(theme.getComponentStyle()); + } + + @Override + protected void updateBean4CustomEditors(FormTheme theme) { + super.updateBean4CustomEditors(theme); + ThemedFormBodyStyle formBodyStyle = formBodyStyleSettingPane.updateBean(); + theme.setBodyStyle(formBodyStyle); + + ThemedComponentStyle componentStyle = componentStyleSettingPane.updateBean(); + theme.setComponentStyle(componentStyle); + } } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java index 1158a8eb5d..f0f25f677f 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ReportThemeProfilePane.java @@ -25,28 +25,37 @@ public class ReportThemeProfilePane extends TemplateThemeProfilePane createThemeEditorPane() { + return new ReportThemeEditorPane(config); } @Override public String title4PopupWindow() { return Toolkit.i18nText("Fine-Design_Basic_Report_Theme_Profile_Dialog_Title"); } + + private static class ReportThemeEditorPane extends TemplateThemeEditorPane { + + private final ReportBodyStyleEditPane reportBodyStyleSettingPane; + + public ReportThemeEditorPane(TemplateThemeConfig config) { + super(config); + this.reportBodyStyleSettingPane = new ReportBodyStyleEditPane(); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Template_Background"), reportBodyStyleSettingPane); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Cell_Style"), createCellStyleSettingPane()); + addCustomEditorPane(Toolkit.i18nText("Fine-Design_Predefined_Chart_Style"), createChartStyleSettingPane()); + } + + @Override + public void populateBean4CustomEditors(ReportTheme theme) { + super.populateBean4CustomEditors(theme); + reportBodyStyleSettingPane.populateBean(theme.getBodyStyle()); + } + + @Override + public void updateBean4CustomEditors(ReportTheme theme) { + super.updateBean4CustomEditors(theme); + theme.setBodyStyle(this.reportBodyStyleSettingPane.updateBean()); + } + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java index 543df64eb0..ea649033ea 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeBlock.java @@ -64,6 +64,7 @@ public class TemplateThemeBlock extends JPanel { TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { this.name = name; + this.setName(name); this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker; this.config = config; this.profilePane = profilePane; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java new file mode 100644 index 0000000000..e924080ef6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeEditorPane.java @@ -0,0 +1,301 @@ +package com.fr.design.mainframe.theme; + +import com.fr.base.theme.FineColorFlushUtils; +import com.fr.base.theme.FineColorManager; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.base.theme.settings.ThemedCellStyleList; +import com.fr.base.theme.settings.ThemedColorScheme; +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; +import com.fr.design.gui.frpane.AttributeChangeListener; +import com.fr.design.gui.frpane.UITabbedPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayout; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.theme.edit.CellStyleListEditPane; +import com.fr.design.mainframe.theme.edit.ChartStyleEditPane; +import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane; +import com.fr.design.mainframe.theme.edit.ui.ColorListPane; +import com.fr.design.mainframe.theme.edit.ui.LabelUtils; +import com.fr.design.mainframe.theme.ui.AutoCheckTextField; +import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField; +import com.fr.design.mainframe.theme.ui.BorderUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.util.List; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/8/13 + */ +public abstract class TemplateThemeEditorPane extends JPanel { + public static final int LEFT_TITLE_PANE_HEIGHT = 539; + + public static final int RIGHT_PANE_WIDTH = 362; + public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT; + + protected AutoCheckThemeNameTextField nameTextField; + private UILabel nameErrorLabel; + protected ColorListPane colorListPane; + protected CellStyleListEditPane cellStyleSettingPane; + protected ChartStyleEditPane chartStyleSettingPane; + + protected boolean isPopulating = false; + protected UITabbedPane uiTabbedPane; + + private final TemplateThemeConfig config; + + private boolean refreshingThemedColor = false; + private T theme; + + private AttributeChangeListener changeListener; + private AutoCheckTextField.CheckListener themeNameCheckListener; + + public TemplateThemeEditorPane(TemplateThemeConfig config) { + super(); + this.config = config; + theme = config.createNewTheme(); + initializePane(); + } + + private void initializePane() { + setLayout(new BorderLayout(0, 0)); + setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT)); + JPanel nameEditPane = createNameEditPane(); + add(nameEditPane, BorderLayout.NORTH); + + JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); + settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH); + settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER); + + add(settingPane, BorderLayout.CENTER); + } + + private JPanel createNameEditPane() { + nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); + nameErrorLabel.setVisible(false); + + nameTextField = new AutoCheckThemeNameTextField<>(); + nameTextField.setThemeConfig(config); + nameTextField.setEditable(false); + nameTextField.setEnabled(false); + nameTextField.setPreferredSize(new Dimension(165, 20)); + nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() { + @Override + public void onChecked(String error, boolean valid) { + nameErrorLabel.setVisible(StringUtils.isNotEmpty(error)); + nameErrorLabel.setText(error); + + themeNameCheckListener.onChecked(error, valid); + } + }); + + double p = TableLayout.PREFERRED; + + JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ + new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField }, + new Component[] { null, nameErrorLabel }, + }, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0); + + container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + return container; + } + + private JPanel createColorSchemeEditPane() { + colorListPane = new ColorListPane(); + + double p = TableLayout.PREFERRED; + double[] rowSize = new double[]{p, p, p}; + double[] columnSize = {p, p}; + + JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + colorListContainerPane.add(colorListPane, BorderLayout.WEST); + + UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153)); + + JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ + {LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane}, + {null, tipLabel}, + }, + rowSize, columnSize, 18, 7); + content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + + JPanel borderContainer = new JPanel(new BorderLayout()); + borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title"))); + borderContainer.add(content); + + JPanel container = new JPanel(new BorderLayout()); + container.add(borderContainer, BorderLayout.CENTER); + + colorListPane.addColorChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + if (refreshingThemedColor) { + return; + } + List colors = colorListPane.update(); + refreshingThemedColor = true; + onColorSchemeChanged(colors); + refreshingThemedColor = false; + + fireAttributeChange(); + } + }); + + return container; + } + private void onColorSchemeChanged(List colors) { + FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors); + T theme = updateBean(); + FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme); + FineColorManager.traverse(theme, replaceByColorScheme); + populateBean4CustomEditors(theme); + //图表渐变色 + chartStyleSettingPane.populateGradientBar(colors); + this.repaint(); + } + + protected JPanel createCustomEditorsPane() { + JPanel container = new JPanel(new BorderLayout()); + container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title"))); + + uiTabbedPane = new UITabbedPane(); + uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1)); + container.add(uiTabbedPane, BorderLayout.CENTER); + + return container; + } + + public void addCustomEditorPane(String title, final Component component) { + AbstractAttrNoScrollPane settingPane = new NoBorderAbstractAttrNoScrollPane() { + @Override + protected JPanel createContentPane() { + JPanel contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentPane.add(component, BorderLayout.CENTER); + return contentPane; + } + }; + settingPane.addAttributeChangeListener(new AttributeChangeListener() { + @Override + public void attributeChange() { + fireAttributeChange(); + } + }); + uiTabbedPane.addTab(title, settingPane); + } + protected JPanel createCellStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + cellStyleSettingPane = new CellStyleListEditPane(); + cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() { + @Override + public void attributeChange() { + fireAttributeChange(); + } + }); + container.add(cellStyleSettingPane); + return container; + } + protected JPanel createChartStyleSettingPane() { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + chartStyleSettingPane = new ChartStyleEditPane(); + container.add(chartStyleSettingPane); + return container; + } + + public void populateBean(T theme) { + this.theme = theme; + isPopulating = true; + + String name = theme.getName(); + setThemeNameEditable(StringUtils.isEmpty(name)); + + nameTextField.setText(name); + + colorListPane.populate(theme.getColorScheme().getColors()); + + populateBean4CustomEditors(theme); + isPopulating = false; + } + + protected void populateBean4CustomEditors(T theme) { + cellStyleSettingPane.populateBean(theme.getCellStyleList()); + chartStyleSettingPane.populateBean(theme.getChartStyle()); + } + + public T updateBean() { + if (theme == null) { + theme = config.createNewTheme(); + } + + theme.setName(this.nameTextField.getText()); + + ThemedColorScheme colorScheme = theme.getColorScheme(); + colorScheme.setColors(this.colorListPane.update()); + theme.setColorScheme(colorScheme); + + updateBean4CustomEditors(theme); + + return theme; + } + + protected void updateBean4CustomEditors(T theme) { + ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean(); + theme.setCellStyleList(cellStyleConfig); + + theme.setChartStyle(this.chartStyleSettingPane.updateBean()); + } + + public void setThemeNameEditable(boolean editable) { + nameTextField.setEditable(editable); + nameTextField.setEnabled(editable); + } + + public boolean checkNameValid() { + return nameTextField.checkValid(); + } + + public String getThemeName() { + return nameTextField.getText(); + } + + public List getCurrentColorScheme() { + return colorListPane.update(); + } + + private void fireAttributeChange() { + if (!isPopulating && !refreshingThemedColor && changeListener != null) { + changeListener.attributeChange(); + } + } + + public void addAttributeChangeListener(AttributeChangeListener changeListener) { + this.changeListener = changeListener; + } + public void addThemeNameCheckListener(AutoCheckTextField.CheckListener checkListener) { + this.themeNameCheckListener = checkListener; + } + + private static abstract class NoBorderAbstractAttrNoScrollPane extends AbstractAttrNoScrollPane { + @Override + protected void initContentPane() { + super.initContentPane(); + if (leftContentPane != null) { + // 修正 AbstractAttrNoScrollPane 的默认行为 + leftContentPane.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); + } + } + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java similarity index 91% rename from designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java rename to designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java index be9dec1600..f721923e94 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeManagePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridControlPane.java @@ -51,34 +51,34 @@ import static com.fr.design.i18n.Toolkit.i18nText; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class TemplateThemeManagePane extends BasicPane { - public static final int CONTENT_WIDTH = TemplateThemeListPane.CONTENT_WIDTH + 10; - public static final int CONTENT_HEIGHT = TemplateThemeListPane.CONTENT_HEIGHT + 37; +public class TemplateThemeGridControlPane extends BasicPane { + public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 20; + public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37; private final RemoveThemeAction removeAction; private final UIButton setTheme4NewTemplateButton; private final TemplateThemeConfig config; - private final TemplateThemeListPane themeListPane; + private final TemplateThemeGridPane themeListPane; private final TemplateThemeProfilePane profilePane; private final AsyncThemeFetcher asyncThemeFetcher; - public static TemplateThemeManagePane createFormThemesManagerPane() { + public static TemplateThemeGridControlPane createFormThemesManagerPane() { FormThemeConfig config = FormThemeConfig.getInstance(); FormThemeProfilePane editPane = new FormThemeProfilePane(config); - return new TemplateThemeManagePane<>(config, editPane); + return new TemplateThemeGridControlPane<>(config, editPane); } - public static TemplateThemeManagePane createReportThemesManagerPane() { + public static TemplateThemeGridControlPane createReportThemesManagerPane() { ReportThemeConfig config = ReportThemeConfig.getInstance(); ReportThemeProfilePane editPane = new ReportThemeProfilePane(config); - return new TemplateThemeManagePane<>(config, editPane); + return new TemplateThemeGridControlPane<>(config, editPane); } - public TemplateThemeManagePane(TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { + public TemplateThemeGridControlPane(TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { this.config = config; this.profilePane = profilePane; - this.themeListPane = new TemplateThemeListPane<>(true, config, profilePane); + this.themeListPane = new TemplateThemeGridPane<>(true, config, profilePane); this.removeAction = new RemoveThemeAction(false); this.setTheme4NewTemplateButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Default_Setting")); this.asyncThemeFetcher = new AsyncThemeFetcher<>(1, config); @@ -92,7 +92,7 @@ public class TemplateThemeManagePane extends BasicPane private void initializePane() { setLayout(FRGUIPaneFactory.createBorderLayout()); - setBorder(BorderFactory.createEmptyBorder(5, 5, 0, 5)); + setBorder(BorderFactory.createEmptyBorder(5, 10, 0, 10)); setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); add(createActionsContainer(), BorderLayout.NORTH); @@ -179,7 +179,7 @@ public class TemplateThemeManagePane extends BasicPane @Override public void afterRollback() { super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this), + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); @@ -225,11 +225,11 @@ public class TemplateThemeManagePane extends BasicPane @Override public void actionPerformed(ActionEvent e) { - T theme = TemplateThemeManagePane.this.themeListPane.getSelectedTheme(); + T theme = TemplateThemeGridControlPane.this.themeListPane.getSelectedTheme(); if (theme == null) { return; } - int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this), + int result = FineJOptionPane.showConfirmDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Pane_Delete_Tip", theme.getName()), Toolkit.i18nText("Fine-Design_Basic_Delete"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); if (result == JOptionPane.YES_OPTION) { @@ -237,7 +237,7 @@ public class TemplateThemeManagePane extends BasicPane @Override public void afterRollback() { super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this), + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this), i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), i18nText("Fine-Design_Basic_Alert"), JOptionPane.WARNING_MESSAGE); @@ -269,7 +269,7 @@ public class TemplateThemeManagePane extends BasicPane } private void createNewTheme(T prototypeTheme) { - Window parent = SwingUtilities.getWindowAncestor(TemplateThemeManagePane.this); + Window parent = SwingUtilities.getWindowAncestor(TemplateThemeGridControlPane.this); TemplateThemeProfileDialog profileDialog = new TemplateThemeProfileDialog<>(parent, profilePane); try { T theme = (T) prototypeTheme.clone(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java new file mode 100644 index 0000000000..40838dbd83 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPagesPane.java @@ -0,0 +1,337 @@ +package com.fr.design.mainframe.theme; + +import com.fr.base.ScreenResolution; +import com.fr.base.theme.FormTheme; +import com.fr.base.theme.FormThemeConfig; +import com.fr.base.theme.ReportTheme; +import com.fr.base.theme.ReportThemeConfig; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.dialog.BasicPane; +import com.fr.design.event.ChangeEvent; +import com.fr.design.event.ChangeListener; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.frpane.UITabbedPane; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.theme.dialog.TemplateThemeDialog; +import com.fr.design.mainframe.theme.provider.ThemeManageActionProvider; +import com.fr.design.mainframe.theme.ui.BreadcrumbBar; +import com.fr.stable.ArrayUtils; +import com.fr.stable.unit.FU; +import com.fr.workspace.WorkContext; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.border.CompoundBorder; +import javax.swing.border.LineBorder; +import java.awt.BasicStroke; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; +import java.awt.Stroke; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/10/9 + */ +public class TemplateThemeGridPagesPane extends JPanel { + public static final String COMPLETE_BUTTON = "theme_button_complete"; + private BreadcrumbBar breadcrumbBar; + private JPanel contentPane; + private CardLayout cardLayout; + + private TemplateThemeGridPagePane themeUsingPane; + private TemplateThemeGridPagePane themeManagingPane; + + private PageChangeListener pageChangeListener; + private TemplateThemeGridPagePane currentTemplateThemeGridPagePane; + + public TemplateThemeGridPagesPane() { + initializePane(); + } + + private void initializePane() { + setLayout(new BorderLayout()); + setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + + breadcrumbBar = new BreadcrumbBar(); + breadcrumbBar.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + add(breadcrumbBar, BorderLayout.NORTH); + + contentPane = new JPanel(); + contentPane.setBorder(new CompoundBorder( + new TopLineBorder(new Color(0xE0E0E1), 1), + BorderFactory.createEmptyBorder(10, 0, 0, 0))); + cardLayout = new CardLayout(); + contentPane.setLayout(cardLayout); + add(contentPane, BorderLayout.CENTER); + + + themeUsingPane = new TemplateThemeUsingPane(); + contentPane.add(themeUsingPane, themeUsingPane.getTitle()); + themeManagingPane = new TemplateThemeManagingPane(); + contentPane.add(themeManagingPane, themeManagingPane.getTitle()); + + showThemeUsingPane(); + } + + public void showThemeUsingPane() { + if (currentTemplateThemeGridPagePane != themeUsingPane) { + cardLayout.show(contentPane, themeUsingPane.getTitle()); + currentTemplateThemeGridPagePane = themeUsingPane; + if (pageChangeListener != null) { + pageChangeListener.onPageChangeListener(); + } + breadcrumbBar.clear(); + breadcrumbBar.addCrumb(themeUsingPane.getTitle(), new BreadcrumbBar.BreadcrumbBackListener() { + @Override + public void onBreadcrumbBack(String text) { + cardLayout.show(contentPane, themeUsingPane.getTitle()); + currentTemplateThemeGridPagePane = themeUsingPane; + if (pageChangeListener != null) { + pageChangeListener.onPageChangeListener(); + } + } + }); + } + } + + public void showThemeManagingPane() { + if (currentTemplateThemeGridPagePane != themeManagingPane) { + cardLayout.show(contentPane, themeManagingPane.getTitle()); + currentTemplateThemeGridPagePane = themeManagingPane; + if (pageChangeListener != null) { + pageChangeListener.onPageChangeListener(); + } + breadcrumbBar.addCrumb(themeManagingPane.getTitle(), null); + } + } + + public UIButton[] createLeftButtons() { + UIButton[] buttons = new UIButton[] {}; + if (currentTemplateThemeGridPagePane != themeManagingPane && WorkContext.getCurrent().isRoot()) { + buttons = ArrayUtils.addAll(buttons, createOpenThemeManagerButton()); + } + return buttons; + } + + public UIButton[] createRightButtons() { + UIButton[] buttons = new UIButton[] {}; + buttons = ArrayUtils.addAll(buttons, createExtraButtons()); + buttons = ArrayUtils.addAll(buttons, createCompleteButton()); + return buttons; + } + + private UIButton createOpenThemeManagerButton() { + UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title")); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + showThemeManagingPane(); + } + }); + return button; + } + + private UIButton[] createExtraButtons() { + List uiButtonList = new ArrayList<>(); + + Set providers = ExtraDesignClassManager.getInstance().getArray(ThemeManageActionProvider.MARK_STRING); + for (ThemeManageActionProvider provider : providers) { + uiButtonList.add(provider.createButton(new ThemeManageActionProvider.ThemeManageActionContext() { + + @Override + public TemplateThemeDialog getDialog() { + Container container = getRootPane().getParent(); + if (container instanceof TemplateThemeDialog) { + return (TemplateThemeDialog) container; + } + return null; + } + + @Override + public TemplateThemeConfig getConfig() { + return currentTemplateThemeGridPagePane.getConfig(); + } + })); + } + + return uiButtonList.toArray(new UIButton[]{}); + } + + private UIButton createCompleteButton() { + UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete")); + button.setName(COMPLETE_BUTTON); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Container container = getRootPane().getParent(); + if (container instanceof TemplateThemeDialog) { + ((TemplateThemeDialog) container).exit(); + } + } + }); + return button; + } + + public void exit() { + themeUsingPane.exit(); + themeManagingPane.exit(); + } + + public void setPageChangeListener(PageChangeListener changeListener) { + this.pageChangeListener = changeListener; + } + + public interface PageChangeListener { + void onPageChangeListener(); + } + + public static class TopLineBorder extends LineBorder { + private final FU fu; + + private TopLineBorder(Color color, int thickness) { + super(color, thickness); + fu = FU.getInstance(thickness); + } + + @Override + public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { + Graphics2D g2d = (Graphics2D)g; + + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + g2d.setColor(getLineColor()); + int thickness = Math.max(1, fu.toPixI(ScreenResolution.getScreenResolution())); + g2d.setStroke(new BasicStroke(thickness)); + g2d.drawLine(0, 0, width, thickness); + + g2d.setStroke(oldStroke); + g2d.setColor(oldColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + } + + public abstract static class TemplateThemeGridPagePane extends BasicPane { + public abstract TemplateThemeConfig getConfig(); + + public void exit() { } + } + + public static class TemplateThemeUsingPane extends TemplateThemeGridPagePane { + private final JTemplate template; + public final TemplateThemeGridPane themeListPane; + + public TemplateThemeUsingPane() { + super(); + setLayout(new BorderLayout()); + setBorder(new CompoundBorder( + BorderFactory.createLineBorder(new Color(0xE0E0E1)), + BorderFactory.createEmptyBorder(0, 10, 0, 10))); + + template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); + themeListPane = new TemplateThemeGridPane<>(false, config, null); + + themeListPane.startListenThemeConfig(); + + themeListPane.setSelectedChangeListener(new ChangeListener() { + @Override + public void fireChanged(ChangeEvent event) { + TemplateTheme theme = themeListPane.getSelectedTheme(); + if (theme != null) { + template.setTemplateTheme(theme); + themeListPane.repaint(); + } + } + }); + + add(themeListPane, BorderLayout.CENTER); + } + + @Override + public TemplateThemeConfig getConfig() { + return template.getUsingTemplateThemeConfig(); + } + + @Override + public void exit() { + themeListPane.stopListenThemeConfig(); + themeListPane.stopAsyncFetchTheme(); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"); + } + } + + public static class TemplateThemeManagingPane extends TemplateThemeGridPagePane { + private final UITabbedPane tabbedPane; + private final TemplateThemeGridControlPane formThemesManagerPane; + private final TemplateThemeGridControlPane reportThemesManagerPane; + + public TemplateThemeManagingPane() { + setLayout(FRGUIPaneFactory.createBorderLayout()); + + tabbedPane = new UITabbedPane(); + tabbedPane.setTabBorderColor(new Color(0xE0E0E1)); + add(tabbedPane, BorderLayout.CENTER); + + formThemesManagerPane = TemplateThemeGridControlPane.createFormThemesManagerPane(); + formThemesManagerPane.startListenThemeConfig(); + reportThemesManagerPane = TemplateThemeGridControlPane.createReportThemesManagerPane(); + reportThemesManagerPane.startListenThemeConfig(); + + tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Form_Tab"), formThemesManagerPane); + tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Report_Tab"), reportThemesManagerPane); + + tabbedPane.setSelectedIndex(0); + JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); + if (config == reportThemesManagerPane.getConfig()) { + tabbedPane.setSelectedIndex(1); + } + } + + @Override + public TemplateThemeConfig getConfig() { + if (tabbedPane.getSelectedIndex() == 0) { + return FormThemeConfig.getInstance(); + } else { + return ReportThemeConfig.getInstance(); + } + } + + @Override + public void exit() { + formThemesManagerPane.stopListenThemeConfig(); + formThemesManagerPane.stopAsyncFetchTheme(); + reportThemesManagerPane.stopListenThemeConfig(); + reportThemesManagerPane.stopAsyncFetchTheme(); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java similarity index 89% rename from designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java rename to designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java index fca01386c4..2af4950f53 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeListPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeGridPane.java @@ -2,17 +2,19 @@ package com.fr.design.mainframe.theme; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.TemplateThemeConfig; -import com.fr.base.theme.settings.ThemeThumbnail; import com.fr.design.designer.IntervalConstants; import com.fr.design.dialog.BasicPane; import com.fr.design.event.ChangeEvent; import com.fr.design.event.ChangeListener; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.widget.FRWidgetFactory; +import com.fr.design.widget.WidgetBoundsPaneFactory; import com.fr.stable.StringUtils; import javax.swing.BorderFactory; import javax.swing.JPanel; +import javax.swing.ScrollPaneConstants; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; @@ -27,12 +29,12 @@ import java.util.Map; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class TemplateThemeListPane extends BasicPane { +public class TemplateThemeGridPane extends BasicPane { public static final int BLOCK_COUNT_ROW_LINE = 3; public static final int BLOCK_GAP = IntervalConstants.INTERVAL_L1; public static final int CONTENT_WIDTH = TemplateThemeBlock.CONTENT_WIDTH * BLOCK_COUNT_ROW_LINE + BLOCK_GAP * (BLOCK_COUNT_ROW_LINE - 1) + 10; public static final int BLOCK_ROWS_PER_PAGE = 3; - public static final int CONTENT_HEIGHT = TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1); + public static final int CONTENT_HEIGHT = Math.min(527, TemplateThemeBlock.CONTENT_HEIGHT * BLOCK_ROWS_PER_PAGE + BLOCK_GAP * (BLOCK_ROWS_PER_PAGE + 1)); public static final int ASYNC_FETCH_THEME_THREAD_COUNT = 10; private final AsyncThemeFetcher asyncThemeFetcher; @@ -51,7 +53,7 @@ public class TemplateThemeListPane extends BasicPane { private ChangeListener changeListener; - public TemplateThemeListPane(boolean displayTheme4NewTemplateMarker, TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { + public TemplateThemeGridPane(boolean displayTheme4NewTemplateMarker, TemplateThemeConfig config, TemplateThemeProfilePane profilePane) { this.displayTheme4NewTemplateMarker = displayTheme4NewTemplateMarker; this.config = config; this.profilePane = profilePane; @@ -64,14 +66,19 @@ public class TemplateThemeListPane extends BasicPane { setLayout(FRGUIPaneFactory.createBorderLayout()); setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); - contentListPane.setBorder(BorderFactory.createEmptyBorder(BLOCK_GAP, 0, BLOCK_GAP, 0)); + contentListPane.setBorder(BorderFactory.createEmptyBorder(BLOCK_GAP, 0, BLOCK_GAP, 10)); contentListPane.setLayout(new GridLayout(0, BLOCK_COUNT_ROW_LINE, BLOCK_GAP, BLOCK_GAP)); fillContentListPane(); - JPanel wrapper = FRGUIPaneFactory.createBorderLayout_S_Pane(); - wrapper.add(contentListPane, BorderLayout.NORTH); + JPanel wrapper1 = FRGUIPaneFactory.createBorderLayout_S_Pane(); + wrapper1.add(contentListPane, BorderLayout.NORTH); + JPanel wrapper2 = FRGUIPaneFactory.createBorderLayout_S_Pane(); + wrapper2.add(wrapper1, BorderLayout.WEST); - UIScrollPane scrollPane = new UIScrollPane(wrapper); + UIScrollPane scrollPane = new UIScrollPane(wrapper2); + scrollPane.setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); + scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED); scrollPane.setBorder(BorderFactory.createEmptyBorder()); add(scrollPane, BorderLayout.CENTER); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java index 19885763cc..c302cf1ad8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemePreviewPane.java @@ -48,9 +48,6 @@ public abstract class TemplateThemePreviewPane extends int height = getHeight(); try { - // 使用TYPE_INT_RGB和new Color(255, 255, 255, 1)设置有透明背景buffer image, - // 使得创建出来的透明像素是(255, 255, 255, 1),而不是(0, 0, 0, 0) - // 这样不支持透明通道缩略图的旧设计器打开新设计器创建的模版时,就不会创建出拥有黑色背景的缩略图 image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = image.createGraphics(); // 创建一个支持透明背景的buffer image @@ -58,8 +55,6 @@ public abstract class TemplateThemePreviewPane extends g2d.dispose(); g2d = image.createGraphics(); - g2d.fillRect(0, 0, width, height); - g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,RenderingHints.VALUE_TEXT_ANTIALIAS_ON); g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2d.clipRect(0, 0, width, height); @@ -80,6 +75,9 @@ public abstract class TemplateThemePreviewPane extends @Override public void paintComponent(Graphics g) { g.clearRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); + // 添加个默认白色,否则因为上面的clearRect导致无背景时会出现黑色 + g.setColor(Color.WHITE); + g.fillRect(0, 0, PREVIEW_WIDTH, PREVIEW_HEIGHT); paintBackground((Graphics2D) g); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java index aef2959e35..bc787bb18b 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/TemplateThemeProfilePane.java @@ -1,62 +1,39 @@ package com.fr.design.mainframe.theme; -import com.fr.base.theme.FineColorFlushUtils; -import com.fr.base.theme.FineColorManager; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.TemplateThemeConfig; import com.fr.base.theme.settings.ThemeThumbnail; -import com.fr.base.theme.settings.ThemedCellStyleList; -import com.fr.base.theme.settings.ThemedChartStyle; -import com.fr.base.theme.settings.ThemedColorScheme; -import com.fr.design.designer.IntervalConstants; +import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.FineJOptionPane; -import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; import com.fr.design.gui.frpane.AttributeChangeListener; -import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.itextfield.UITextField; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.theme.dialog.TemplateThemeProfileDialog; -import com.fr.design.mainframe.theme.edit.CellStyleListEditPane; -import com.fr.design.mainframe.theme.edit.ChartStyleEditPane; -import com.fr.design.mainframe.theme.edit.ui.ColorListExtendedPane; -import com.fr.design.mainframe.theme.edit.ui.ColorListPane; import com.fr.design.mainframe.theme.edit.ui.LabelUtils; +import com.fr.design.mainframe.theme.ui.AutoCheckTextField; +import com.fr.design.mainframe.theme.ui.AutoCheckThemeNameTextField; import com.fr.design.mainframe.theme.ui.BorderUtils; +import com.fr.design.mainframe.toast.DesignerToastMsgUtil; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.general.Inter; import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; import com.fr.transaction.CallBackAdaptor; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; import javax.swing.BorderFactory; -import javax.swing.JComponent; import javax.swing.JDialog; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Component; import java.awt.Dimension; import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; -import java.util.List; import static com.fr.design.i18n.Toolkit.i18nText; @@ -65,71 +42,37 @@ import static com.fr.design.i18n.Toolkit.i18nText; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public abstract class TemplateThemeProfilePane extends AbstractAttrNoScrollPane { +public abstract class TemplateThemeProfilePane extends BasicPane { public static final int TITLE_BORDER_FONT = 12; public static final int LEFT_TITLE_PANE_WIDTH = 627; public static final int LEFT_TITLE_PANE_HEIGHT = 539; public static final int PREVIEW_PANE_WIDTH = LEFT_TITLE_PANE_WIDTH - 10; public static final int PREVIEW_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT - TITLE_BORDER_FONT - 16; - public static final int RIGHT_PANE_WIDTH = 362; - public static final int RIGHT_PANE_HEIGHT = LEFT_TITLE_PANE_HEIGHT; - public static final int COLOR_SCHEME_TITLE_PANE_WIDTH = 298; - public static final int COLOR_SCHEME_TITLE_PANE_HEIGHT = 174 + TITLE_BORDER_FONT / 2; - protected TemplateThemePreviewPane themePreviewPane; - - protected UITextField nameTextField; - private UILabel nameErrorLabel; - protected ColorListPane colorListPane; - private ColorListExtendedPane colorListExtendedPane; - protected CellStyleListEditPane cellStyleSettingPane; - protected ChartStyleEditPane chartStyleSettingPane; + protected TemplateThemeEditorPane themeEditorPane; protected boolean isPopulating = false; - protected UITabbedPane uiTabbedPane; + protected boolean isMutable = false; - private final TemplateThemeConfig config; + protected final TemplateThemeConfig config; private UIButton saveButton = new UIButton(); private UIButton saveAsButton = new UIButton(); - private boolean refreshingThemedColor = false; - - private boolean currentIsNewTheme; - private T theme; + private TemplateThemeProfileActionListener actionListener = new TemplateThemeProfileActionAdapter(); public TemplateThemeProfilePane(TemplateThemeConfig config) { + super(); this.config = config; - theme = config.createNewTheme(); - } - @Override - protected JPanel createContentPane() { - JPanel container = new JPanel(new BorderLayout(5, 0)); - container.add(createLeftPane(), BorderLayout.CENTER); - container.add(createRightPane(), BorderLayout.EAST); - addAttributeChangeListener(new AttributeChangeListener() { - @Override - public void attributeChange() { - if (!isPopulating && !refreshingThemedColor) { - valueChangeAction(); - } - } - }); - return container; + initializePane(); } - @Override - protected void initContentPane() { - super.initContentPane(); - if (leftContentPane != null) { - // 修正 AbstractAttrNoScrollPane 的默认行为 - leftContentPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6)); - } - } - - public void valueChangeAction() { - themePreviewPane.refresh(updateBean()); + private void initializePane() { + setLayout(new BorderLayout(5, 0)); + setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 6)); + add(createLeftPane(), BorderLayout.CENTER); + add(createRightPane(), BorderLayout.EAST); } @Override @@ -153,220 +96,58 @@ public abstract class TemplateThemeProfilePane extends return titleContainer; } private JPanel createRightPane() { - JPanel container = new JPanel(new BorderLayout(0, 0)); - container.setPreferredSize(new Dimension(RIGHT_PANE_WIDTH, RIGHT_PANE_HEIGHT)); - JPanel nameEditPane = createNameEditPane(); - container.add(nameEditPane, BorderLayout.NORTH); - - JPanel settingPane = new JPanel(new BorderLayout(0, IntervalConstants.INTERVAL_L1)); - container.add(settingPane, BorderLayout.CENTER); - settingPane.add(createColorSchemeEditPane(), BorderLayout.NORTH); - settingPane.add(createCustomEditorsPane(), BorderLayout.CENTER); - - uiTabbedPane.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - valueChangeAction(); - } - }); - - return container; - } - - private JPanel createNameEditPane() { - nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); - nameErrorLabel.setVisible(false); - - nameTextField = new UITextField(); - nameTextField.setEnabled(false); - nameTextField.setPreferredSize(new Dimension(165, 20)); - nameTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - - @Override - public void removeUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - - @Override - public void changedUpdate(DocumentEvent e) { - - } - }); - nameTextField.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, false, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - } - } - + themeEditorPane = createThemeEditorPane(); + themeEditorPane.addAttributeChangeListener(new AttributeChangeListener() { @Override - public void focusLost(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); + public void attributeChange() { + if (isPopulating) { + return; } + themePreviewPane.refresh(updateBean()); + saveButton.setEnabled(themeEditorPane.checkNameValid() && isMutable); } }); - - double p = TableLayout.PREFERRED; - - JPanel container = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{ - new Component[] { LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Name")), nameTextField }, - new Component[] { null, nameErrorLabel }, - }, new double[] { 20, 20}, new double[] { p, 165}, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_W0); - - container.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); - return container; - } - private JPanel createColorSchemeEditPane() { - colorListPane = new ColorListPane(); - colorListExtendedPane = new ColorListExtendedPane(); - - JPanel extendedContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); - colorListExtendedPane.setBackground(null); - colorListExtendedPane.setOpaque(false); - extendedContainer.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); - extendedContainer.setBackground(Color.WHITE); - extendedContainer.add(colorListExtendedPane); - - double p = TableLayout.PREFERRED; - double[] rowSize = new double[]{p, p, p}; - double[] columnSize = {p, p}; - - JPanel colorListContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - colorListContainerPane.add(colorListPane, BorderLayout.WEST); - - JPanel previewLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - previewLabelPane.add(LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Preview_Label")), BorderLayout.NORTH); - - UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Tip"), new Color(153, 153, 153)); - tipLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); - - JPanel content = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ - {LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Edit_Label")), colorListContainerPane}, - {null, tipLabel}, - {previewLabelPane, extendedContainer}, - }, - rowSize, columnSize, 18, 7); - content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - - JPanel borderContainer = new JPanel(new BorderLayout()); - borderContainer.setPreferredSize(new Dimension(COLOR_SCHEME_TITLE_PANE_WIDTH, COLOR_SCHEME_TITLE_PANE_HEIGHT)); - borderContainer.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Color_Scheme_Title"))); - borderContainer.add(content); - - JPanel container = new JPanel(new BorderLayout()); - container.add(borderContainer, BorderLayout.WEST); - - colorListPane.addColorChangeListener(new ChangeListener() { + themeEditorPane.addThemeNameCheckListener(new AutoCheckTextField.CheckListener() { @Override - public void stateChanged(ChangeEvent e) { - if (refreshingThemedColor) { + public void onChecked(String error, boolean valid) { + if (isPopulating) { return; } - List colors = colorListPane.update(); - refreshingThemedColor = true; - onColorSchemeChanged(colors); - refreshingThemedColor = false; + saveButton.setEnabled(valid && isMutable); + actionListener.onThemeNameChecked(themeEditorPane.getThemeName(), valid); } }); - return container; + return themeEditorPane; } - protected JPanel createCustomEditorsPane() { - JPanel container = new JPanel(new BorderLayout()); - container.setBorder(BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Custom_Settings_Title"))); - uiTabbedPane = new UITabbedPane(); - uiTabbedPane.setBorder(BorderFactory.createEmptyBorder(10, 5, 10, 1)); - container.add(uiTabbedPane, BorderLayout.NORTH); + public abstract TemplateThemePreviewPane createThemePreviewPane(); + public abstract TemplateThemeEditorPane createThemeEditorPane(); - return container; - } - public void addCustomEditorPane(String title, JComponent component) { - component.setPreferredSize(new Dimension(317, 239)); - uiTabbedPane.addTab(title, component); - } - protected JPanel createCellStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - cellStyleSettingPane = new CellStyleListEditPane(); - cellStyleSettingPane.registerAttrChangeListener(new AttributeChangeListener() { - @Override - public void attributeChange() { - valueChangeAction(); - } - }); - container.add(cellStyleSettingPane); - return container; - } - protected JPanel createChartStyleSettingPane() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - chartStyleSettingPane = new ChartStyleEditPane(); - container.add(chartStyleSettingPane); - return container; - } + public void populateBean(T theme) { + isPopulating = true; - public abstract TemplateThemePreviewPane createThemePreviewPane(); + isMutable = theme.isMutable(); - public void onColorSchemeChanged(List colors) { - colorListExtendedPane.populate(colors); - FineColorManager.FineColorReplaceByColorScheme replaceByColorScheme = new FineColorManager.FineColorReplaceByColorScheme(colors); - T theme = updateBean(); - FineColorFlushUtils.replaceCacheObject(theme, replaceByColorScheme); - FineColorManager.traverse(theme, replaceByColorScheme); - populateBean4CustomEditors(theme); - //图表渐变色 - chartStyleSettingPane.populateGradientBar(colors); + themeEditorPane.populateBean(theme); themePreviewPane.refresh(theme); - this.repaint(); - } - - public void populateBean(T theme) { - this.theme = theme; - isPopulating = true; String name = theme.getName(); - currentIsNewTheme = config.cachedFetch(name) == null; - - nameTextField.setText(name); - nameTextField.setEnabled(StringUtils.isEmpty(name)); if (saveButton != null) { - saveButton.setEnabled(theme.isMutable() && !currentIsNewTheme); + saveButton.setEnabled(isMutable); } if (saveAsButton != null) { - saveAsButton.setEnabled(!currentIsNewTheme); + saveAsButton.setEnabled(StringUtils.isNotEmpty(name)); } + actionListener.onInitialize(theme); - colorListPane.populate(theme.getColorScheme().getColors()); - colorListExtendedPane.populate(colorListPane.update()); - - populateBean4CustomEditors(theme); - - themePreviewPane.refresh(theme); isPopulating = false; } - protected void populateBean4CustomEditors(T theme) { - cellStyleSettingPane.populateBean(theme.getCellStyleList()); - chartStyleSettingPane.populateBean(theme.getChartStyle()); - } - public T updateBean() { - if (theme == null) { - theme = config.createNewTheme(); - } - - theme.setName(this.nameTextField.getText()); + T theme = themeEditorPane.updateBean(); Image thumbnailImage = themePreviewPane.createThumbnailImage(); if (thumbnailImage != null) { @@ -375,24 +156,55 @@ public abstract class TemplateThemeProfilePane extends theme.setThumbnail(thumbnail); } - ThemedCellStyleList cellStyleConfig = this.cellStyleSettingPane.updateBean(); - theme.setCellStyleList(cellStyleConfig); - - ThemedColorScheme colorScheme = theme.getColorScheme(); - colorScheme.setColors(this.colorListPane.update()); - theme.setColorScheme(colorScheme); - - theme.setChartStyle(this.chartStyleSettingPane.updateBean()); - - updateBean(theme); return theme; } - public List getCurrentColorScheme() { - return colorListPane.update(); + public TemplateThemeEditorPane getThemeEditorPane() { + return themeEditorPane; + } + + public void save(CallBackAdaptor callBack) { + T theme; + try { + theme = (T) updateBean().clone(); + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + return; + } + save(theme, callBack); + } + public void save(String name, CallBackAdaptor callBack) { + T theme = null; + try { + theme = (T) updateBean().clone(); + } catch (CloneNotSupportedException ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + return; + } + theme.setName(name); + save(theme, callBack); } + private void save(T theme, CallBackAdaptor callBack) { + theme.setRemovable(true); + theme.setMutable(true); + config.addTheme(theme, true, new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + themeEditorPane.setThemeNameEditable(false); + callBack.afterCommit(); + } - protected abstract void updateBean(T theme); + @Override + public void afterRollback() { + super.afterRollback(); + FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), + i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), + i18nText("Fine-Design_Basic_Alert"), + JOptionPane.WARNING_MESSAGE); + } + }); + } public UIButton createSaveButton() { saveButton = new UIButton(); @@ -401,29 +213,16 @@ public abstract class TemplateThemeProfilePane extends saveButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - T theme = updateBean(); - boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(currentIsNewTheme, true, currentIsNewTheme, true, nameTextField, nameErrorLabel, saveButton); - if (canBeSaved && theme != null) { - theme.setName(nameTextField.getText()); - config.addTheme(theme, true, new CallBackAdaptor() { - @Override - public void afterCommit() { - super.afterCommit(); - currentIsNewTheme = false; - nameTextField.setEnabled(false); - saveAsButton.setEnabled(true); - } - - @Override - public void afterRollback() { - super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), - i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), - i18nText("Fine-Design_Basic_Alert"), - JOptionPane.WARNING_MESSAGE); - } - }); - } + save(new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + saveButton.setEnabled(false); + saveAsButton.setEnabled(true); + actionListener.onSaved(config.cachedFetch(getName())); + DesignerToastMsgUtil.toastPrompt(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Save_Successfully")); + } + }); } }); return saveButton; @@ -444,7 +243,7 @@ public abstract class TemplateThemeProfilePane extends private class SaveAsDialog extends JDialog { private final TemplateThemeProfileDialog parent; - private UITextField nameTextField; + private AutoCheckThemeNameTextField nameTextField; private UILabel nameErrorLabel; private UIButton confirmButton; @@ -470,6 +269,18 @@ public abstract class TemplateThemeProfilePane extends } private void initializeComponents() { + nameTextField = new AutoCheckThemeNameTextField<>(); + nameTextField.setThemeConfig(config); + nameTextField.setPreferredSize(new Dimension(180, 20)); + nameTextField.setNameCheckListener(new AutoCheckTextField.CheckListener() { + @Override + public void onChecked(String error, boolean valid) { + nameErrorLabel.setVisible(StringUtils.isNotEmpty(error)); + nameErrorLabel.setText(error); + confirmButton.setEnabled(valid); + } + }); + nameErrorLabel = LabelUtils.createLabel(StringUtils.EMPTY, Color.RED); nameErrorLabel.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 0)); @@ -478,47 +289,16 @@ public abstract class TemplateThemeProfilePane extends confirmButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - saveAsNew(nameTextField.getText()); - } - }); - - nameTextField = new UITextField(); - nameTextField.getDocument().addDocumentListener(new DocumentListener() { - @Override - public void insertUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void removeUpdate(DocumentEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void changedUpdate(DocumentEvent e) { - - } - }); - nameTextField.addFocusListener(new FocusAdapter() { - @Override - public void focusGained(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, false, true, true, nameTextField, nameErrorLabel, confirmButton); - } - } - - @Override - public void focusLost(FocusEvent e) { - if (isEnabled()) { - checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton); - } + save(nameTextField.getText(), new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + exit(); + parent.exit(); + } + }); } }); - nameTextField.setPreferredSize(new Dimension(180, 20)); } private JPanel createActionsContainer() { @@ -552,82 +332,33 @@ public abstract class TemplateThemeProfilePane extends return container; } - private void saveAsNew(String name) { - T newThemeObject = null; - try { - newThemeObject = (T) updateBean().clone(); - } catch (CloneNotSupportedException ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - return; - } - boolean canBeSaved = checkThemeCanBeSavedAndUpdateUI(true, true, true, true, nameTextField, nameErrorLabel, confirmButton); - if (canBeSaved && newThemeObject != null) { - newThemeObject.setName(name); - newThemeObject.setRemovable(true); - newThemeObject.setMutable(true); - config.addTheme(newThemeObject, true, new CallBackAdaptor() { - @Override - public void afterCommit() { - super.afterCommit(); - exit(); - parent.exit(); - } - - @Override - public void afterRollback() { - super.afterRollback(); - FineJOptionPane.showMessageDialog(SwingUtilities.getWindowAncestor(TemplateThemeProfilePane.this), - i18nText("Fine-Design_Basic_Template_Theme_Operation_Failed_Tip"), - i18nText("Fine-Design_Basic_Alert"), - JOptionPane.WARNING_MESSAGE); - } - }); - } - } - public void exit() { this.dispose(); } } - private boolean isThemeNameEmpty(String name) { - return StringUtils.isEmpty(name); + public void addProfileActionListener(TemplateThemeProfileActionListener actionListener) { + if (actionListener != null) { + this.actionListener = actionListener; + } } - private boolean isThemeNameDuplicated(String name) { - return config.cachedFetch(name) != null; + public interface TemplateThemeProfileActionListener { + + void onInitialize(TemplateTheme theme); + + void onThemeNameChecked(String name, boolean valid); + + void onSaved(TemplateTheme theme); } - private boolean checkThemeCanBeSavedAndUpdateUI( - boolean checkEmpty, - boolean displayEmptyTip, - boolean checkDuplicated, - boolean displayDuplicatedTip, - UITextField textField, - UILabel errorLabel, UIButton... actionButtons) { - String name = textField.getText(); - - boolean valid = true; - errorLabel.setText(StringUtils.EMPTY); - if (checkEmpty && isThemeNameEmpty(name)) { - valid = false; - if (displayEmptyTip) { - errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip")); - } - } else if (checkDuplicated && isThemeNameDuplicated(name)) { - valid = false; - if (displayDuplicatedTip) { - errorLabel.setText(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip")); - } - } + public static class TemplateThemeProfileActionAdapter implements TemplateThemeProfileActionListener { - errorLabel.setVisible(!valid); - if (actionButtons != null && actionButtons.length > 0) { - for (UIButton button : actionButtons) { - if (button != null) { - button.setEnabled(valid); - } - } - } + @Override + public void onInitialize(TemplateTheme theme) {} + + @Override + public void onThemeNameChecked(String name, boolean valid) { } - return valid; + @Override + public void onSaved(TemplateTheme theme) {} } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java index ed2e22d29b..875cc6bae6 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeDialog.java @@ -26,6 +26,9 @@ public abstract class TemplateThemeDialog extends JDialog { public static final int DIALOG_BOTTOM_ACTION_BUTTON_GAP = 10; public static final int DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT = 20; + private final JPanel contentContainer; + private final JPanel actionContainer; + public TemplateThemeDialog(Window parent, String title, int contentWidth, int contentHeight) { super(parent, ModalityType.APPLICATION_MODAL); @@ -44,25 +47,45 @@ public abstract class TemplateThemeDialog extends JDialog { } }); GUICoreUtils.centerWindow(this); + + contentContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + actionContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + contentContainer.add(actionContainer, BorderLayout.SOUTH); + setContentPane(contentContainer); } - protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] rightButtons) { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.add(contentPane, BorderLayout.CENTER); - container.add(createActionsContainer(rightButtons), BorderLayout.SOUTH); - return container; + protected void setupContentPane() { + contentContainer.add(createContentPane(), BorderLayout.CENTER, 0); } - protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] leftButtons, UIButton[] rightButtons) { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.add(contentPane, BorderLayout.CENTER); - container.add(createActionsContainer(leftButtons, rightButtons), BorderLayout.SOUTH); - return container; + protected JPanel createContentPane() { + return new JPanel(); } + protected UIButton[] createLeftButtons() { + return new UIButton[] {}; + } + protected UIButton[] createRightButtons() { + return new UIButton[] {}; + } - private JPanel createActionsContainer(UIButton... buttons) { - return this.createActionsContainer(FlowLayout.RIGHT, buttons); + public void setupActionButtons() { + JPanel leftPane = createActionsContainer(FlowLayout.LEFT, createLeftButtons()); + JPanel rightPane = createActionsContainer(FlowLayout.RIGHT, createRightButtons()); + + actionContainer.removeAll(); + actionContainer.add(leftPane, BorderLayout.WEST); + actionContainer.add(rightPane, BorderLayout.EAST); + + actionContainer.invalidate(); + actionContainer.repaint(); + } + + protected final JPanel createDialogContentPane(JPanel contentPane, UIButton[] rightButtons) { + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(contentPane, BorderLayout.CENTER); + container.add(createRightActionsContainer(rightButtons), BorderLayout.SOUTH); + return container; } private JPanel createActionsContainer(int align, UIButton... buttons) { @@ -84,21 +107,12 @@ public abstract class TemplateThemeDialog extends JDialog { return container; } - protected int getPaddingVertical(){ - return (DIALOG_BOTTOM_ACTION_BAR_HEIGHT - DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT) / 2; + private JPanel createRightActionsContainer(UIButton... buttons) { + return createActionsContainer(FlowLayout.RIGHT, buttons); } - - - private JPanel createActionsContainer(UIButton[] leftButtons, UIButton[] rightButtons) { - JPanel leftPane = createActionsContainer(FlowLayout.LEFT, leftButtons); - JPanel rightPane = createActionsContainer(FlowLayout.RIGHT, rightButtons); - - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.add(leftPane, BorderLayout.WEST); - container.add(rightPane, BorderLayout.EAST); - - return container; + private int getPaddingVertical(){ + return (DIALOG_BOTTOM_ACTION_BAR_HEIGHT - DIALOG_BOTTOM_ACTION_BUTTON_HEIGHT) / 2; } public void exit() { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java new file mode 100644 index 0000000000..917f078d52 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeGridPagesDialog.java @@ -0,0 +1,56 @@ +package com.fr.design.mainframe.theme.dialog; + +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.theme.TemplateThemeGridPagesPane; +import com.fr.design.mainframe.theme.TemplateThemeGridPane; + +import javax.swing.JPanel; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/8/13 + */ +public class TemplateThemeGridPagesDialog extends TemplateThemeDialog implements TemplateThemeGridPagesPane.PageChangeListener { + public static final int CONTENT_WIDTH = TemplateThemeGridPane.CONTENT_WIDTH + 48; + public static final int CONTENT_HEIGHT = TemplateThemeGridPane.CONTENT_HEIGHT + 37; + + protected TemplateThemeGridPagesPane overallPane; + + public TemplateThemeGridPagesDialog() { + super(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); + + setupContentPane(); + setupActionButtons(); + } + + @Override + protected JPanel createContentPane() { + overallPane = new TemplateThemeGridPagesPane(); + overallPane.setPageChangeListener(this); + return overallPane; + } + + @Override + protected UIButton[] createLeftButtons() { + return overallPane.createLeftButtons(); + } + + @Override + protected UIButton[] createRightButtons() { + return overallPane.createRightButtons(); + } + + @Override + public void exit() { + overallPane.exit(); + super.exit(); + } + + @Override + public void onPageChangeListener() { + setupActionButtons(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java index 0049092a01..93e5b09e60 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeManageDialog.java @@ -12,8 +12,9 @@ import com.fr.design.gui.frpane.UITabbedPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; -import com.fr.design.mainframe.theme.TemplateThemeManagePane; +import com.fr.design.mainframe.theme.TemplateThemeGridControlPane; import com.fr.design.mainframe.theme.provider.ThemeManageActionProvider; import javax.swing.BorderFactory; @@ -32,106 +33,10 @@ import java.util.Set; * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class TemplateThemeManageDialog extends TemplateThemeDialog { +public class TemplateThemeManageDialog extends TemplateThemeGridPagesDialog { - private final TemplateThemeManageDialogContentPane contentPane; - - public TemplateThemeManageDialog(Window parent) { - super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title"), - TemplateThemeManageDialogContentPane.CONTENT_WIDTH, TemplateThemeManageDialogContentPane.CONTENT_HEIGHT); - contentPane = new TemplateThemeManageDialogContentPane(); - - setContentPane(createDialogContentPane(contentPane, createActionButtons())); - } - - @Override - public void exit(){ - contentPane.exit(); - super.exit(); - } - - private UIButton[] createActionButtons() { - List uiButtonList = new ArrayList<>(); - - Set providers = ExtraDesignClassManager.getInstance().getArray(ThemeManageActionProvider.MARK_STRING); - for (ThemeManageActionProvider provider : providers) { - uiButtonList.add(provider.createButton(new ThemeManageActionProvider.ThemeManageActionContext() { - - @Override - public TemplateThemeDialog getDialog() { - return TemplateThemeManageDialog.this; - } - - @Override - public TemplateThemeConfig getConfig() { - return contentPane.getConfig(); - } - })); - } - - uiButtonList.add(createCompleteButton()); - - return uiButtonList.toArray(new UIButton[]{}); - } - - private UIButton createCompleteButton() { - UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Complete")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - exit(); - } - }); - return button; - } - - public static class TemplateThemeManageDialogContentPane extends JPanel { - public static final int CONTENT_WIDTH = TemplateThemeManagePane.CONTENT_WIDTH + 24; - public static final int CONTENT_HEIGHT = TemplateThemeManagePane.CONTENT_HEIGHT + 40; - - private final UITabbedPane tabbedPane; - private final TemplateThemeManagePane formThemesManagerPane; - private final TemplateThemeManagePane reportThemesManagerPane; - - public TemplateThemeManageDialogContentPane() { - setLayout(FRGUIPaneFactory.createBorderLayout()); - setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); - setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); - - tabbedPane = new UITabbedPane(); - add(tabbedPane, BorderLayout.NORTH); - - formThemesManagerPane = TemplateThemeManagePane.createFormThemesManagerPane(); - formThemesManagerPane.startListenThemeConfig(); - reportThemesManagerPane = TemplateThemeManagePane.createReportThemesManagerPane(); - reportThemesManagerPane.startListenThemeConfig(); - - tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Form_Tab"), formThemesManagerPane); - tabbedPane.addTab(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Report_Tab"), reportThemesManagerPane); - - tabbedPane.setSelectedIndex(0); - JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (template != null) { - TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); - if (config == reportThemesManagerPane.getConfig()) { - tabbedPane.setSelectedIndex(1); - } - } - } - - public TemplateThemeConfig getConfig() { - if (tabbedPane.getSelectedIndex() == 0) { - return FormThemeConfig.getInstance(); - } else { - return ReportThemeConfig.getInstance(); - } - } - - public void exit() { - formThemesManagerPane.stopListenThemeConfig(); - formThemesManagerPane.stopAsyncFetchTheme(); - reportThemesManagerPane.stopListenThemeConfig(); - reportThemesManagerPane.stopAsyncFetchTheme(); - } + public TemplateThemeManageDialog() { + super(); + overallPane.showThemeManagingPane(); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java index 3a6a9d3838..a76597f8e8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeProfileDialog.java @@ -25,22 +25,33 @@ import java.util.Set; * Created by Starryi on 2021/8/13 */ public class TemplateThemeProfileDialog extends TemplateThemeDialog { - private static final int PADDING_VERTICAL = 4; public static TemplateThemeProfilePane currentVisibleProfilePane; public static final int CONTENT_WIDTH = 1010; public static final int CONTENT_HEIGHT = 542; + private final TemplateThemeProfilePane profilePane; public TemplateThemeProfileDialog(Window parent, TemplateThemeProfilePane profilePane) { super(parent, profilePane.getTitle(), CONTENT_WIDTH, CONTENT_HEIGHT); + this.profilePane = profilePane; + TemplateThemeProfileDialog.currentVisibleProfilePane = profilePane; + + setupContentPane(); + setupActionButtons(); + } + + @Override + protected JPanel createContentPane() { JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); content.setPreferredSize(new Dimension(CONTENT_WIDTH, CONTENT_HEIGHT)); content.add(profilePane, BorderLayout.CENTER); + return content; + } - setContentPane(createDialogContentPane(content, createActionButtons(profilePane))); - - currentVisibleProfilePane = profilePane; + @Override + protected UIButton[] createRightButtons() { + return createActionButtons(profilePane); } @Override @@ -51,7 +62,7 @@ public class TemplateThemeProfileDialog extends Templat public static List getEditingColorScheme() { if (currentVisibleProfilePane != null) { - return currentVisibleProfilePane.getCurrentColorScheme(); + return currentVisibleProfilePane.getThemeEditorPane().getCurrentColorScheme(); } return null; } @@ -60,10 +71,6 @@ public class TemplateThemeProfileDialog extends Templat return currentVisibleProfilePane != null; } - protected int getPaddingVertical(){ - return PADDING_VERTICAL; - } - private UIButton[] createActionButtons(final TemplateThemeProfilePane profilePane) { List uiButtonList = new ArrayList<>(); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java index 9c9f9220e4..420a7ed439 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/dialog/TemplateThemeUsingDialog.java @@ -1,111 +1,13 @@ package com.fr.design.mainframe.theme.dialog; -import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.TemplateThemeConfig; -import com.fr.base.theme.ThemedTemplate; -import com.fr.design.event.ChangeEvent; -import com.fr.design.event.ChangeListener; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.mainframe.theme.TemplateThemeListPane; -import com.fr.design.mainframe.theme.ui.BorderUtils; -import com.fr.workspace.WorkContext; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import javax.swing.border.CompoundBorder; -import java.awt.BorderLayout; -import java.awt.Window; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - /** * @author Starryi * @version 1.0 * Created by Starryi on 2021/8/13 */ -public class -TemplateThemeUsingDialog extends TemplateThemeDialog { - public static final int CONTENT_WIDTH = TemplateThemeListPane.CONTENT_WIDTH + 42; - public static final int CONTENT_HEIGHT = TemplateThemeListPane.CONTENT_HEIGHT + 23; - - private final TemplateThemeListPane themeListPane; - private final ThemedTemplate currentTemplate; - - public TemplateThemeUsingDialog(Window parent, ThemedTemplate template, TemplateThemeConfig config) { - super(parent, Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Title"), CONTENT_WIDTH, CONTENT_HEIGHT); - - this.currentTemplate = template; - this.themeListPane = new TemplateThemeListPane<>(false, config, null); - - JPanel content = createContent(); - UIButton openThemeManagerButton = createOpenThemeManagerButton(); - UIButton completeButton = createCompleteButton(); - - setContentPane(createDialogContentPane(content, - new UIButton[]{ openThemeManagerButton }, - new UIButton[]{ completeButton } - )); - - themeListPane.startListenThemeConfig(); - - themeListPane.setSelectedChangeListener(new ChangeListener() { - @Override - public void fireChanged(ChangeEvent event) { - TemplateTheme theme = themeListPane.getSelectedTheme(); - if (theme != null) { - currentTemplate.setTemplateTheme(theme); - themeListPane.repaint(); - } - } - }); - } - - private JPanel createContent() { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); - - JPanel themeListPaneContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); - themeListPaneContainer.setBorder(new CompoundBorder( - BorderUtils.createTitleBorder(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Select"), 12), - BorderFactory.createEmptyBorder(0, 10, 0, 10) - )); - themeListPaneContainer.add(themeListPane, BorderLayout.CENTER); - container.add(themeListPaneContainer, BorderLayout.CENTER); - - return container; - } - - private UIButton createOpenThemeManagerButton() { - if (WorkContext.getCurrent().isRoot()) { - UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Manager_Dialog_Title")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - TemplateThemeManageDialog dialog = new TemplateThemeManageDialog(TemplateThemeUsingDialog.this); - dialog.setVisible(true); - } - }); - return button; - } - return null; - } - - private UIButton createCompleteButton() { - UIButton button = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Using_Dialog_Complete")); - button.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - exit(); - } - }); - return button; - } - - public void exit() { - themeListPane.stopListenThemeConfig(); - themeListPane.stopAsyncFetchTheme(); - super.exit(); +public class TemplateThemeUsingDialog extends TemplateThemeGridPagesDialog { + public TemplateThemeUsingDialog() { + super(); + overallPane.showThemeUsingPane(); } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java index 53e216b0d6..de62a195d4 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ComponentStyleEditPane.java @@ -2,8 +2,7 @@ package com.fr.design.mainframe.theme.edit; import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.design.designer.IntervalConstants; -import com.fr.design.dialog.AttrScrollPane; -import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.style.ComponentBodyStylePane; import com.fr.design.gui.style.ComponentIntegralStylePane; import com.fr.design.gui.style.ComponentTitleStylePane; @@ -18,10 +17,9 @@ import com.fr.general.act.BorderPacker; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; -import javax.swing.JScrollPane; +import javax.swing.JTextArea; import java.awt.BorderLayout; import java.awt.Color; -import java.awt.Dimension; /** * @author Starryi @@ -50,7 +48,8 @@ public class ComponentStyleEditPane extends JPanel { }, new JComponent[] { createTabContainer(componentTitleStylePane), createTabContainer(componentBodyStylePane), createTabContainer(componentIntegralStylePane) } ); - add(content, BorderLayout.NORTH); + content.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + add(content, BorderLayout.CENTER); } public void populateBean(ThemedComponentStyle style) { @@ -115,21 +114,20 @@ public class ComponentStyleEditPane extends JPanel { } private JComponent createTabContainer(final JPanel component) { - JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); - container.setPreferredSize(new Dimension(container.getPreferredSize().width, 220)); + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel tipLabelPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); tipLabelPane.setBorder(BorderFactory.createEmptyBorder(3, 0, 0, 0)); - UILabel tipLabel = LabelUtils.createLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153)); + JTextArea tipLabel = LabelUtils.createAutoWrapLabel(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Component_Style_Tip"), new Color(153, 153, 153)); tipLabelPane.add(tipLabel); - container.add(tipLabelPane, BorderLayout.NORTH); - - container.add(new AttrScrollPane() { - @Override - protected JPanel createContentPane() { - return component; - } - }, BorderLayout.CENTER); + content.add(tipLabelPane, BorderLayout.NORTH); + content.add(component, BorderLayout.CENTER); + + UIScrollPane scrollPane = new UIScrollPane(content); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(scrollPane, BorderLayout.CENTER); return container; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java index 53e4d9a912..b2d182422e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/CellStyleEditPane.java @@ -12,7 +12,7 @@ import com.fr.design.gui.frpane.AttributeChangeListener; import com.fr.design.gui.style.AbstractBasicStylePane; import com.fr.design.gui.style.AlignmentPane; import com.fr.design.gui.style.BorderPane; -import com.fr.design.gui.style.FormatPane; +import com.fr.design.gui.style.TextFontTippedPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.theme.ui.BorderUtils; @@ -94,7 +94,7 @@ public class CellStyleEditPane extends MultiTabPane { @Override protected List initPaneList() { paneList = new ArrayList<>(); - paneList.add(new FormatPane()); + paneList.add(new TextFontTippedPane(false)); paneList.add(new BorderPane()); paneList.add(new AlignmentPane()); return paneList; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java index 7104572da6..a70a24d8d9 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/cell/NoBorderPaneCellStyleEditPane.java @@ -2,7 +2,7 @@ package com.fr.design.mainframe.theme.edit.cell; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.style.AlignmentPane; -import com.fr.design.gui.style.FormatPane; +import com.fr.design.gui.style.TextFontTippedPane; import java.util.ArrayList; import java.util.List; @@ -12,7 +12,7 @@ public class NoBorderPaneCellStyleEditPane extends CellStyleEditPane { @Override protected List initPaneList() { paneList = new ArrayList<>(); - paneList.add(new FormatPane()); + paneList.add(new TextFontTippedPane(false)); paneList.add(new AlignmentPane()); return paneList; } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java index 2b099ed306..13769cfc64 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/LabelUtils.java @@ -3,6 +3,9 @@ package com.fr.design.mainframe.theme.edit.ui; import com.fr.design.gui.ilable.UILabel; import com.fr.general.FRFont; +import javax.swing.BorderFactory; +import javax.swing.JTextArea; +import javax.swing.plaf.basic.BasicTextAreaUI; import java.awt.Color; import java.awt.Font; @@ -26,4 +29,20 @@ public class LabelUtils { uiLabel.setFont(newFont); return uiLabel; } + + public static JTextArea createAutoWrapLabel(String title, Color color) { + JTextArea tipLabel = new JTextArea(); + tipLabel.setUI(new BasicTextAreaUI()); + tipLabel.setForeground(color); + Font newFont = FRFont.getInstance(tipLabel.getFont().getFontName(), Font.PLAIN, 12); + tipLabel.setFont(newFont); + tipLabel.setBorder(BorderFactory.createEmptyBorder()); + tipLabel.setEnabled(false); + tipLabel.setText(title); + tipLabel.setLineWrap(true); + tipLabel.setWrapStyleWord(true); + tipLabel.setOpaque(false); + tipLabel.setBackground(null); + return tipLabel; + } } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java index 3f4667e111..c1c8371674 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/edit/ui/TabbedPane.java @@ -25,7 +25,6 @@ public class TabbedPane extends JPanel { public TabbedPane(String[] names, JComponent[] panes) { setLayout(FRGUIPaneFactory.createBorderLayout()); - setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); for (JComponent pane :panes) { pane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java index cb854a3f35..cfd2781aa8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ComponentPreviewPane.java @@ -31,6 +31,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; +import java.awt.Insets; import java.awt.RenderingHints; import java.awt.Shape; import java.awt.Stroke; @@ -89,6 +90,37 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th } + @Override + protected void paintBorder(Graphics g) { + super.paintBorder(g); + + paintSeparator((Graphics2D) g); + } + + private void paintSeparator(Graphics2D g2d) { + Border border = getBorder(); + if (border instanceof LineBorder && titlePane != null) { + Border containerBorder = container.getBorder(); + Insets insets = containerBorder.getBorderInsets(container); + int y = titlePane.getHeight() + insets.top; + + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + Color lineColor = ((LineBorder) border).getLineColor(); + int thickness = ((LineBorder) border).getThickness(); + g2d.setColor(lineColor); + g2d.setStroke(new BasicStroke(thickness * 2)); + g2d.drawLine(0, y, getWidth(), y); + + g2d.setStroke(oldStroke); + g2d.setColor(oldColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + } + @Override public void paint(Graphics g) { Graphics2D g2d = (Graphics2D) g; @@ -99,7 +131,20 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th Utils.clipByRoundBorder(g2d, getWidth(), getHeight(), roundedBorder.getRoundedCorner(), roundedBorder.getThickness()); } - int titleHeight = titlePane == null ? 0 : titlePane.getHeight(); + Border containerBorder = container.getBorder(); + Insets insets = containerBorder.getBorderInsets(container); + int titleHeight = titlePane == null ? 0 : titlePane.getHeight() + insets.top; + //绘制标题背景 + if (titlePane != null) { + Label data = titlePane.getData(); + float opacity = data.getBackgroundOpacity(); + Background background = data.getBackground(); + if (background != null) { + Utils.paintBackground((Graphics2D) g, background, new Rectangle2D.Double(0, 0, getWidth(), titleHeight), opacity); + } + } + + //绘制主体背景 Utils.paintBackground(g2d, style.getBackground(), new Rectangle2D.Double(0, titleHeight, getWidth(), getHeight() - titleHeight), style.getAlpha()); Utils.paintBackground(g2d, style.getBorderImage(), new Rectangle2D.Double(0, 0, getWidth(), getHeight()), style.getBorderImageOpacity()); @@ -130,20 +175,16 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th data.setInsetImagePadding(titlePacker.getInsetImagePadding()); data.setInsetRelativeTextLeft(titlePacker.isInsetRelativeTextLeft()); data.setInsetRelativeTextRight(titlePacker.isInsetRelativeTextRight()); - this.setBorder(new BottomLineBorder(componentStyle.getStyle().getColor(), componentStyle.getStyle().getBorder())); + } + + public Label getData(){ + return data; } @Override public void paintComponent(Graphics g) { super.paintComponent(g); - Dimension size = getSize(); - Background background = data.getBackground(); - float opacity = data.getBackgroundOpacity(); - if (background != null) { - Utils.paintBackground((Graphics2D) g, background, new Rectangle2D.Double(0, 0, size.getWidth(), size.getHeight()), opacity); - } - Graphics2D g2d = (Graphics2D) g.create(); Background inset = data.getInsetImage(); Image insetImage = inset instanceof ImageBackground ? ((ImageBackground) inset).getImage() : null; @@ -161,31 +202,6 @@ public abstract class ComponentPreviewPane extends UINoOpaquePanel implements Th } - public static class BottomLineBorder extends LineBorder { - - private BottomLineBorder(Color color, int thickness) { - super(color, thickness); - } - - @Override - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - Graphics2D g2d = (Graphics2D) g; - - Color oldColor = g2d.getColor(); - Stroke oldStroke = g2d.getStroke(); - - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - g2d.setColor(getLineColor()); - g2d.setStroke(new BasicStroke(getThickness() * 2)); - g2d.drawLine(0, height, width, height); - - g2d.setStroke(oldStroke); - g2d.setColor(oldColor); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - } - } - private static class Utils { private static void paintBackground(Graphics2D g2d, Background background, Shape shape, float opacity) { diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java index 18ac4b962d..25a1daee92 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/FormThemePreviewPane.java @@ -14,6 +14,7 @@ import com.fr.design.mainframe.theme.preview.ecpreview.ECComponentPreviewPane; import com.fr.general.Background; import com.fr.log.FineLoggerFactory; import com.fr.plugin.chart.PiePlot4VanChart; +import com.fr.plugin.chart.attr.VanChartLegend; import com.fr.plugin.chart.attr.axis.VanChartAxis; import com.fr.plugin.chart.base.AttrLabel; import com.fr.plugin.chart.base.VanChartTools; @@ -34,7 +35,6 @@ import java.awt.Graphics2D; import java.awt.geom.Rectangle2D; import static com.fr.design.i18n.Toolkit.i18nText; - /** * @author Starryi * @version 1.0 @@ -65,7 +65,7 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane { } }; columnChartPanel.setLayout(new BorderLayout()); - columnChartPreviewPane = createChartPreviewPane(initColumnChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Column_Title")); + columnChartPreviewPane = createChartPreviewPane(initColumnChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title1")); columnChartPanel.add(columnChartPreviewPane, BorderLayout.CENTER); JPanel pieChartPanel = new UINoOpaquePanel() { @@ -74,7 +74,7 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane { } }; pieChartPanel.setLayout(new BorderLayout()); - pieChartPreviewPane = createChartPreviewPane(initPieChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Pie_Title")); + pieChartPreviewPane = createChartPreviewPane(initPieChart(), i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Comp_Title2")); pieChartPanel.add(pieChartPreviewPane, BorderLayout.CENTER); chartContent.add(columnChartPanel, BorderLayout.CENTER); chartContent.add(pieChartPanel, BorderLayout.EAST); @@ -180,11 +180,14 @@ public class FormThemePreviewPane extends TemplateThemePreviewPane { vanChartTools.setFullScreen(false); PiePlot4VanChart plot = chart.getPlot(); - plot.getLegend().setPosition(Constants.BOTTOM); + VanChartLegend legend = (VanChartLegend) plot.getLegend(); + legend.setPosition(Constants.BOTTOM); + legend.setCustomSize(true); + legend.setMaxHeight(28); plot.getGradientStyle().setGradientType(GradientType.NONE); plot.setInnerRadiusPercent(75); plot.getRadius().setRadiusType(RadiusType.FIXED); - plot.getRadius().setRadius(80); + plot.getRadius().setRadius(70); Object[] category = {StringUtils.EMPTY}; Object[] series = {"A1", "B1", "C1", "D1", "E1", "F1", "G1", "H1"}; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java index 4493ed2630..5f7725ffa3 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECPreviewPane.java @@ -2,20 +2,16 @@ package com.fr.design.mainframe.theme.preview.ecpreview; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.settings.ThemedCellStyleList; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.theme.preview.UINoOpaquePanel; import com.fr.design.mainframe.theme.preview.ecpreview.cell.AbstractPreviewCell; import com.fr.design.mainframe.theme.preview.ecpreview.cell.PreviewCell; -import com.fr.log.FineLoggerFactory; - import javax.swing.BorderFactory; import javax.swing.JPanel; - import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.GridLayout; -import java.io.BufferedReader; -import java.io.StringReader; import java.util.ArrayList; import java.util.List; @@ -25,70 +21,41 @@ import java.util.List; * Created by Starryi on 2021/8/13 */ public class ECPreviewPane extends AbstractECPreviewPane { - private static String csv = - "城市 当月目标 当月完成 月完成率 年完成率\n" + - "合肥市 248,938 348,938 140% 140%\n" + - "邵阳市 248,938 348,938 140% 140%\n" + - "合计 1,071,460 1,371,460 128% 128%"; - private final List DATA_LIST = createDataList(); - private static final String BLANK_CHAR = " "; - private List headerCellList = new ArrayList<>(); - private List contentCellList = new ArrayList<>(); - private List hightLightCellList = new ArrayList<>(); - - private List createDataList() { - List data = new ArrayList<>(); - try (BufferedReader reader = new BufferedReader(new StringReader(csv))) { - String textLine; - while ((textLine = reader.readLine()) != null) { - String[] texts = textLine.split(BLANK_CHAR); - data.add(texts); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - return data; - } - + private final List headerCellList = new ArrayList<>(); + private final List contentCellList = new ArrayList<>(); + private final List highLightCellList = new ArrayList<>(); + private static final int COL_COUNT = 5; + private static final int CONTENT_ROW_COUNT = 2; public ECPreviewPane() { this.setPreferredSize(new Dimension(517, 147)); this.setBorder(BorderFactory.createEmptyBorder(0, 1, 2, 1)); this.setLayout(FRGUIPaneFactory.createBorderLayout()); - String[] titleArr = DATA_LIST.get(0); - String[] endArr = DATA_LIST.get(DATA_LIST.size() - 1); JPanel titlePane = new UINoOpaquePanel(new GridLayout()); this.add(titlePane, BorderLayout.NORTH); - for (String title : titleArr) { - PreviewCell cell = new PreviewCell(title); + for (int i = 0; i < COL_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); cell.setPreferredSize(new Dimension(103, 36)); titlePane.add(cell); headerCellList.add(cell); } - JPanel contentPane = new UINoOpaquePanel(new GridLayout(2, 5, 0, 0)); this.add(contentPane, BorderLayout.CENTER); - for (int i = 1; i < DATA_LIST.size() - 1; i++) { - String[] textLine = DATA_LIST.get(i); - for (int j = 0; j < textLine.length; j++) { - String text = textLine[j]; - PreviewCell cell = new PreviewCell(text); - cell.setPreferredSize(new Dimension(103, 33)); - contentPane.add(cell); - contentCellList.add(cell); - } + for (int i = 0; i < COL_COUNT * CONTENT_ROW_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text")); + cell.setPreferredSize(new Dimension(103, 33)); + contentPane.add(cell); + contentCellList.add(cell); } JPanel endPane = new UINoOpaquePanel(new GridLayout()); this.add(endPane, BorderLayout.SOUTH); - for (String text : endArr) { - PreviewCell cell = new PreviewCell(text); + for (int i = 0; i < COL_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text")); cell.setPreferredSize(new Dimension(103, 33)); endPane.add(cell); - hightLightCellList.add(cell); + highLightCellList.add(cell); } - - } @Override @@ -96,7 +63,7 @@ public class ECPreviewPane extends AbstractECPreviewPane { ThemedCellStyleList cellStyleConfig = theme.getCellStyleList(); refresh(headerCellList, getReportHeaderStyle(cellStyleConfig)); refresh(contentCellList, getMainContentStyle(cellStyleConfig)); - refresh(hightLightCellList, getHighLightStyle(cellStyleConfig)); + refresh(highLightCellList, getHighLightStyle(cellStyleConfig)); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java index 231233196d..63d75449dc 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/preview/ecpreview/ECReportPreviewPane.java @@ -22,13 +22,15 @@ import java.util.ArrayList; import java.util.List; public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreviewed { - private List headerTitleCellList = new ArrayList<>(); - private List headerCellList = new ArrayList<>(); - private List titleCellList = new ArrayList<>(); - private List contentCellList = new ArrayList<>(); - private List highLightCellList = new ArrayList<>(); + private final List headerTitleCellList = new ArrayList<>(); + private final List headerCellList = new ArrayList<>(); + private final List titleCellList = new ArrayList<>(); + private final List contentCellList = new ArrayList<>(); + private final List highLightCellList = new ArrayList<>(); + private static final int CONTENT_ROW_COUNT = 3; + private static final int COL_COUNT = 5; - private PreviewPane previewPane; + private final PreviewPane previewPane; public ECReportPreviewPane() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); @@ -47,7 +49,7 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview public PreviewPane() { this.setPreferredSize(new Dimension(517, 270)); - this.setBorder(BorderFactory.createEmptyBorder(7, 10, 5, 10)); + this.setBorder(BorderFactory.createEmptyBorder(5, 10, 5, 10)); this.setLayout(FRGUIPaneFactory.createBorderLayout()); JPanel northPane = createNorthPane(); @@ -58,26 +60,26 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview private JPanel createNorthPane() { JPanel northPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); - AbstractPreviewCell bigTitleCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Big_Title")); + AbstractPreviewCell bigTitleCell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Cell_Style_Big_Title")); bigTitleCell.setPreferredSize(new Dimension(615, 46)); headerTitleCellList.add(bigTitleCell); northPane.add(bigTitleCell, BorderLayout.NORTH); - CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Product"), - Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Statistical_Dimension")}, - new Point2D[]{new Point(159, 71), new Point(226, 49)}); - cornerCell.setPreferredSize(new Dimension(226, 71)); + CornerPreviewCell cornerCell = new CornerPreviewCell(new String[]{Toolkit.i18nText("Fine-Design_Basic_Column_Name"), + Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Data"), Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_Row_Name")}, + new Point2D[]{new Point(159, 71), new Point(225, 49)}); + cornerCell.setPreferredSize(new Dimension(225, 71)); headerCellList.add(cornerCell); northPane.add(cornerCell, BorderLayout.WEST); JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); northPane.add(centerPane, BorderLayout.CENTER); - PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Statistical_By_Area")); + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title")); titleCellList.add(cell); cell.setPreferredSize(new Dimension(308, 38)); centerPane.add(cell, BorderLayout.NORTH); JPanel eastSouthPane = new UINoOpaquePanel(new GridLayout()); - PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_East_China")); - PreviewCell cell2 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_South_China")); - PreviewCell cell3 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Subtotal")); + PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); + PreviewCell cell2 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); + PreviewCell cell3 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); headerCellList.add(cell1); headerCellList.add(cell2); headerCellList.add(cell3); @@ -92,14 +94,14 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview JPanel centerPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); JPanel westPane = FRGUIPaneFactory.createBorderLayout_NO_Opaque_Pane(); centerPane.add(westPane, BorderLayout.WEST); - PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Drink")); + PreviewCell cell1 = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Small_Title")); titleCellList.add(cell1); cell1.setPreferredSize(new Dimension(112, 153)); westPane.add(cell1, BorderLayout.WEST); JPanel gridPane = new UINoOpaquePanel(new GridLayout(5, 1)); - for (int i = 0; i < 5; i++) { - PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Profile_Pane_EC_Apple_Juice")); - cell.setPreferredSize(new Dimension(114, 31)); + for (int i = 0; i < COL_COUNT; i++) { + PreviewCell cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Header")); + cell.setPreferredSize(new Dimension(113, 31)); headerCellList.add(cell); gridPane.add(cell); } @@ -107,14 +109,16 @@ public class ECReportPreviewPane extends UINoOpaquePanel implements ThemePreview JPanel innerCenterPane = new UINoOpaquePanel(new GridLayout(5, 3)); centerPane.add(innerCenterPane, BorderLayout.CENTER); - for (int i = 0; i < 15; i++) { - PreviewCell cell = new PreviewCell("35600"); - cell.setPreferredSize(new Dimension(123, 31)); - if ((i + 1) % 3 == 0) { + for (int i = 0; i < COL_COUNT * CONTENT_ROW_COUNT; i++) { + PreviewCell cell ; + if ((i + 1) % CONTENT_ROW_COUNT == 0) { + cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Highlight_Text")); highLightCellList.add(cell); } else { + cell = new PreviewCell(Toolkit.i18nText("Fine-Design_Basic_Predefined_Style_Main_Text")); contentCellList.add(cell); } + cell.setPreferredSize(new Dimension(123, 31)); innerCenterPane.add(cell); } diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java new file mode 100644 index 0000000000..9ce5a3d5d3 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckTextField.java @@ -0,0 +1,100 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StringUtils; + +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/18 + */ +public class AutoCheckTextField extends UITextField implements DocumentListener, FocusListener { + private DuplicateChecker duplicatedChecker; + private CheckListener checkListener; + + public AutoCheckTextField() { + getDocument().addDocumentListener(this); + addFocusListener(this); + } + + public void setDuplicatedChecker(DuplicateChecker checker) { + this.duplicatedChecker = checker; + } + public void setNameCheckListener(CheckListener checkListener) { + this.checkListener = checkListener; + } + + private boolean isEmpty(String name) { + return StringUtils.isEmpty(name); + } + private boolean isDuplicated(String name) { + if (duplicatedChecker != null) { + return duplicatedChecker.isDuplicated(name); + } + return false; + } + private boolean checkValid(boolean notifyEmptyTip) { + String name = getText(); + + String error = StringUtils.EMPTY; + boolean valid = true; + if (isEditable()) { + if (isEmpty(name)) { + valid = false; + if (notifyEmptyTip) { + error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Empty_Name_Error_Tip"); + } + } else if (isDuplicated(name)) { + valid = false; + error = Toolkit.i18nText("Fine-Design_Basic_Template_Theme_Edit_Pane_Duplicated_Name_Error_Tip"); + } + } + + if (checkListener != null) { + checkListener.onChecked(error, valid); + } + + return valid; + } + public boolean checkValid() { + return checkValid(true); + } + + @Override + public void insertUpdate(DocumentEvent e) { + checkValid(false); + } + + @Override + public void removeUpdate(DocumentEvent e) { + checkValid(false); + } + + @Override + public void changedUpdate(DocumentEvent e) { + + } + + @Override + public void focusGained(FocusEvent e) { + checkValid(false); + } + + @Override + public void focusLost(FocusEvent e) { + checkValid(true); + } + + public interface CheckListener { + void onChecked(String error, boolean valid); + } + public interface DuplicateChecker { + boolean isDuplicated(String name); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java new file mode 100644 index 0000000000..804c8493d2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/AutoCheckThemeNameTextField.java @@ -0,0 +1,26 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/18 + */ +public class AutoCheckThemeNameTextField extends AutoCheckTextField { + private TemplateThemeConfig config; + + public AutoCheckThemeNameTextField() { + setDuplicatedChecker(new DuplicateChecker() { + @Override + public boolean isDuplicated(String name) { + return config != null && config.contains(name); + } + }); + } + + public void setThemeConfig(TemplateThemeConfig config) { + this.config = config; + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java new file mode 100644 index 0000000000..bc466972ef --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/theme/ui/BreadcrumbBar.java @@ -0,0 +1,114 @@ +package com.fr.design.mainframe.theme.ui; + +import com.fr.design.gui.ilable.UILabel; + +import javax.swing.BorderFactory; +import javax.swing.JButton; +import javax.swing.JPanel; +import javax.swing.plaf.basic.BasicButtonUI; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/10/9 + */ +public class BreadcrumbBar extends JPanel { + private JButton currentCrumb; + + public BreadcrumbBar() { + setLayout(new FlowLayout(FlowLayout.LEFT, 0, 0)); + } + + public void addCrumb(final String text, final BreadcrumbBackListener backListener) { + if (currentCrumb != null) { + currentCrumb.setSelected(false); + add(createSeparator()); + } + final JButton breadcrumb = createBreadcrumb(text); + breadcrumb.setSelected(true); + add(breadcrumb); + currentCrumb = breadcrumb; + + final int index = getComponentCount() - 1; + breadcrumb.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + removeTailCrumbs(index + 1); + + breadcrumb.setSelected(true); + currentCrumb = breadcrumb; + if (backListener != null) { + backListener.onBreadcrumbBack(text); + } + } + }); + } + + private void removeTailCrumbs(int from) { + Component[] components = getComponents(); + for (int i = from; i < components.length; i++) { + remove(components[i]); + } + revalidate(); + repaint(); + } + + public void clear() { + removeAll(); + currentCrumb = null; + } + + protected Component createSeparator() { + UILabel separator = new UILabel("/"); + separator.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 8)); + separator.setPreferredSize(new Dimension(separator.getPreferredSize().width, 17)); + + return separator; + } + + protected JButton createBreadcrumb(String text) { + JButton button = new BreadcrumbButton(text); + button.setPreferredSize(new Dimension(button.getPreferredSize().width, 17)); + return button; + } + + public static class BreadcrumbButton extends JButton { + + public BreadcrumbButton(String text) { + super(text); + setMargin(new Insets(0, 0, 0, 0)); + setBorder(BorderFactory.createEmptyBorder()); + setUI(new BasicButtonUI()); + setBorderPainted(false); + setOpaque(false); + setBackground(null); + } + + @Override + public Insets getMargin() { + Insets insets = super.getMargin(); + if (insets != null) { + insets.set(0, 0, 0, 0); + } + return insets; + } + + @Override + public void setSelected(boolean b) { + super.setSelected(b); + setForeground(b ? new Color(0x419BF9) : new Color(0x838384)); + repaint(); + } + } + + public interface BreadcrumbBackListener { + void onBreadcrumbBack(String text); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index d8e5b4a57e..c4ad83ca7a 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java @@ -40,6 +40,7 @@ import com.fr.design.actions.server.GlobalParameterAction; import com.fr.design.actions.server.GlobalTableDataAction; import com.fr.design.actions.server.PlatformManagerAction; import com.fr.design.actions.server.PluginManagerAction; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.file.NewTemplatePane; import com.fr.design.fun.MenuHandler; import com.fr.design.fun.OemProcessor; @@ -407,7 +408,9 @@ public abstract class ToolBarMenuDock { menuDef.addShortCut(new OpenRecentReportMenuDef()); - addCloseCurrentTemplateAction(menuDef); + if (!DesignModeContext.isDuchampMode()) { + addCloseCurrentTemplateAction(menuDef); + } scs = plus.shortcut4FileMenu(); if (!ArrayUtils.isEmpty(scs)) { @@ -466,6 +469,10 @@ public abstract class ToolBarMenuDock { return new UILabel(); } + public Component createGuideEntryPane() { + return new UILabel(); + } + public Component createNotificationCenterPane(){ return new UILabel(); } @@ -491,10 +498,12 @@ public abstract class ToolBarMenuDock { if (!DesignerMode.isAuthorityEditing()) { addPluginManagerAction(menuDef); - menuDef.addShortCut( - new FunctionManagerAction(), - new GlobalParameterAction() - ); + menuDef.addShortCut(new FunctionManagerAction()); + + if (!DesignModeContext.isDuchampMode()) { + menuDef.addShortCut(new GlobalParameterAction()); + } + } diff --git a/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java b/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java index 057b561fa0..115b9617ce 100644 --- a/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java +++ b/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java @@ -1,18 +1,8 @@ package com.fr.design.os.impl; -import com.fr.design.data.datapane.connect.ConnectionManagerPane; -import com.fr.design.dialog.BasicDialog; -import com.fr.design.dialog.DialogActionAdapter; -import com.fr.design.editlock.EditLockUtils; +import com.fr.design.data.datapane.connect.ConnectionListPane; import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.DesignerFrame; -import com.fr.file.ConnectionConfig; import com.fr.stable.os.support.OSBasedAction; -import com.fr.transaction.CallBackAdaptor; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; -import com.fr.report.LockItem; -import static com.fr.design.actions.server.ConnectionListAction.doWithDatasourceManager; /** * 数据连接窗口 @@ -33,54 +23,7 @@ public class DatabaseDialogAction implements OSBasedAction { } private void openDesignDatabaseManager() { - DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); - final ConnectionConfig datasourceManager = ConnectionConfig.getInstance(); - final ConnectionManagerPane databaseManagerPane = new ConnectionManagerPane() { - public void complete() { - ConnectionConfig connectionConfig = datasourceManager.mirror(); - populate(connectionConfig); - } - - protected void renameConnection(String oldName, String newName) { - datasourceManager.renameConnection(oldName, newName); - } - }; - final BasicDialog databaseListDialog = databaseManagerPane.showLargeWindow(designerFrame, null); - databaseListDialog.addDialogActionListener(new DialogActionAdapter() { - public void doOk() { - if (!databaseManagerPane.isNamePermitted()) { - databaseListDialog.setDoOKSucceed(false); - return; - } - Configurations.modify(new WorkerFacade(ConnectionConfig.class) { - @Override - public void run() { - databaseManagerPane.update(datasourceManager); - } - }.addCallBack(new CallBackAdaptor() { - @Override - public boolean beforeCommit() { - //如果更新失败,则不关闭对话框,也不写xml文件,并且将对话框定位在请重命名的那个对象页面 - return doWithDatasourceManager(datasourceManager, databaseManagerPane, databaseListDialog); - } - - @Override - public void afterCommit() { - DesignerContext.getDesignerBean("databasename").refreshBeanElement(); - // 定义数据连接弹窗关闭后,解锁 - EditLockUtils.unlock(LockItem.CONNECTION); - } - })); - } - - @Override - public void doCancel() { - super.doCancel(); - // 定义数据连接弹窗关闭后,解锁 - EditLockUtils.unlock(LockItem.CONNECTION); - } - }); - databaseListDialog.setVisible(true); + ConnectionListPane.showDialog(DesignerContext.getDesignerFrame()); } diff --git a/designer-base/src/main/java/com/fr/design/report/fit/AdaptiveFrmFitAttrModel.java b/designer-base/src/main/java/com/fr/design/report/fit/AdaptiveFrmFitAttrModel.java new file mode 100644 index 0000000000..2196b1d403 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/report/fit/AdaptiveFrmFitAttrModel.java @@ -0,0 +1,55 @@ +package com.fr.design.report.fit; + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.report.fit.provider.AbstractFitAttrModelProvider; + +import com.fr.form.fit.common.LightTool; +import com.fr.form.fit.config.FormFitConfig; +import com.fr.form.main.Form; +import com.fr.report.fit.ReportFitAttr; + + +public class AdaptiveFrmFitAttrModel extends AbstractFitAttrModelProvider { + + public FitType[] getFitTypes() { + return new FitType[]{ + FitType.DOUBLE_FIT, + FitType.HORIZONTAL_FIT, + FitType.NOT_FIT + }; + } + + public String getFitName() { + return Toolkit.i18nText("Fine-Designer_Fit_Report_Scale_Method"); + } + + @Override + public String getModelName() { + return Toolkit.i18nText("Fine-Design_New_Decision_Report"); + } + + @Override + public ReportFitAttr getGlobalReportFitAttr() { + return FormFitConfig.getInstance().getNewFitAttr(); + } + + @Override + public void setGlobalReportFitAttr(ReportFitAttr reportFitAttr) { + FormFitConfig.getInstance().setNewFitAttr(reportFitAttr); + } + + @Override + public int getPriority() { + return 2; + } + + @Override + public boolean isAvailable(JTemplate jTemplate) { + if (jTemplate.getTarget() instanceof Form) { + return LightTool.containNewFormFlag((Form) jTemplate.getTarget()); + } + return false; + } + +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/report/fit/BaseFitAttrPane.java b/designer-base/src/main/java/com/fr/design/report/fit/BaseFitAttrPane.java new file mode 100644 index 0000000000..2c38d597c4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/report/fit/BaseFitAttrPane.java @@ -0,0 +1,239 @@ +package com.fr.design.report.fit; + +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.beans.BasicBeanPane; +import com.fr.design.gui.ibutton.UIRadioButton; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.DesignSizeI18nManager; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.report.fit.menupane.FitPreviewPane; +import com.fr.design.report.fit.menupane.FitRadioGroup; +import com.fr.design.report.fit.menupane.FontRadioGroup; +import com.fr.design.report.fit.provider.FitAttrModelProvider; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.general.ComparatorUtils; +import com.fr.report.fit.ReportFitAttr; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.ItemListener; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Comparator; +import java.util.Set; +import java.util.stream.Collectors; + +import static com.fr.design.i18n.Toolkit.i18nText; + +public abstract class BaseFitAttrPane extends BasicBeanPane { + + protected JPanel contentJPanel; + protected UILabel belowSetLabel; + protected UIComboBox itemChoose; + protected java.util.List fitAttrModelList = new ArrayList<>(); + + public FontRadioGroup fontRadioGroup; + public FitRadioGroup adaptRadioGroup; + public JPanel attrJPanel; + public FitPreviewPane previewJPanel; + public FitAttrModel fitAttrModel; + private static final int BELOW_SET_COMPONENT_HSPACE = 8; + + + protected BaseFitAttrPane() { + initFitAttrModel(); + } + + private void initFitAttrModel() { + fitAttrModelList.add(new FrmFitAttrModel()); + fitAttrModelList.add(new CptFitAttrModel()); + fitAttrModelList.add(new AdaptiveFrmFitAttrModel()); + + Set fitAttrModelProviders = ExtraDesignClassManager.getInstance().getArray(FitAttrModelProvider.XML_TAG); + + for (FitAttrModelProvider fitAttrModelProvider : fitAttrModelProviders) { + fitAttrModelList.add(fitAttrModelProvider); + } + + fitAttrModelList = fitAttrModelList.stream().sorted(Comparator.comparing(FitAttrModel::getPriority).reversed()).collect(Collectors.toList()); + } + + protected void populateModel(FitAttrModel fitAttrModel) { + this.fitAttrModel = fitAttrModel; + if (attrJPanel != null) { + contentJPanel.remove(attrJPanel); + } + if (previewJPanel != null) { + contentJPanel.remove(previewJPanel); + } + + fontRadioGroup = new FontRadioGroup(); + adaptRadioGroup = new FitRadioGroup(); + initAttrJPanel(); + initPreviewJPanel(); + } + + + protected void initAttrJPanel() { + int colCount = fitAttrModel.getFitTypes().length + 1; + Component[][] components = new Component[2][colCount]; + initFitRadioGroup(fontRadioGroup, i18nText("Fine-Designer_Fit-Font"), new String[]{i18nText("Fine-Designer_Fit"), i18nText("Fine-Designer_Fit-No")}, components[0]); + initFitRadioGroup(adaptRadioGroup, fitAttrModel.getFitName(), Arrays.stream(fitAttrModel.getFitTypes()).map(FitType::description).toArray(String[]::new), components[1]); + + double[] rowSize = new double[2]; + double[] columnSize = new double[colCount]; + for (int i = 0; i < rowSize.length; i++) { + rowSize[i] = 20; + } + for (int i = 0; i < columnSize.length; i++) { + if (i == 0) { + columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.firstColumn").getWidth(); + } else { + columnSize[i] = DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.column").getWidth(); + } + } + + attrJPanel = TableLayoutHelper.createTableLayoutPane(components, rowSize, columnSize); + attrJPanel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0)); + contentJPanel.add(attrJPanel); + } + + private void initFitRadioGroup(FitRadioGroup fitRadioGroup, String name, String[] options, Component[] components) { + components[0] = new UILabel(name); + for (int i = 0; i < options.length; i++) { + + if (options[i] != null) { + UIRadioButton fontFitRadio = new UIRadioButton(options[i]); + fitRadioGroup.add(fontFitRadio); + components[i + 1] = fontFitRadio; + } else { + components[i + 1] = null; + } + } + fitRadioGroup.addActionListener(getPreviewActionListener()); + } + + protected ActionListener getPreviewActionListener() { + return new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + refreshPreviewJPanel(); + } + }; + } + + protected void refreshPreviewJPanel() { + String previewIndex = getPreviewIndex(); + previewJPanel.refreshPreview(previewIndex, fontRadioGroup.isEnabled()); + } + + protected String getPreviewIndex() { + return getStateInPC(adaptRadioGroup.getSelectRadioIndex()) + "" + fontRadioGroup.getSelectRadioIndex(); + } + + protected void initPreviewJPanel() { + previewJPanel = new FitPreviewPane(); + previewJPanel.setBorder(BorderFactory.createEmptyBorder(0, getPreviewJPanelLeft(), 0, 0)); + contentJPanel.add(previewJPanel); + } + + private int getPreviewJPanelLeft() { + int left = 0; + if (belowSetLabel.getPreferredSize() != null) { + left = belowSetLabel.getPreferredSize().width + BELOW_SET_COMPONENT_HSPACE; + } + return left; + } + + protected int getStateInPC(int index) { + FitType[] fitTypes = fitAttrModel.getFitTypes(); + return fitTypes[index].getState(); + } + + protected int getOptionIndex(int state) { + FitType[] fitTypes = fitAttrModel.getFitTypes(); + for (int i = 0; i < fitTypes.length; i++) { + if (ComparatorUtils.equals(state, fitTypes[i].getState())) { + return i; + } + } + return 0; + } + + + @Override + public void populateBean(ReportFitAttr ob) { + fontRadioGroup.selectIndexButton(ob.isFitFont() ? 0 : 1); + adaptRadioGroup.selectIndexButton(getOptionIndex(ob.fitStateInPC())); + refreshPreviewJPanel(); + } + + @Override + public ReportFitAttr updateBean() { + ReportFitAttr reportFitAttr = new ReportFitAttr(); + reportFitAttr.setFitFont(fontRadioGroup.isFontFit()); + reportFitAttr.setFitStateInPC(getStateInPC(adaptRadioGroup.getSelectRadioIndex())); + return reportFitAttr; + } + + + public void setEnabled(boolean enabled) { + super.setEnabled(enabled); + fontRadioGroup.setEnabled(enabled); + adaptRadioGroup.setEnabled(enabled); + refreshPreviewJPanel(); + } + + @Override + protected String title4PopupWindow() { + return i18nText("Fine-Designer_PC_Fit_Attr"); + } + + protected abstract String[] getItemNames(); + + protected void initComponents() { + this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + contentJPanel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(false, FlowLayout.LEFT, 0, 0); + this.add(contentJPanel); + initItemChoose(); + initPrompt(); + } + + + private void initItemChoose() { + JPanel chooseJPanel = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + ItemListener itemListener = getItemListener(); + itemChoose = new UIComboBox(getItemNames()); + itemChoose.addItemListener(itemListener); + belowSetLabel = new UILabel(i18nText("Fine-Design_Report_Blow_Set")); + JPanel hSpaceLabel = new JPanel(); + hSpaceLabel.setSize(BELOW_SET_COMPONENT_HSPACE, 0); + JPanel buttonPane = GUICoreUtils.createFlowPane(new Component[]{ + belowSetLabel, hSpaceLabel, itemChoose}, FlowLayout.LEFT); + chooseJPanel.add(buttonPane); + chooseJPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0)); + contentJPanel.add(chooseJPanel); + } + + + protected abstract ItemListener getItemListener(); + + + public void populate(ReportFitAttr reportFitAttr) { + + } + + protected void initPrompt() { + } + + protected void refresh() { + validate(); + repaint(); + revalidate(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/report/fit/CptFitAttrModel.java b/designer-base/src/main/java/com/fr/design/report/fit/CptFitAttrModel.java new file mode 100644 index 0000000000..176f2cee1a --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/report/fit/CptFitAttrModel.java @@ -0,0 +1,51 @@ +package com.fr.design.report.fit; + + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; +import com.fr.report.fit.ReportFitAttr; +import com.fr.report.fit.ReportFitConfig; + + +public class CptFitAttrModel implements FitAttrModel { + + @Override + public FitType[] getFitTypes() { + return new FitType[]{ + FitType.HORIZONTAL_FIT, + FitType.DOUBLE_FIT, + FitType.NOT_FIT + }; + } + + @Override + public String getFitName() { + return Toolkit.i18nText("Fine-Designer_Fit-Element"); + } + + + @Override + public String getModelName() { + return Toolkit.i18nText("Fine-Design_Basic_Plain_Report"); + } + + @Override + public ReportFitAttr getGlobalReportFitAttr() { + return ReportFitConfig.getInstance().getCptFitAttr(); + } + + @Override + public void setGlobalReportFitAttr(ReportFitAttr reportFitAttr) { + ReportFitConfig.getInstance().setCptFitAttr(reportFitAttr); + } + + @Override + public int getPriority() { + return 0; + } + + @Override + public boolean isAvailable(JTemplate jTemplate) { + return jTemplate.isJWorkBook(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/report/fit/FitAttrModel.java b/designer-base/src/main/java/com/fr/design/report/fit/FitAttrModel.java new file mode 100644 index 0000000000..1d1ac02f0d --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/report/fit/FitAttrModel.java @@ -0,0 +1,44 @@ +package com.fr.design.report.fit; + +import com.fr.design.mainframe.JTemplate; +import com.fr.report.fit.ReportFitAttr; + +public interface FitAttrModel { + /** + * @Description 名称,比如:普通报表、决策报表等 + **/ + String getModelName(); + + /** + * @Description 自适应选项的名称,比如返回:表格 + **/ + String getFitName(); + + /** + * @Description 自适应选项 + **/ + FitType[] getFitTypes(); + + + /** + * @Description 获取全局的自适应属性 + **/ + ReportFitAttr getGlobalReportFitAttr(); + + /** + * @Description 设置全局的自适应属性 + * @param: reportFitAttr + **/ + void setGlobalReportFitAttr(ReportFitAttr reportFitAttr); + + /** + * @Description 优先级 + **/ + int getPriority(); + + /** + * @Description 是否可用 + * @param: jTemplate + **/ + boolean isAvailable(JTemplate jTemplate); +} diff --git a/designer-base/src/main/java/com/fr/design/report/fit/FrmFitAttrModel.java b/designer-base/src/main/java/com/fr/design/report/fit/FrmFitAttrModel.java new file mode 100644 index 0000000000..258dfbf49c --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/report/fit/FrmFitAttrModel.java @@ -0,0 +1,53 @@ +package com.fr.design.report.fit; + + +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; +import com.fr.report.fit.ReportFitAttr; +import com.fr.report.fit.ReportFitConfig; + + +public class FrmFitAttrModel implements FitAttrModel { + + + @Override + public String getModelName() { + return Toolkit.i18nText("Fine-Design_Basic_Decision_Report"); + } + + @Override + public String getFitName() { + return Toolkit.i18nText("Fine-Designer_Fit-Element"); + } + + public FitType[] getFitTypes() { + return new FitType[]{ + FitType.DEFAULT, + FitType.HORIZONTAL_FIT, + FitType.DOUBLE_FIT, + FitType.NOT_FIT + }; + } + + @Override + public ReportFitAttr getGlobalReportFitAttr() { + return ReportFitConfig.getInstance().getFrmFitAttr(); + } + + @Override + public void setGlobalReportFitAttr(ReportFitAttr reportFitAttr) { + ReportFitConfig.getInstance().setFrmFitAttr(reportFitAttr); + } + + @Override + public int getPriority() { + return 1; + } + + @Override + public boolean isAvailable(JTemplate jTemplate) { + return !jTemplate.isJWorkBook(); + } + + +} diff --git a/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java b/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java index ae0cfd2b65..c1dd3afd6e 100644 --- a/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java +++ b/designer-base/src/main/java/com/fr/design/report/fit/menupane/ReportFitAttrAction.java @@ -1,10 +1,10 @@ package com.fr.design.report.fit.menupane; -import com.fr.base.svg.IconUtils; import com.fr.design.actions.JTemplateAction; import com.fr.design.beans.BasicBeanPane; import com.fr.design.dialog.DialogActionAdapter; import com.fr.design.dialog.UIDialog; +import com.fr.design.i18n.DesignSizeI18nManager; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JTemplate; @@ -35,22 +35,6 @@ public class ReportFitAttrAction extends JTemplateAction { return null; } }; - private static final MenuKeySet REPORT_FIT_ATTR_ELEMENTCASE = new MenuKeySet() { - @Override - public char getMnemonic() { - return 'T'; - } - - @Override - public String getMenuName() { - return Toolkit.i18nText("Fine-Designer_PC_Element_Case_Fit_Attr"); - } - - @Override - public KeyStroke getKeyStroke() { - return null; - } - }; public ReportFitAttrAction(JTemplate jTemplate) { super(jTemplate); @@ -58,12 +42,7 @@ public class ReportFitAttrAction extends JTemplateAction { } private void initMenuStyle() { - JTemplate jTemplate = getEditingComponent(); - if (jTemplate.isJWorkBook()) { - this.setMenuKeySet(REPORT_FIT_ATTR); - } else { - this.setMenuKeySet(REPORT_FIT_ATTR_ELEMENTCASE); - } + this.setMenuKeySet(REPORT_FIT_ATTR); this.setName(getMenuKeySet().getMenuKeySetName() + "..."); this.setMnemonic(getMenuKeySet().getMnemonic()); this.setSmallIcon("/com/fr/design/images/reportfit/fit"); @@ -82,24 +61,19 @@ public class ReportFitAttrAction extends JTemplateAction { } final FitProvider wbTpl = (FitProvider) jwb.getTarget(); ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); - if (jwb.isJWorkBook()) { - final TemplateFitAttrPane attrPane = new TemplateFitAttrPane(); - showReportFitDialog(fitAttr, jwb, wbTpl, attrPane); - } else { - final ReportFitAttrPane attrPane = new ReportFitAttrPane(); - showReportFitDialog(fitAttr, jwb, wbTpl, attrPane); - } + TemplateFitAttrPane templateFitAttrPane = new TemplateFitAttrPane(jwb); + showReportFitDialog(fitAttr, jwb, wbTpl, templateFitAttrPane); } private void showReportFitDialog(ReportFitAttr fitAttr, final JTemplate jwb, final FitProvider wbTpl, final BasicBeanPane attrPane) { attrPane.populateBean(fitAttr); - UIDialog dialog = attrPane.showMediumWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { + UIDialog dialog = attrPane.showWindowWithCustomSize(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { @Override public void doOk() { wbTpl.setReportFitAttr(attrPane.updateBean()); jwb.fireTargetModified(); } - }); + }, DesignSizeI18nManager.getInstance().i18nDimension("com.fr.design.report.fit.templatePane.dialog")); dialog.setVisible(true); } diff --git a/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java b/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java index 66673fc5f5..8854b0ee92 100644 --- a/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java +++ b/designer-base/src/main/java/com/fr/design/report/fit/menupane/TemplateFitAttrPane.java @@ -1,55 +1,92 @@ package com.fr.design.report.fit.menupane; -import com.fr.design.beans.BasicBeanPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.report.fit.BaseFitAttrPane; +import com.fr.design.report.fit.FitAttrModel; +import com.fr.general.ComparatorUtils; +import com.fr.report.fit.FitProvider; import com.fr.report.fit.ReportFitAttr; -import javax.swing.BorderFactory; -import javax.swing.BoxLayout; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; -/** - * Created by 夏翔 on 2016/6/24. - */ -public class TemplateFitAttrPane extends BasicBeanPane { - private TemplateBrowserFitAttrPane attrPane; +public class TemplateFitAttrPane extends BaseFitAttrPane { - public TemplateFitAttrPane() { + private JTemplate jwb; + + public TemplateFitAttrPane(JTemplate jwb) { + this.jwb = jwb; initComponents(); } - private void initComponents() { - this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); - this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); - attrPane = new TemplateBrowserFitAttrPane(); - this.add(attrPane); + @Override + protected void initComponents() { + super.initComponents(); + for (FitAttrModel fitAttrModel : fitAttrModelList) { + if (fitAttrModel.isAvailable(jwb)) { + populateModel(fitAttrModel); + break; + } + } + } + @Override + public void populateBean(ReportFitAttr reportFitAttr) { + if (reportFitAttr == null) { + itemChoose.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_Using_Server_Report_View_Settings")); + } else { + itemChoose.setSelectedItem(Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single")); + } + populate(reportFitAttr); } - /** - * 展示界面 - * - * @param fitAttr 自适应属性 - */ - public void populateBean(ReportFitAttr fitAttr) { - attrPane.populateBean(fitAttr); + public void populate(ReportFitAttr reportFitAttr) { + if (reportFitAttr == null) { + reportFitAttr = fitAttrModel.getGlobalReportFitAttr(); + } + + super.setEnabled(isTemplateSingleSet()); + super.populateBean(reportFitAttr); } - /** - * 提交数据 - * - * @return 界面上的更新数据 - */ public ReportFitAttr updateBean() { - return attrPane.updateBean(); + if (!isTemplateSingleSet()) { + return null; + } else { + return super.updateBean(); + } + } + + @Override + protected String[] getItemNames() { + return new String[]{Toolkit.i18nText("Fine-Design_Report_Using_Server_Report_View_Settings"), + Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single")}; + } + + @Override + protected ItemListener getItemListener() { + return new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + if(isTemplateSingleSet()){ + if (jwb != null) { + FitProvider wbTpl = (FitProvider) jwb.getTarget(); + ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); + populate(fitAttr); + } + }else { + populate(fitAttrModel.getGlobalReportFitAttr()); + } + } + } + }; } - /** - * 标题 - * - * @return 标题 - */ - protected String title4PopupWindow() { - return com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_PC_Fit_Attr"); + private boolean isTemplateSingleSet() { + return ComparatorUtils.equals(Toolkit.i18nText("Fine-Design_Report_I_Want_To_Set_Single"), itemChoose.getSelectedItem()); } -} +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/report/fit/provider/AbstractFitAttrModelProvider.java b/designer-base/src/main/java/com/fr/design/report/fit/provider/AbstractFitAttrModelProvider.java new file mode 100644 index 0000000000..44d048b7de --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/report/fit/provider/AbstractFitAttrModelProvider.java @@ -0,0 +1,18 @@ +package com.fr.design.report.fit.provider; + +import com.fr.stable.fun.mark.API; + + +@API(level = FitAttrModelProvider.CURRENT_LEVEL) +public abstract class AbstractFitAttrModelProvider implements FitAttrModelProvider { + + @Override + public int currentAPILevel() { + return CURRENT_LEVEL; + } + + @Override + public String mark4Provider() { + return getClass().getName(); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/report/fit/provider/FitAttrModelProvider.java b/designer-base/src/main/java/com/fr/design/report/fit/provider/FitAttrModelProvider.java new file mode 100644 index 0000000000..88f7335d42 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/report/fit/provider/FitAttrModelProvider.java @@ -0,0 +1,11 @@ +package com.fr.design.report.fit.provider; + + +import com.fr.design.report.fit.FitAttrModel; +import com.fr.stable.fun.mark.Mutable; + + +public interface FitAttrModelProvider extends Mutable, FitAttrModel { + String XML_TAG = "FitAttrModelProvider"; + int CURRENT_LEVEL = 1; +} diff --git a/designer-base/src/main/java/com/fr/design/style/color/ColorFactory.java b/designer-base/src/main/java/com/fr/design/style/color/ColorFactory.java index b643752b39..0ab0d8f381 100644 --- a/designer-base/src/main/java/com/fr/design/style/color/ColorFactory.java +++ b/designer-base/src/main/java/com/fr/design/style/color/ColorFactory.java @@ -3,7 +3,7 @@ package com.fr.design.style.color; import java.awt.Color; public interface ColorFactory { - + public static final Color MenuColors[] = { Color.black, new Color(153, 51, 0), @@ -72,17 +72,17 @@ public interface ColorFactory { }; public static final Color STANDARD_COLORS[] = { - new Color(166, 89, 66), - new Color(166, 123, 66), - new Color(166, 66, 66), - new Color(103, 166, 66), - new Color(66, 121, 166), - new Color(68, 66, 166), - new Color(98, 66, 166), - new Color(146, 66, 166), - new Color(75, 18, 89), - new Color(89, 18, 51) + new Color(234, 68, 49), + new Color(179, 96, 36), + new Color(232, 147, 37), + new Color(109, 214, 50), + new Color(51, 147, 219), + new Color(56, 54, 179), + new Color(93, 54, 179), + new Color(154, 54, 179), + new Color(127, 76, 217), + new Color(179, 36, 102) }; - -} \ No newline at end of file + +} diff --git a/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java b/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java index f38e69a8bf..180055b3e0 100644 --- a/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java +++ b/designer-base/src/main/java/com/fr/design/style/color/NewColorSelectPane.java @@ -39,8 +39,10 @@ import java.util.List; public class NewColorSelectPane extends BasicPane implements ColorSelectable { private static final long serialVersionUID = -8634152305687249392L; - private static final int WIDTH = 197; - private static final int HEIGHT = 250; + private static final int WIDTH = 216; + private static final int HEIGHT = 230; + + private static final int DEFAULT_COLOR_HOR_INTERVAL = 4; //颜色衍生的数量 private static final int DEFAULT_DERIVE_COUNT = 5; @@ -81,7 +83,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { initSelectButton(isSupportTransparent); // center JPanel centerPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_S_Pane(); - centerPane.setBorder(BorderFactory.createEmptyBorder(10, 4, 0, 4)); + centerPane.setBorder(BorderFactory.createEmptyBorder(10, 6, 0, 6)); this.add(centerPane, BorderLayout.CENTER); menuColorPane = getMenuColorPane(); @@ -126,14 +128,14 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { customButton.setCursor(new Cursor(Cursor.HAND_CURSOR)); JPanel centerPane1 = new JPanel(new BorderLayout(0, 0)); - centerPane1.setBorder(BorderFactory.createEmptyBorder(9, 0, 11, 0)); + centerPane1.setBorder(BorderFactory.createEmptyBorder(8, 0, 9, 0)); centerPane1.add(customButton, BorderLayout.CENTER); customButton.setPreferredSize(new Dimension(197, 20)); centerPane.add(centerPane1); } private JPanel createStandardColorPane() { - JPanel jPanel = new JPanel(new GridLayout(1, 10, 3, 0)); + JPanel jPanel = new JPanel(new GridLayout(1, 10, DEFAULT_COLOR_HOR_INTERVAL, 0)); Color[] colorArray = ColorFactory.STANDARD_COLORS; for (int i = 0; i < colorArray.length; i++) { jPanel.add(new ColorCell(colorArray[i], this)); @@ -150,8 +152,8 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { themeColorPane.add(menuColorPane, BorderLayout.SOUTH); menuColorPane.setLayout(new BorderLayout(0, 10)); - JPanel northPane = new JPanel(new GridLayout(1, 8, 3, 0)); - JPanel centerPane = new JPanel(new GridLayout(1, 8, 3, 0)); + JPanel northPane = new JPanel(new GridLayout(1, 8, DEFAULT_COLOR_HOR_INTERVAL, 0)); + JPanel centerPane = new JPanel(new GridLayout(1, 8, DEFAULT_COLOR_HOR_INTERVAL, 0)); menuColorPane.add(northPane, BorderLayout.NORTH); menuColorPane.add(centerPane, BorderLayout.CENTER); @@ -189,7 +191,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { northPane.add(themeColorCellGrid[i][0]); } for (int i = 0; i < colorArray.length; i++) { - JPanel columnPane = new JPanel(new GridLayout(DEFAULT_DERIVE_COUNT - 1, 1, 0, 3)); + JPanel columnPane = new JPanel(new GridLayout(DEFAULT_DERIVE_COUNT - 1, 1, 0, 0)); for (int j = 1; j < DEFAULT_DERIVE_COUNT; j++) { columnPane.add(themeColorCellGrid[i][j]); } @@ -233,7 +235,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { private void initMenuColorPane() { - menuColorPane.setLayout(new GridLayout(5, 8, 3, 3)); + menuColorPane.setLayout(new GridLayout(5, 8, DEFAULT_COLOR_HOR_INTERVAL, 0)); Color[] colorArray = this.getColorArray(); for (int i = 0; i < colorArray.length; i++) { Color color = colorArray[i] == null ? UsedColorPane.DEFAULT_COLOR : colorArray[i]; @@ -409,7 +411,7 @@ public class NewColorSelectPane extends BasicPane implements ColorSelectable { private void initialComponents() { int total = columns; JPanel panel = new JPanel(); - panel.setLayout(new GridLayout(1, columns + 1, 3, 3)); + panel.setLayout(new GridLayout(1, columns + 1, DEFAULT_COLOR_HOR_INTERVAL, 0)); panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); //最近使用颜色 Color[] colors = DesignerEnvManager.getEnvManager().getColorConfigManager().getColors(); diff --git a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java index 8c7ed5ac5a..09fa2bbc08 100644 --- a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java @@ -17,15 +17,17 @@ import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; import com.teamdev.jxbrowser.chromium.swing.BrowserView; +import com.teamdev.jxbrowser.event.Observer; import javax.swing.JDialog; import javax.swing.SwingUtilities; import javax.swing.WindowConstants; -import java.util.Map; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.io.File; +import java.util.Map; /** * @author richie @@ -157,6 +159,38 @@ public class ModernUIPane extends BasicPane { return null; } + public void disposeBrowser() { + + if(browser != null) { + browser.dispose(); + browser = null; + } + + } + + public void clearCache() { + if (browser != null) { + browser.getCacheStorage().clearCache(); + File file = new File(browser.getContext().getCacheDir()); + if (file.exists()) { + file.delete(); + } + } + } + + public void executeJavaScript(String javaScript) { + if (browser != null) { + browser.executeJavaScript(javaScript); + } + } + + public JSValue executeJavaScriptAndReturnValue(String javaScript) { + if (browser != null) { + return browser.executeJavaScriptAndReturnValue(javaScript); + } + return null; + } + public static class Builder implements BuilderDiff { private ModernUIPane pane; @@ -293,6 +327,12 @@ public class ModernUIPane extends BasicPane { return this; } + @Override + public Builder prepareForV7(Class event, Observer listener) { + // do nothing + return this; + } + public ModernUIPane build() { return pane; } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java b/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java index 33c817c948..9e6168514f 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java @@ -4,6 +4,7 @@ import com.fr.design.ui.ModernUIPane; import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; import com.teamdev.jxbrowser.chromium.events.LoadListener; import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; +import com.teamdev.jxbrowser.event.Observer; /** * 封装jxbrwoser v6/v7的构建方式的差异 @@ -20,5 +21,6 @@ public interface BuilderDiff { ModernUIPane.Builder prepareForV7(InjectJsCallback callback); + ModernUIPane.Builder prepareForV7(Class event, Observer listener); } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java b/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java index 5ae56627e9..68b8950f7c 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java @@ -11,6 +11,17 @@ import com.fr.stable.os.OperatingSystem; public class ModernUIPaneFactory { public static ModernUIPane.Builder modernUIPaneBuilder() { + + if (isV7()) { + return new NewModernUIPane.Builder<>(); + } else { + return new ModernUIPane.Builder<>(); + } + + } + + public static boolean isV7() { + // 7.15的class不存在时 走老版本 boolean hasJxBrowserV7_15 = true; try { @@ -18,10 +29,8 @@ public class ModernUIPaneFactory { } catch (ClassNotFoundException e) { hasJxBrowserV7_15 = false; } - if (OperatingSystem.isWindows() && hasJxBrowserV7_15) { - return new NewModernUIPane.Builder<>(); - } else { - return new ModernUIPane.Builder<>(); - } + + return OperatingSystem.isWindows() && hasJxBrowserV7_15; + } } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java index 33747d3f15..d755d4e05f 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java @@ -15,6 +15,7 @@ import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; import com.teamdev.jxbrowser.engine.Engine; import com.teamdev.jxbrowser.engine.EngineOptions; import com.teamdev.jxbrowser.engine.RenderingMode; +import com.teamdev.jxbrowser.event.Observer; import com.teamdev.jxbrowser.js.JsObject; import com.teamdev.jxbrowser.net.Scheme; import com.teamdev.jxbrowser.view.swing.BrowserView; @@ -80,30 +81,33 @@ public class NewModernUIPane extends ModernUIPane { private void showDebuggerDialog() { JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this)); - Engine engine = Engine.newInstance( - EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED) - .addSwitch("--disable-google-traffic") - .remoteDebuggingPort(9222).build()); - Browser debugger = engine.newBrowser(); + + Browser debugger = browser.engine().newBrowser(); BrowserView debuggerView = BrowserView.newInstance(debugger); dialog.add(debuggerView, BorderLayout.CENTER); dialog.setSize(new Dimension(800, 400)); GUICoreUtils.centerWindow(dialog); dialog.setVisible(true); dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + browser.devTools().remoteDebuggingUrl().ifPresent(url -> { debugger.navigation().loadUrl(url); }); } private void initializeBrowser() { - EngineOptions options; + EngineOptions.Builder builder; if (scheme != null && requestCallback != null) { - options = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").addScheme(scheme, requestCallback).build(); - } else { - options = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").build(); + builder = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").addScheme(scheme, requestCallback); + } else { + builder = EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic"); + } + + if (DesignerEnvManager.getEnvManager().isOpenDebug()) { + builder.remoteDebuggingPort(9222); } - Engine engine = Engine.newInstance(options); + + Engine engine = Engine.newInstance(builder.build()); browser = engine.newBrowser(); // 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的 @@ -161,6 +165,29 @@ public class NewModernUIPane extends ModernUIPane { return null; } + public void disposeBrowser() { + + if (browser != null) { + browser.close(); + browser = null; + } + + } + + public void clearCache() { + if (browser != null) { + browser.engine().httpCache().clear(); + } + } + + public void executeJavaScript(String javaScript) { + if (browser != null) { + browser.mainFrame().ifPresent(frame -> { + frame.executeJavaScript(javaScript); + }); + } + } + public static class Builder extends ModernUIPane.Builder { private NewModernUIPane pane = new NewModernUIPane<>(); @@ -191,7 +218,7 @@ public class NewModernUIPane extends ModernUIPane { @Override public NewModernUIPane.Builder withURL(final String url) { pane.scheme = Scheme.of("file"); - pane.requestCallback = new NxComplexInterceptRequestCallback(null); + pane.requestCallback = new NxComplexInterceptRequestCallback(null); pane.browser.navigation().loadUrl(url); return this; } @@ -301,6 +328,14 @@ public class NewModernUIPane extends ModernUIPane { return prepare(callback); } + @Override + public ModernUIPane.Builder prepareForV7(Class event, Observer listener) { + + pane.browser.navigation().on(event, listener); + + return this; + } + @Override public NewModernUIPane build() { return pane; diff --git a/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java b/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java index 1d93611386..24134dce18 100644 --- a/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/ComponentUtils.java @@ -1,11 +1,13 @@ package com.fr.design.utils; import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; import javax.swing.*; import java.awt.*; import java.awt.geom.Rectangle2D; import java.util.ArrayList; +import java.util.List; /** * 工具类,提供常用的工具方法 @@ -151,4 +153,62 @@ public class ComponentUtils { } return false; } + + public static Component findComponentByName(Component container, String componentName) { + Component target = null; + if (container instanceof Container) { + for (Component component: ((Container)container).getComponents()) { + if (componentName.equals(component.getName())) { + return component; + } + if (component instanceof JRootPane) { + JRootPane nestedJRootPane = (JRootPane)component; + target = findComponentByName(nestedJRootPane.getContentPane(), componentName); + } else if (component instanceof Container){ + target = findComponentByName( component, componentName); + } + if (target != null) { + return target; + } + } + } + return null; + } + + public static Component findComponentByClass(Component container, Class clazz) { + Component target = null; + if (container instanceof Container) { + for (Component component: ((Container)container).getComponents()) { + if (clazz.isInstance(component)) { + return component; + } + if (component instanceof JRootPane) { + JRootPane nestedJRootPane = (JRootPane)component; + target = findComponentByClass(nestedJRootPane.getContentPane(), clazz); + } else if (component instanceof Container){ + target = findComponentByClass(component, clazz); + } + if (target != null) { + return target; + } + } + } + return null; + } + + public static List findComponentsByClass(Component container, Class clazz) { + List components= new ArrayList<>(); + if (container instanceof Container) { + for (Component component: ((Container)container).getComponents()) { + if (clazz.isInstance(component)) { + components.add(component); + continue; + } + if (component instanceof Container){ + components.addAll(findComponentsByClass(component, clazz)); + } + } + } + return components; + } } \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java b/designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java new file mode 100644 index 0000000000..abae997e39 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/utils/gui/AdjustWorkBookDefaultStyleUtils.java @@ -0,0 +1,46 @@ +package com.fr.design.utils.gui; + +import com.fr.base.Style; +import com.fr.base.background.ColorBackground; +import com.fr.design.base.mode.DesignModeContext; +import com.fr.report.cell.CellElement; +import com.fr.report.cell.FloatElement; + +import java.awt.Color; + +/** + * @author shine + * @version 10.0 + * Created by shine on 2021/9/6 + */ +public class AdjustWorkBookDefaultStyleUtils { + + private static final Color TEMPLATE_BACKGROUND = new Color(16, 11, 43); + private static final Color CELL_ELEMENT_BORDER = new Color(110, 110, 110); + + public static void adjustCellElement(CellElement cellElement) { + if (DesignModeContext.isDuchampMode()) { + Style style = cellElement.getStyle(); + style = style.deriveFRFont(style.getFRFont().applyForeground(Color.WHITE)); + style = style.deriveBorder(0, CELL_ELEMENT_BORDER, + 0, CELL_ELEMENT_BORDER, + 0, CELL_ELEMENT_BORDER, + 0, CELL_ELEMENT_BORDER); + cellElement.setStyle(style); + } + } + + public static void adjustFloatElement(FloatElement floatElement) { + if (DesignModeContext.isDuchampMode()) { + Style style = floatElement.getStyle(); + style = style.deriveBackground(ColorBackground.getInstance(TEMPLATE_BACKGROUND)); + style = style.deriveFRFont(style.getFRFont().applyForeground(Color.WHITE)); + floatElement.setStyle(style); + } + } + + public static Color adjustBack(Color color) { + return DesignModeContext.isDuchampMode() ? TEMPLATE_BACKGROUND : color; + } + +} diff --git a/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java b/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java index a89e367d64..ac75786314 100644 --- a/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java +++ b/designer-base/src/main/java/com/fr/design/utils/gui/GUICoreUtils.java @@ -38,7 +38,6 @@ import com.fr.stable.Constants; import com.fr.stable.OperatingSystem; import com.fr.stable.StringUtils; -import java.awt.Container; import javax.swing.AbstractButton; import javax.swing.Action; import javax.swing.BorderFactory; @@ -67,10 +66,13 @@ import javax.swing.tree.TreePath; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Container; import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.Font; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; import java.awt.GridLayout; import java.awt.Image; import java.awt.Point; @@ -82,8 +84,6 @@ import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.awt.image.BufferedImage; import java.awt.image.ImageObserver; -import java.awt.GraphicsDevice; -import java.awt.GraphicsEnvironment; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -176,7 +176,7 @@ public final class GUICoreUtils { if (style.getBackground() instanceof ColorBackground) { textField.setBackground(((ColorBackground) style.getBackground()).getColor()); } else { - textField.setBackground(Color.WHITE); + textField.setBackground(AdjustWorkBookDefaultStyleUtils.adjustBack(Color.WHITE)); } } diff --git a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java index 819660a99d..40e6683eb5 100644 --- a/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java +++ b/designer-base/src/main/java/com/fr/design/worker/open/OpenWorker.java @@ -7,12 +7,14 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrameFileDealerPane; import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.DesignUtils; import com.fr.design.worker.WorkerManager; import com.fr.exception.DecryptTemplateException; import com.fr.file.FILE; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; import javax.swing.JOptionPane; import javax.swing.SwingWorker; import javax.swing.UIManager; @@ -61,7 +63,7 @@ public class OpenWorker extends SwingWorker { } catch (CancellationException ignored) { return; } catch (Throwable t) { - processFailed(); + processFailed(StringUtils.EMPTY); Throwable cause = t.getCause(); if (cause instanceof DecryptTemplateException) { FineJOptionPane.showMessageDialog( @@ -91,6 +93,11 @@ public class OpenWorker extends SwingWorker { if (slowly && templateCallable != null) { try { JTemplate book = templateCallable.call(); + if (inValidDesigner(book)) { + String text = Toolkit.i18nText("Fine-Design_Report_Template_Version_Not_Match", DesignUtils.parseVersion(book.getTarget().getDesignerVersion())); + processFailed(text); + return; + } FILE tplFile = book.getEditingFILE(); JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); // 当前tab页是正在打开的模板 @@ -117,11 +124,21 @@ public class OpenWorker extends SwingWorker { WorkerManager.getInstance().removeWorker(taskName); } - private void processFailed() { + private boolean inValidDesigner(JTemplate jt) { + return jt.isOldDesigner(false) || (!jt.isJWorkBook() && jt.isNewDesigner(false)); + } + + private void processFailed(String text) { this.template.setOpenFailed(true); this.template.setOpening(false); - DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showOpenFailedCover(); - DesignerFrameFileDealerPane.getInstance().stateChange(); + JTemplate currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + // 需要判断当前打开的模板是不是异步执行后失败的模板 是的话立即展示失败后的提示内容 否则只设置下失败的提示内容 + if (ComparatorUtils.equals(currentTemplate.getEditingFILE().getName(), this.template.getEditingFILE().getName())) { + DesignerContext.getDesignerFrame().getCenterTemplateCardPane().showOpenFailedCover(text); + DesignerFrameFileDealerPane.getInstance().stateChange(); + } else { + this.template.setTemplateOpenFailedTip(text); + } WorkerManager.getInstance().removeWorker(taskName); } diff --git a/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java b/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java index d07d42b3e2..6e4f2d803f 100644 --- a/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java +++ b/designer-base/src/main/java/com/fr/design/write/submit/CustomJobPane.java @@ -13,6 +13,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; +import com.fr.stable.ListMap; import com.fr.stable.StringUtils; import com.fr.design.utils.gui.GUICoreUtils; @@ -115,7 +116,12 @@ public abstract class CustomJobPane extends BasicBeanPane { @Override public void populateBean(Object ob) { - if (ob instanceof AbstractClassJob) { + if (ob == null) { + // 自定义提交新增时初始化页面 REPORT-59256 + this.classNameTextField.setText(StringUtils.EMPTY); + this.objectProperiesPane.populateBean(new ListMap()); + } + else if (ob instanceof AbstractClassJob) { AbstractClassJob cj = (AbstractClassJob) ob; this.classNameTextField.setText(cj.getClassName()); this.objectProperiesPane.populateBean(cj.getPropertyMap()); diff --git a/designer-base/src/main/java/com/fr/env/ErrorDialog.java b/designer-base/src/main/java/com/fr/env/ErrorDialog.java index be91955f2f..a26c673a45 100644 --- a/designer-base/src/main/java/com/fr/env/ErrorDialog.java +++ b/designer-base/src/main/java/com/fr/env/ErrorDialog.java @@ -39,7 +39,7 @@ public class ErrorDialog extends JDialog implements ActionListener { messagePanel.setBorder(BorderFactory.createEmptyBorder(5,0,0,0)); MessageWithLink messageWithLink = new MessageWithLink(message + ",", Toolkit.i18nText("Fine-Design_Basic_Sync_Help"), CloudCenter.getInstance().acquireUrlByKind("help.replacejars", "https://help.fanruan.com/finereport/doc-view-3268.html")); - messageWithLink.setPreferredSize(new Dimension(108, 20)); + messageWithLink.setPreferredSize(new Dimension(150, 20)); JPanel messageLinkPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); messageLinkPane.setBorder(BorderFactory.createEmptyBorder(5, 8, 5, 0)); messageLinkPane.add(messageWithLink); diff --git a/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java index 8117f87395..fd4b98e33e 100644 --- a/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java +++ b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java @@ -5,6 +5,7 @@ import com.fr.design.dialog.link.MessageWithLink; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextarea.UITextArea; +import com.fr.design.i18n.DesignSizeI18nManager; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; @@ -62,7 +63,7 @@ public class SyncFailedPluginsDialog extends JDialog { JPanel messagePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); MessageWithLink messageWithLink = new MessageWithLink(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugin_Fail_Suggestion"),Toolkit.i18nText("Fine-Design_Basic_Sync_Deal_Immediately"), CloudCenter.getInstance().acquireUrlByKind("help.installplugins", "https://help.fanruan.com/finereport/doc-view-2198.html")); - messageWithLink.setPreferredSize(new Dimension(316, 20)); + messageWithLink.setPreferredSize(DesignSizeI18nManager.getInstance().i18nDimension("com.fr.env.SyncFailedPluginsDialog.messageWithLink")); messagePane.add(messageWithLink); messagePane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 0)); diff --git a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java index 5ea393ba64..c21c82c75a 100644 --- a/designer-base/src/main/java/com/fr/file/FILEChooserPane.java +++ b/designer-base/src/main/java/com/fr/file/FILEChooserPane.java @@ -29,6 +29,9 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.JTemplate; import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; import com.fr.file.filetree.FileNode; import com.fr.file.filter.ChooseFileFilter; import com.fr.file.filter.FILEFilter; @@ -45,6 +48,8 @@ import com.fr.stable.os.windows.WindowsDetector; import com.fr.stable.project.ProjectConstants; import com.fr.workspace.WorkContext; +import com.fr.workspace.Workspace; +import com.fr.workspace.WorkspaceEvent; import javax.swing.AbstractAction; import javax.swing.AbstractListModel; import javax.swing.ActionMap; @@ -66,7 +71,6 @@ import javax.swing.ListModel; import javax.swing.ListSelectionModel; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; -import javax.swing.UIManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.event.ListSelectionEvent; @@ -644,7 +648,7 @@ public class FILEChooserPane extends BasicPane { this.suffix = suffix; if (!text.endsWith(suffix)) { - text = text + suffix; + text = removeSuffix(text) + suffix; } fileNameTextField.removeDocumentListener(); fileNameTextField.setText(text); @@ -660,6 +664,14 @@ public class FILEChooserPane extends BasicPane { fileNameTextField.setFilter(new DefaultCompletionFilter(names)); } + /** + * 移除文件后缀的方法 + * 解决cptx文件的另存为操作默认会出现双后缀的bug(xxx.cptx.cpt) + **/ + private String removeSuffix(String text){ + return FileExtension.CPTX.matchExtension(text) ? text.substring(0, text.length() - FileExtension.CPTX.getSuffix().length()) : text; + } + /** * 打开对话框 @@ -1326,6 +1338,12 @@ public class FILEChooserPane extends BasicPane { LocationButtonPane.this.repaint(10); } }); + EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener() { + @Override + public void on(Event event, Workspace param) { + setPopDir(null); + } + }); } public void highLightButton(FILE dir) { diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java b/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java index e988e04e73..15e3c8bf90 100644 --- a/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java +++ b/designer-base/src/main/java/com/fr/nx/app/designer/toolbar/TransformResultInfo.java @@ -57,7 +57,7 @@ public class TransformResultInfo { return InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Success_Tip"); case UNSUPPORT: return transformLog + "\n" - + InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_Transform_Unsupport_Tip"); + + InterProviderFactory.getProvider().getLocText("Fine-Plugin_Engine_X_Unsupport_Tip"); } return transformLog; } diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptAndCptxCompatibilityUtil.java b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptAndCptxCompatibilityUtil.java new file mode 100644 index 0000000000..0b1a65657a --- /dev/null +++ b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptAndCptxCompatibilityUtil.java @@ -0,0 +1,88 @@ +package com.fr.nx.app.designer.utils; + +import com.fr.base.extension.FileExtension; +import com.fr.design.mainframe.JTemplate; +import com.fr.file.FILE; +import com.fr.main.TemplateWorkBook; +import com.fr.report.report.Report; +import com.fr.report.stable.LayerReportAttr; +import com.fr.report.worksheet.WorkSheet; + +/** + * @author fly.li + * @version 10.0 + * Created on 2021/09/12 + */ +public class CptAndCptxCompatibilityUtil { + + /** + * 判断是否需要重新编译 + **/ + public static boolean needRecompile(String oldName, JTemplate jTemplate){ + FILE editingFILE = jTemplate.getEditingFILE(); + String path = editingFILE.getPath(); + //只有在旧文件是cptx文件并且新文件是cpt文件时才会改变报表引擎属性 + boolean isCptxConvertToCpt = FileExtension.CPTX.matchExtension(oldName) && FileExtension.CPT.matchExtension(path); + if (isCptxConvertToCpt && !setFrEngineAttr(jTemplate)){ + isCptxConvertToCpt = false; + } + return (isCptxConvertToCpt || isSaveAs(jTemplate, oldName, path)); + } + + /** + * 判断是不是cptx模板或者开启了的新引擎的cpt模板的另存为操作 + **/ + private static boolean isSaveAs(JTemplate jTemplate, String oldName, String newName){ + return isEngineXEnable(jTemplate.getTarget(), newName) && ((FileExtension.CPTX.matchExtension(oldName) && FileExtension.CPTX.matchExtension(newName)) || (FileExtension.CPT.matchExtension(oldName) && FileExtension.CPT.matchExtension(newName))); + } + + /** + * cptx另存为cpt需要修改报表引擎属性 + **/ + private static boolean setFrEngineAttr(JTemplate jTemplate){ + WorkSheet workSheet = gainWorkSheet(jTemplate.getTarget()); + if (workSheet == null){ + return false; + }else { + LayerReportAttr layerReportAttr = workSheet.getLayerReportAttr(); + if (layerReportAttr == null){ + layerReportAttr = new LayerReportAttr(); + workSheet.setLayerReportAttr(layerReportAttr); + } + layerReportAttr.setClientPaging(true); + layerReportAttr.setEngineState(0); + return true; + } + } + + /** + * 是否启用了新引擎的判断 + * cptx自动走新引擎(非兼容模式),cpt需要进行设置 + * */ + public static boolean isEngineXEnable(Object workBook, String fileName){ + WorkSheet workSheet = gainWorkSheet(workBook); + LayerReportAttr layerReportAttr = gainLayerReportAttr(workSheet); + return isEngineXEnable(layerReportAttr, fileName); + } + + private static LayerReportAttr gainLayerReportAttr(WorkSheet workSheet){ + if (workSheet != null){ + LayerReportAttr layerReportAttr = workSheet.getLayerReportAttr(); + return layerReportAttr; + } else { + return null; + } + } + + private static WorkSheet gainWorkSheet(Object workBook){ + if (workBook == null || !(workBook instanceof TemplateWorkBook)){ + return null; + } + Report report = ((TemplateWorkBook) workBook).getReport(0); + return report instanceof WorkSheet ? (WorkSheet)report : null; + } + + private static boolean isEngineXEnable(LayerReportAttr layerReportAttr, String fileName){ + return (layerReportAttr!= null && layerReportAttr.isClientPaging() && layerReportAttr.getEngineState() == LayerReportAttr.ENGINE_X) || FileExtension.CPTX.matchExtension(fileName); + } +} diff --git a/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptCompileUtil.java b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptCompileUtil.java new file mode 100644 index 0000000000..36c1846709 --- /dev/null +++ b/designer-base/src/main/java/com/fr/nx/app/designer/utils/CptCompileUtil.java @@ -0,0 +1,153 @@ +package com.fr.nx.app.designer.utils; + +import com.fr.base.extension.FileExtension; +import com.fr.design.mainframe.JTemplate; +import com.fr.file.FILE; +import com.fr.file.FileNodeFILE; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.main.impl.WorkBook; +import com.fr.nx.app.designer.cptx.io.DesignReadWritableProvider; +import com.fr.nx.app.designer.monitor.DesignerMetricRecorder; +import com.fr.nx.app.designer.toolbar.TransformResult; +import com.fr.nx.app.designer.toolbar.TransformResultInfo; +import com.fr.nx.compile.CompileStatus; +import com.fr.nx.compile.ReportCompiler; +import com.fr.nx.compile.adapter.LegacyWorkBookAdapter; +import com.fr.nx.compile.util.ReportCompileUtils; +import com.fr.nx.cptx.CptxIOManager; +import com.fr.nx.cptx.cache.CptxTemplatePool; +import com.fr.nx.cptx.entry.CptxTemplate; +import com.fr.nx.cptx.io.handle.CptxTemplateHandle; +import com.fr.nx.cptx.monitor.CompileMonitorHandler; +import com.fr.nx.cptx.utils.CptxFileUtils; +import com.fr.nx.data.layer.LayerItem; +import com.fr.nx.data.layer.LayerProps; +import com.fr.nx.template.compile.CompiledReport; + +import java.io.OutputStream; + + +public class CptCompileUtil { + public static void compile(JTemplate jtemplate) { + if (jtemplate == null || jtemplate.getEditingFILE() == null) { + return; + } + FILE file = jtemplate.getEditingFILE(); + String path = file.getPath(); + Object target = jtemplate.getTarget(); + /* + * 如果是cpt并且引擎设置正确,执行预编译,如果是cptx文件也执行预编译。在JStreamWork中,保存和另存为流程都进行了重新编译。 + * 但是由于之前的DefaultTemplateResource.saveTemplate的原因导致JStreamWork::saveFile()不能执行--cptx的保存不能进行预编译, + * 应该是流程的误改动,这里改回来,保存时仍然执行预编译。 + * 预编译本不应该受引擎模式的影响,但是cpt文件在设置为新引擎后是需要进行编译的 + * */ + + if (!CptAndCptxCompatibilityUtil.isEngineXEnable(target, path)){ + return; + } + WorkBook workbook = (WorkBook) jtemplate.getTarget(); + TransformResultInfo resultInfo = compile0(workbook, file); + unSupportLog(resultInfo); + + } + + private static TransformResultInfo compile0(WorkBook workbook, FILE file) { + if (!(file instanceof FileNodeFILE)) { + try { + OutputStream outputStream = file.asOutputStream(); + workbook.export(outputStream); + return TransformResultInfo.generateResult(TransformResult.SUCCESS).saved(true); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return TransformResultInfo.generateResult(TransformResult.FAILED).saved(false); + } + } + boolean saved; + CompiledReport report = null; + CompileStatus compileStatus = CompileStatus.SUCCEED; + if (workbook == null || file == null) { + return TransformResultInfo + .generateResult(TransformResult.FAILED, "work and file must not be null") + .saved(false); + } + String failMessage = null; + // 编译 + ReportCompiler compiler; + try { + compiler = new ReportCompiler(new LegacyWorkBookAdapter(workbook)); + long startTime = System.currentTimeMillis(); + compiler.compile(); + report = compiler.getCompiledReport(); + // 折叠树埋点 + LayerProps props = ReportCompileUtils.getLayerProps(report); + LayerItem[] items; + if (props != null && (items = props.getLayerItems()) != null) { + CompileMonitorHandler.submitTreeCompileFocusPoint( + startTime, file.getPath(), items.length, + props.getExpandLayer(), true + ); + } + compileStatus = compiler.getStatus(); + failMessage = compiler.getFailMessage(); + long endTime = System.currentTimeMillis(); + CompileMonitorHandler.submitCompileMessage(startTime, endTime, file.getPath(), ""); + if (compileStatus != CompileStatus.SUCCEED) { + DesignerMetricRecorder.submitUnSupportTransform( + TransformResult.UNSUPPORT, + workbook.getTemplateID(), + file.getName(), + compileStatus == CompileStatus.FAILED_UNSUPPORT ? failMessage : null + ); + } + } catch (Exception exception) { + String templateID = workbook.getTemplateID(); + String fileName = file.getName(); + DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, templateID, fileName, exception); + FineLoggerFactory.getLogger().error(exception.getMessage(), exception); + } + + // 构建编译结果,当前的 cptx template 是未经反序列化钩子处理过的 cptx 模版对象,不能直接用于模版预览 + CptxTemplate template = CptxIOManager.createCptxTemplate(workbook, report, compileStatus, failMessage); + // 保存 + DesignReadWritableProvider cptx = new DesignReadWritableProvider(file); + CptxTemplateHandle handle = CptxIOManager.create(template, cptx); + try { + saved = handle.save(); + } catch (Exception exception) { + // 存储cptx格式报错或者失败 + FineLoggerFactory.getLogger().error(exception.getMessage(), exception); + DesignerMetricRecorder.submitFailedTransform(TransformResult.FAILED, workbook.getTemplateID(), file.getName(), exception); + return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(false); + } + // 读取可 web 预览模版并缓存 + try { + CptxTemplate previewCptxTemplate = CptxIOManager.open(cptx).getTemplate(); + CptxTemplatePool.getInstance().addCptxTemplate(CptxFileUtils.getFormatPath(file.getPath()), previewCptxTemplate); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + if (report == null) { + // 编译报错或者失败 + return TransformResultInfo.generateResult(TransformResult.FAILED, failMessage).saved(saved); + } + return TransformResultInfo.generateResult(TransformResult.parse(compileStatus), failMessage).saved(saved); + } + + private static boolean needDoAfterCompile(TransformResult result) { + return ComparatorUtils.equals(TransformResult.SUCCESS, result) + || ComparatorUtils.equals(TransformResult.UNSUPPORT, result); + } + + private static void unSupportLog(TransformResultInfo transformResultInfo){ + TransformResult result = transformResultInfo.getResult(); + //这里只打印模板转换不支持的信息,没有打印模板转换失败的信息 + if (result.equals(TransformResult.UNSUPPORT)){ + FineLoggerFactory.getLogger().error(transformResultInfo.getTransformLog()); + } + } + + private static boolean isUnSupportFileType(String path){ + return FileExtension.CPT.matchExtension(path) || FileExtension.CPTX.matchExtension(path); + } +} diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties index ef851ffe3f..686c3da8a8 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_en.properties @@ -7,4 +7,9 @@ com.fr.env.RemoteEnvPane.dialog=458*132 com.fr.design.version.check.dialog=490*95 com.fr.design.version.detail.label=750*30 com.fr.design.version.detail.dialog=900*500 -com.fr.design.web.pane.text.field=450*20 \ No newline at end of file +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*36 +com.fr.design.web.pane.text.field=450*20 +com.fr.design.actions.server.dialog=800*630 +com.fr.design.report.fit.templatePane.dialog=800*400 +com.fr.design.report.fit.firstColumn=120*20 +com.fr.design.report.fit.column=160*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties index 379c257449..5937b272ae 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ja_JP.properties @@ -6,4 +6,9 @@ com.fr.env.RemoteEnvPane.dialog=458*132 com.fr.design.version.check.dialog=430*95 com.fr.design.version.detail.label=650*30 com.fr.design.version.detail.dialog=800*500 -com.fr.design.web.pane.text.field=400*20 \ No newline at end of file +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*36 +com.fr.design.web.pane.text.field=400*20 +com.fr.design.actions.server.dialog=700*630 +com.fr.design.report.fit.templatePane.dialog=600*400 +com.fr.design.report.fit.firstColumn=170*20 +com.fr.design.report.fit.column=100*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties index 62ee87a7c4..5615b35556 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_ko_KR.properties @@ -6,4 +6,9 @@ com.fr.env.RemoteEnvPane.dialog=458*132 com.fr.design.version.check.dialog=450*95 com.fr.design.version.detail.label=700*30 com.fr.design.version.detail.dialog=850*500 -com.fr.design.web.pane.text.field=450*20 \ No newline at end of file +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*36 +com.fr.design.web.pane.text.field=450*20 +com.fr.design.actions.server.dialog=700*630 +com.fr.design.report.fit.templatePane.dialog=600*400 +com.fr.design.report.fit.firstColumn=130*20 +com.fr.design.report.fit.column=100*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties index fff64947d9..c507fcc083 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh.properties @@ -7,4 +7,9 @@ com.fr.env.RemoteEnvPane.dialog=308*132 com.fr.design.version.check.dialog=230*95 com.fr.design.version.detail.label=450*30 com.fr.design.version.detail.dialog=600*500 -com.fr.design.web.pane.text.field=450*20 \ No newline at end of file +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*20 +com.fr.design.web.pane.text.field=450*20 +com.fr.design.actions.server.dialog=700*630 +com.fr.design.report.fit.templatePane.dialog=600*400 +com.fr.design.report.fit.firstColumn=80*20 +com.fr.design.report.fit.column=100*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties index 4b2de3f02c..8a383a4387 100644 --- a/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties +++ b/designer-base/src/main/resources/com/fr/design/i18n/dimension_zh_TW.properties @@ -6,4 +6,9 @@ com.fr.env.RemoteEnvPane.dialog=308*132 com.fr.design.version.check.dialog=230*95 com.fr.design.version.detail.label=450*30 com.fr.design.version.detail.dialog=600*500 -com.fr.design.web.pane.text.field=450*20 \ No newline at end of file +com.fr.env.SyncFailedPluginsDialog.messageWithLink=316*20 +com.fr.design.web.pane.text.field=450*20 +com.fr.design.actions.server.dialog=700*630 +com.fr.design.report.fit.templatePane.dialog=600*400 +com.fr.design.report.fit.firstColumn=80*20 +com.fr.design.report.fit.column=100*20 \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/images/transparent_background.png b/designer-base/src/main/resources/com/fr/design/images/transparent_background.png index cfb233f46e..4f942536f8 100644 Binary files a/designer-base/src/main/resources/com/fr/design/images/transparent_background.png and b/designer-base/src/main/resources/com/fr/design/images/transparent_background.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_down.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_down.png new file mode 100644 index 0000000000..cf65b3bc4f Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_down.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_right.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_right.png new file mode 100644 index 0000000000..a1ac42cfea Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/arrow_right.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/close.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/close.png new file mode 100644 index 0000000000..6f17a8e1c7 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/close.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_all.svg b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_all.svg new file mode 100644 index 0000000000..f18c158027 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_all.svg @@ -0,0 +1,13 @@ + + + 全部完成 + + + + + + + + + + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_none.svg b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_none.svg new file mode 100644 index 0000000000..ec078243bf --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_none.svg @@ -0,0 +1,13 @@ + + + 未完成@2x + + + + + + + + + + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_some.svg b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_some.svg new file mode 100644 index 0000000000..e6151ea038 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/mainframe/guide/complete_some.svg @@ -0,0 +1,23 @@ + + + 部分完成 + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/guide.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/guide.png new file mode 100644 index 0000000000..ef5a197834 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/guide.png differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/loading.gif b/designer-base/src/main/resources/com/fr/design/mainframe/guide/loading.gif new file mode 100644 index 0000000000..90d13277af Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/loading.gif differ diff --git a/designer-base/src/main/resources/com/fr/design/mainframe/guide/success.png b/designer-base/src/main/resources/com/fr/design/mainframe/guide/success.png new file mode 100644 index 0000000000..efd7a04f4b Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/mainframe/guide/success.png differ diff --git a/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java b/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java index 8600a8c149..2d54fc8189 100644 --- a/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java +++ b/designer-chart/src/main/java/com/fr/design/ChartTypeInterfaceManager.java @@ -149,7 +149,7 @@ public class ChartTypeInterfaceManager implements ExtraChartDesignClassManagerPr public static WidgetOption[] initWidgetOption() { - String[] chartIDs = ChartTypeManager.getInstance().getAllChartIDs(); + String[] chartIDs = ChartTypeManager.getInstance().getChartIDs4Create(); ChartWidgetOption[] child = new ChartWidgetOption[chartIDs.length]; int index = 0; diff --git a/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java b/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java index a5937c1d9d..d31cd32088 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/chart/ChartTypePane.java @@ -31,7 +31,7 @@ import java.awt.Component; public class ChartTypePane extends ChartCommonWizardPane implements CallbackEvent { private static final long serialVersionUID = -1175602484968520546L; - private String[] chartIDs = ChartTypeManager.getInstanceWithCheck().getAllChartIDs(); + private String[] chartIDs = ChartTypeManager.getInstanceWithCheck().getChartIDs4Create(); private JList mainTypeList = null; private JList iconViewList = null; diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java index 90b0e88054..2d4d5fef6c 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/ChartPropertyPane.java @@ -55,6 +55,8 @@ public class ChartPropertyPane extends BaseChartPropertyPane { chartEditPane.setContainer(container); currentID = plotID; resetChartEditPane(); + } else { + chartEditPane.resetLastChartCollection(); } } diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java index d6acb929a7..70b7130f12 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java @@ -118,6 +118,10 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare this.listenerList.remove(ChartEditPaneActionListener.class, l); } + public void resetLastChartCollection() { + this.lastCollection = null; + } + private void fireAttributeChange(ChartCollection chartCollection) { // Guaranteed to return a non-null array Object[] listeners = listenerList.getListenerList(); diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java index 1fdd6e9fd8..7260fe581c 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypeButtonPane.java @@ -660,7 +660,7 @@ public class ChartTypeButtonPane extends BasicBeanPane implemen //记录改变前的plotID String lastPlotID = editingCollection == null ? StringUtils.EMPTY : editingCollection.getSelectedChartProvider(ChartProvider.class).getID(); changeCollectionSelected(getButtonName()); - setSelectedWithFireListener(true); + setSelected(true, true); fireSelectedChanged(); //需要先更新,最后重构面板 diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java index 985ee28afa..2eea49f16d 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/gui/ChartTypePane.java @@ -4,6 +4,7 @@ import com.fr.chart.chartattr.ChartCollection; import com.fr.chart.charttypes.ChartTypeManager; import com.fr.chartx.attr.ChartProvider; import com.fr.design.ChartTypeInterfaceManager; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.beans.FurtherBasicBeanPane; import com.fr.design.dialog.BasicScrollPane; import com.fr.design.dialog.DialogActionAdapter; @@ -18,6 +19,7 @@ import com.fr.design.mainframe.chart.gui.item.FlexibleComboBox; import com.fr.design.mainframe.chart.gui.item.ItemEventType; import com.fr.design.mainframe.chart.gui.type.AbstractChartTypePane; import com.fr.design.mainframe.chart.mode.ChartEditContext; +import com.fr.design.mainframe.chart.mode.ChartEditMode; import com.fr.design.module.DesignModuleFactory; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; @@ -173,7 +175,7 @@ public class ChartTypePane extends AbstractChartAttrPane { Map>> allChartTypePane, ActionListener autoButtonListener) { - String[] chartIDs = ChartTypeManager.getInstance().getAllChartIDsIncludeDisabled(); + String[] chartIDs = ChartTypeManager.getInstance().getAllChartIDs(); for (String id : chartIDs) { @@ -288,7 +290,9 @@ public class ChartTypePane extends AbstractChartAttrPane { Map.Entry> entry = iterator.next(); String plotID = entry.getKey(); if (ignore || ChartTypeManager.enabledChart(plotID)) { - cards.add(entry.getValue()); + if (ChartTypeManager.getInstance().isShowInDesigner(plotID)) { + cards.add(entry.getValue()); + } } } @@ -310,7 +314,9 @@ public class ChartTypePane extends AbstractChartAttrPane { //第一步就是重构cards cards.clear(); - if (enabledChart) { + if (ChartEditContext.duchampMode()) { + addOnePlotIDCards(priority, chartID); + } else if (enabledChart) { if (collection.getChartCount() == 1) { addAllCards(); } else { diff --git a/designer-chart/src/main/java/com/fr/design/module/ChartPreStyleListPane.java b/designer-chart/src/main/java/com/fr/design/module/ChartPreStyleListPane.java index 0c3f85b1bc..99d048a811 100644 --- a/designer-chart/src/main/java/com/fr/design/module/ChartPreStyleListPane.java +++ b/designer-chart/src/main/java/com/fr/design/module/ChartPreStyleListPane.java @@ -147,4 +147,4 @@ public class ChartPreStyleListPane extends JListControlPane { this.shortCut.setEnabled(nameableList.getModel().getSize() > 1); } } -} +} \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/custom/other/VanChartCustomInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/custom/other/VanChartCustomInteractivePane.java index 8aab51b3f8..82a62f02cd 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/custom/other/VanChartCustomInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/custom/other/VanChartCustomInteractivePane.java @@ -44,6 +44,9 @@ public class VanChartCustomInteractivePane extends VanChartInteractivePane { @Override protected void updateHyperlink(Plot plot){ + if (hyperlinkPane == null) { + return; + } hyperlinkPane.updateBean(chart); } diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java index c97f3a8ec8..dc72b90221 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/other/VanChartInteractivePane.java @@ -471,7 +471,11 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { } protected Component[][] createToolBarComponents() { - return new Component[][]{ + return ChartEditContext.duchampMode() ? new Component[][]{ + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Content")), isSort}, + new Component[]{null, fullScreenDisplay}, + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Layout")), collapse}, + } : new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Content")), isSort}, new Component[]{null, exportImages}, new Component[]{null, fullScreenDisplay}, @@ -480,7 +484,10 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { } protected Component[][] createToolBarComponentsWithOutSort() { - return new Component[][]{ + return ChartEditContext.duchampMode() ? new Component[][]{ + new Component[]{null, fullScreenDisplay}, + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Layout")), collapse} + } : new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Content")), exportImages}, new Component[]{null, fullScreenDisplay}, new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Chart_Layout")), collapse} @@ -685,7 +692,9 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { } protected void updateHyperlink(Plot plot) { - superLink.update(plot); + if (superLink != null) { + superLink.update(plot); + } } private void updateChartTools(VanChart chart) { @@ -734,6 +743,9 @@ public class VanChartInteractivePane extends AbstractVanChartScrollPane { private void updateAutoRefresh(VanChart chart) { + if (autoRefreshPane == null) { + return; + } RefreshMoreLabel refreshMoreLabel = chart.getRefreshMoreLabel(); if (refreshMoreLabel == null) { diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/component/VanChartAxisButtonPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/component/VanChartAxisButtonPane.java index d5f866c818..3020093278 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/component/VanChartAxisButtonPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/style/axis/component/VanChartAxisButtonPane.java @@ -356,7 +356,7 @@ public class VanChartAxisButtonPane extends BasicBeanPane { if (isEnabled()) { noSelected(); changeAxisSelected(getButtonName()); - setSelectedWithFireListener(true); + setSelected(true, true); fireSelectedChanged(); } } diff --git a/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java index 80962fd86b..7ada5f9c58 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/drillmap/designer/other/VanChartDrillMapInteractivePane.java @@ -100,7 +100,12 @@ public class VanChartDrillMapInteractivePane extends VanChartInteractivePaneWith double f = TableLayout.FILL; double[] columnSize = {f}; double[] rowSize = {p, p, p, p, p, p}; - Component[][] components = new Component[][]{ + Component[][] components = ChartEditContext.duchampMode() ? new Component[][]{ + new Component[]{null}, + new Component[]{createTitlePane(Toolkit.i18nText("Fine-Design_Chart_Character"), textAttrPane)}, + new Component[]{backgroundPane}, + new Component[]{selectBackgroundPane} + } : new Component[][]{ new Component[]{null}, new Component[]{createTitlePane(Toolkit.i18nText("Fine-Design_Chart_Character"), textAttrPane)}, new Component[]{backgroundPane}, diff --git a/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java index 49e4391b55..566a1a0a67 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/gauge/VanChartGaugeSeriesPane.java @@ -16,6 +16,7 @@ import com.fr.design.layout.TableLayoutHelper; import com.fr.design.mainframe.chart.gui.ChartStylePane; import com.fr.design.mainframe.chart.gui.style.series.ColorPickerPaneWithMaxMin; import com.fr.design.mainframe.chart.gui.style.series.UIColorPickerPane; +import com.fr.design.mainframe.chart.mode.ChartEditContext; import com.fr.design.style.color.ColorSelectBox; import com.fr.general.ComparatorUtils; import com.fr.plugin.chart.attr.GaugeDetailStyle; @@ -198,7 +199,9 @@ public class VanChartGaugeSeriesPane extends VanChartMultiColorSeriesPane { if (attrLabelDetail == null || attrLabelDetail.getTextAttr() == null) { return; } - attrLabelDetail.getTextAttr().setFRFont(VanChartGaugePlot.THERMOMETER_LABEL_FONT); + if (!ChartEditContext.duchampMode()) { + attrLabelDetail.getTextAttr().setFRFont(VanChartGaugePlot.THERMOMETER_LABEL_FONT); + } if (gaugeLayout.getSelectedIndex() == 0) { attrLabel.getAttrLabelDetail().setPosition(Constants.LEFT); attrLabel.getGaugeValueLabelDetail().setPosition(Constants.LEFT); diff --git a/designer-chart/src/main/java/com/fr/van/chart/map/designer/other/VanChartMapInteractivePane.java b/designer-chart/src/main/java/com/fr/van/chart/map/designer/other/VanChartMapInteractivePane.java index a6ede0df7e..1d49fd8348 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/map/designer/other/VanChartMapInteractivePane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/map/designer/other/VanChartMapInteractivePane.java @@ -35,6 +35,9 @@ public class VanChartMapInteractivePane extends VanChartInteractivePaneWithMapZo @Override protected void updateHyperlink(Plot plot) { + if (hyperlinkPane == null) { + return; + } hyperlinkPane.updateBean(plot); } diff --git a/designer-form/src/main/java/com/fr/design/actions/FormFitAttrAction.java b/designer-form/src/main/java/com/fr/design/actions/FormFitAttrAction.java deleted file mode 100644 index 2828abef24..0000000000 --- a/designer-form/src/main/java/com/fr/design/actions/FormFitAttrAction.java +++ /dev/null @@ -1,83 +0,0 @@ -package com.fr.design.actions; - -import com.fr.design.beans.BasicBeanPane; -import com.fr.design.dialog.DialogActionAdapter; -import com.fr.design.dialog.UIDialog; -import com.fr.design.fit.DesignerUIModeConfig; -import com.fr.design.fit.NewJForm; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.menu.MenuKeySet; -import com.fr.report.fit.FitProvider; -import com.fr.report.fit.ReportFitAttr; - -import javax.swing.KeyStroke; -import java.awt.event.ActionEvent; - -/** - * Created by Administrator on 2015/7/6 0006. - */ -public class FormFitAttrAction extends JTemplateAction { - private static final MenuKeySet REPORT_FIT_ATTR_ELEMENTCASE = new MenuKeySet() { - @Override - public char getMnemonic() { - return 'T'; - } - - @Override - public String getMenuName() { - return DesignerUIModeConfig.getInstance().newUIMode() ? - com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_PC_Adaptive_Attr") : - com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_PC_Element_Case_Fit_Attr"); - } - - @Override - public KeyStroke getKeyStroke() { - return null; - } - }; - - public FormFitAttrAction(JTemplate jTemplate) { - super(jTemplate); - initMenuStyle(); - } - - private void initMenuStyle() { - this.setMenuKeySet(REPORT_FIT_ATTR_ELEMENTCASE); - this.setName(getMenuKeySet().getMenuKeySetName() + "..."); - this.setMnemonic(getMenuKeySet().getMnemonic()); - this.setSmallIcon(DesignerUIModeConfig.getInstance().newUIMode() ? - "/com/fr/design/images/reportfit/fit.png": - "/com/fr/design/images/reportfit/fit"); - } - - /** - * Action触发事件 - * - * @param e 事件 - */ - @Override - public void actionPerformed(ActionEvent e) { - final JTemplate jwb = getEditingComponent(); - if (jwb == null || !(jwb instanceof NewJForm)) { - return; - } - final FitProvider wbTpl = (FitProvider) jwb.getTarget(); - ReportFitAttr fitAttr = wbTpl.getReportFitAttr(); - NewJForm newJForm = (NewJForm) jwb; - BasicBeanPane attrPane = newJForm.getJFormType().obtainAttrPane(newJForm); - showFitDialog(fitAttr, jwb, wbTpl, attrPane); - } - - private void showFitDialog(ReportFitAttr fitAttr, final JTemplate jwb, final FitProvider wbTpl, final BasicBeanPane attrPane) { - attrPane.populateBean(fitAttr); - UIDialog dialog = attrPane.showMediumWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() { - @Override - public void doOk() { - wbTpl.setReportFitAttr(attrPane.updateBean()); - jwb.fireTargetModified(); - } - }); - dialog.setVisible(true); - } -} diff --git a/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java b/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java index c867be8d24..5ce51b673c 100644 --- a/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java +++ b/designer-form/src/main/java/com/fr/design/actions/NewFormAction.java @@ -1,13 +1,8 @@ package com.fr.design.actions; -import com.fr.base.svg.IconUtils; -import com.fr.design.mainframe.BaseJForm; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.JTemplate; import com.fr.design.menu.MenuKeySet; - -import com.fr.stable.bridge.StableFactory; +import com.fr.design.widget.ui.designer.NewFormPane; import javax.swing.KeyStroke; import java.awt.event.ActionEvent; @@ -31,8 +26,7 @@ public class NewFormAction extends UpdateAction { * @param e 事件 */ public void actionPerformed(ActionEvent e) { - BaseJForm jform = StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, BaseJForm.class); - DesignerContext.getDesignerFrame().addAndActivateJTemplate((JTemplate) jform); + new NewFormPane().showWindow(); } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java index f10b877e27..438699b86c 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/LayoutAdapter.java @@ -1,7 +1,12 @@ package com.fr.design.designer.beans; import com.fr.design.beans.GroupModel; +import com.fr.design.designer.beans.adapters.layout.DefaultDesignerBaseOperate; +import com.fr.design.designer.beans.adapters.layout.DesignerBaseOperate; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; /** * 该接口是LayoutManager的BeanInfo类。标准Java平台没有提供布局管理器的BeanInfo类, @@ -50,11 +55,11 @@ public interface LayoutAdapter { * @param creator 被添加的新组件 * @param x 添加的位置x,该位置是相对于container的 * @param y 添加的位置y,该位置是相对于container的 - * @param accept 是否添加新组件 + * @param accept 是否添加新组件 * @return 是否添加成功,成功返回true,否则false */ boolean addBean(XCreator creator, int x, int y, boolean accept); - + /** * 返回该布局管理适配器的Painter,为容器提供放置位置的标识。 */ @@ -104,4 +109,36 @@ public interface LayoutAdapter { * @param initHeight 组件之前高度 */ void removeBean(XCreator creator, int initWidth, int initHeight); + + /** + * 获取布局下控件树render + * @param creator + * @return + */ + default XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator) { + return new DefaultXCreatorTreeCellRender(creator); + } + + /** + * 获取布局下支持的设计器基本操作 + * @return + */ + default DesignerBaseOperate getDesignerBaseOperate() { + return new DefaultDesignerBaseOperate(); + } + + /** + * 是否支持修改间距 + * @return + */ + default boolean supportModifyInsert() { + return true; + } + + void dragStart(XCreator xCreator, SelectionModel selectionModel); + + default void dragOver(XCreator xCreator, SelectionModel selectionModel, int x, int y) { + + }; + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/PredefinedLayout.java b/designer-form/src/main/java/com/fr/design/designer/beans/PredefinedLayout.java new file mode 100644 index 0000000000..ba184e5702 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/PredefinedLayout.java @@ -0,0 +1,35 @@ +package com.fr.design.designer.beans; + +import java.io.Serializable; + +public class PredefinedLayout implements Serializable { + private static final String IMAGE_PATH = "/com/fr/design/form/layouts/images/"; + private static final String TEMPLATE_PATH = "/com/fr/design/form/layouts/templates/"; + private String template; + private String realStyle; + private String simpleStyle; + + public String getTemplate() { + return TEMPLATE_PATH + template; + } + + public void setTemplate(String template) { + this.template = template; + } + + public String getRealStyle() { + return IMAGE_PATH + realStyle; + } + + public void setRealStyle(String realStyle) { + this.realStyle = realStyle; + } + + public String getSimpleStyle() { + return IMAGE_PATH + simpleStyle; + } + + public void setSimpleStyle(String simpleStyle) { + this.simpleStyle = simpleStyle; + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java index 94c84a87d4..7e1329b93b 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/CutAction.java @@ -2,7 +2,6 @@ package com.fr.design.designer.beans.actions; import com.fr.design.base.mode.DesignModeContext; -import com.fr.design.designer.beans.actions.behavior.ComponentEnable; import com.fr.design.designer.beans.actions.behavior.CutableEnable; import com.fr.design.mainframe.FormDesigner; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java index c2fec8f392..75a7442514 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/FormDeleteAction.java @@ -41,6 +41,14 @@ public class FormDeleteAction extends FormWidgetEditAction { return comp; } + @Override + public JComponent createToolBarComponentByName(String componentName) { + JComponent comp = super.createToolBarComponentByName(componentName); + // 除了 BACKSPACE 之外,DELETE 键也要能删除(直接在此处添加绑定,没有按钮提示) + comp.registerKeyboardAction(this, KeyStroke.getKeyStroke(KeyEvent.VK_DELETE, 0), JComponent.WHEN_IN_FOCUSED_WINDOW); + return comp; + } + /** * 删除 * diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java index ef35097b21..00e229e680 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/PasteAction.java @@ -1,6 +1,7 @@ package com.fr.design.designer.beans.actions; import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.designer.beans.actions.behavior.PasteEnable; import com.fr.design.mainframe.FormDesigner; import javax.swing.KeyStroke; @@ -15,6 +16,7 @@ public class PasteAction extends FormWidgetEditAction { this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_M_Edit_Paste")); this.setMnemonic('P'); this.setSmallIcon("/com/fr/design/images/m_edit/paste"); + this.setUpdateBehavior(new PasteEnable()); this.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V, DEFAULT_MODIFIER)); } @@ -22,10 +24,5 @@ public class PasteAction extends FormWidgetEditAction { public boolean executeActionReturnUndoRecordNeeded() { return DesignModeContext.doPaste(getEditingComponent()); } - - @Override - public void update() { - this.setEnabled(true); - } - + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/PasteEnable.java b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/PasteEnable.java new file mode 100644 index 0000000000..47c5c5af1a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/actions/behavior/PasteEnable.java @@ -0,0 +1,16 @@ +package com.fr.design.designer.beans.actions.behavior; + +import com.fr.design.designer.beans.actions.FormWidgetEditAction; +import com.fr.design.mainframe.FormDesigner; + +public class PasteEnable implements UpdateBehavior { + @Override + public void doUpdate(FormWidgetEditAction action) { + FormDesigner designer = action.getEditingComponent(); + if (designer == null) { + action.setEnabled(false); + return; + } + action.setEnabled(designer.isCurrentComponentPastable()); + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java index 5fdc8f3de7..cb7a7a6207 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/component/CompositeComponentAdapter.java @@ -29,6 +29,7 @@ import java.awt.Dimension; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; import java.beans.IntrospectionException; import java.util.ArrayList; import java.util.Collections; @@ -64,13 +65,15 @@ public class CompositeComponentAdapter implements ComponentAdapter { @Override public void paintComponentMascot(Graphics g) { - //自适应交叉点渲染有点问题,拖拽的控件设置成半透明 - Graphics2D g2d = (Graphics2D) g; - AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER,.5f); - g2d.setComposite(composite); - xCreator.paint(g2d); + //自适应交叉点渲染有点问题,拖拽的控件设置成半透明 + Graphics2D g2d = (Graphics2D) g; + AlphaComposite composite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, .5f); + g2d.setComposite(composite); + BufferedImage im = new BufferedImage(xCreator.getWidth(), xCreator.getHeight(), BufferedImage.TYPE_INT_ARGB); + xCreator.paint(im.getGraphics()); + g.drawImage(im, 0, 0, xCreator.initEditorSize().width - 1, xCreator.initEditorSize().height - 1, null); g.setColor(XCreatorConstants.RESIZE_BOX_BORDER_COLOR); - g.drawRect(0, 0, xCreator.getWidth() - 1, xCreator.getHeight() - 1); + g.drawRect(0, 0, xCreator.initEditorSize().width - 1, xCreator.initEditorSize().height - 1); } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java index e9851a7e87..98b6c88558 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/AbstractLayoutAdapter.java @@ -4,6 +4,7 @@ import com.fr.design.beans.GroupModel; import com.fr.design.designer.beans.ConstraintsGroupModel; import com.fr.design.designer.beans.HoverPainter; import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.beans.painters.NullPainter; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XLayoutContainer; @@ -203,4 +204,11 @@ public abstract class AbstractLayoutAdapter implements LayoutAdapter { public XLayoutContainer getContainer() { return this.container; } + + public void dragStart(XCreator xCreator, SelectionModel selectionModel){ + selectionModel.removeCreator(xCreator, xCreator.getWidth(), xCreator.getHeight()); + selectionModel.setSelectedCreator(container); + } + + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DefaultDesignerBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DefaultDesignerBaseOperate.java new file mode 100644 index 0000000000..f3ec959393 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DefaultDesignerBaseOperate.java @@ -0,0 +1,23 @@ +package com.fr.design.designer.beans.adapters.layout; + +public class DefaultDesignerBaseOperate implements DesignerBaseOperate{ + @Override + public boolean supportCopyAction() { + return true; + } + + @Override + public boolean supportCutAction() { + return true; + } + + @Override + public boolean supportPasteAction() { + return true; + } + + @Override + public boolean supportDeleteAction() { + return true; + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DesignerBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DesignerBaseOperate.java new file mode 100644 index 0000000000..410daf8b5b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/DesignerBaseOperate.java @@ -0,0 +1,33 @@ +package com.fr.design.designer.beans.adapters.layout; + +public interface DesignerBaseOperate { + + /** + * 是否支持复制 + * + * @return boolean + */ + boolean supportCopyAction(); + + /** + * 是否支持剪切 + * + * @return boolean + */ + boolean supportCutAction(); + + /** + * 是否支持粘贴 + * + * @return boolean + */ + boolean supportPasteAction(); + + /** + * 是否支持删除 + * + * @return boolean + */ + boolean supportDeleteAction(); + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRCardMainBorderLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRCardMainBorderLayoutAdapter.java index 9718d4a6fd..726c397060 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRCardMainBorderLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRCardMainBorderLayoutAdapter.java @@ -4,11 +4,12 @@ import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.form.layout.FRBorderLayout; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.ui.util.UIUtil; import com.fr.general.ComparatorUtils; - -import javax.swing.JOptionPane; import java.awt.BorderLayout; import java.awt.Rectangle; @@ -46,18 +47,42 @@ public class FRCardMainBorderLayoutAdapter extends FRBorderLayoutAdapter { Rectangle rectangle = creator.getBounds(); //不能超出控件边界 if (ComparatorUtils.equals(constraints, BorderLayout.NORTH) || ComparatorUtils.equals(constraints, BorderLayout.SOUTH)) { - int containerHeight = container.getHeight(); - if (rectangle.height > containerHeight) { - FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Beyond_Tablayout_Bounds")); - return true; - } + return isBeyondMinConstraint(rectangle.height, container.getHeight()); } else if (ComparatorUtils.equals(constraints, BorderLayout.EAST) || ComparatorUtils.equals(constraints, BorderLayout.WEST)) { - int containerWidth = container.getWidth(); - if (rectangle.width > containerWidth) { - FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Beyond_Tablayout_Bounds")); - return true; - } + return isBeyondMinConstraint(rectangle.width, container.getWidth()); } return false; } + + /** + * 是否超出最小限制 + * + * @param minConstraint 最小限制 + * @param value 数值 + * @return 是否超出最小限制 + */ + private boolean isBeyondMinConstraint(int minConstraint, int value) { + if (minConstraint > value) { + FineJOptionPane.showMessageDialog(null, com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Beyond_Tablayout_Bounds")); + if (container.getBackupBound() != null) { + // 手动拖动导致变矮的场景 + container.setSize(container.getBackupBound().getSize()); + } else { + // 自适应布局平分高度导致变矮的场景 + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + if (jt != null) { + jt.undo(); + } + } + }); + + } + return true; + } else { + return false; + } + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java index c893268ba1..d17e9689e6 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFitLayoutAdapter.java @@ -7,7 +7,8 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.beans.GroupModel; import com.fr.design.designer.beans.ConstraintsGroupModel; import com.fr.design.designer.beans.HoverPainter; -import com.fr.design.designer.beans.painters.FRFitLayoutPainter; +import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; @@ -19,6 +20,7 @@ import com.fr.design.designer.creator.cardlayout.XWCardTitleLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.designer.properties.FRFitLayoutConstraints; import com.fr.design.designer.properties.FRFitLayoutPropertiesGroupModel; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; import com.fr.design.fun.FormWidgetOptionProvider; import com.fr.design.utils.ComponentUtils; import com.fr.form.ui.LayoutBorderStyle; @@ -43,8 +45,6 @@ import java.util.Set; * @date 2014-6-24 */ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { - - public static final String WIDGETPANEICONPATH = "/com/fr/web/images/form/resources/layout_absolute.png"; private static final int DEPENDING_SCOPE = 3; private HoverPainter painter; //区分拖拽和编辑宽高 @@ -58,6 +58,8 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { isEdit = edit; } + private LayoutAdapter frLayoutState; + /** * 构造函数 * @@ -65,10 +67,18 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { */ public FRFitLayoutAdapter(XLayoutContainer container) { super(container); - painter = new FRFitLayoutPainter(container); initMinSize(); + this.frLayoutState = new FRNoFixLayoutAdapter(this, container, minWidth, minHeight, actualVal); + painter = this.frLayoutState.getPainter(); + } + + + public void setFrLayoutState(LayoutAdapter frLayoutState){ + this.frLayoutState = frLayoutState; + painter = this.frLayoutState.getPainter(); } + private void initMinSize() { XWFitLayout layout = (XWFitLayout) container; minWidth = layout.getActualMinWidth(); @@ -100,16 +110,7 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { */ @Override public void addComp(XCreator child, int x, int y) { - fix(child, x, y); - if (child.shouldScaleCreator() || child.hasTitleStyle()) { - addParentCreator(child); - } else { - container.add(child, child.toData().getWidgetName()); - } - XWFitLayout layout = (XWFitLayout) container; - // 更新对应的BoundsWidget - layout.updateBoundsWidget(); - updateCreatorBackBound(); + frLayoutState.addBean(child, x, y); } public void updateCreatorBackBound() { @@ -130,11 +131,6 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { } - private void addParentCreator(XCreator child) { - XLayoutContainer parentPanel = child.initCreatorWrapper(minHeight); - container.add(parentPanel, child.toData().getWidgetName()); - } - /** * 能否对应位置放置当前组件 * @@ -155,31 +151,16 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { //如果当前处于边缘地带, 那么就把他贴到父容器上 boolean isMatchEdge = matchEdge(x, y); - int componentHeight = comp.getHeight(); - int componentWidth = comp.getWidth(); - //上半部分高度 - int upHeight = (int) (componentHeight * TOP_HALF) + comp.getY(); - //下半部分高度 - int downHeight = (int) (componentHeight * BOTTOM_HALF) + comp.getY(); - //布局控件要先判断是不是可编辑 XLayoutContainer topLayout = XCreatorUtils.getHotspotContainer((XCreator) comp).getTopLayout(); - boolean access = topLayout != null && !isMatchEdge && !topLayout.isEditable() && !topLayout.acceptType(XWAbsoluteLayout.class) && !isExtraContainer(comp) && !topLayout.isDragInAble(); - if (access) { + boolean access = topLayout != null && !isMatchEdge && !topLayout.acceptType(XWAbsoluteLayout.class) && !isExtraContainer(comp) && !topLayout.isDragInAble(); + //topLayout.getParent() != container说明当前增加的组件所在容器是嵌套在外部的自适应容器内部的,此时需要判断增加组件所在容器是否可编辑,不可编辑的话就直接返回 false + //否则说明就是往当前自适应容器内部添加组件,不需要判断其是否可编辑 + if (access && (topLayout.getParent() != container && !topLayout.isEditable())) { return false; } - if (isCrossPointArea(comp, x, y)) { - return canAcceptWhileCrossPoint(comp, x, y); - } - - if (isTrisectionArea(comp, x, y)) { - return canAcceptWhileTrisection(comp, x, y); - } - - boolean horizonValid = componentWidth >= minWidth * 2 + actualVal; - boolean verticalValid = componentHeight >= minHeight * 2 + actualVal; - return y > upHeight && y < downHeight ? horizonValid : verticalValid; + return this.frLayoutState.accept(creator, x, y); } private boolean isExtraContainer(Component comp) { @@ -206,7 +187,7 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { * @param y 纵坐标 * @return 是否在组件边缘 */ - public boolean matchEdge(int x, int y) { + private boolean matchEdge(int x, int y) { if (intersectsEdge(x, y, container)) { //寻找最近的fit, 在边缘地段添加的控件, 将其送给该fit XLayoutContainer parent = container.findNearestFit(); @@ -760,15 +741,9 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { super.fixTrisect(currentComp, child, x, y); } - /** - * 删除组件或者重新拖动时,其它组件重新计算位置大小 - */ - protected void delete(XCreator creator, int creatorWidth, int creatorHeight) { - int x = creator.getX(); - int y = creator.getY(); - recalculateChildrenSize(x, y, creatorWidth, creatorHeight, true); + public void removeBean(XCreator creator, int creatorWidth, int creatorHeight) { + frLayoutState.removeBean(creator, creatorWidth, creatorHeight); } - /** * 重新计算内部组件大小 * @@ -1216,11 +1191,11 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { /** * 删除或拉伸上边框 调整上方的组件位置大小 */ - protected boolean calculateUpRelatComponent(int objHeight) { + private boolean calculateUpRelatComponent(int objHeight) { return calculateUpRelatComponent(objHeight, false); } - protected boolean calculateUpRelatComponent(int objHeight, boolean isDel) { + private boolean calculateUpRelatComponent(int objHeight, boolean isDel) { if (!isDel && isBeyondAdjustHeightScope(objHeight)) { return false; } @@ -1248,4 +1223,25 @@ public class FRFitLayoutAdapter extends FRBodyLayoutAdapter { public ConstraintsGroupModel getLayoutConstraints(XCreator creator) { return new FRFitLayoutConstraints((XWFitLayout) container, creator); } + + public XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator){ + return frLayoutState.getLayoutTreeCellRender(creator); + } + + @Override + public DesignerBaseOperate getDesignerBaseOperate() { + return frLayoutState.getDesignerBaseOperate(); + } + + public boolean supportModifyInsert() { + return frLayoutState.supportModifyInsert(); + } + + public void dragStart(XCreator xCreator, SelectionModel selectionModel){ + frLayoutState.dragStart(xCreator, selectionModel); + } + + public void dragOver(XCreator xCreator, SelectionModel selectionModel,int x, int y) { + frLayoutState.dragOver(xCreator, selectionModel,x,y); + }; } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFixLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFixLayoutAdapter.java new file mode 100644 index 0000000000..7fe0f5d7a6 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRFixLayoutAdapter.java @@ -0,0 +1,139 @@ +package com.fr.design.designer.beans.adapters.layout; + +import com.fr.base.svg.IconUtils; +import com.fr.design.designer.beans.HoverPainter; +import com.fr.design.designer.beans.models.ModelUtil; +import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.beans.painters.FRFixLayoutPainter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XOccupiedLayout; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.WidgetPropertyPane; +import com.fr.form.ui.container.OccupiedLayout; +import javax.swing.Icon; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; + +public class FRFixLayoutAdapter extends AbstractLayoutAdapter { + private static final Icon OCCUPIED_ICON = IconUtils.readIcon("/com/fr/design/form/images/occupied_layout.png"); + + public FRFixLayoutAdapter( XLayoutContainer container) { + super(container); + } + + public void addComp(XCreator child, int x, int y) { + Component component = container.getComponentAt(x, y); + if (component == container) { + return; + } + child.setLocation(component.getX(), component.getY()); + child.setSize(component.getWidth(), component.getHeight()); + if (child.shouldScaleCreator() || child.hasTitleStyle()) { + XLayoutContainer parentPanel = child.initCreatorWrapper(21); + container.replaceXcreator(parentPanel, (XCreator) component); + } else { + container.replaceXcreator(child, (XCreator) component); + } + if (child.getBackupRectangle() != null && child.getParent() == container) { + Component origin = container.getComponentAt(child.getBackupRectangle().x + 5, child.getBackupRectangle().y + 5); + if (origin == container) { + return; + } + if (origin instanceof XOccupiedLayout) { + ((XOccupiedLayout) origin).getLayoutAdapter().addBean((XCreator) component, child.getBackupRectangle().x + 5, child.getBackupRectangle().y + 5); + } + } + } + + @Override + public void delete(XCreator creator, int creatorWidth, int creatorHeight) { + //固定布局下不支持移除占位块组件 + if (creator.acceptType(XOccupiedLayout.class)){ + return; + } + OccupiedLayout occupiedLayout = new OccupiedLayout(); + FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + XOccupiedLayout xoccupiedLayout = new XOccupiedLayout(occupiedLayout, new Dimension()); + ModelUtil.renameWidgetName(formDesigner.getTarget(), xoccupiedLayout); + xoccupiedLayout.setLocation(creator.getX(), creator.getY()); + xoccupiedLayout.setSize(creatorWidth, creatorHeight); + container.replaceXcreator(xoccupiedLayout,creator); + } + + + @Override + public XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator) { + return new DefaultXCreatorTreeCellRender(creator) { + @Override + public void paint(Graphics g, Component c) { + if (!getxCreator().acceptType(XOccupiedLayout.class)) { + OCCUPIED_ICON.paintIcon(c, g, 0, 0); + } + super.paint(g, c); + } + }; + } + + @Override + public boolean supportModifyInsert() { + return false; + } + + @Override + public DesignerBaseOperate getDesignerBaseOperate() { + return new DesignerBaseOperate() { + @Override + public boolean supportCopyAction() { + return false; + } + + @Override + public boolean supportCutAction() { + return false; + } + + @Override + public boolean supportPasteAction() { + return false; + } + + @Override + public boolean supportDeleteAction() { + return true; + } + }; + } + + @Override + public boolean accept(XCreator creator, int x, int y) { + Component component = container.getComponentAt(x, y); + return component != container; + } + + + @Override + public HoverPainter getPainter() { + return new FRFixLayoutPainter(container); + } + + @Override + public void dragStart(XCreator xCreator, SelectionModel selectionModel) { + //do nothing + } + + public void dragOver(XCreator xCreator, SelectionModel selectionModel, int x, int y) { + //当鼠标移出被拖拽的组件时,才将组件从selectionmodel 中移出 + if (xCreator.getBackupRectangle()!= null && !xCreator.getBackupRectangle().contains(x, y) + && selectionModel.getSelection().contains(xCreator.toData())) { + selectionModel.removeCreator(xCreator, xCreator.getWidth(), xCreator.getHeight()); + selectionModel.setSelectedCreator(container); + } + + } + + ; +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRNoFixLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRNoFixLayoutAdapter.java new file mode 100644 index 0000000000..aaeedfc8da --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRNoFixLayoutAdapter.java @@ -0,0 +1,149 @@ +package com.fr.design.designer.beans.adapters.layout; + +import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.beans.painters.AbstractPainter; +import com.fr.design.designer.beans.painters.FRFitLayoutPainter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; + +import java.awt.Component; +import java.util.ArrayList; + +public class FRNoFixLayoutAdapter extends AbstractLayoutAdapter { + private static final double TOP_HALF = 0.25; + private static final double BOTTOM_HALF = 0.75; + private final int minWidth; + private final int minHeight; + private final int actualVal; + private final FRBodyLayoutAdapter parentLayoutAdapter; + + + public FRNoFixLayoutAdapter(FRBodyLayoutAdapter parentLayoutAdapter, XLayoutContainer container, int minWidth, int minHeight, int actualVal) { + super(container); + this.parentLayoutAdapter = parentLayoutAdapter; + this.minWidth = minWidth; + this.minHeight = minHeight; + this.actualVal = actualVal; + } + + @Override + public void addComp(XCreator child, int x, int y) { + fix(child, x, y); + if (child.shouldScaleCreator() || child.hasTitleStyle()) { + addParentCreator(child); + } else { + container.add(child, child.toData().getWidgetName()); + } + XWFitLayout layout = (XWFitLayout) container; + // 更新对应的BoundsWidget + layout.updateBoundsWidget(); + updateCreatorBackBound(); + } + + private void updateCreatorBackBound() { + for (int i = 0, size = container.getComponentCount(); i < size; i++) { + XCreator creator = (XCreator) container.getComponent(i); + creator.updateChildBound(minHeight); + creator.setBackupBound(creator.getBounds()); + //tab布局用到 + ArrayList childrenList = creator.getTargetChildrenList(); + for (int j = 0; j < childrenList.size(); j++) { + XWTabFitLayout tabLayout = (XWTabFitLayout) childrenList.get(j); + for (int m = 0; m < tabLayout.getComponentCount(); m++) { + XCreator childCreator = tabLayout.getXCreator(m); + childCreator.setBackupBound(childCreator.getBounds()); + } + } + } + } + + private void addParentCreator(XCreator child) { + XLayoutContainer parentPanel = child.initCreatorWrapper(minHeight); + container.add(parentPanel, child.toData().getWidgetName()); + } + + private void fix(XCreator child, int x, int y) { + Component parentComp = container.getComponentAt(x, y); + if (container.getComponentCount() == 0) { + child.setLocation(0, 0); + child.setSize(parentComp.getWidth(), parentComp.getHeight()); + } else if (parentLayoutAdapter.isCrossPointArea(parentComp, x, y)) { + //交叉区域插入组件时,根据具体位置进行上下或者左右或者相邻三个组件的位置大小插入 + parentLayoutAdapter.fixCrossPointArea(parentComp, child, x, y); + return; + } else if (parentLayoutAdapter.isTrisectionArea(parentComp, x, y)) { + // 在边界三等分区域,就不再和组件二等分了 + parentLayoutAdapter.fixTrisect(parentComp, child, x, y); + return; + } else { + parentLayoutAdapter.fixHalve(parentComp, child, x, y); + } + } + + @Override + public void delete(XCreator creator, int creatorWidth, int creatorHeight) { + int x = creator.getX(); + int y = creator.getY(); + ((FRFitLayoutAdapter) parentLayoutAdapter).recalculateChildrenSize(x, y, creatorWidth, creatorHeight, true); + } + + + @Override + public boolean supportModifyInsert() { + return true; + } + + @Override + public DesignerBaseOperate getDesignerBaseOperate() { + return new DefaultDesignerBaseOperate() { + @Override + public boolean supportCutAction() { + return container.getComponentCount() > 1; + } + }; + } + + @Override + public boolean accept(XCreator creator, int x, int y) { + Component comp = container.getComponentAt(x, y); + if (comp == null || checkInterval(comp)) { + return false; + } + int componentHeight = comp.getHeight(); + int componentWidth = comp.getWidth(); + //上半部分高度 + int upHeight = (int) (componentHeight * TOP_HALF) + comp.getY(); + //下半部分高度 + int downHeight = (int) (componentHeight * BOTTOM_HALF) + comp.getY(); + + if (parentLayoutAdapter.isCrossPointArea(comp, x, y)) { + return parentLayoutAdapter.canAcceptWhileCrossPoint(comp, x, y); + } + + if (parentLayoutAdapter.isTrisectionArea(comp, x, y)) { + return parentLayoutAdapter.canAcceptWhileTrisection(comp, x, y); + } + + boolean horizonValid = componentWidth >= minWidth * 2 + actualVal; + boolean verticalValid = componentHeight >= minHeight * 2 + actualVal; + return y > upHeight && y < downHeight ? horizonValid : verticalValid; + } + + // 间隔区域 + private boolean checkInterval(Component comp) { + return container.getComponentCount() > 0 && comp == container; + } + + @Override + public AbstractPainter getPainter() { + return new FRFitLayoutPainter(container); + } + + @Override + public void dragStart(XCreator xCreator, SelectionModel selectionModel) { + selectionModel.removeCreator(xCreator, xCreator.getWidth(), xCreator.getHeight()); + selectionModel.setSelectedCreator(container); + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FROccupiedLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FROccupiedLayoutAdapter.java new file mode 100644 index 0000000000..00dc41aedb --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FROccupiedLayoutAdapter.java @@ -0,0 +1,63 @@ +package com.fr.design.designer.beans.adapters.layout; + +import com.fr.design.designer.beans.HoverPainter; +import com.fr.design.designer.beans.painters.FROccupiedLayoutPainter; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; +import com.fr.design.utils.gui.LayoutUtils; +import java.awt.Color; +import java.awt.Component; +import java.awt.Graphics; + +public class FROccupiedLayoutAdapter extends AbstractLayoutAdapter { + + public FROccupiedLayoutAdapter(XLayoutContainer container) { + super(container); + painter = new FROccupiedLayoutPainter(container); + } + + private HoverPainter painter; + + + @Override + protected void addComp(XCreator creator, int x, int y) { + if (container.getComponentCount() == 0) { + creator.setLocation(container.getLocation().x, container.getLocation().y); + creator.setSize(container.getWidth(), container.getHeight()); + XLayoutContainer parent = (XLayoutContainer) container.getParent(); + if (creator.shouldScaleCreator() || creator.hasTitleStyle()) { + XLayoutContainer parentPanel = creator.initCreatorWrapper(21); + parent.replaceXcreator(parentPanel, container); + } else { + parent.replaceXcreator(creator, container); + } + LayoutUtils.layoutContainer(parent); + } + } + + @Override + public HoverPainter getPainter() { + return painter; + } + + @Override + public boolean accept(XCreator creator, int x, int y) { + return container.getComponentCount() == 0; + } + + public XCreatorTreeCellRender getLayoutTreeCellRender(XCreator creator) { + return new DefaultXCreatorTreeCellRender(creator) { + @Override + public void paint(Graphics g, Component c) { + super.paint(g, c); + Color oldColor = g.getColor(); + g.setColor(Color.RED); + g.drawRect(0, 0, 16, 16); + g.setColor(oldColor); + } + }; + } + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java b/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java index 58f58c0758..e023e1f4d5 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/events/DesignerEditor.java @@ -77,12 +77,12 @@ public class DesignerEditor implements PropertyChangeListe } } - public void paintEditor(Graphics g, Dimension size, PaddingMargin margin) { + public void paintEditor(Graphics g, Dimension size, Insets margin) { if (this.comp != null) { - int marginLeft = margin != null ? margin.getLeft() : 0; - int marginTop = margin != null ? margin.getTop() : 0; - int marginRight = margin != null ? margin.getRight() : 0; - int marginBottom = margin != null ? margin.getBottom() : 0; + int marginLeft = margin.left; + int marginTop = margin.top; + int marginRight = margin.right; + int marginBottom = margin.bottom; int horizonMargin = marginLeft + marginRight; int verticalMargin = marginTop + marginBottom; diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java index c0b6cd400a..1926b57b13 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/AddingModel.java @@ -4,8 +4,8 @@ import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.adapters.component.CompositeComponentAdapter; import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWAbsoluteLayout; import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.mainframe.FormDesigner; import com.fr.design.utils.ComponentUtils; @@ -51,9 +51,8 @@ public class AddingModel { this.creator = xCreator; this.creator.backupCurrentSize(); this.creator.backupParent(); - this.creator.setSize(xCreator.initEditorSize()); - currentX = x - (xCreator.getWidth() / 2); - currentY = y - (xCreator.getHeight() / 2); + currentX = x - (xCreator.initEditorSize().width / 2); + currentY = y - (xCreator.initEditorSize().height / 2); } /** @@ -93,8 +92,8 @@ public class AddingModel { * @param y 坐标 */ public void moveTo(int x, int y) { - currentX = x - (this.creator.getWidth() / 2); - currentY = y - (this.creator.getHeight() / 2); + currentX = x - (this.creator.initEditorSize().width / 2); + currentY = y - (this.creator.initEditorSize().height / 2); } public XCreator getXCreator() { @@ -125,11 +124,10 @@ public class AddingModel { */ public boolean add2Container(FormDesigner designer, XLayoutContainer container, int x, int y) { //考虑不同布局嵌套的情况,获取顶层容器 - XLayoutContainer xLayoutContainer = container.getTopLayout(); - if (xLayoutContainer != null && xLayoutContainer.acceptType(XWAbsoluteLayout.class)) { + XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container); + if (xLayoutContainer != null) { container = xLayoutContainer; } - Rectangle rect = ComponentUtils.getRelativeBounds(container); if (!ComparatorUtils.equals(container.getOuterLayout(), container.getBackupParent())) { added = container.getLayoutAdapter().addBean(creator, @@ -142,4 +140,5 @@ public class AddingModel { y + designer.getVerticalScaleValue() - rect.y); return added; } + } diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java index 0f75896e1b..dda70b96f8 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java @@ -18,7 +18,7 @@ import java.util.Set; /** * created by Harrison on 2020/06/05 **/ -abstract class ModelUtil { +public abstract class ModelUtil { public static void renameWidgetName(Form form, XCreator xCreator) { diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/NewFormModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/NewFormModel.java new file mode 100644 index 0000000000..141f6b1f3a --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/NewFormModel.java @@ -0,0 +1,68 @@ +package com.fr.design.designer.beans.models; + +import com.fr.design.designer.beans.PredefinedLayout; +import com.fr.design.i18n.Toolkit; +import com.fr.general.IOUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; +import com.fr.third.fasterxml.jackson.databind.ObjectMapper; + +import java.io.InputStream; +import java.io.Serializable; +import java.util.HashMap; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; + +public class NewFormModel implements Serializable { + private static final String CONFIG_FILE_PATH = "/com/fr/design/form/layouts/config.json"; + private static NewFormModel holder = null; + private Map> config = new LinkedHashMap<>(); + + private final Map i18nMap = new HashMap() {{ + put("2-4", Toolkit.i18nText("Fine-Design_Layout_Two_To_Four_Module")); + put("5-7", Toolkit.i18nText("Fine-Design_Layout_Five_To_Seven_Module")); + put("multi", Toolkit.i18nText("Fine-Design_Layout_Multi_Module")); + }}; + + public static NewFormModel getInstance() { + if (holder == null) { + try { + holder = new ObjectMapper().readValue(readConfigFile(), NewFormModel.class); + } catch (Exception e) { + holder = new NewFormModel(); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + return holder; + } + + private NewFormModel() { + + } + + private synchronized static String readConfigFile() { + String result = StringUtils.EMPTY; + InputStream is = null; + try { + is = IOUtils.readResource(CONFIG_FILE_PATH); + result = IOUtils.inputStream2String(is); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } finally { + IOUtils.close(is); + } + return result; + } + + public Map> getConfig() { + return config; + } + + public void setConfig(Map> config) { + for (String key : config.keySet()) { + String i18nKey = StringUtils.isNotEmpty(i18nMap.get(key)) ? i18nMap.get(key) : key; + this.config.put(i18nKey, config.get(key)); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java index df645e2dfe..963f60e6c3 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java @@ -140,11 +140,28 @@ public class SelectionModel { if (cutSelection != null) { cutSelection.cut2ClipBoard(clipboard); designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_CUTED); + setSelectedCreator(hasSelectedParaComponent() ? designer.getParaComponent() : designer.getRootComponent()); designer.repaint(); } } } + /** + * 判断是否选中参数面板中的组件 + * @return boolean + */ + private boolean hasSelectedParaComponent() { + XCreator[] roots = selection.getSelectedCreators(); + if (roots.length > 0) { + for (XCreator creator : roots) { + if ((creator.getParent() instanceof XWParameterLayout)) { + return true; + } + } + } + return false; + } + /** * 复制当前选中的组件到剪切板 */ @@ -320,8 +337,7 @@ public class SelectionModel { } designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_DELETED); - setSelectedCreator(isInPara ? designer.getParaComponent() : designer.getRootComponent()); - + setSelectedCreator(isInPara? designer.getParaComponent() : designer.getRootComponent()); // 触发事件 designer.repaint(); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/painters/FRFixLayoutPainter.java b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FRFixLayoutPainter.java new file mode 100644 index 0000000000..0f0aa2a6d2 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FRFixLayoutPainter.java @@ -0,0 +1,130 @@ +package com.fr.design.designer.beans.painters; + +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XOccupiedLayout; +import com.fr.design.form.util.XCreatorConstants; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Rectangle; +import java.awt.Stroke; + +public class FRFixLayoutPainter extends AbstractPainter { + + /** + * 构造函数 + * + * @param container + */ + public FRFixLayoutPainter(XLayoutContainer container) { + super(container); + } + + /** + * 组件渲染 + * + * @param g 画图类 + * @param startX 开始位置x + * @param startY 开始位置y + */ + @Override + public void paint(Graphics g, int startX, int startY) { + super.paint(g, startX, startY); + int x = hotspot.x - hotspot_bounds.x ; + int y = hotspot.y - hotspot_bounds.y ; + Component currentComp = container.getComponentAt(x, y); + if (currentComp == null) { + return; + } + boolean accept = currentComp != container; + if (accept) { + OperateState state = OperateState.DEFAULT; + if (currentComp == creator) { + state = OperateState.COMPONENT_DRAG_OUT; + } else if (!((XCreator) currentComp).acceptType(XOccupiedLayout.class)) { + state = OperateState.COMPONENT_REPLACE; + } + Rectangle currentCompRec = new Rectangle(currentComp.getX() - startX, currentComp.getY() - startY, currentComp.getWidth(), currentComp.getHeight()); + state.paint(g, creator.getBackupRectangle(), currentCompRec, new Rectangle(x, y, creator.initEditorSize().width, ((XCreator) currentComp).initEditorSize().height)); + } else { + Color bColor = XCreatorConstants.LAYOUT_FORBIDDEN_COLOR; + int[] hot_rec = new int[]{x, y, 0, 0}; + drawHotspot(g, x, y, hot_rec[2], hot_rec[3], bColor, false, false); + } + + } + + + enum OperateState { + COMPONENT_REPLACE { + @Override + void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds) { + Graphics2D g2d = (Graphics2D) g; + Color color = g2d.getColor(); + Stroke backup = g2d.getStroke(); + Composite backupComp = g2d.getComposite(); + + g2d.setColor(XCreatorConstants.REPLACE_OCCUPIED_LAYOUT_COLOR); + g2d.setStroke(XCreatorConstants.DASH_STROKE); + //绘制当前组件的边框 + g2d.drawRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height); + //底色透明度0.2 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + //绘制进行替换的时候,被替换的组件的底色 + g2d.fillRect(currentRectangle.x, currentRectangle.y, currentRectangle.width, currentRectangle.height); + + //绘制原组件位置处的占位块 + if (oriRectangle != null) { + g2d.setColor(XCreatorConstants.DRAG_OUT_OCCUPIED_LAYOUT_COLOR); + //如果是从其他占位块上拖过来的,绘制下其他占位块的状态 + g2d.drawRect(oriRectangle.x + 1, oriRectangle.y + 1, oriRectangle.width - 2, oriRectangle.height - 2); + //底色透明度0.2 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + //绘制进行替换的时候,被替换的组件的底色 + g2d.fillRect(oriRectangle.x, oriRectangle.y, oriRectangle.width, oriRectangle.height); + } + //还原 + g2d.setComposite(backupComp); + g2d.setStroke(backup); + g2d.setColor(color); + } + }, + COMPONENT_DRAG_OUT { + @Override + void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds) { + Graphics2D g2d = (Graphics2D) g; + Color color = g2d.getColor(); + Stroke backup = g2d.getStroke(); + Composite backupComp = g2d.getComposite(); + // 设置线条的样式 + g2d.setStroke(XCreatorConstants.DASH_STROKE); + g2d.setColor(XCreatorConstants.DRAG_OUT_OCCUPIED_LAYOUT_COLOR); + //如果是从其他占位块上拖过来的,绘制下其他占位块的状态 + g2d.drawRect(oriRectangle.x, oriRectangle.y, oriRectangle.width, oriRectangle.height); + //底色透明度0.2 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + //绘制进行替换的时候,被替换的组件的底色 + g2d.fillRect(oriRectangle.x, oriRectangle.y, oriRectangle.width, oriRectangle.height); + + g2d.setComposite(backupComp); + g2d.setStroke(backup); + g2d.setColor(color); + } + }, + DEFAULT { + @Override + void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds) { + + } + }; + + abstract void paint(Graphics g, Rectangle oriRectangle, Rectangle currentRectangle, Rectangle hotspot_bounds); + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/painters/FROccupiedLayoutPainter.java b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FROccupiedLayoutPainter.java new file mode 100644 index 0000000000..3a973b116f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/beans/painters/FROccupiedLayoutPainter.java @@ -0,0 +1,56 @@ +package com.fr.design.designer.beans.painters; + +import com.fr.design.designer.beans.adapters.layout.FROccupiedLayoutAdapter; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.form.util.XCreatorConstants; + +import java.awt.AlphaComposite; +import java.awt.Color; +import java.awt.Component; +import java.awt.Composite; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Stroke; + +public class FROccupiedLayoutPainter extends AbstractPainter { + + /** + * 构造函数 + * + * @param container 容器 + */ + public FROccupiedLayoutPainter(XLayoutContainer container) { + super(container); + } + + @Override + public void paint(Graphics g, int startX, int startY) { + int x = hotspot.x - hotspot_bounds.x; + int y = hotspot.y - hotspot_bounds.y; + FROccupiedLayoutAdapter adapter = (FROccupiedLayoutAdapter) container.getLayoutAdapter(); + Component currentComp = container.getComponentAt(x, y); + if (currentComp == null) { + return; + } + boolean accept = adapter.accept(creator, x, y); + if (accept) { + Color backupColor = g.getColor(); + Graphics2D g2d = (Graphics2D) g; + Stroke backupStroke = g2d.getStroke(); + Composite backupComposite = g2d.getComposite(); + g2d.setColor(XCreatorConstants.DRAG_IN_OCCUPIED_LAYOUT_COLOR); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.05f)); + g2d.fillRect(container.getX() - startX, container.getY() - startY, container.getWidth(), container.getHeight()); + + g2d.setStroke(XCreatorConstants.DASH_STROKE); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.2f)); + g2d.drawRect(container.getX() - startX + 1, container.getY() - startY + 1, container.getWidth() - 2, container.getHeight() - 2); + g2d.setStroke(backupStroke); + g2d.setComposite(backupComposite); + g2d.setColor(backupColor); + } + + } + + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java index df84109463..f99864c629 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XBorderStyleWidgetCreator.java @@ -40,6 +40,7 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ protected double backgroundOpacity4Painting; // 设计器预览界面中绘制组件背景图 protected Background borderImage4Painting; // 设计器预览界面中绘制边框图片 protected double borderImageOpacity4Painting; + protected Insets paddingInsets4Painting; public XBorderStyleWidgetCreator(Widget widget, Dimension initSize) { super(widget, initSize); @@ -87,6 +88,24 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ this.borderImageOpacity4Painting = opacity; } + public void setPaddingInsets4Painting(PaddingMargin margin) { + if (this.paddingInsets4Painting == null) { + this.paddingInsets4Painting = new Insets(0, 0, 0, 0); + } + if (margin == null) { + this.paddingInsets4Painting.set(0, 0, 0, 0); + } else { + this.paddingInsets4Painting.set(margin.getTop(), margin.getLeft(), margin.getBottom(), margin.getRight()); + } + } + + protected Insets getPaddingInsets4Painting() { + if (this.paddingInsets4Painting == null) { + this.paddingInsets4Painting = new Insets(0, 0, 0, 0); + } + return this.paddingInsets4Painting; + } + /** * 返回容器对应的widget * @return 同上 @@ -104,6 +123,15 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ refreshStylePreviewEffect(); } + /** + * @deprecated 该方法在样式数据模型发生变化,如主题更新/body布局类型切换等均会被调用,并不仅限于初始化, + * 因此原方法名称废弃,不应当被继续使用 + * @link {{@link #refreshStylePreviewEffect()}} + */ + protected void initStyle() { + refreshStylePreviewEffect(); + } + public void refreshStylePreviewEffect() { BorderPacker style = toData().getBorderStyle(); refreshBorderAndBackgroundStylePreviewEffect(); @@ -117,6 +145,15 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ reshuffleBorderAndBackgroundPaintingEffectIfTitleExists(); } + /** + * @deprecated 该方法在样式数据模型发生变化,如主题更新/图表默认开启标题等时均会被调用,并不仅限于初始化, + * 因此原方法名称废弃,不应当被继续使用 + * @link {{@link #refreshBorderAndBackgroundStylePreviewEffect()} ()}} + */ + protected void initBorderAndBackgroundStyle() { + refreshBorderAndBackgroundStylePreviewEffect(); + } + public void refreshBorderAndBackgroundStylePreviewEffect() { BorderPacker style = toData().getBorderStyle(); LineBorder DEFAULT_LINE_BORDER = (LineBorder) DEFALUTBORDER; @@ -236,12 +273,7 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ parentCreator.setBorder(border); // 容器绘制完整边框 bodyCreator.setBorder(BorderFactory.createEmptyBorder()); // body不绘制边框 - titleCreator.setBorder(BorderFactory.createEmptyBorder()); // title绘制底部边框 - if (border instanceof LineBorder) { - Color color = ((LineBorder) border).getLineColor(); - int thickness = ((LineBorder) border).getThickness(); - titleCreator.setBorder(new BottomLineBorder(color, thickness)); - } + titleCreator.setBorder(BorderFactory.createEmptyBorder()); // title不绘制边框 if (bodyCreator instanceof XBorderStyleWidgetCreator) { XBorderStyleWidgetCreator styledBodyXCreator = (XBorderStyleWidgetCreator) bodyCreator; @@ -353,11 +385,13 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ */ @Override public Insets getInsets() { - PaddingMargin padding = toData().getMargin(); - if (padding == null) { - return new Insets(0, 0, 0, 0); - } - return new Insets(padding.getTop(), padding.getLeft(), padding.getBottom(), padding.getRight()); + Container parent = this.getParent(); + if (parent instanceof XWTitleLayout && parent.getComponentCount() > 1) { + setPaddingInsets4Painting(null); + } else { + setPaddingInsets4Painting(toData().getMargin()); + } + return getPaddingInsets4Painting(); } /** @@ -368,32 +402,6 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ } - // 适用于标题栏的底部边框 - public static class BottomLineBorder extends LineBorder { - - private BottomLineBorder(Color color, int thickness) { - super(color, thickness); - } - - @Override - public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { - Graphics2D g2d = (Graphics2D)g; - - Color oldColor = g2d.getColor(); - Stroke oldStroke = g2d.getStroke(); - - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - - g2d.setColor(getLineColor()); - g2d.setStroke(new BasicStroke(getThickness() * 2)); - g2d.drawLine(0, height, width, height); - - g2d.setStroke(oldStroke); - g2d.setColor(oldColor); - g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); - } - } - public static class NoBackgroundPaneUI extends BasicPanelUI { @Override public void update(Graphics g, JComponent c) { diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java index ee166d27e9..1ab6d1a310 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XChartEditor.java @@ -230,7 +230,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { @Override public void paintForeground(Graphics2D g) { Dimension size = getSize(); - PaddingMargin margin = toData().getMargin(); + Insets paddingInsets = getInsets(); if (!isEditing) { // CHART-20568 & CHART-20627 @@ -238,12 +238,12 @@ public class XChartEditor extends XBorderStyleWidgetCreator { // 同时这里又在下层绘制了一遍ChartComponent,导致图表进入编辑状态,会出现两个重叠的ChartComponent。 // 考虑到编辑中,FormDesigner中的ChartComponent位于上层,下层的ChartComponent实际上没什么用,所以可以不用绘制 // 下层的ChartComponent - designerEditor.paintEditor(g, size, margin); + designerEditor.paintEditor(g, size, paddingInsets); } if (coverPanel != null) { - int horizonMargin = margin != null ? margin.getLeft() + margin.getRight() : 0; - int verticalMargin = margin != null ? margin.getTop() + margin.getBottom() : 0; + int horizonMargin = paddingInsets.left + paddingInsets.right; + int verticalMargin = paddingInsets.top + paddingInsets.bottom; coverPanel.setSize(size.width - horizonMargin, size.height - verticalMargin); } super.paintForeground(g); @@ -274,23 +274,24 @@ public class XChartEditor extends XBorderStyleWidgetCreator { return; } FormDesigner designer = editingMouseListener.getDesigner(); - SelectionModel selectionModel = editingMouseListener.getSelectionModel(); isEditing = e.getButton() == MouseEvent.BUTTON1 && (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR); - displayCoverPane(!isEditing); - selectionModel.selectACreatorAtMouseEvent(e); - editingMouseListener.refreshTopXCreator(isEditing); + startEditing(editingMouseListener, designer, isEditing); + } + @Override + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + displayCoverPane(!editing); + SelectionModel selectionModel = editingMouseListener.getSelectionModel(); + selectionModel.reset(); + selectionModel.selectACreator(this); + editingMouseListener.refreshTopXCreator(editing); if (editingMouseListener.stopEditing()) { - if (this != (XCreator) designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - if (isEditing) { - EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_SETTINGS); - } - editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); - if (isEditing) { - EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_SETTINGS); - } + isEditing = editing; + ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); + editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); + if (editing) { + EastRegionContainerPane.getInstance().switchTabTo(EastRegionContainerPane.KEY_WIDGET_SETTINGS); } } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java index e825285585..4601c268a6 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreator.java @@ -7,10 +7,12 @@ import com.fr.base.GraphHelper; import com.fr.base.vcs.DesignerMode; import com.fr.design.ExtraDesignClassManager; import com.fr.design.actions.UpdateAction; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.events.DesignerEditor; import com.fr.design.designer.beans.models.SelectionModel; +import com.fr.design.designer.creator.operate.XCreatorBaseOperate; +import com.fr.design.designer.creator.operate.DefaultXCreatorBaseOperate; +import com.fr.design.designer.treeview.DefaultXCreatorTreeCellRender; +import com.fr.design.designer.treeview.XCreatorTreeCellRender; import com.fr.design.designer.ui.SelectedPopupDialog; import com.fr.design.fun.ShareWidgetUIProcessor; import com.fr.design.fun.WidgetPropertyUIProvider; @@ -28,10 +30,12 @@ import com.fr.design.plugin.DesignerPluginContext; import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WTitleLayout; +import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; +import java.awt.event.MouseListener; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JFrame; @@ -62,7 +66,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo protected static final Dimension MIDDLE_PREFERRED_SIZE = new Dimension(80, 50); protected static final Dimension BIG_PREFERRED_SIZE = new Dimension(80, 80); // barry: 拖拽控件时,控件要恢复原始大小,就先把控件当前大小备份到这里。 - protected Dimension backupSize; + protected Rectangle backupRectangle; protected XLayoutContainer backupParent; protected Widget data; @@ -107,11 +111,15 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * 应用备份的大小 */ public void useBackupSize() { - if (this.backupSize != null) { - setSize(this.backupSize); + if (this.backupRectangle != null) { + setSize(new Dimension(this.backupRectangle.width, this.backupRectangle.height)); } } + public Rectangle getBackupRectangle(){ + return this.backupRectangle; + } + /** * 初始化组件大小 */ @@ -128,7 +136,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * 备份当前大小 */ public void backupCurrentSize() { - this.backupSize = getSize(); + this.backupRectangle = getBounds(); } public XLayoutContainer getBackupParent() { @@ -546,21 +554,31 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo * @param e 鼠标点击事件 */ public void respondClick(EditingMouseListener editingMouseListener,MouseEvent e){ - FormDesigner designer = editingMouseListener.getDesigner(); SelectionModel selectionModel = editingMouseListener.getSelectionModel(); if (e.getClickCount() <= 1) { selectionModel.selectACreatorAtMouseEvent(e); } - editingMouseListener.refreshTopXCreator(); + } - if (editingMouseListener.stopEditing() && this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); + /** + * + * 进入编辑模式 + */ + public void startEditing() { + FormDesigner designer = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + MouseListener[] listeners = designer.getMouseListeners(); + if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { + startEditing(((EditingMouseListener) listeners[0]), designer, true); } } + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + // do nothing + // 子类按需实现 + } + /** * 删除相关组件 * @@ -787,7 +805,7 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo int formDesignerWidth = designer.getWidth(); int formDesignerHeight = designer.getHeight(); // 不超过可绘制区域 - int extraX = Math.min(creatorRightX, formDesignerWidth); + int extraX = creatorRightX < 0 ? 0 : Math.min(creatorRightX, formDesignerWidth); int extraY = creatorRightY < 0 ? 0 : Math.min(creatorRightY, formDesignerHeight); if (designer.isFormParaDesigner() && extraY + this.getHeight() >= formDesignerHeight) { @@ -894,4 +912,24 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo } return ((XCreator) this.getParent()).getLevel() + 1; } + + /** + * 获取组件在组件树中的显示方式 + * @return + */ + public XCreatorTreeCellRender getComponentTreeCellRender(){ + if (this.getBackupParent()!= null){ + return this.getBackupParent().getLayoutAdapter().getLayoutTreeCellRender(this); + } + return new DefaultXCreatorTreeCellRender(this); + } + + /** + * 获取组件支持的基本操作 + * @return + */ + public XCreatorBaseOperate getXCreatorBaseOperate() { + return new DefaultXCreatorBaseOperate(); + } + } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java index 1c09113f1c..4087231522 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java @@ -55,6 +55,7 @@ import com.fr.form.ui.TreeComboBoxEditor; import com.fr.form.ui.TreeEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.WidgetErrorMarker; +import com.fr.form.ui.container.OccupiedLayout; import com.fr.form.ui.container.WAbsoluteBodyLayout; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WBorderLayout; @@ -138,6 +139,7 @@ public class XCreatorUtils { xLayoutMap.put(WBorderLayout.class, XWBorderLayout.class); xLayoutMap.put(WCardLayout.class, XWCardLayout.class); xLayoutMap.put(WVerticalBoxLayout.class, XWVerticalBoxLayout.class); + xLayoutMap.put(OccupiedLayout.class, XOccupiedLayout.class); xLayoutMap.put(WFitLayout.class, XWFitLayout.class); xLayoutMap.put(WScaleLayout.class, XWScaleLayout.class); @@ -273,7 +275,7 @@ public class XCreatorUtils { try { creator = Reflect.on(clazz).create(widget, d).get(); } catch (Exception ignore) { - + FineLoggerFactory.getLogger().error(ignore.getMessage(), ignore); } if (creator == null) { FineLoggerFactory.getLogger().error("Error to create xcreator!"); @@ -379,6 +381,7 @@ public class XCreatorUtils { return null; } + public static void setupTemplateTheme(XCreator container, final boolean forceFollowingTheme, final FormTheme currentTemplateUsingTheme, TemplateThemeCompatible compatible) { FineColorGather colorGather = new FineColorManager.FineColorReplaceByTheme(currentTemplateUsingTheme, compatible); Form.traversalWidget(container.toData(), new WidgetGather() { @@ -399,4 +402,22 @@ public class XCreatorUtils { FineColorFlushUtils.replaceCacheObject(container.toData(), colorGather); FineColorManager.traverse(container.toData(), colorGather); } + + + /** + * 获取容器组件的顶层正编辑的组件 + */ + @Nullable + public static XLayoutContainer getTopEditableContainer(XLayoutContainer container) { + if (container == null) { + return null; + } + XLayoutContainer xLayoutContainer = container.getTopLayout(); + if (xLayoutContainer != null && xLayoutContainer.getParent() != null) { + if (!xLayoutContainer.isEditable()) { + return (XLayoutContainer) xLayoutContainer.getParent(); + } + } + return null; + } } \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java index b561151e85..42a14aee30 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XElementCase.java @@ -33,7 +33,7 @@ import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.util.Set; -public class XElementCase extends XBorderStyleWidgetCreator implements FormElementCaseContainerProvider , Releasable { +public class XElementCase extends XBorderStyleWidgetCreator implements FormElementCaseContainerProvider, Releasable { private UILabel imageLable; private FormDesigner designer; private static BufferedImage DEFAULT_BACKGROUND; @@ -50,8 +50,7 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme public XElementCase(ElementCaseEditor widget, Dimension initSize) { super(widget, initSize); - - + widget.getElementCaseImage().adjustImageSize(initSize.width, initSize.height, false); } protected void initXCreatorProperties() { @@ -269,6 +268,12 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme return toData().getElementCase(); } + @Override + public void doLayout() { + super.doLayout(); + this.updateECImage(); + } + public String getElementCaseContainerName() { return toData().getWidgetName(); } @@ -319,11 +324,13 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme private void switchTab(MouseEvent e, EditingMouseListener editingMouseListener) { FormDesigner designer = editingMouseListener.getDesigner(); - if (e.getButton() == MouseEvent.BUTTON1 && - (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR)) { - //切换设计器 - designer.switchTab(this); - } + startEditing(editingMouseListener, designer, e.getButton() == MouseEvent.BUTTON1 && + (e.getClickCount() == 2 || designer.getCursor().getType() == Cursor.HAND_CURSOR)); + } + + @Override + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + designer.switchTab(this); } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java index f1d4c4f6d3..801f18969f 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XLayoutContainer.java @@ -4,9 +4,11 @@ package com.fr.design.designer.creator; import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.form.layout.FRLayoutManager; import com.fr.design.form.util.XCreatorConstants; import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.widget.editors.PaddingMarginEditor; import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor; @@ -50,6 +52,8 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme private volatile boolean dragInAble; + protected boolean isFixLayout = false; + public void setMouseEnter(boolean mouseEnter) { isMouseEnter = mouseEnter; } @@ -59,6 +63,10 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme this.addContainerListener(this); } + public void setFixLayout(boolean isFixLayout){ + this.isFixLayout = isFixLayout; + } + /** * 得到属性名 * @@ -586,4 +594,22 @@ public abstract class XLayoutContainer extends XBorderStyleWidgetCreator impleme public void setDragInAble(boolean dragInAble) { this.dragInAble = dragInAble; } + + @Override + protected void startEditing(EditingMouseListener editingMouseListener, FormDesigner designer, boolean editing) { + SelectionModel selectionModel = editingMouseListener.getSelectionModel(); + selectionModel.reset(); + selectionModel.selectACreator(this); + setEditable(editing); + editingMouseListener.refreshTopXCreator(editing); + designer.repaint(); + } + + public boolean supportFixLayout(){ + return false; + } + + public void replaceXcreator(XCreator newCreator, XCreator oldCreator){ + + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XOccupiedLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XOccupiedLayout.java new file mode 100644 index 0000000000..561a9437ce --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XOccupiedLayout.java @@ -0,0 +1,81 @@ +package com.fr.design.designer.creator; + +import com.fr.design.designer.beans.LayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.FROccupiedLayoutAdapter; +import com.fr.design.designer.creator.operate.DefaultXCreatorBaseOperate; +import com.fr.design.designer.creator.operate.XCreatorBaseOperate; +import com.fr.design.form.layout.FRFitLayout; +import com.fr.design.form.util.XCreatorConstants; +import com.fr.form.ui.container.OccupiedLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Stroke; + +public class XOccupiedLayout extends XLayoutContainer { + + public XOccupiedLayout() { + this(new OccupiedLayout(), new Dimension()); + } + + + public XOccupiedLayout(OccupiedLayout widget, Dimension initSize) { + super(widget, initSize); + initLayoutManager(); + } + + public String createDefaultName() { + return "box"; + } + + @Override + protected void initLayoutManager() { + this.setLayout(new FRFitLayout()); + } + + @Override + public LayoutAdapter getLayoutAdapter() { + return new FROccupiedLayoutAdapter(this); + } + + + public String getIconPath() { + return "/com/fr/design/form/images/occupied_layout.png"; + } + + + @Override + public boolean isComponentTreeLeaf() { + //在控件树上表现为叶子节点(组件放置到占位块中的时候,会删除占位块,只展示组件) + return true; + } + + public XCreatorBaseOperate getXCreatorBaseOperate() { + return new DefaultXCreatorBaseOperate() { + @Override + public boolean supportSelected() { + return false; + } + }; + } + + + @Override + public void paint(Graphics g) { + drawOccupiedComponentBounds(g); + } + + private void drawOccupiedComponentBounds(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + Color color = g2d.getColor(); + Stroke backup = g2d.getStroke(); + // 设置线条的样式 + g2d.setStroke(XCreatorConstants.DASH_STROKE); + g2d.setColor(XCreatorConstants.EMPTY_OCCUPIED_LAYOUT_COLOR); + g2d.drawRect(1, 1, this.getWidth() - 2, this.getHeight() - 2); + g2d.setStroke(backup); + g2d.setColor(color); + } + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java index e222b44866..f249a651e1 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWAbsoluteLayout.java @@ -490,21 +490,9 @@ public class XWAbsoluteLayout extends XLayoutContainer { return; } FormDesigner designer = editingMouseListener.getDesigner(); - SelectionModel selectionModel = editingMouseListener.getSelectionModel(); boolean isEditing = isEditable() || e.getButton() == MouseEvent.BUTTON1 && (designer.getCursor().getType() == Cursor.HAND_CURSOR || e.getClickCount() == 2); - setEditable(isEditing); - - selectionModel.selectACreatorAtMouseEvent(e); - designer.repaint(); - editingMouseListener.refreshTopXCreator(isEditing); - - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); - } - } + startEditing(editingMouseListener, designer, isEditing); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java index 191add9b82..da4d235f07 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XWFitLayout.java @@ -2,6 +2,8 @@ package com.fr.design.designer.creator; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRFitLayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.FRFixLayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.FRNoFixLayoutAdapter; import com.fr.design.designer.beans.location.Direction; import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; @@ -80,7 +82,12 @@ public class XWFitLayout extends XLayoutContainer { @Override public LayoutAdapter getLayoutAdapter() { - return new FRFitLayoutAdapter(this); + FRFitLayoutAdapter layoutAdapter = new FRFitLayoutAdapter(this); + + if (isFixLayout) { + layoutAdapter.setFrLayoutState(new FRFixLayoutAdapter(this)); + } + return layoutAdapter; } @Override @@ -789,7 +796,6 @@ public class XWFitLayout extends XLayoutContainer { layout.setContainerHeight(containerHeight); layout.setContainerWidth(containerWidth); addCompInterval(getAcualInterval()); - // REPORT-54410: 决策报表,模板中其他组件的宽高修改会影响绝对画布块中组件的宽高和位置 // 绝对布局内的组件尺寸调整需要在绝对布局的bound排除GAP后进行,否则计算出的 // 组件尺寸缩放比例会有问题 @@ -867,7 +873,27 @@ public class XWFitLayout extends XLayoutContainer { BoundsWidget bw = (BoundsWidget) wlayout.getBoundsWidget(wgt); wlayout.removeWidget(bw); updateBoundsWidget(); - ((FRFitLayoutAdapter)getLayoutAdapter()).updateCreatorBackBound(); + ((FRFitLayoutAdapter) getLayoutAdapter()).updateCreatorBackBound(); + } + + public void replaceXcreator(XCreator newCreator, XCreator oldCreator) { + WFitLayout wlayout = this.toData(); + Widget wgt = oldCreator.toData(); + BoundsWidget bw = (BoundsWidget) wlayout.getBoundsWidget(wgt); + wlayout.removeWidget(bw); + wlayout.addWidget(new BoundsWidget(newCreator.toData(), bw.getBounds())); + newCreator.setBackupParent(this); + isRefreshing = true; + this.remove(oldCreator); + this.add(newCreator); + dealDirections(newCreator, false); + //对于新增的绝对布局的组件,需要更新下内部组件的大小 + if (newCreator.acceptType(XWAbsoluteLayout.class)){ + ((XWAbsoluteLayout) newCreator).updateBoundsWidget(); + newCreator.setBackupBound(newCreator.getBounds()); + } + isRefreshing = false; + LayoutUtils.layoutContainer(this); } /** @@ -1005,7 +1031,7 @@ public class XWFitLayout extends XLayoutContainer { * @return 默认返回true */ public boolean canAddInterval(int interval) { - int val = interval/2; + int val = (interval - this.toData().getCompInterval())/2; for (int i=0, len=this.getComponentCount(); i 1) { + XCreator bodyCreator = getBodyCreator(); + if (bodyCreator instanceof XBorderStyleWidgetCreator) { + XBorderStyleWidgetCreator styleBodyCreator = (XBorderStyleWidgetCreator) bodyCreator; + setPaddingInsets4Painting(styleBodyCreator.toData().getMargin()); + return getPaddingInsets4Painting(); + } + } + return super.getInsets(); + } + @Override protected void initXCreatorProperties() { super.initXCreatorProperties(); @@ -174,6 +189,37 @@ public class XWTitleLayout extends DedicateLayoutContainer { } + @Override + protected void paintBorder(Graphics g) { + super.paintBorder(g); + paintSeparator((Graphics2D) g); + } + + private void paintSeparator(Graphics2D g2d) { + Border border = getBorder(); + XCreator titleCreator = getTitleCreator(); + if (border instanceof LineBorder && titleCreator != null) { + int height = titleCreator.getHeight(); + Insets paddingInsets = getInsets(); + int y = height + paddingInsets.top; + + Color oldColor = g2d.getColor(); + Stroke oldStroke = g2d.getStroke(); + + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + + Color lineColor = ((LineBorder) border).getLineColor(); + int thickness = ((LineBorder) border).getThickness(); + g2d.setColor(lineColor); + g2d.setStroke(new BasicStroke(thickness * 2)); + g2d.drawLine(0, y, getWidth(), y); + + g2d.setStroke(oldStroke); + g2d.setColor(oldColor); + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_OFF); + } + } + @Override public void paintBackground(Graphics2D g2d) { if (getComponentCount() > 1) { @@ -187,12 +233,15 @@ public class XWTitleLayout extends DedicateLayoutContainer { Composite oldComposite = g2d.getComposite(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) this.titleBackgroundOpacity4Painting)); XCreator titleCreator = getTitleCreator(); - int titleHeight = titleCreator != null ? titleCreator.getHeight() : 0; + if (titleCreator != null) { + int height = titleCreator.getHeight(); + Insets paddingInsets = getInsets(); - Shape shape = new Rectangle2D.Double(0, 0, getWidth(), titleHeight); - titleBackground4Painting.paint(g2d, shape); + Shape shape = new Rectangle2D.Double(0, 0, getWidth(), height + paddingInsets.top); + titleBackground4Painting.paint(g2d, shape); - g2d.setComposite(oldComposite); + g2d.setComposite(oldComposite); + } } } @@ -201,14 +250,18 @@ public class XWTitleLayout extends DedicateLayoutContainer { Composite oldComposite = g2d.getComposite(); g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, (float) this.bodyBackgroundOpacity4Painting)); - XCreator titleCreator = getTitleCreator(); - int titleHeight = titleCreator != null ? titleCreator.getHeight() : 0; - // 兼容性考虑,组件样式背景不作用在标题范围内,只作用在控件整体,但同时不能遮挡作用于整体的边框图片 - // 所以考虑样式背景与边框图片都由XWTitleLayout绘制,但样式背景要向下偏移标题栏的高度 - Shape shape = new Rectangle2D.Double(0, titleHeight, getWidth(), getHeight() - titleHeight); - bodyBackground4Painting.paint(g2d, shape); + XCreator bodyCreator = getBodyCreator(); + + if (bodyCreator != null) { + int y = bodyCreator.getY(); + int height = bodyCreator.getHeight(); + Insets paddingInsets = getInsets(); - g2d.setComposite(oldComposite); + Shape shape = new Rectangle2D.Double(0, y, getWidth(), height + paddingInsets.bottom); + bodyBackground4Painting.paint(g2d, shape); + + g2d.setComposite(oldComposite); + } } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java index 7718e266f2..d774e34895 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardAddButton.java @@ -1,8 +1,6 @@ package com.fr.design.designer.creator.cardlayout; import com.fr.base.BaseUtils; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XButton; import com.fr.design.designer.creator.XLayoutContainer; @@ -101,11 +99,6 @@ public class XCardAddButton extends XButton { addTab(index); this.tagLayout.adjustComponentWidth(); - if (editingMouseListener.stopEditing()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } - FormHierarchyTreePane.getInstance().refreshRoot(); //将焦点切换到新增的tab对应的tabfitLayout上 showNewTab(editingMouseListener,index); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java index 18bab55287..85436c72fd 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java @@ -6,8 +6,6 @@ package com.fr.design.designer.creator.cardlayout; import com.fr.base.BaseUtils; import com.fr.base.GraphHelper; import com.fr.base.background.ColorBackground; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XButton; import com.fr.design.designer.creator.XCreator; @@ -32,7 +30,6 @@ import com.fr.general.ComparatorUtils; import com.fr.general.FRFont; import com.fr.general.act.TitlePacker; import com.fr.general.cardtag.TemplateStyle; -import com.fr.stable.ProductConstants; import com.fr.stable.unit.PT; import javax.swing.*; @@ -176,10 +173,6 @@ public class XCardSwitchButton extends XButton { tabFitLayout.setxCardSwitchButton(xCardSwitchButton); selectionModel.setSelectedCreator(tabFitLayout); - if (editingMouseListener.stopEditing()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } if(SwingUtilities.isRightMouseButton(e)){ showPopupMenu(editingMouseListener, e, index, maxIndex); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java index b784187e77..578b509ec0 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardLayout.java @@ -62,10 +62,6 @@ public class XWCardLayout extends XLayoutContainer { public static final String DEFAULT_NAME = "cardlayout"; - - //默认蓝色标题背景 - private static final Color TITLE_COLOR = new Color(51, 132, 240); - public XWCardLayout(WCardLayout widget, Dimension initSize) { super(widget, initSize); } @@ -399,19 +395,10 @@ public class XWCardLayout extends XLayoutContainer { @Override public void refreshStylePreviewEffect() { BorderPacker style = toData().getBorderStyle(); - initBorderTitleStyle(style); refreshBorderAndBackgroundStylePreviewEffect(); clearOrShowTitleLayout(ComparatorUtils.equals(style.getType(), LayoutBorderStyle.TITLE)); } - private void initBorderTitleStyle(BorderPacker style) { - //初始化默认标题样式 - style.setType(LayoutBorderStyle.TITLE); - style.setBorder(Constants.LINE_THIN); - TitlePacker widgetTitle = style.getTitle(); - widgetTitle.setBackground(ColorBackground.getInstance(TITLE_COLOR)); - } - //隐藏或显示标题部分 protected void clearOrShowTitleLayout(boolean isTitleStyle) { XWCardMainBorderLayout mainLayout = (XWCardMainBorderLayout) this.getBackupParent(); diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java index 0db348a399..fdc01be1e9 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java @@ -377,21 +377,9 @@ public class XWCardMainBorderLayout extends XWBorderLayout { return; } FormDesigner designer = editingMouseListener.getDesigner(); - SelectionModel selectionModel = editingMouseListener.getSelectionModel(); boolean isEditing = e.getButton() == MouseEvent.BUTTON1 && (designer.getCursor().getType() == Cursor.HAND_CURSOR || e.getClickCount() == 2); - setEditable(isEditing); - - selectionModel.selectACreatorAtMouseEvent(e); - editingMouseListener.refreshTopXCreator(isEditing); - designer.repaint(); - - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, isEditing ? adapter.getDesignerEditor() : null, adapter); - } - } + startEditing(editingMouseListener, designer, isEditing); } /** diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java index 010a382178..ceb334028a 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java @@ -6,7 +6,6 @@ package com.fr.design.designer.creator.cardlayout; import com.fr.base.GraphHelper; import com.fr.base.ScreenResolution; 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.FRWCardTagLayoutAdapter; import com.fr.design.designer.beans.models.SelectionModel; @@ -242,19 +241,12 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout { */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - FormDesigner designer = editingMouseListener.getDesigner(); SelectionModel selectionModel = editingMouseListener.getSelectionModel(); if (e.getClickCount() <= 1) { selectionModel.selectACreatorAtMouseEvent(e); } editingMouseListener.refreshTopXCreator(); - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } - } } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java index f6f6b2b411..7cdca0a0bc 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTitleLayout.java @@ -3,8 +3,6 @@ */ package com.fr.design.designer.creator.cardlayout; -import com.fr.design.designer.beans.AdapterBus; -import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; @@ -198,20 +196,12 @@ public class XWCardTitleLayout extends XWBorderLayout { */ public void respondClick(EditingMouseListener editingMouseListener, MouseEvent e) { - FormDesigner designer = editingMouseListener.getDesigner(); SelectionModel selectionModel = editingMouseListener.getSelectionModel(); if (e.getClickCount() <= 1) { selectionModel.selectACreatorAtMouseEvent(e); } editingMouseListener.refreshTopXCreator(); - - if (editingMouseListener.stopEditing()) { - if (this != designer.getRootComponent()) { - ComponentAdapter adapter = AdapterBus.getComponentAdapter(designer, this); - editingMouseListener.startEditing(this, adapter.getDesignerEditor(), adapter); - } - } } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java index d72a8f4fe3..10f080f697 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWTabFitLayout.java @@ -639,4 +639,8 @@ public class XWTabFitLayout extends XWFitLayout { public boolean isTopable() { return true; } + + public boolean supportFixLayout(){ + return false; + } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/operate/DefaultXCreatorBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/creator/operate/DefaultXCreatorBaseOperate.java new file mode 100644 index 0000000000..897b06ce44 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/creator/operate/DefaultXCreatorBaseOperate.java @@ -0,0 +1,29 @@ +package com.fr.design.designer.creator.operate; + + +public class DefaultXCreatorBaseOperate implements XCreatorBaseOperate { + @Override + public boolean supportSelected() { + return true; + } + + @Override + public boolean supportCopyAction() { + return true; + } + + @Override + public boolean supportCutAction() { + return true; + } + + @Override + public boolean supportPasteAction() { + return true; + } + + @Override + public boolean supportDeleteAction() { + return true; + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/operate/XCreatorBaseOperate.java b/designer-form/src/main/java/com/fr/design/designer/creator/operate/XCreatorBaseOperate.java new file mode 100644 index 0000000000..3412501b36 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/creator/operate/XCreatorBaseOperate.java @@ -0,0 +1,15 @@ +package com.fr.design.designer.creator.operate; + +import com.fr.design.designer.beans.adapters.layout.DesignerBaseOperate; + +public interface XCreatorBaseOperate extends DesignerBaseOperate { + + /** + * 是否支持选中 + * + * @return boolean + */ + boolean supportSelected(); + + +} diff --git a/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java b/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java index e3b9b81750..5aad58379c 100644 --- a/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java +++ b/designer-form/src/main/java/com/fr/design/designer/treeview/ComponentTreeCellRenderer.java @@ -4,7 +4,6 @@ import com.fr.base.BaseUtils; import com.fr.design.constants.UIConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; -import com.fr.design.mainframe.share.util.ShareComponentUtils; import com.fr.log.FineLoggerFactory; import javax.swing.BorderFactory; @@ -15,8 +14,7 @@ import java.awt.Component; import java.awt.Graphics; public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { - private boolean needAddShareIcon = false; - private static final Icon SHARE_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/reuse_icon.png"); + private XCreatorTreeCellRender treeCellRender; public ComponentTreeCellRenderer() { } @@ -36,9 +34,8 @@ public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { } if (icon != null) { setIcon(icon); - this.needAddShareIcon = ShareComponentUtils.isShareWidgetWithChild((XCreator) value); } - + this.treeCellRender = ((XCreator) value).getComponentTreeCellRender(); } this.setBorder(BorderFactory.createEmptyBorder(1, 0, 1, 0)); this.setBackgroundNonSelectionColor(UIConstants.TREE_BACKGROUND); @@ -48,9 +45,7 @@ public class ComponentTreeCellRenderer extends DefaultTreeCellRenderer { public void paint(Graphics g) { super.paint(g); - if (needAddShareIcon) { - SHARE_ICON.paintIcon(this, g, 10, 0); - } + treeCellRender.paint(g, this); } @Override diff --git a/designer-form/src/main/java/com/fr/design/designer/treeview/DefaultXCreatorTreeCellRender.java b/designer-form/src/main/java/com/fr/design/designer/treeview/DefaultXCreatorTreeCellRender.java new file mode 100644 index 0000000000..702925e713 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/treeview/DefaultXCreatorTreeCellRender.java @@ -0,0 +1,29 @@ +package com.fr.design.designer.treeview; + +import com.fr.base.BaseUtils; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.mainframe.share.util.ShareComponentUtils; + +import javax.swing.Icon; +import java.awt.Component; +import java.awt.Graphics; + +public class DefaultXCreatorTreeCellRender implements XCreatorTreeCellRender { + private static final Icon SHARE_ICON = BaseUtils.readIcon("/com/fr/design/images/toast/reuse_icon.png"); + private XCreator xCreator; + + public DefaultXCreatorTreeCellRender(XCreator creator) { + this.xCreator = creator; + } + + public XCreator getxCreator(){ + return xCreator; + } + + @Override + public void paint(Graphics g, Component c) { + if (ShareComponentUtils.isShareWidgetWithChild( xCreator)) { + SHARE_ICON.paintIcon(c, g, 10, 0); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/designer/treeview/XCreatorTreeCellRender.java b/designer-form/src/main/java/com/fr/design/designer/treeview/XCreatorTreeCellRender.java new file mode 100644 index 0000000000..d919400bed --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/designer/treeview/XCreatorTreeCellRender.java @@ -0,0 +1,8 @@ +package com.fr.design.designer.treeview; + +import java.awt.Component; +import java.awt.Graphics; + +public interface XCreatorTreeCellRender { + void paint(Graphics g, Component c); +} diff --git a/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java index f806a72c0c..e4da44c469 100644 --- a/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java +++ b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java @@ -11,11 +11,9 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.mainframe.CoverReportPane; -import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; import com.fr.form.ui.Widget; import com.fr.general.IOUtils; -import com.fr.stable.ArrayUtils; import javax.swing.*; import java.awt.*; @@ -23,7 +21,6 @@ import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; import java.util.ArrayList; import java.util.List; @@ -72,13 +69,8 @@ public class PopupControlPanel extends JPanel { editButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - int x = rectangle.x + rectangle.width / 2; - int y = rectangle.y + rectangle.height / 2; XCreator childCreator = PopupControlPanel.this.creator.getEditingChildCreator(); - MouseListener[] listeners = designer.getMouseListeners(); - if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { - childCreator.respondClick(((EditingMouseListener) listeners[0]), new MouseEvent(childCreator, MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), x, y, 2, false)); - } + childCreator.startEditing(); } }); return editButton; diff --git a/designer-form/src/main/java/com/fr/design/fit/NewJForm.java b/designer-form/src/main/java/com/fr/design/fit/NewJForm.java index fe192b59b9..6859c12310 100644 --- a/designer-form/src/main/java/com/fr/design/fit/NewJForm.java +++ b/designer-form/src/main/java/com/fr/design/fit/NewJForm.java @@ -13,7 +13,6 @@ import com.fr.design.fit.common.AdaptiveSwitchUtil; import com.fr.design.fit.common.LayoutTool; import com.fr.form.fit.NewFormMarkAttr; import com.fr.design.fit.common.TemplateTool; -import com.fr.design.actions.FormFitAttrAction; import com.fr.design.actions.NewFormMobileAttrAction; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.preview.DeveloperPreview; @@ -53,6 +52,12 @@ public class NewJForm extends JForm { changePaneSize(); } + public NewJForm(Form form) { + super(form); + init(); + changePaneSize(); + } + public NewJForm(Form form, FILE file, Parameter[] parameters) { this(form, file); } @@ -86,7 +91,7 @@ public class NewJForm extends JForm { Rectangle rectangle = LayoutTool.getAbsoluteBodySize(this); if (!isNewJFrom() && (rectangle.width != bodyWidth || rectangle.height != bodyHeight)) { TemplateTool.onlyChangeAbsoluteBodySize(bodyHeight, bodyWidth, this); - } else if(isNewJFrom()){ + } else if (isNewJFrom()) { if (rectangle.width > bodyWidth && rectangle.height > bodyHeight) { TemplateTool.onlyChangeAbsoluteBodySize(rectangle.height, rectangle.width, this); } else if (rectangle.width > bodyWidth) { @@ -123,9 +128,9 @@ public class NewJForm extends JForm { @Override public ShortCut[] shortcut4TemplateMenu() { if (this.index == FORM_TAB) { - return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), new FormFitAttrAction(this)}, new ShortCut[0]); + return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), getReportFitAttrAction()}, new ShortCut[0]); } else { - return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), new FormFitAttrAction(this)}, this.getElementCaseDesign().shortcut4TemplateMenu()); + return ArrayUtils.addAll(new ShortCut[]{new TemplateParameterAction(this), new NewFormMobileAttrAction(this), getReportFitAttrAction()}, this.getElementCaseDesign().shortcut4TemplateMenu()); } } @@ -177,7 +182,7 @@ public class NewJForm extends JForm { private void processColumnAbsorbingEffect(XWTitleLayout xwTitleLayout, DynamicUnitList columnUnitList, Dimension bound) { int temp = 0; - int resolution = DesignerUIModeConfig.getInstance().getScreenResolution();; + int resolution = DesignerUIModeConfig.getInstance().getScreenResolution(); int difference = 0; int i = 0; while (true) { @@ -201,7 +206,7 @@ public class NewJForm extends JForm { private void processRowAbsorbingEffect(XWTitleLayout xwTitleLayout, DynamicUnitList rowUnitList, Dimension bound) { int temp = hasTitle(xwTitleLayout) ? TITLE_HEIGHT : 0; - int resolution =DesignerUIModeConfig.getInstance().getScreenResolution(); + int resolution = DesignerUIModeConfig.getInstance().getScreenResolution(); int difference = 0; int i = 0; while (true) { diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/ElementEditorExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/ElementEditorExtendDefinePane.java deleted file mode 100644 index 20351165e0..0000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/ElementEditorExtendDefinePane.java +++ /dev/null @@ -1,114 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.settings.ThemedComponentStyle; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.CRPropertyDescriptor; -import com.fr.design.designer.creator.PropertyGroupPane; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XElementCase; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.style.FollowingThemePane; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.widget.accessibles.AccessibleElementCaseToolBarEditor; -import com.fr.design.widget.ui.designer.component.PaddingBoundPane; -import com.fr.design.widget.ui.designer.layout.WTitleLayoutDefinePane; -import com.fr.form.main.Form; -import com.fr.form.ui.ElementCaseEditor; -import com.fr.form.ui.PaddingMargin; -import com.fr.form.web.FormToolBarManager; -import com.fr.general.ComparatorUtils; -import com.fr.report.fit.ReportFitAttr; - -import javax.swing.BorderFactory; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; -import java.util.ArrayList; -import java.util.List; - -/** - * Created by kerry on 2020-04-09 - */ -public class ElementEditorExtendDefinePane extends WTitleLayoutDefinePane { - private final PaddingBoundPane paddingBoundPane; - private AccessibleElementCaseToolBarEditor elementCaseToolBarEditor; - private PropertyGroupPane extraPropertyGroupPane; - private PcFitExpandablePane pcFitExpandablePane; - - private static final String FIT_STATE_PC = "fitStateInPC"; - - public ElementEditorExtendDefinePane(XCreator xCreator) { - super(xCreator); - paddingBoundPane = new PaddingBoundPane(); - themePane.addFollowThemePane(paddingBoundPane, new FollowingThemePane.FollowingThemeActionChangeListener() { - @Override - public void onFollowingTheme(boolean following) { - paddingBoundPane.setVisible(!following); - - if (following) { - TemplateTheme theme = themePane.getUsingTheme(); - if (theme instanceof FormTheme) { - ThemedComponentStyle style = ((FormTheme) theme).getComponentStyle(); - int top = style.getPaddingTop(); - int bottom = style.getPaddingBottom(); - int left = style.getPaddingLeft(); - int right = style.getPaddingRight(); - paddingBoundPane.populateBean(new PaddingMargin(top, left, bottom, right)); - } - } - } - }); - } - - protected JPanel createCenterPane() { - JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - elementCaseToolBarEditor = new AccessibleElementCaseToolBarEditor(); - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_EC_Toolbar")), elementCaseToolBarEditor}, - }; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); - panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0)); - CRPropertyDescriptor[] extraTableEditor = removeOldFitEditor(((XElementCase) creator).getExtraTableEditor()); - extraPropertyGroupPane = new PropertyGroupPane(extraTableEditor, creator); - centerPane.add(panel, BorderLayout.NORTH); - if (extraTableEditor.length > 0) { - centerPane.add(extraPropertyGroupPane, BorderLayout.CENTER); - } - pcFitExpandablePane = new PcFitExpandablePane(this); - centerPane.add(pcFitExpandablePane, BorderLayout.SOUTH); - return centerPane; - } - - private CRPropertyDescriptor[] removeOldFitEditor(CRPropertyDescriptor[] extraTableEditor) { - List list = new ArrayList(); - for (CRPropertyDescriptor crPropertyDescriptor : extraTableEditor) { - if (!ComparatorUtils.equals(FIT_STATE_PC, crPropertyDescriptor.getName())) { - list.add(crPropertyDescriptor); - } - } - return list.toArray(new CRPropertyDescriptor[list.size()]); - } - - protected ElementCaseEditor updateSubBean() { - ElementCaseEditor elementCaseEditor = (ElementCaseEditor) creator.toData(); - if (themePane.isFollowingTheme() || ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { - paddingBoundPane.update(elementCaseEditor); - } - elementCaseEditor.setToolBars((FormToolBarManager[]) elementCaseToolBarEditor.getValue()); - ReportFitAttr fitAttr = pcFitExpandablePane.update(); - elementCaseEditor.setReportFitAttr(fitAttr); - return elementCaseEditor; - } - - - protected void populateSubBean(ElementCaseEditor ob) { - paddingBoundPane.populate(ob); - elementCaseToolBarEditor.setValue(ob.getToolBars()); - extraPropertyGroupPane.populate(ob); - pcFitExpandablePane.populate(ob.getReportFitAttr()); - - } -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteBodyLayoutExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteBodyLayoutExtendDefinePane.java deleted file mode 100644 index 563ed16aa6..0000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteBodyLayoutExtendDefinePane.java +++ /dev/null @@ -1,198 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.base.io.IOFile; -import com.fr.base.iofile.attr.WatermarkAttr; -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XWFitLayout; -import com.fr.design.designer.properties.items.FRLayoutTypeItems; -import com.fr.design.designer.properties.items.Item; -import com.fr.design.foldablepane.UIExpandablePane; -import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.style.FollowingThemePane; -import com.fr.design.gui.xpane.LayoutStylePane; -import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.WidgetPropertyPane; -import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; -import com.fr.design.utils.gui.UIComponentUtils; -import com.fr.design.widget.FRWidgetFactory; -import com.fr.design.widget.ui.designer.component.WidgetBoundPane; -import com.fr.design.widget.ui.designer.layout.FRAbsoluteLayoutDefinePane; -import com.fr.form.ui.LayoutBorderStyle; -import com.fr.form.ui.container.WAbsoluteBodyLayout; -import com.fr.form.ui.container.WAbsoluteLayout; -import com.fr.form.ui.container.WBodyLayoutType; -import com.fr.general.act.BorderPacker; -import com.fr.report.core.ReportUtils; - -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; - -/** - * Created by kerry on 2020-04-22 - */ -public class FRAbsoluteBodyLayoutExtendDefinePane extends FRAbsoluteLayoutDefinePane { - private static final int MAX_LABEL_WIDTH = 80; - - protected FollowingThemePane themePane; - private LayoutStylePane stylePane; - private AccessibleBodyWatermarkEditor watermarkEditor; - - private UIComboBox layoutCombox; - private WBodyLayoutType layoutType = WBodyLayoutType.ABSOLUTE; - - public FRAbsoluteBodyLayoutExtendDefinePane(XCreator xCreator) { - super(xCreator); - } - - - public void initComponent() { - initUIComboBox(); - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - - JPanel panel1 = FRGUIPaneFactory.createBorderLayout_S_Pane(); - this.add(panel1, BorderLayout.CENTER); - - UIExpandablePane scalePane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Area_Scaling"), - 280, 20, - createAreaScalePane() - ); - panel1.add(scalePane, BorderLayout.NORTH); - - UIExpandablePane advancedPane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), - 280, 20, - this.createAdvancePane()); - panel1.add(advancedPane, BorderLayout.CENTER); - - } - - public JPanel createAdvancePane() { - JPanel advancedContentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - - themePane = new FollowingThemePane(Toolkit.i18nText("Fine-Design_Form_Body_Style_Setting")); - stylePane = new LayoutStylePane(); - themePane.addFollowThemePane(stylePane, new FollowingThemePane.FollowingThemeActionChangeListener() { - @Override - public void onFollowingTheme(boolean following) { - stylePane.supportBodyStyle(!following); - - BorderPacker style = stylePane.updateBean(); - if (following) { - TemplateTheme theme = themePane.getUsingTheme(); - if (theme instanceof FormTheme) { - style = ((FormTheme) theme).getBodyStyle().merge(style); - } - } - stylePane.populateBean((LayoutBorderStyle) style); - } - }); - advancedContentPane.add(themePane, BorderLayout.NORTH); - - watermarkEditor = new AccessibleBodyWatermarkEditor(); - JPanel watermarkPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), watermarkEditor} - }, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1); - watermarkPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - advancedContentPane.add(watermarkPane, BorderLayout.CENTER); - - return advancedContentPane; - } - - public JPanel createAreaScalePane() { - initLayoutComboBox(); - - UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")); - - JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - {layoutTypeLabel, layoutCombox} - }, - TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - - contentPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - - JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - containerPane.add(contentPane, BorderLayout.CENTER); - containerPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - - return containerPane; - } - - public void initLayoutComboBox() { - Item[] items = FRLayoutTypeItems.ITEMS; - DefaultComboBoxModel model = new DefaultComboBoxModel(); - for (Item item : items) { - model.addElement(item); - } - layoutCombox = new UIComboBox(model); - layoutCombox.setSelectedIndex(1); - } - - @Override - public String title4PopupWindow() { - return "absoluteBodyLayout"; - } - - public void populateSubPane(WAbsoluteLayout ob) { - layoutCombox.setSelectedIndex(1); - themePane.supportFollowingTheme(ob.supportThemed()); - themePane.setFollowingTheme(ob.isBorderStyleFollowingTheme()); - stylePane.populateBean((LayoutBorderStyle) ob.getBorderStyle()); - watermarkEditor.setValue(ReportUtils.getWatermarkAttrFromTemplate(getCurrentIOFile())); - } - - public WAbsoluteBodyLayout updateSubPane() { - WAbsoluteBodyLayout layout = (WAbsoluteBodyLayout) creator.toData(); - Item item = (Item) layoutCombox.getSelectedItem(); - Object value = item.getValue(); - int state = 0; - if (value instanceof Integer) { - state = (Integer) value; - } - - if (layoutType == WBodyLayoutType.ABSOLUTE) { - ((XWFitLayout) creator.getBackupParent()).toData().resetStyle(); - if (state == WBodyLayoutType.FIT.getTypeValue()) { - XWFitLayout xwFitLayout = ((XWFitLayout)creator.getBackupParent()); - xwFitLayout.switch2FitBodyLayout(creator); - copyLayoutAttr(layout, xwFitLayout.toData()); - } - } - layout.setBorderStyleFollowingTheme(themePane.isFollowingTheme()); - layout.setBorderStyle(stylePane.updateBean()); - updateWatermark(); - return layout; - } - - private void updateWatermark() { - WatermarkAttr watermark = (WatermarkAttr) watermarkEditor.getValue(); - if (watermark != null) { - IOFile ioFile = getCurrentIOFile(); - ioFile.addAttrMark(watermark); - } - } - - private IOFile getCurrentIOFile() { - return WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); - } - - @Override - public DataCreatorUI dataUI() { - return null; - } - - -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteLayoutExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteLayoutExtendDefinePane.java deleted file mode 100644 index 60ffae3eb2..0000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRAbsoluteLayoutExtendDefinePane.java +++ /dev/null @@ -1,27 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.design.designer.creator.XCreator; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.widget.ui.designer.layout.AbstractFRLayoutDefinePane; -import com.fr.form.ui.container.WAbsoluteLayout; - -/** - * Created by kerry on 2020-04-22 - */ -public class FRAbsoluteLayoutExtendDefinePane extends AbstractFRLayoutDefinePane { - - public FRAbsoluteLayoutExtendDefinePane(XCreator xCreator) { - super(xCreator); - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - } - - @Override - public void populateBean(WAbsoluteLayout ob) { - } - - @Override - public WAbsoluteLayout updateBean() { - WAbsoluteLayout wAbsoluteLayout = (WAbsoluteLayout) creator.toData(); - return wAbsoluteLayout; - } -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRFitLayoutExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/FRFitLayoutExtendDefinePane.java deleted file mode 100644 index 78e2c5c3a3..0000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/FRFitLayoutExtendDefinePane.java +++ /dev/null @@ -1,282 +0,0 @@ -package com.fr.design.fit.attrpane; - - -import com.fr.base.io.IOFile; -import com.fr.base.iofile.attr.WatermarkAttr; -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XLayoutContainer; -import com.fr.design.designer.creator.XWAbsoluteBodyLayout; -import com.fr.design.designer.creator.XWFitLayout; -import com.fr.design.designer.creator.XWScaleLayout; -import com.fr.design.designer.properties.items.FRLayoutTypeItems; -import com.fr.design.designer.properties.items.Item; -import com.fr.design.foldablepane.UIExpandablePane; -import com.fr.design.gui.icombobox.UIComboBox; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.ispinner.UISpinner; -import com.fr.design.gui.style.FollowingThemePane; -import com.fr.design.gui.xpane.LayoutStylePane; -import com.fr.design.i18n.Toolkit; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.FormSelectionUtils; -import com.fr.design.mainframe.WidgetPropertyPane; -import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; -import com.fr.design.utils.gui.UIComponentUtils; -import com.fr.design.widget.FRWidgetFactory; -import com.fr.design.widget.ui.designer.component.PaddingBoundPane; -import com.fr.design.widget.ui.designer.layout.AbstractFRLayoutDefinePane; -import com.fr.form.ui.LayoutBorderStyle; -import com.fr.form.ui.Widget; -import com.fr.form.ui.container.WAbsoluteBodyLayout; -import com.fr.form.ui.container.WAbsoluteLayout; -import com.fr.form.ui.container.WBodyLayoutType; -import com.fr.form.ui.container.WFitLayout; -import com.fr.general.ComparatorUtils; -import com.fr.general.act.BorderPacker; -import com.fr.log.FineLoggerFactory; -import com.fr.report.core.ReportUtils; - -import javax.swing.BorderFactory; -import javax.swing.DefaultComboBoxModel; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dimension; - -/** - * Created by kerry on 2020-04-22 - */ -public class FRFitLayoutExtendDefinePane extends AbstractFRLayoutDefinePane { - private static final int ADAPT_LABEL_MAX_WIDTH = 80; - private XWFitLayout xWFitLayout; - private WFitLayout wFitLayout; - private UIComboBox layoutComboBox; - private UISpinner componentIntervel; - private PaddingBoundPane paddingBound; - private FollowingThemePane themePane; - private LayoutStylePane stylePane; - private AccessibleBodyWatermarkEditor watermarkEditor; - - public FRFitLayoutExtendDefinePane(XCreator xCreator) { - super(xCreator); - this.xWFitLayout = (XWFitLayout) xCreator; - wFitLayout = xWFitLayout.toData(); - initComponent(); - } - - - public void initComponent() { - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - UIExpandablePane layoutExpandablePane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout"), - 280, 20, - createLayoutPane() - ); - this.add(layoutExpandablePane, BorderLayout.NORTH); - - JPanel advancePane = createAdvancePane(); - UIExpandablePane advanceExpandablePane = new UIExpandablePane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), - 280, 20, - advancePane - ); - this.add(advanceExpandablePane, BorderLayout.CENTER); - } - - public JPanel createAdvancePane() { - JPanel contentPane0 = FRGUIPaneFactory.createBorderLayout_S_Pane(); - - themePane = new FollowingThemePane(Toolkit.i18nText("Fine-Design_Form_Body_Style_Setting")); - stylePane = new LayoutStylePane(); - themePane.addFollowThemePane(stylePane, new FollowingThemePane.FollowingThemeActionChangeListener() { - @Override - public void onFollowingTheme(boolean following) { - stylePane.supportBodyStyle(!following); - - BorderPacker style = stylePane.updateBean(); - if (following) { - TemplateTheme theme = themePane.getUsingTheme(); - if (theme instanceof FormTheme) { - style = ((FormTheme) theme).getBodyStyle().merge(style); - } - } - stylePane.populateBean((LayoutBorderStyle) style); - } - }); - contentPane0.add(themePane, BorderLayout.NORTH); - - JPanel contentPane1 = FRGUIPaneFactory.createBorderLayout_S_Pane(); - contentPane0.add(contentPane1, BorderLayout.CENTER); - - watermarkEditor = new AccessibleBodyWatermarkEditor(); - JPanel waterMarkPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark")), watermarkEditor} - }, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W3, IntervalConstants.INTERVAL_L1); - waterMarkPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); - contentPane1.add(waterMarkPane, BorderLayout.NORTH); - - paddingBound = new PaddingBoundPane(); - contentPane1.add(paddingBound, BorderLayout.CENTER); - - return contentPane0; - } - - public JPanel createLayoutPane() { - JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - - layoutComboBox = initUIComboBox(FRLayoutTypeItems.ITEMS); - componentIntervel = new UISpinner(0, Integer.MAX_VALUE, 1, 0); - JPanel componentIntervelPane = UIComponentUtils.wrapWithBorderLayoutPane(componentIntervel); - - UILabel intervalLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Component_Interval")); - - JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")), layoutComboBox}, - {intervalLabel, componentIntervelPane} - }, - TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - containerPane.add(contentPane, BorderLayout.CENTER); - - return containerPane; - } - - - public UIComboBox initUIComboBox(Item[] items) { - DefaultComboBoxModel model = new DefaultComboBoxModel(); - for (Item item : items) { - model.addElement(item); - } - return new UIComboBox(model); - } - - - @Override - public String title4PopupWindow() { - return "fitLayout"; - } - - @Override - public void populateBean(WFitLayout ob) { - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - XLayoutContainer rootLayout = selectedBodyLayout(formDesigner); - if (rootLayout != formDesigner.getRootComponent() - && formDesigner.getSelectionModel().getSelection().getSelectedCreator() == formDesigner.getRootComponent()) { - formDesigner.getSelectionModel().setSelectedCreators( - FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{selectedBodyLayout(formDesigner).toData()})); - - } - paddingBound.populate(ob); - layoutComboBox.setSelectedIndex(ob.getBodyLayoutType().getTypeValue()); - componentIntervel.setValue(ob.getCompInterval()); - themePane.supportFollowingTheme(ob.supportThemed()); - themePane.setFollowingTheme(ob.isBorderStyleFollowingTheme()); - stylePane.populateBean((LayoutBorderStyle) ob.getBorderStyle()); - watermarkEditor.setValue(ReportUtils.getWatermarkAttrFromTemplate(getCurrentIOFile())); - } - - private XLayoutContainer selectedBodyLayout(FormDesigner formDesigner) { - XLayoutContainer rootLayout = formDesigner.getRootComponent(); - if (rootLayout.getComponentCount() == 1 && rootLayout.getXCreator(0).acceptType(XWAbsoluteBodyLayout.class)) { - rootLayout = (XWAbsoluteBodyLayout) rootLayout.getXCreator(0); - } - return rootLayout; - } - - - @Override - public WFitLayout updateBean() { - WFitLayout layout = (WFitLayout) creator.toData(); - if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { - paddingBound.update(layout); - } - layout.setBorderStyleFollowingTheme(themePane.isFollowingTheme()); - LayoutBorderStyle borderStyle = stylePane.updateBean(); - if (borderStyle != null) { - layout.setBorderStyle(borderStyle); - } - updateWatermark(); - Item item = (Item) layoutComboBox.getSelectedItem(); - Object value = item.getValue(); - int state = 0; - if (value instanceof Integer) { - state = (Integer) value; - } - //todo 验证下 - layout.setLayoutType(WBodyLayoutType.parse(state)); - try { - if (state == WBodyLayoutType.ABSOLUTE.getTypeValue()) { - WAbsoluteBodyLayout wAbsoluteBodyLayout = new WAbsoluteBodyLayout("body"); - wAbsoluteBodyLayout.setCompState(WAbsoluteLayout.STATE_FIXED); - Component[] components = xWFitLayout.getComponents(); - xWFitLayout.removeAll(); - layout.resetStyle(); - XWAbsoluteBodyLayout xwAbsoluteBodyLayout = xWFitLayout.getBackupParent() == null ? new XWAbsoluteBodyLayout(wAbsoluteBodyLayout, new Dimension(0, 0)) : (XWAbsoluteBodyLayout) xWFitLayout.getBackupParent(); - xWFitLayout.getLayoutAdapter().addBean(xwAbsoluteBodyLayout, 0, 0); - for (Component component : components) { - XCreator xCreator = (XCreator) component; - //部分控件被ScaleLayout包裹着,绝对布局里面要放出来 - if (xCreator.acceptType(XWScaleLayout.class)) { - if (xCreator.getComponentCount() > 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) { - component = xCreator.getComponent(0); - component.setBounds(xCreator.getBounds()); - } - } - xwAbsoluteBodyLayout.add(component); - } - copyLayoutAttr(wFitLayout, wAbsoluteBodyLayout); - xWFitLayout.setBackupParent(xwAbsoluteBodyLayout); - FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); - formDesigner.getSelectionModel().setSelectedCreators( - FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout})); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - - } - - int intervelValue = (int) componentIntervel.getValue(); - if (xWFitLayout.canAddInterval(intervelValue)) { -// 设置完间隔后,要同步处理界面组件,容器刷新后显示出对应效果 - setLayoutGap(intervelValue); - } - - return layout; - } - - private void updateWatermark() { - WatermarkAttr watermark = (WatermarkAttr) watermarkEditor.getValue(); - if (watermark != null) { - IOFile ioFile = getCurrentIOFile(); - ioFile.addAttrMark(watermark); - } - } - - private IOFile getCurrentIOFile() { - return WidgetPropertyPane.getInstance().getEditingFormDesigner().getTarget(); - } - - private void setLayoutGap(int value) { - int interval = wFitLayout.getCompInterval(); - if (value != interval) { - xWFitLayout.moveContainerMargin(); - xWFitLayout.moveCompInterval(xWFitLayout.getAcualInterval()); - wFitLayout.setCompInterval(value); - xWFitLayout.addCompInterval(xWFitLayout.getAcualInterval()); - } - } - - @Override - public DataCreatorUI dataUI() { - return null; - } - -} diff --git a/designer-form/src/main/java/com/fr/design/fit/attrpane/RootDesignExtendDefinePane.java b/designer-form/src/main/java/com/fr/design/fit/attrpane/RootDesignExtendDefinePane.java deleted file mode 100644 index 8a8aa404ac..0000000000 --- a/designer-form/src/main/java/com/fr/design/fit/attrpane/RootDesignExtendDefinePane.java +++ /dev/null @@ -1,303 +0,0 @@ -package com.fr.design.fit.attrpane; - -import com.fr.base.BaseUtils; -import com.fr.design.ExtraDesignClassManager; -import com.fr.design.data.DataCreatorUI; -import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.CRPropertyDescriptor; -import com.fr.design.designer.creator.PropertyGroupPane; -import com.fr.design.designer.creator.XCreator; -import com.fr.design.designer.creator.XWParameterLayout; -import com.fr.design.designer.properties.PropertyTab; -import com.fr.design.file.HistoryTemplateListPane; -import com.fr.design.fit.DesignerUIModeConfig; -import com.fr.design.fit.common.TemplateTool; -import com.fr.design.foldablepane.UIExpandablePane; -import com.fr.design.fun.ParameterExpandablePaneUIProvider; -import com.fr.design.gui.ibutton.UIButtonGroup; -import com.fr.design.gui.icheckbox.UICheckBox; -import com.fr.design.gui.ilable.UILabel; -import com.fr.design.gui.ispinner.UISpinner; -import com.fr.design.gui.itextfield.UITextField; -import com.fr.design.layout.FRGUIPaneFactory; -import com.fr.design.layout.TableLayout; -import com.fr.design.layout.TableLayoutHelper; -import com.fr.design.mainframe.FormDesigner; -import com.fr.design.mainframe.FormSelection; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor; -import com.fr.design.utils.gui.LayoutUtils; -import com.fr.design.utils.gui.UIComponentUtils; -import com.fr.design.widget.ui.designer.AbstractDataModify; -import com.fr.design.widget.ui.designer.component.UIBoundSpinner; -import com.fr.form.ui.container.WParameterLayout; -import com.fr.general.Background; -import com.fr.report.stable.FormConstants; - -import javax.swing.BorderFactory; -import javax.swing.Icon; -import javax.swing.JPanel; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Rectangle; -import java.util.Set; - -public class RootDesignExtendDefinePane extends AbstractDataModify { - private XWParameterLayout root; - private UISpinner designerWidth; - private UISpinner paraHeight; - private UICheckBox displayReport; - private UICheckBox useParamsTemplate; - private AccessibleBackgroundEditor background; - private UIButtonGroup hAlignmentPane; - private UITextField labelNameTextField; - //是否是新设计模式下决策报表 - private boolean newForm; - private PropertyGroupPane extraPropertyGroupPane; - - public RootDesignExtendDefinePane(XCreator xCreator) { - super(xCreator); - newForm = TemplateTool.getCurrentEditingNewJForm() != null && DesignerUIModeConfig.getInstance().newUIMode(); - this.root = (XWParameterLayout) xCreator; - initComponent(); - } - - - public void initComponent() { - this.setLayout(FRGUIPaneFactory.createBorderLayout()); - if (newForm) { - paraHeight = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0); - } else { - designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); - } - JPanel advancePane = createAdvancePane(); - UIExpandablePane advanceExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, advancePane); - this.add(advanceExpandablePane, BorderLayout.NORTH); - JPanel layoutPane = createBoundsPane(); - UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Size"), 280, 20, layoutPane); - this.add(layoutExpandablePane, BorderLayout.CENTER); - this.addExtraUIExpandablePaneFromPlugin(); - } - - private void addExtraUIExpandablePaneFromPlugin() { - Set pluginCreators = ExtraDesignClassManager.getInstance().getArray(ParameterExpandablePaneUIProvider.XML_TAG); - JPanel panel = FRGUIPaneFactory.createYBoxEmptyBorderPane(); - for (ParameterExpandablePaneUIProvider provider : pluginCreators) { - UIExpandablePane uiExpandablePane = provider.createUIExpandablePane(); - PropertyTab propertyTab = provider.addToWhichPropertyTab(); - if (uiExpandablePane != null && propertyTab == PropertyTab.ATTR) { - panel.add(uiExpandablePane); - } - } - this.add(panel, BorderLayout.SOUTH); - } - - public JPanel createBoundsPane() { - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {p}; - double[] columnSize = {p, f}; - int[][] rowCount = {{1, 1}}; - Component[] component = newForm ? new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Design_Height")), paraHeight} : - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Desin_Width")), designerWidth}; - Component[][] components = new Component[][]{component}; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); - jPanel.add(panel); - return jPanel; - } - - public JPanel createAdvancePane() { - if (newForm) { - return getNewFormAdvancePane(); - } else { - return getTemplateAdvancePane(); - } - } - - /** - * @Description: 获取的非新决策报表AdvancePane - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private JPanel getTemplateAdvancePane() { - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - labelNameTextField = new UITextField(); - displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); - UIComponentUtils.setLineWrap(displayReport); - useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); - background = new AccessibleBackgroundEditor(); - Icon[] hAlignmentIconArray = {BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_left_normal.png"), - BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_center_normal.png"), - BaseUtils.readIcon("/com/fr/design/images/m_format/cellstyle/h_right_normal.png"),}; - Integer[] hAlignment = new Integer[]{FormConstants.LEFTPOSITION, FormConstants.CENTERPOSITION, FormConstants.RIGHTPOSITION}; - hAlignmentPane = new UIButtonGroup(hAlignmentIconArray, hAlignment); - hAlignmentPane.setAllToolTips(new String[]{com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Left") - , com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Center"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_StyleAlignment_Right")}); - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p, p, p}; - double[] columnSize = {p, f}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, - new Component[]{displayReport, null}, - new Component[]{useParamsTemplate, null}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Display_Position")), hAlignmentPane} - }; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); - panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - CRPropertyDescriptor[] extraTableEditor = new CRPropertyDescriptor[0]; - extraTableEditor = root.getExtraTableEditor(); - extraPropertyGroupPane = new PropertyGroupPane(extraTableEditor, root); - - jPanel.add(panel, BorderLayout.NORTH); - jPanel.add(extraPropertyGroupPane, BorderLayout.CENTER); - return jPanel; - } - - /** - * @Description: 获取新决策报表的AdvancePane - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private JPanel getNewFormAdvancePane() { - JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); - labelNameTextField = new UITextField(); - displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); - UIComponentUtils.setLineWrap(displayReport); - useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); - background = new AccessibleBackgroundEditor(); - - double f = TableLayout.FILL; - double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p, p}; - double[] columnSize = {p, f}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}}; - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, - new Component[]{displayReport, null}, - new Component[]{useParamsTemplate, null} - }; - JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); - panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); - - jPanel.add(panel, BorderLayout.NORTH); - - return jPanel; - } - - @Override - public String title4PopupWindow() { - return "parameter"; - } - - @Override - public void populateBean(WParameterLayout ob) { - labelNameTextField.setText(ob.getLabelName()); - background.setValue(ob.getBackground()); - displayReport.setSelected(ob.isDelayDisplayContent()); - useParamsTemplate.setSelected(ob.isUseParamsTemplate()); - if (newForm) { - FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); - paraHeight.setValue(designer.getParaHeight()); - } else { - designerWidth.setValue(ob.getDesignWidth()); - hAlignmentPane.setSelectedItem(ob.getPosition()); - - if (extraPropertyGroupPane != null) { - extraPropertyGroupPane.populate(ob); - } - } - } - - - @Override - public WParameterLayout updateBean() { - if (newForm) { - return updateNewFormBean(); - } else { - return updateTemplateBean(); - } - } - - /** - * @Description: 更新非新决策报表的bean - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private WParameterLayout updateTemplateBean() { - WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); - wParameterLayout.setLabelName(labelNameTextField.getText()); - if (isCompsOutOfDesignerWidth((int) designerWidth.getValue())) { - designerWidth.setValue(wParameterLayout.getDesignWidth()); - } else { - wParameterLayout.setDesignWidth((int) designerWidth.getValue()); - } - wParameterLayout.setDelayDisplayContent(displayReport.isSelected()); - wParameterLayout.setUseParamsTemplate(useParamsTemplate.isSelected()); - JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); - jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); - wParameterLayout.setBackground((Background) background.getValue()); - wParameterLayout.setPosition((Integer) hAlignmentPane.getSelectedItem()); - return wParameterLayout; - } - - /** - * @Description: 更新新决策报表的bean - * @param - * @return: - * @Author: Henry.Wang - * @date: 2020/11/05 15:36 - */ - private WParameterLayout updateNewFormBean() { - WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); - wParameterLayout.setLabelName(labelNameTextField.getText()); - - wParameterLayout.setDelayDisplayContent(displayReport.isSelected()); - wParameterLayout.setUseParamsTemplate(useParamsTemplate.isSelected()); - JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); - jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); - wParameterLayout.setBackground((Background) background.getValue()); - //设置参数模板面板的高度 - int height = (int) paraHeight.getTextField().getValue(); - FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); - FormSelection selection = designer.getSelectionModel().getSelection(); - XCreator creator = designer.getParaComponent(); - Rectangle rectangle = creator.getBounds(); - Rectangle newRectangle = new Rectangle(rectangle.x, rectangle.y, rectangle.width, height); - creator.setBounds(newRectangle); - if (paraHeight.getValue() != newRectangle.height) - paraHeight.setValue(newRectangle.height); - designer.setParaHeight(newRectangle.height); - designer.getArea().doLayout(); - LayoutUtils.layoutContainer(creator); - selection.fixCreator(designer); - designer.repaint(); - return wParameterLayout; - } - - private boolean isCompsOutOfDesignerWidth(int designerWidth) { - for (int i = 0; i < root.getComponentCount(); i++) { - Component comp = root.getComponent(i); - if (comp.getX() + comp.getWidth() > designerWidth) { - return true; - } - } - return false; - } - - @Override - public DataCreatorUI dataUI() { - return null; - } -} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java b/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java index 8c55e8ab0a..a5df5fabda 100644 --- a/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java +++ b/designer-form/src/main/java/com/fr/design/fit/common/AdaptiveSwitchUtil.java @@ -3,39 +3,24 @@ package com.fr.design.fit.common; import com.fr.design.data.DesignTableDataManager; import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.fit.NewJForm; -import com.fr.design.fit.attrpane.ElementEditorExtendDefinePane; -import com.fr.design.fit.attrpane.FRAbsoluteBodyLayoutExtendDefinePane; -import com.fr.design.fit.attrpane.FRAbsoluteLayoutExtendDefinePane; -import com.fr.design.fit.attrpane.FRFitLayoutExtendDefinePane; -import com.fr.design.fit.attrpane.RootDesignExtendDefinePane; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.JTemplate; -import com.fr.design.parameter.RootDesignDefinePane; import com.fr.design.preview.FormAdaptivePreview; import com.fr.design.preview.FormPreview; -import com.fr.design.widget.Appearance; -import com.fr.design.widget.FormWidgetDefinePaneFactoryBase; -import com.fr.design.widget.ui.designer.layout.ElementEditorDefinePane; -import com.fr.design.widget.ui.designer.layout.FRAbsoluteBodyLayoutDefinePane; -import com.fr.design.widget.ui.designer.layout.FRAbsoluteLayoutDefinePane; -import com.fr.design.widget.ui.designer.layout.FRFitLayoutDefinePane; import com.fr.file.FILE; import com.fr.file.MemFILE; import com.fr.form.main.Form; import com.fr.form.main.WidgetGather; -import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteBodyLayout; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.form.ui.container.WFitLayout; -import com.fr.form.ui.container.WParameterLayout; import com.fr.form.ui.widget.CRBoundsWidget; import com.fr.log.FineLoggerFactory; import com.fr.report.fit.ReportFitAttr; import javax.swing.SwingUtilities; -import java.util.Set; /** * Created by kerry on 2020-06-02 @@ -55,16 +40,6 @@ public class AdaptiveSwitchUtil { public static void switch2NewUIMode() { DesignerUIModeConfig.getInstance().setNewUIMode(); - FormWidgetDefinePaneFactoryBase.registerDefinePane(ElementCaseEditor.class, - new Appearance(ElementEditorExtendDefinePane.class, "elementCaseEditor")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WFitLayout.class, - new Appearance(FRFitLayoutExtendDefinePane.class, "wFitLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteBodyLayout.class, - new Appearance(FRAbsoluteBodyLayoutExtendDefinePane.class, "wAbsoluteBodyLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteLayout.class, - new Appearance(FRAbsoluteLayoutExtendDefinePane.class, "wAbsoluteLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WParameterLayout.class, - new Appearance(RootDesignExtendDefinePane.class, "wParameterLayout")); } public static void switch2OldUI() { @@ -74,16 +49,6 @@ public class AdaptiveSwitchUtil { public static void switch2OldUIMode() { DesignerUIModeConfig.getInstance().setOldUIMode(); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteLayout.class, - new Appearance(FRAbsoluteLayoutDefinePane.class, "wAbsoluteLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(ElementCaseEditor.class, - new Appearance(ElementEditorDefinePane.class, "elementCaseEditor")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WAbsoluteBodyLayout.class, - new Appearance(FRAbsoluteBodyLayoutDefinePane.class, "wAbsoluteBodyLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WFitLayout.class, - new Appearance(FRFitLayoutDefinePane.class, "wFitLayout")); - FormWidgetDefinePaneFactoryBase.registerDefinePane(WParameterLayout.class, - new Appearance(RootDesignDefinePane.class, "wParameterLayout")); } public static void reload() { diff --git a/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java b/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java index 3f0d2826f3..2be67555a6 100644 --- a/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java +++ b/designer-form/src/main/java/com/fr/design/form/layout/FRTitleLayout.java @@ -6,6 +6,7 @@ package com.fr.design.form.layout; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Insets; import java.awt.LayoutManager; import com.fr.form.ui.container.WLayout; @@ -123,15 +124,20 @@ public class FRTitleLayout implements FRLayoutManager, LayoutManager{ synchronized (target.getTreeLock()) { int width = target.getWidth(); int height = target.getHeight(); - int titleH = title==null ? 0 : WTitleLayout.TITLE_HEIGHT; + Insets insets = target.getInsets(); + int titleH = title == null ? 0 : WTitleLayout.TITLE_HEIGHT; + insets = title == null ? new Insets(0, 0, 0, 0) : insets; + width = Math.max(0, width - insets.left - insets.right); + height = Math.max(0, height - insets.top - insets.bottom); + for (int i=0; i< target.getComponentCount(); i++) { Component comp = target.getComponent(i); if (comp != null) { if (comp == title) { - comp.setBounds(0, 0, width, WTitleLayout.TITLE_HEIGHT); + comp.setBounds(insets.left, insets.top, width, WTitleLayout.TITLE_HEIGHT); } else if (comp == body) { int y = titleH + gap; - comp.setBounds(0, y, width, height-y); + comp.setBounds(insets.left, y + insets.top, width, height - y); } } } diff --git a/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java b/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java index 72c7b8bfd1..02ea653f2b 100644 --- a/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java +++ b/designer-form/src/main/java/com/fr/design/form/parameter/FormParaTargetMode.java @@ -1,7 +1,6 @@ package com.fr.design.form.parameter; -import com.fr.base.svg.IconUtils; import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.properties.WidgetPropertyTable; import com.fr.design.gui.core.WidgetOption; @@ -12,6 +11,7 @@ import com.fr.form.main.parameter.FormParameterUI; import com.fr.form.parameter.FormSubmitButton; +import com.fr.form.ui.PageFixedRowComboBox; import java.util.ArrayList; public class FormParaTargetMode extends FormDesignerModeForSpecial { @@ -28,7 +28,9 @@ public class FormParaTargetMode extends FormDesignerModeForSpecial { namedIntegralStylePane.setVisible(supporting); } } -} +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java index 2d0bb383fc..0c86493485 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/ComponentTree.java @@ -13,11 +13,8 @@ import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.gui.itree.UITreeUI; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; - import java.awt.Rectangle; -import java.awt.event.MouseListener; import java.util.Stack; import java.util.function.Consumer; import javax.swing.BorderFactory; @@ -98,6 +95,10 @@ public class ComponentTree extends JTree { public void setSelectionPath(TreePath path) { // 不管点击哪一项,都要先退出编辑状态(图表、报表块、绝对布局、tab块) + Object widget = path.getLastPathComponent(); + if(widget == null ||!((XCreator)widget).getXCreatorBaseOperate().supportSelected()){ + return; + } designer.stopEditing(path); super.setSelectionPath(path); } @@ -361,7 +362,6 @@ public class ComponentTree extends JTree { @Override public void mouseMoved(MouseEvent e) { - Point p = e.getPoint(); int selRow = tree.getRowForLocation(p.x, p.y); TreeCellRenderer r = tree.getCellRenderer(); @@ -370,10 +370,12 @@ public class ComponentTree extends JTree { Point point = tree.getPathBounds(path).getLocation(); SwingUtilities.convertPointToScreen(point, tree); XCreator comp = (XCreator) path.getLastPathComponent(); - popupPreviewPane(point.y, comp); - } else { - hidePreviewPane(); + if (comp.getXCreatorBaseOperate().supportSelected()) { + popupPreviewPane(point.y, comp); + return; + } } + hidePreviewPane(); } @Override @@ -386,8 +388,9 @@ public class ComponentTree extends JTree { onMouseEvent(e, new Consumer() { @Override public void accept(XCreator creator) { - if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 && !designer.isFormParaDesigner()) { - startEditing(creator, e); + if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 && !designer.isFormParaDesigner() + &&creator.getXCreatorBaseOperate().supportSelected()) { + startEditing(creator); } } }); @@ -399,7 +402,7 @@ public class ComponentTree extends JTree { onMouseEvent(e, new Consumer() { @Override public void accept(XCreator creator) { - if (e.getButton() == MouseEvent.BUTTON1) { + if (e.getButton() == MouseEvent.BUTTON1 && creator.getXCreatorBaseOperate().supportSelected()) { selectedCreator = creator; } } @@ -455,18 +458,11 @@ public class ComponentTree extends JTree { * 组件进入编辑状态 * * @param comp - * @param e */ - private void startEditing(XCreator comp, MouseEvent e) { + private void startEditing(XCreator comp) { designer.getSelectionModel().selectACreator(comp); - Rectangle rectangle = getRelativeBounds(comp); - int x = rectangle.x + rectangle.width / 2; - int y = rectangle.y + rectangle.height / 2; XCreator creator = comp.getEditingChildCreator(); - MouseListener[] listeners = designer.getMouseListeners(); - if (ArrayUtils.isNotEmpty(listeners) && listeners[0] instanceof EditingMouseListener) { - responseClickAll(creator, (EditingMouseListener) listeners[0], new MouseEvent(creator, MouseEvent.MOUSE_CLICKED, e.getWhen(), e.getModifiers(), x, y, e.getClickCount(), false)); - } + responseEditing(creator); // 放到事件尾部执行 SwingUtilities.invokeLater(new Runnable() { @Override @@ -488,10 +484,8 @@ public class ComponentTree extends JTree { * * * @param creator - * @param editingMouseListener - * @param mouseEvent */ - public void responseClickAll(XCreator creator, EditingMouseListener editingMouseListener, MouseEvent mouseEvent) { + private void responseEditing(XCreator creator) { Stack stack = new Stack<>(); stack.push(creator); while (creator.getParent() instanceof XCreator) { @@ -499,7 +493,7 @@ public class ComponentTree extends JTree { stack.push(creator); } while (!stack.isEmpty()) { - stack.pop().respondClick(editingMouseListener, mouseEvent); + stack.pop().startEditing(); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java b/designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java new file mode 100644 index 0000000000..15aec31d58 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java @@ -0,0 +1,31 @@ +package com.fr.design.mainframe; + +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/23 + */ +public class DesignerScaleMouseWheelHandler implements MouseWheelListener { + private final ScalePane scalePane; + private final int step; + + public DesignerScaleMouseWheelHandler(ScalePane scalePane, int step) { + this.scalePane = scalePane; + this.step = step; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + int dir = e.getWheelRotation(); + JFormSliderPane slidePane = this.scalePane.getSlidePane(); + int old_resolution = slidePane.getShowValue(); + slidePane.setShowValue(old_resolution - (dir * step)); + } + + public interface ScalePane { + JFormSliderPane getSlidePane(); + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java b/designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java new file mode 100644 index 0000000000..82d2cb1b8b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java @@ -0,0 +1,279 @@ +package com.fr.design.mainframe; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; +import java.awt.Component; +import java.awt.Rectangle; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * 实现设计器面板的触摸板滚动移动交互 https://work.fineres.com/browse/REPORT-55989 + * + * mouseWheelMoved 的具体实现来自 + * @link {javax.swing.plaf.basic.BasicScrollPaneUI.Handler#mouseWheelMoved} + * scrollByUnits 的具体实现来自 + * @link {javax.swing.plaf.basic.BasicScrollPaneUI#scrollByUnits} + * scrollByBlock 的具体实现来自 + * @link {javax.swing.plaf.basic.BasicScrollPaneUI#scrollByBlock} + */ +public class DesignerTranslateMouseWheelHandler implements MouseWheelListener { + private final ScrollPane scrollpane; + + public DesignerTranslateMouseWheelHandler(ScrollPane scrollpane) { + this.scrollpane = scrollpane; + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (scrollpane.isWheelScrollingEnabled() && + e.getWheelRotation() != 0) { + JScrollBar toScroll = scrollpane.getVerticalScrollBar(); + int direction = e.getWheelRotation() < 0 ? -1 : 1; + int orientation = SwingConstants.VERTICAL; + + // find which scrollbar to scroll, or return if none + if (toScroll == null || !toScroll.isVisible() + || e.isShiftDown()) { + toScroll = scrollpane.getHorizontalScrollBar(); + if (toScroll == null || !toScroll.isVisible()) { + return; + } + orientation = SwingConstants.HORIZONTAL; + } + + e.consume(); + + if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { + JViewport vp = scrollpane.getViewport(); + if (vp == null) { return; } + Component comp = vp.getView(); + int units = Math.abs(e.getUnitsToScroll()); + + // When the scrolling speed is set to maximum, it's possible + // for a single wheel click to scroll by more units than + // will fit in the visible area. This makes it + // hard/impossible to get to certain parts of the scrolling + // Component with the wheel. To make for more accurate + // low-speed scrolling, we limit scrolling to the block + // increment if the wheel was only rotated one click. + boolean limitScroll = Math.abs(e.getWheelRotation()) == 1; + + // Check if we should use the visibleRect trick + Object fastWheelScroll = toScroll.getClientProperty( + "JScrollBar.fastWheelScrolling"); + if (Boolean.TRUE == fastWheelScroll && + comp instanceof Scrollable) { + // 5078454: Under maximum acceleration, we may scroll + // by many 100s of units in ~1 second. + // + // BasicScrollBarUI.scrollByUnits() can bog down the EDT + // with repaints in this situation. However, the + // Scrollable interface allows us to pass in an + // arbitrary visibleRect. This allows us to accurately + // calculate the total scroll amount, and then update + // the GUI once. This technique provides much faster + // accelerated wheel scrolling. + Scrollable scrollComp = (Scrollable) comp; + Rectangle viewRect = vp.getViewRect(); + int startingX = viewRect.x; + boolean leftToRight = + comp.getComponentOrientation().isLeftToRight(); + int scrollMin = toScroll.getMinimum(); + int scrollMax = toScroll.getMaximum() - + toScroll.getModel().getExtent(); + + if (limitScroll) { + int blockIncr = + scrollComp.getScrollableBlockIncrement(viewRect, + orientation, + direction); + if (direction < 0) { + scrollMin = Math.max(scrollMin, + toScroll.getValue() - blockIncr); + } + else { + scrollMax = Math.min(scrollMax, + toScroll.getValue() + blockIncr); + } + } + + for (int i = 0; i < units; i++) { + int unitIncr = + scrollComp.getScrollableUnitIncrement(viewRect, + orientation, direction); + // Modify the visible rect for the next unit, and + // check to see if we're at the end already. + if (orientation == SwingConstants.VERTICAL) { + if (direction < 0) { + viewRect.y -= unitIncr; + if (viewRect.y <= scrollMin) { + viewRect.y = scrollMin; + break; + } + } + else { // (direction > 0 + viewRect.y += unitIncr; + if (viewRect.y >= scrollMax) { + viewRect.y = scrollMax; + break; + } + } + } + else { + // Scroll left + if ((leftToRight && direction < 0) || + (!leftToRight && direction > 0)) { + viewRect.x -= unitIncr; + if (leftToRight) { + if (viewRect.x < scrollMin) { + viewRect.x = scrollMin; + break; + } + } + } + // Scroll right + else if ((leftToRight && direction > 0) || + (!leftToRight && direction < 0)) { + viewRect.x += unitIncr; + if (leftToRight) { + if (viewRect.x > scrollMax) { + viewRect.x = scrollMax; + break; + } + } + } + else { + assert false : "Non-sensical ComponentOrientation / scroll direction"; + } + } + } + // Set the final view position on the ScrollBar + if (orientation == SwingConstants.VERTICAL) { + toScroll.setValue(viewRect.y); + } + else { + if (leftToRight) { + toScroll.setValue(viewRect.x); + } + else { + // rightToLeft scrollbars are oriented with + // minValue on the right and maxValue on the + // left. + int newPos = toScroll.getValue() - + (viewRect.x - startingX); + if (newPos < scrollMin) { + newPos = scrollMin; + } + else if (newPos > scrollMax) { + newPos = scrollMax; + } + toScroll.setValue(newPos); + } + } + } + else { + // Viewport's view is not a Scrollable, or fast wheel + // scrolling is not enabled. + scrollByUnits(toScroll, direction, + units, limitScroll); + } + } + else if (e.getScrollType() == + MouseWheelEvent.WHEEL_BLOCK_SCROLL) { + scrollByBlock(toScroll, direction); + } + } + } + + /* + * Method for scrolling by a unit increment. + * Added for mouse wheel scrolling support, RFE 4202656. + * + * If limitByBlock is set to true, the scrollbar will scroll at least 1 + * unit increment, but will not scroll farther than the block increment. + * See BasicScrollPaneUI.Handler.mouseWheelMoved(). + */ + static void scrollByUnits(JScrollBar scrollbar, int direction, + int units, boolean limitToBlock) { + // This method is called from BasicScrollPaneUI to implement wheel + // scrolling, as well as from scrollByUnit(). + int delta; + int limit = -1; + + if (limitToBlock) { + if (direction < 0) { + limit = scrollbar.getValue() - + scrollbar.getBlockIncrement(direction); + } + else { + limit = scrollbar.getValue() + + scrollbar.getBlockIncrement(direction); + } + } + + for (int i=0; i 0) { + delta = scrollbar.getUnitIncrement(direction); + } + else { + delta = -scrollbar.getUnitIncrement(direction); + } + + int oldValue = scrollbar.getValue(); + int newValue = oldValue + delta; + + // Check for overflow. + if (delta > 0 && newValue < oldValue) { + newValue = scrollbar.getMaximum(); + } + else if (delta < 0 && newValue > oldValue) { + newValue = scrollbar.getMinimum(); + } + if (oldValue == newValue) { + break; + } + + if (limitToBlock && i > 0) { + assert limit != -1; + if ((direction < 0 && newValue < limit) || + (direction > 0 && newValue > limit)) { + break; + } + } + scrollbar.setValue(newValue); + } + } + + /* + * Method for scrolling by a block increment. + * Added for mouse wheel scrolling support, RFE 4202656. + */ + static void scrollByBlock(JScrollBar scrollbar, int direction) { + // This method is called from BasicScrollPaneUI to implement wheel + // scrolling, and also from scrollByBlock(). + int oldValue = scrollbar.getValue(); + int blockIncrement = scrollbar.getBlockIncrement(direction); + int delta = blockIncrement * ((direction > 0) ? +1 : -1); + int newValue = oldValue + delta; + + // Check for overflow. + if (delta > 0 && newValue < oldValue) { + newValue = scrollbar.getMaximum(); + } + else if (delta < 0 && newValue > oldValue) { + newValue = scrollbar.getMinimum(); + } + + scrollbar.setValue(newValue); + } + + public interface ScrollPane { + boolean isWheelScrollingEnabled(); + JScrollBar getVerticalScrollBar(); + JScrollBar getHorizontalScrollBar(); + JViewport getViewport(); + } +} \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java index a7244c0f2a..b0463a685a 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/EditingMouseListener.java @@ -636,7 +636,7 @@ public class EditingMouseListener extends MouseInputAdapter { XCreator oldCreator = creator; creator = processTopLayoutMouseClick(creator); - if (creator != null) { + if (creator != null && creator.getXCreatorBaseOperate().supportSelected()) { // tab块处于未编辑状态 boolean uneditedTab = designer.getCursor().getType() != Cursor.HAND_CURSOR && creator.acceptType(XWCardMainBorderLayout.class) && !((XWCardMainBorderLayout) creator).isEditable(); // 点击不在tab块的button中 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java index 16dc8593ec..e08c1c652d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java @@ -1,12 +1,21 @@ package com.fr.design.mainframe; import com.fr.common.inputevent.InputEventBaseOnOS; +import com.fr.design.actions.UpdateAction; +import com.fr.design.constants.UIConstants; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWBorderLayout; import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIButtonUI; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.PopupMenuItem; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.design.utils.gui.GUIPaintUtils; import com.fr.form.fit.NewFormMarkAttr; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UINumberField; @@ -20,15 +29,20 @@ import com.fr.design.scrollruler.VerticalRuler; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.main.mobile.FormMobileAttr; +import com.fr.form.ui.container.WBodyLayoutType; import com.fr.form.ui.container.WBorderLayout; -import com.fr.general.FRScreen; +import com.fr.form.ui.container.WFitLayout; +import com.fr.general.IOUtils; import com.fr.stable.AssistUtils; import javax.swing.AbstractAction; +import javax.swing.Action; +import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.KeyStroke; +import javax.swing.SwingConstants; import javax.swing.border.LineBorder; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; @@ -38,6 +52,8 @@ import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; @@ -58,10 +74,11 @@ public class FormArea extends JComponent implements ScrollRulerComponent { private static final double SLIDER_MIN = 10.0; private static final String SCALE_PLUS_COMMAND = "scale_plus"; private static final String SCALE_MINUS_COMMAND = "scale_minus"; + public static final String FIX_LAYOUT_SWITCH_BUTTON = "fix_layout_switch_button"; public static final double DEFAULT_SLIDER = 100.0; private static final int ROTATIONS = 50; - private static final int SHOWVALMAX = 400; - private static final int SHOWVALMIN = 10; + public static final int SHOWVALMAX = 400; + public static final int SHOWVALMIN = 10; private static final int RESIZE_PANE_GAP = 8; private static final int MOBILE_ONLY_WIDTH = 375; private static final int MOBILE_ONLY_HEIGHT = 560; @@ -80,6 +97,8 @@ public class FormArea extends JComponent implements ScrollRulerComponent { // 初始时滑块值为100,托动后的值设为START_VALUE; private double START_VALUE = DEFAULT_SLIDER; private double screenValue; + private UIButton fixLayoutSwitchButton; + private boolean isFixLayoutEditState; public FormScrollBar getHorScrollBar() { @@ -116,10 +135,24 @@ public class FormArea extends JComponent implements ScrollRulerComponent { addFormRuler(); } this.setFocusTraversalKeysEnabled(false); - this.designer.addMouseWheelListener(showValSpinnerMouseWheelListener); + + + this.designer.addMouseWheelListener(new FormAreaMouseWheelHandler(this)); registerShortCutKey(); } + public FormScrollBar getVerticalScrollBar() { + return verScrollBar; + } + + public FormScrollBar getHorizontalScrollBar() { + return horScrollBar; + } + + public JFormSliderPane getSlidePane() { + return slidePane; + } + /** * 注册缩放快捷键 * mac: command + 和 command - @@ -153,16 +186,44 @@ public class FormArea extends JComponent implements ScrollRulerComponent { widthPane.setEnabled(!formMobileAttr.isMobileOnly()); } - MouseWheelListener showValSpinnerMouseWheelListener = new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - if (InputEventBaseOnOS.isControlDown(e)) { - int dir = e.getWheelRotation(); - int old_resolution = slidePane.getShowValue(); - slidePane.setShowValue(old_resolution - (dir * SHOWVALMIN)); + private UIButton createFixLayoutSwitchButton(){ + UIButton button = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_No_Fix_Layout")); + button.setIcon(IOUtils.readIcon("/com/fr/base/images/share/filter_combo.png")); + button.setName(FIX_LAYOUT_SWITCH_BUTTON); + button.setUI(new UIButtonUI(){ + @Override + protected void paintBorder(Graphics g, UIButton b) { + } - } - }; + protected void doExtraPainting(UIButton b, Graphics2D g2d, int w, int h, String selectedRoles) { + if (isPressed(b) && b.isPressedPainted()) { + GUIPaintUtils.fillPressed(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles)); + } else if (isRollOver(b)) { + GUIPaintUtils.fillRollOver(g2d, 0, 0, w, h, b.isRoundBorder(), b.getRectDirection(), b.isDoneAuthorityEdited(selectedRoles), b.isPressedPainted()); + } + } + }); + button.setHorizontalTextPosition(SwingConstants.LEFT); + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setPreferredSize(new Dimension(180, 59)); + popupMenu.setOnlyText(true); + popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); + popupMenu.add(new PopupMenuItem(new Switch2NoFixLayoutAction())); + popupMenu.add(new PopupMenuItem(new Switch2FixLayoutAction())); + button.setComponentPopupMenu(popupMenu); + button.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + GUICoreUtils.showPopupMenu(popupMenu, fixLayoutSwitchButton, 0, -59); + } + }); + button.setVisible(!isAbsoluteBodyLayout()); + return button; + } + + private boolean isAbsoluteBodyLayout() { + return ((WFitLayout) designer.getRootComponent().toData()).getBodyLayoutType() == WBodyLayoutType.ABSOLUTE; + } @@ -175,6 +236,11 @@ public class FormArea extends JComponent implements ScrollRulerComponent { double[] rowSize = {f}; double[] columnSize = {p, f, p, p, p, p, p, f, p}; UILabel tipsPane = new UILabel("form"); + fixLayoutSwitchButton = createFixLayoutSwitchButton(); + JPanel layoutSwitchPane = FRGUIPaneFactory.createLeftFlowZeroGapBorderPane(); + layoutSwitchPane.setBorder(BorderFactory.createEmptyBorder(0, 12, 0, 0)); + layoutSwitchPane.add(fixLayoutSwitchButton); + widthPane = new UINumberField(); widthPane.setPreferredSize(new Dimension(60, 0)); heightPane = new UINumberField(); @@ -183,7 +249,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { slidePane = JFormSliderPane.getInstance(); JPanel resizePane = TableLayoutHelper.createCommonTableLayoutPane( - new JComponent[][]{{tipsPane, new UILabel(), widthPane, + new JComponent[][]{{tipsPane, layoutSwitchPane, widthPane, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Indent_Pixel")), new UILabel("x"), heightPane, new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Indent_Pixel")), @@ -198,6 +264,25 @@ public class FormArea extends JComponent implements ScrollRulerComponent { slidePane.addValueChangeListener(showValSpinnerChangeListener); } + public void undoFixLayoutState(boolean isFixLayout) { + getFormEditor().getRootComponent().setFixLayout(isFixLayout); + this.switchLayout(isFixLayout); + } + + public void switchBodyLayout(XLayoutContainer xLayoutContainer) { + this.fixLayoutSwitchButton.setVisible(xLayoutContainer.supportFixLayout()); + this.switchLayout(false); + } + + private void switchLayout(boolean isFixLayout) { + this.isFixLayoutEditState = isFixLayout; + this.fixLayoutSwitchButton.setText(isFixLayout ? com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Fix_Layout") : + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_No_Fix_Layout")); + FormMobileAttr formMobileAttr = designer.getTarget().getFormMobileAttr(); + widthPane.setEnabled(!isFixLayout && !formMobileAttr.isMobileOnly()); + heightPane.setEnabled(!isFixLayout); + } + private void setWidgetsConfig() { widthPane.setHorizontalAlignment(widthPane.CENTER); @@ -281,8 +366,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { if(object instanceof XCreator){ updateCreatorsBackupBound((XCreator) object); } - } - } + } } //设置宽度的控件及响应事件 @@ -817,7 +901,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { } this.slidePane.setShowValue((int) slide); - } + } /** @@ -899,4 +983,43 @@ public class FormArea extends JComponent implements ScrollRulerComponent { } + public boolean isFixLayout(){ + return this.isFixLayoutEditState; + } + + class Switch2NoFixLayoutAction extends UpdateAction{ + public Switch2NoFixLayoutAction(){ + this.putValue(Action.SMALL_ICON, null); + this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_No_Fix_Layout")); + this.setSmallIcon("/com/fr/design/form/images/no_fix_layout_icon.png"); + } + + @Override + public void actionPerformed(ActionEvent e) { + getFormEditor().getRootComponent().setFixLayout(false); + switchLayout(false); + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); + DesignerContext.getDesignerFrame().refresh(); + } + } + + class Switch2FixLayoutAction extends UpdateAction{ + + public Switch2FixLayoutAction(){ + this.putValue(Action.SMALL_ICON, null); + this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Fix_Layout")); + this.setSmallIcon("/com/fr/design/form/images/fix_layout_icon.png"); + } + + @Override + public void actionPerformed(ActionEvent e) { + getFormEditor().getRootComponent().setFixLayout(true); + switchLayout(true); + designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_EDITED); + DesignerContext.getDesignerFrame().refresh(); + } + } + + + } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java b/designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java new file mode 100644 index 0000000000..6c4095a452 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java @@ -0,0 +1,75 @@ +package com.fr.design.mainframe; + +import com.fr.common.inputevent.InputEventBaseOnOS; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/24 + */ +public class FormAreaMouseWheelHandler implements MouseWheelListener { + private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; + private final DesignerScaleMouseWheelHandler scaleMouseWheelHandler; + + public FormAreaMouseWheelHandler(FormArea formArea) { + translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new FormAreaScrollPaneAdapter(formArea)); + scaleMouseWheelHandler = new DesignerScaleMouseWheelHandler(new FormAreaScalePaneAdapter(formArea), FormArea.SHOWVALMIN); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (InputEventBaseOnOS.isControlDown(e)) { + scaleMouseWheelHandler.mouseWheelMoved(e); + } else { + translateMouseWheelHandler.mouseWheelMoved(e); + } + } + + private static class FormAreaScalePaneAdapter implements DesignerScaleMouseWheelHandler.ScalePane { + private final FormArea formArea; + + public FormAreaScalePaneAdapter(FormArea formArea) { + this.formArea = formArea; + } + + @Override + public JFormSliderPane getSlidePane() { + return formArea.getSlidePane(); + } + } + + private static class FormAreaScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { + private final FormArea formArea; + private final JViewport viewport; + + public FormAreaScrollPaneAdapter(FormArea formArea) { + this.formArea = formArea; + this.viewport = new JViewport(); + } + + @Override + public boolean isWheelScrollingEnabled() { + return true; + } + + @Override + public JScrollBar getVerticalScrollBar() { + return formArea.getVerticalScrollBar(); + } + + @Override + public JScrollBar getHorizontalScrollBar() { + return formArea.getHorizontalScrollBar(); + } + + @Override + public JViewport getViewport() { + return this.viewport; + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java index 7db972e9be..af4d2ae2de 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormCreatorDropTarget.java @@ -79,7 +79,7 @@ public class FormCreatorDropTarget extends DropTarget { this.tabDragInner = new TabDragInner(designer); } - private void adding(int x, int y) { + public void adding(int x, int y) { // 当前鼠标所在的组件 XCreator hoveredComponent = designer.getComponentAt(x, y); // 获取该组件所在的焦点容器 @@ -193,7 +193,6 @@ public class FormCreatorDropTarget extends DropTarget { private void dealWithContainer(int x, int y, XLayoutContainer container) { HoverPainter painter = null; - if (container != current || designer.getPainter() == null) { // 如果焦点容器不是当前容器 if (current != null) { @@ -204,15 +203,9 @@ public class FormCreatorDropTarget extends DropTarget { throw new IllegalArgumentException("container can not be null!"); } //获取painter的时候要考虑布局之间嵌套的问题 - XLayoutContainer xLayoutContainer = container.getTopLayout(); - if (xLayoutContainer != null && xLayoutContainer.getParent() != null - && ((XLayoutContainer) xLayoutContainer.getParent()).acceptType(XWAbsoluteLayout.class)) { - if (!xLayoutContainer.isEditable()) { - xLayoutContainer = (XLayoutContainer) xLayoutContainer.getParent(); - } - } + XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container); painter = AdapterBus.getContainerPainter(designer, - xLayoutContainer != null && xLayoutContainer.acceptType(XWAbsoluteLayout.class) ? xLayoutContainer : container); + xLayoutContainer != null ? xLayoutContainer : container); // 为界面设计器设置提示渲染提示器 designer.setPainter(painter); @@ -227,8 +220,9 @@ public class FormCreatorDropTarget extends DropTarget { } } if (painter != null) { + XLayoutContainer xLayoutContainer = XCreatorUtils.getTopEditableContainer(container); // 为提示渲染器设置焦点位置、区域等渲染参数 - Rectangle rect = ComponentUtils.getRelativeBounds(container); + Rectangle rect = ComponentUtils.getRelativeBounds(xLayoutContainer != null ? xLayoutContainer : container); rect.x -= designer.getArea().getHorizontalValue(); rect.y -= designer.getArea().getVerticalValue(); painter.setRenderingBounds(rect); @@ -236,7 +230,7 @@ public class FormCreatorDropTarget extends DropTarget { painter.setCreator(addingModel.getXCreator()); } } - + private void promptUser(int x, int y, XLayoutContainer container) { if (!addingModel.getXCreator().canEnterIntoParaPane() && container.acceptType(XWParameterLayout.class)) { promptButton.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Forbid_Drag_Into_Para_Pane")); @@ -288,6 +282,7 @@ public class FormCreatorDropTarget extends DropTarget { int y = designer.getRelativeY(loc.y); hovering(x, y); tabDragInner.canDragIn(designer.getComponentAt(x, y), x, y); + designer.draggingComponent(x, y); } /** diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java index cbe9e87e65..3eb40b6a28 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesigner.java @@ -1,10 +1,6 @@ package com.fr.design.mainframe; import com.fr.base.Parameter; -import com.fr.base.ScreenResolution; -import com.fr.base.theme.FormTheme; -import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.TemplateThemeCompatible; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignState; @@ -22,7 +18,9 @@ import com.fr.design.designer.beans.actions.MoveToBottomAction; import com.fr.design.designer.beans.actions.MoveToTopAction; import com.fr.design.designer.beans.actions.MoveUpAction; import com.fr.design.designer.beans.actions.PasteAction; +import com.fr.design.designer.beans.adapters.layout.DefaultDesignerBaseOperate; import com.fr.design.designer.beans.adapters.layout.FRParameterLayoutAdapter; +import com.fr.design.designer.beans.adapters.layout.DesignerBaseOperate; import com.fr.design.designer.beans.events.CreatorEventListenerTable; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; @@ -44,7 +42,6 @@ import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.properties.FormWidgetAuthorityEditPane; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.event.DesignerOpenedListener; -import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.form.util.XCreatorConstants; @@ -61,9 +58,7 @@ import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.FormElementCaseContainerProvider; import com.fr.form.FormElementCaseProvider; import com.fr.form.main.Form; -import com.fr.form.main.WidgetGather; import com.fr.form.parameter.FormSubmitButton; -import com.fr.form.ui.AbstractBorderStyleWidget; import com.fr.form.ui.EditorHolder; import com.fr.form.ui.PaddingMargin; import com.fr.form.ui.Widget; @@ -160,6 +155,7 @@ public class FormDesigner extends TargetComponent
implements TreeSelection // 编辑状态的事件表 private CreatorEventListenerTable edit; protected List designerActions; + protected List basicActions; private FormDesignerModeForSpecial desigerMode; private Action switchAction; private FormElementCaseContainerProvider elementCaseContainer; @@ -227,7 +223,7 @@ public class FormDesigner extends TargetComponent implements TreeSelection public Parameter[] getNoRepeatParas(Parameter[] paras) { List paraList = new ArrayList(); - java.util.Set set = new java.util.HashSet(); + Set set = new java.util.HashSet(); for (Parameter p : paras) { if (!set.contains(p.getName().toLowerCase())) { paraList.add(p); @@ -252,7 +248,7 @@ public class FormDesigner extends TargetComponent implements TreeSelection public void refreshParameter() { XLayoutContainer rootContainer = this.getParaComponent(); if (rootContainer != null) { - java.util.List namelist = new ArrayList(); + List namelist = new ArrayList(); rootContainer.getAllXCreatorNameList(rootContainer, namelist); // parameterArray是报表的所有参数, nameList是已经在参数面板添加过控件的参数名 // 与已有的参数列表比较 如果已经存在 就除去 @@ -1014,15 +1010,6 @@ public class FormDesigner extends TargetComponent implements TreeSelection } private void refreshCenter(Widget centerWidget, XLayoutContainer formLayoutContainer) { - // 不存在center块, 说明是新建的模板 - if (centerWidget == null) { - XLayoutContainer layoutContainer = (XLayoutContainer) XCreatorUtils.createXCreator(new WFitLayout("body")); - layoutContainer.setSize(LARGE_PREFERRED_SIZE); - setRootComponent(layoutContainer); - formLayoutContainer.add(rootComponent, WBorderLayout.CENTER); - return; - } - XLayoutContainer centerContainer = (XLayoutContainer) XCreatorUtils.createXCreator(centerWidget); Dimension d = new Dimension(); d.width = ((WFitLayout) centerWidget).getContainerWidth(); @@ -1124,6 +1111,10 @@ public class FormDesigner extends TargetComponent implements TreeSelection return addingModel; } + public void setAddingModel(AddingModel addingModel) { + this.addingModel = addingModel; + } + public XCreator getComponentAt(MouseEvent e) { return getComponentAt(e.getX(), e.getY()); } @@ -1214,20 +1205,28 @@ public class FormDesigner extends TargetComponent implements TreeSelection public void startDraggingComponent(XCreator xCreator, MouseEvent lastPressEvent, int x, int y) { // 根据所选择的组件的BeanInfo生成相应的AddingModel // AddingModel和StateModel不一样,适合当前选择的组件相关的 - int creatorWidth = xCreator.getWidth(); - int creatorHeight = xCreator.getHeight(); this.addingModel = new AddingModel(xCreator, x, y); TransferHandler handler = new DesignerTransferHandler(this, addingModel); setTransferHandler(handler); handler.exportAsDrag(this, lastPressEvent, TransferHandler.COPY); - XCreator parent = XCreatorUtils.getParentXLayoutContainer(xCreator); - selectionModel.removeCreator(xCreator, creatorWidth, creatorHeight); - selectionModel.setSelectedCreator(parent); + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xCreator); + parent.getLayoutAdapter().dragStart(xCreator, selectionModel); this.setDropTarget(new FormCreatorDropTarget(this)); // 触发状态添加模式事件 repaint(); } + public void draggingComponent(int x, int y){ + XCreator xCreator = this.addingModel.getXCreator(); + XLayoutContainer parent = XCreatorUtils.getParentXLayoutContainer(xCreator); + if (parent!= null && parent.getLayoutAdapter()!=null){ + parent.getLayoutAdapter().dragOver(xCreator, selectionModel, x, y); + } + + // 触发状态添加模式事件 + repaint(); + } + /** * 改变组件值 * @@ -1313,9 +1312,6 @@ public class FormDesigner extends TargetComponent implements TreeSelection protected void setToolbarButtons() { - //自适应布局和底层都不能删除 - DesignerContext.getDesignerFrame().checkCombineUp(!isRootSelected(), NAME_ARRAY_LIST); - if (isParameterSelected()) { DesignerContext.getDesignerFrame().checkCombineUp(false, PARAMETER_TOOLAR_BAN_LIST); } @@ -1378,14 +1374,37 @@ public class FormDesigner extends TargetComponent implements TreeSelection */ public UpdateAction[] getActions() { if (designerActions == null) { - designerActions = new ArrayList(Arrays.asList(new UpdateAction[]{new CutAction(this), new CopyAction(this), new PasteAction(this), - new FormDeleteAction(this), new MoveToTopAction(this), new MoveToBottomAction(this), - new MoveUpAction(this), new MoveDownAction(this)})); + designerActions = new ArrayList(getBasicActions()); + designerActions.add(new MoveToTopAction(this)); + designerActions.add(new MoveToBottomAction(this)); + designerActions.add(new MoveUpAction(this)); + designerActions.add(new MoveDownAction(this)); dmlActions(designerActions); } return designerActions.toArray(new UpdateAction[designerActions.size()]); } + private List getBasicActions(){ + if (basicActions == null) { + basicActions = new ArrayList(); + basicActions.add(new CutAction(this)); + basicActions.add(new CopyAction(this)); + basicActions.add(new PasteAction(this)); + basicActions.add(new FormDeleteAction(this)); + } + return basicActions; + } + + public JComponent[] getBasicActionComponent() { + List actions = getBasicActions(); + int size = actions.size(); + JComponent[] jComponents = new JComponent[size]; + for (int i = 0; i < size; i++) { + jComponents[i] = actions.get(i).createToolBarComponentByName("Global_Toolbar"); + } + return jComponents; + } + /** * 扩展菜单项 * @@ -1404,16 +1423,34 @@ public class FormDesigner extends TargetComponent implements TreeSelection } } + private DesignerBaseOperate getLayoutBaseOperate(){ + FormSelection selection = this.getSelectionModel().getSelection(); + XCreator creator = selection.getSelectedCreator(); + XLayoutContainer container = (XLayoutContainer) creator.getParent(); + if (container == null) { + return new DefaultDesignerBaseOperate(); + } + return container.getLayoutAdapter().getDesignerBaseOperate(); + } + public boolean isCurrentComponentCutable() { - return !(isRootSelected() || isParameterSelected()); + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return !(isRootSelected() || isParameterSelected()) && designerBaseOperate.supportCutAction(); } public boolean isCurrentComponentCopyable() { - return !(isRootSelected() || isParameterSelected()); + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return !(isRootSelected() || isParameterSelected()) && designerBaseOperate.supportCopyAction(); } public boolean isCurrentComponentDeletable() { - return !isRootSelected(); + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return !isRootSelected() && designerBaseOperate.supportDeleteAction(); + } + + public boolean isCurrentComponentPastable() { + DesignerBaseOperate designerBaseOperate = getLayoutBaseOperate(); + return designerBaseOperate.supportPasteAction(); } // 当前选中控件可以上移一层吗? @@ -1469,6 +1506,10 @@ public class FormDesigner extends TargetComponent implements TreeSelection return formArea; } + public void switchBodyLayout(XLayoutContainer xLayoutContainer){ + formArea.switchBodyLayout(xLayoutContainer); + } + /** * 设置上层区域 * diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java index 776925044b..9284554dcb 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormDesignerUI.java @@ -25,7 +25,6 @@ import com.fr.stable.Constants; import javax.swing.JComponent; import javax.swing.SwingUtilities; -import javax.swing.SwingWorker; import javax.swing.plaf.ComponentUI; import java.awt.AlphaComposite; import java.awt.Color; @@ -114,14 +113,8 @@ public class FormDesignerUI extends ComponentUI { if (designer.getPainter() != null) { // ComponentAdapter和LayoutAdapter提供的额外的Painter,该Painter一般用于提示作用, // 相当于一个浮动层, 要考虑参数面板的高度 - new SwingWorker() { - @Override - protected Void doInBackground() throws Exception { - designer.getPainter().paint(g, designer.getArea().getHorizontalValue(), - designer.getArea().getVerticalValue() + designer.getParaHeight()); - return null; - } - }.execute(); + designer.getPainter().paint(g, designer.getArea().getHorizontalValue(), + designer.getArea().getVerticalValue() + designer.getParaHeight()); } AddingModel addingModel = designer.getAddingModel(); @@ -210,10 +203,10 @@ public class FormDesignerUI extends ComponentUI { } XCreator bean = addingModel.getXCreator(); int x = addingModel.getCurrentX(); - int y = addingModel.getCurrentY(); + int y = addingModel.getCurrentY() ; - int width = bean.getWidth(); - int height = bean.getHeight(); + int width = bean.initEditorSize().width; + int height = bean.initEditorSize().height; Graphics clipg = g.create(x, y, width, height); ArrayList dbcomponents = new ArrayList(); // 禁止双缓冲行为 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java index 5a34339175..ee7918e50f 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormSelection.java @@ -294,7 +294,6 @@ public class FormSelection { creator.setBackupBound(backupBounds); } layoutAdapter.fix(creator); - resetElementCaseImage(creator); } i++; } @@ -322,26 +321,6 @@ public class FormSelection { return false; } - /** - * @Description 重置报表块缩略图 - * @param: creator - * @return void - * @Author Henry.Wang - * @Date 2021/5/21 14:59 - **/ - public void resetElementCaseImage(XCreator creator) { - if (creator instanceof XWTitleLayout) { - XWTitleLayout xwTitleLayout = (XWTitleLayout) creator; - for (int i = 0; i < xwTitleLayout.getComponentCount(); i++) { - Component component = xwTitleLayout.getComponent(i); - if (component instanceof XElementCase) { - XElementCase xElementCase = (XElementCase) component; - xElementCase.updateECImage(); - } - } - } - } - /** * 检查下有没有参数面板,如果存在,处理下参数面板造成的偏移量 * @param rectangle diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java b/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java index e4fb5b7552..8a579b8d19 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormUndoState.java @@ -14,6 +14,7 @@ public class FormUndoState extends BaseUndoState { private double widthValue; private double heightValue; private double slideValue; + private boolean isFixLayout; public FormUndoState(BaseJForm t, FormArea formArea) { super(t); @@ -31,6 +32,7 @@ public class FormUndoState extends BaseUndoState { this.widthValue = formArea.getWidthPaneValue(); this.heightValue = formArea.getHeightPaneValue(); this.slideValue = formArea.getSlideValue(); + this.isFixLayout = formArea.isFixLayout(); } /** @@ -89,6 +91,14 @@ public class FormUndoState extends BaseUndoState { return this.slideValue; } + /** + * 返回是否处于固定布局编辑状态下 + * @return + */ + public boolean isFixLayout(){ + return isFixLayout; + } + @Override public void applyState() { this.getApplyTarget().applyUndoState4Form(this); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java index d792f0eca2..f2268c86cf 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormWidgetDetailPane.java @@ -36,6 +36,7 @@ public class FormWidgetDetailPane extends FormDockView{ private JPanel centerPane; private UIHeadGroup headGroup; private List paneList; + private CardLayout cardLayout; private boolean isEmptyPane = false; @@ -86,7 +87,7 @@ public class FormWidgetDetailPane extends FormDockView{ initPaneList(); this.setBorder(null); - final CardLayout cardLayout = new CardLayout(); + cardLayout = new CardLayout(); centerPane = new JPanel(cardLayout); String[] paneNames = new String[paneList.size()]; for (int i = 0; i < paneList.size(); i++) { @@ -137,6 +138,14 @@ public class FormWidgetDetailPane extends FormDockView{ this.add(panel, BorderLayout.CENTER); } + public void switch2Local() { + cardLayout.show(centerPane, paneList.get(0).getTitle()); + } + + public void swich2Online() { + cardLayout.show(centerPane, paneList.get(1).getTitle()); + } + private UILabel tipLabel(String text) { UILabel tipLabel = new UILabel(text); tipLabel.setHorizontalAlignment(SwingConstants.CENTER); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java index 784a3b690d..bc0c75b30d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/JForm.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/JForm.java @@ -6,12 +6,12 @@ import com.fr.base.Parameter; import com.fr.base.Releasable; import com.fr.base.extension.FileExtension; import com.fr.base.iofile.attr.ExtendSharableAttrMark; -import com.fr.base.theme.TemplateThemeCompatible; -import com.fr.base.vcs.DesignerMode; import com.fr.base.theme.FormTheme; import com.fr.base.theme.FormThemeConfig; import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeCompatible; import com.fr.base.theme.TemplateThemeConfig; +import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignModelAdapter; import com.fr.design.DesignState; import com.fr.design.ExtraDesignClassManager; @@ -23,10 +23,6 @@ import com.fr.design.base.mode.DesignModeContext; import com.fr.design.cell.FloatElementsProvider; import com.fr.design.data.datapane.TableDataTreePane; import com.fr.design.designer.TargetComponent; -import com.fr.design.designer.beans.actions.CopyAction; -import com.fr.design.designer.beans.actions.CutAction; -import com.fr.design.designer.beans.actions.FormDeleteAction; -import com.fr.design.designer.beans.actions.PasteAction; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XComponent; @@ -140,7 +136,11 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm dialog = new TemplateThemeUsingDialog<>(designerFrame, JForm.this, FormThemeConfig.getInstance()); + TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(); dialog.setVisible(true); } }); @@ -598,7 +597,7 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm implements BaseJForm dbcomponents = new ArrayList(); // 禁止双缓冲 ComponentUtils.disableBuffer(creator, dbcomponents); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java index 96b321c930..1b36f08d17 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/AbstractWidgetSelectPane.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe.share; -import com.fr.design.mainframe.share.ui.base.PopupPreviewPane; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; +import com.fr.design.mainframe.share.ui.base.LocalWidgetPopupPreviewPane; import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; @@ -13,16 +14,16 @@ import java.awt.Container; * @Author: Yuan.Wang * @Date: 2021/1/15 */ -public abstract class AbstractWidgetSelectPane extends JPanel { +public abstract class AbstractWidgetSelectPane extends JPanel { private static final int SCROLL_BAR_HEIGHT = 10; - private final PopupPreviewPane previewPane; + private final AbstractWidgetPopupPreviewPane previewPane; private String currentShowWidgetID; public AbstractWidgetSelectPane() { - this.previewPane = new PopupPreviewPane(); + this.previewPane = createPopupPreviewPane(); } - public void showPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + public void showPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { if (ComparatorUtils.equals(currentShowWidgetID, showWidgetID)) { return; } @@ -36,7 +37,7 @@ public abstract class AbstractWidgetSelectPane extends JPanel { this.currentShowWidgetID = StringUtils.EMPTY; } - private void popupPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { + private void popupPreviewPane(PreviewWidgetBlock comp, String showWidgetID) { if (previewPane.isVisible()) { previewPane.setVisible(false); } @@ -44,7 +45,7 @@ public abstract class AbstractWidgetSelectPane extends JPanel { if (!previewPane.isVisible() && comp.getWidth() != 0 && comp.getHeight() != 0) { //父容器是GroupPane,要获得的是GroupPane的父容器 Container parentContainer =getParentContainer(); - previewPane.setComp(comp.getPreviewImage()); + previewPane.populateBean(comp); int popupPosY = comp.getLocationOnScreen().y - parentContainer.getLocationOnScreen().y; if (previewPane.getHeight() + popupPosY > parentContainer.getHeight() + SCROLL_BAR_HEIGHT) { popupPosY -= (previewPane.getHeight() + popupPosY - parentContainer.getHeight() - SCROLL_BAR_HEIGHT); @@ -58,5 +59,7 @@ public abstract class AbstractWidgetSelectPane extends JPanel { } } + protected abstract AbstractWidgetPopupPreviewPane createPopupPreviewPane(); + abstract protected Container getParentContainer(); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java index 476afe8b66..364588813f 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java @@ -81,6 +81,9 @@ import static javax.swing.JOptionPane.ERROR_MESSAGE; * 创建组件事件 */ public class CreateComponentAction extends UpdateAction { + private static final double MAX_WIDTH = 960.0; + private static final double MAX_HEIGHT = 540.0; + ShareUIAspect aspect; /** * 等待时间 500 ms. @@ -114,8 +117,12 @@ public class CreateComponentAction extends UpdateAction { // 获取选中的组件 Triple sharedTriple = ComponentTransformerFactory.getInstance().transform(selection); if (sharedTriple == null) { - FineJOptionPane.showMessageDialog(designerFrame, Toolkit.i18nText("Fine-Design_Share_Select_Error_Tip"), - Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), ERROR_MESSAGE, IOUtils.readIcon("/com/fr/base/images/share/Information_Icon_warning_normal_32x32.png")); + showErrMsgDialog(Toolkit.i18nText("Fine-Design_Share_Select_Error_Tip")); + return; + } + + if (isBeyondMaxSize(sharedTriple.getRight())) { + showErrMsgDialog(Toolkit.i18nText("Fine-Design_Share_Widget_Size_Error_Tip")); return; } @@ -398,4 +405,20 @@ public class CreateComponentAction extends UpdateAction { } return paras; } + + private boolean isBeyondMaxSize(Rectangle rec) { + double width = rec.getWidth(); + double height = rec.getHeight(); + return width > 0 && height > 0 && (width > MAX_WIDTH || height > MAX_HEIGHT); + } + + private void showErrMsgDialog(String err) { + FineJOptionPane.showMessageDialog( + DesignerContext.getDesignerFrame(), + err, + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + ERROR_MESSAGE, + IOUtils.readIcon("/com/fr/base/images/share/Information_Icon_warning_normal_32x32.png") + ); + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java index 126660665a..ed1c2a91db 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/generate/task/ComponentCreator.java @@ -4,6 +4,7 @@ import com.fr.base.TableData; import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.base.iofile.attr.SharableAttrMark; import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.share.generate.impl.AbstractComponentCreatorProcessor; @@ -18,6 +19,7 @@ import com.fr.form.share.utils.ShareUtils; import com.fr.form.ui.AbstractBorderStyleWidget; import com.fr.form.ui.Widget; import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; import com.fr.stable.fun.IOFileAttrMark; import com.fr.workspace.WorkContext; import org.jetbrains.annotations.NotNull; @@ -61,8 +63,13 @@ public class ComponentCreator extends AbstractComponentCreatorProcessor { private void setSuitableTemplateThemeName(JTemplate jt, DefaultSharableWidget info) { TemplateTheme theme = jt.getTemplateTheme(); - if (theme != null) { - info.setSuitableTemplateThemeName(theme.getName()); + if (theme != null ) { + String name = theme.getName(); + TemplateThemeConfig config = jt.getUsingTemplateThemeConfig(); + String name4LegacyTemplate = config.getThemeName4LegacyTemplate(); + if (!StringUtils.equals(name, name4LegacyTemplate)) { + info.setSuitableTemplateThemeName(name); + } } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/DownloadSuitableThemeAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/DownloadSuitableThemeAction.java new file mode 100644 index 0000000000..f8f4cc1a78 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/DownloadSuitableThemeAction.java @@ -0,0 +1,218 @@ +package com.fr.design.mainframe.share.ui.actions; + +import com.fr.base.theme.FormTheme; +import com.fr.base.theme.FormThemeConfig; +import com.fr.base.theme.TemplateTheme; +import com.fr.base.theme.TemplateThemeConfig; +import com.fr.design.DesignerEnvManager; +import com.fr.design.actions.UpdateAction; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.gui.imenu.UIMenuItem; +import com.fr.design.gui.imenu.UIMenuItemUI; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.i18n.Toolkit; +import com.fr.design.login.DesignerLoginHelper; +import com.fr.design.login.DesignerLoginSource; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.share.ui.constants.ColorConstants; +import com.fr.design.mainframe.share.util.DownloadUtils; +import com.fr.design.mainframe.theme.dialog.TemplateThemeUsingDialog; +import com.fr.stable.StringUtils; +import com.fr.transaction.CallBackAdaptor; +import com.fr.workspace.WorkContext; + +import javax.swing.Action; +import javax.swing.JOptionPane; +import javax.swing.SwingWorker; +import java.awt.Color; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import java.util.concurrent.ExecutionException; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/28 + */ +public class DownloadSuitableThemeAction extends UpdateAction { + private final String themePath; + private final UIPopupMenu popupMenu; + private boolean downloading = false; + private JTemplate currentTemplate; + + public DownloadSuitableThemeAction(String themePath, UIPopupMenu popupMenu) { + this.themePath = themePath; + this.popupMenu = popupMenu; + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme")); + } + + @Override + public UIMenuItem createMenuItem() { + return getLoadingMenuItem(); + } + + public LoadingMenuItem getLoadingMenuItem() { + Object object = this.getValue(LoadingMenuItem.class.getName()); + if (object == null) { + UIMenuItem menuItem = new LoadingMenuItem(this); + // 设置名字用作单元测 + menuItem.setName(getName()); + setPressedIcon4Button(menuItem); + setDisabledIcon4Button(menuItem); + object = menuItem; + + this.putValue(LoadingMenuItem.class.getName(), object); + } + return (LoadingMenuItem) object; + } + + @Override + public void actionPerformed(ActionEvent e) { + currentTemplate = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + fetchTheme(); + } + + private boolean checkAuthority() { + if (!WorkContext.getCurrent().isRoot()) { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Message"), + Toolkit.i18nText("Fine-Design_Share_Download_Suitable_Theme_No_Authority_Tip_Title"), + JOptionPane.WARNING_MESSAGE); + return false; + } + + String userName = DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); + if (StringUtils.isEmpty(userName)) { + DesignerLoginHelper.showLoginDialog(DesignerLoginSource.NORMAL); + return false; + } + + return true; + } + + private void fetchTheme() { + if (!checkAuthority()) { + onThemeFetched(null); + return; + } + if (downloading) { + return; + } + downloading = true; + + LoadingMenuItem menuItem = getLoadingMenuItem(); + menuItem.startLoading(); + new SwingWorker() { + + @Override + protected FormTheme doInBackground() { + return DownloadUtils.downloadThemeFile(themePath); + } + + @Override + protected void done() { + FormTheme theme = null; + try { + theme = get(); + } catch (InterruptedException | ExecutionException e) { + e.printStackTrace(); + } + + onThemeFetched(theme); + downloading = false; + LoadingMenuItem menuItem = getLoadingMenuItem(); + menuItem.stopLoading(); + } + }.execute(); + } + + public void onThemeFetched(FormTheme theme) { + popupMenu.menuSelectionChanged(false); + if (theme == null) { + return; + } + saveTheme(theme); + } + + private FormTheme ensureThemeHasUniqueName(FormTheme theme, String expectedName) { + if (!FormThemeConfig.getInstance().contains(expectedName)) { + theme.setName(expectedName); + return theme; + } else { + String newName = (String) FineJOptionPane.showInputDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Share_Rename_Suitable_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Rename"), + FineJOptionPane.QUESTION_MESSAGE, null, null, + expectedName); + + return StringUtils.isEmpty(newName) ? null : ensureThemeHasUniqueName(theme, newName); + } + } + + private void saveTheme(FormTheme theme) { + final FormTheme uniqueNamedTheme = ensureThemeHasUniqueName(theme, theme.getName()); + if (uniqueNamedTheme != null) { + FormThemeConfig.getInstance().addTheme(theme, true, new CallBackAdaptor() { + @Override + public void afterCommit() { + super.afterCommit(); + onThemeSaved(uniqueNamedTheme); + } + + @Override + public void afterRollback() { + super.afterRollback(); + onThemeSaved(null); + } + }); + } else { + onThemeSaved(null); + } + } + + public void onThemeSaved(FormTheme theme) { + if (theme == null) { + return; + } + + TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(); + dialog.addWindowListener(new UsingDialogAdapter(theme)); + dialog.setVisible(true); + } + + public void applyTheme(JTemplate template, final String name, Window dialog) { + TemplateThemeConfig config = template.getUsingTemplateThemeConfig(); + TemplateTheme theme = config.cachedFetch(name); + template.setTemplateTheme(theme); + dialog.repaint(); + } + + private class UsingDialogAdapter extends WindowAdapter { + private final FormTheme theme; + + public UsingDialogAdapter(FormTheme theme) { + this.theme = theme; + } + + @Override + public void windowOpened(WindowEvent e) { + super.windowOpened(e); + Window window = e.getWindow(); + int returnVal = FineJOptionPane.showConfirmDialog( + window, + Toolkit.i18nText("Fine-Design_Share_Apply_Suitable_Theme_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), + FineJOptionPane.OK_CANCEL_OPTION); + if (returnVal == JOptionPane.YES_OPTION) { + applyTheme(currentTemplate, theme.getName(), window); + } + window.removeWindowListener(this); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/Jump2DetailAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/Jump2DetailAction.java new file mode 100644 index 0000000000..698ec7545d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/Jump2DetailAction.java @@ -0,0 +1,53 @@ +package com.fr.design.mainframe.share.ui.actions; + +import com.fr.design.actions.UpdateAction; +import com.fr.design.gui.imenu.UIMenuItem; +import com.fr.design.gui.imenu.UIMenuItemUI; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.share.ui.constants.ColorConstants; +import com.fr.stable.StringUtils; + +import javax.swing.Action; +import java.awt.Color; +import java.awt.Desktop; +import java.awt.event.ActionEvent; +import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/28 + */ +public class Jump2DetailAction extends UpdateAction { + private static final String ONLINE_WIDGET_DETAIL_FORMATTED_URL = "https://market.fanruan.com/reuse/%s"; + private final String id; + + public Jump2DetailAction(String id) { + this.id = id; + this.putValue(Action.SMALL_ICON, null); + this.setName(Toolkit.i18nText("Fine-Design_Share_Jump_To_Detail")); + } + + @Override + public UIMenuItem createMenuItem() { + UIMenuItem menuItem = super.createMenuItem(); + menuItem.setOpaque(true); + menuItem.setBackground(ColorConstants.BACKGROUND); + menuItem.setUI(new SharedComponentActionMenuItemUI()); + return menuItem; + } + + @Override + public void actionPerformed(ActionEvent e) { + if (StringUtils.isNotEmpty(id)) { + Desktop desktop = Desktop.getDesktop(); + try { + desktop.browse(new URI(String.format(ONLINE_WIDGET_DETAIL_FORMATTED_URL, id))); + } catch (IOException | URISyntaxException ioException) { + ioException.printStackTrace(); + } + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/LoadingMenuItem.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/LoadingMenuItem.java new file mode 100644 index 0000000000..883a306446 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/LoadingMenuItem.java @@ -0,0 +1,54 @@ +package com.fr.design.mainframe.share.ui.actions; + +import com.fr.design.gui.imenu.UIMenuItem; +import com.fr.design.mainframe.share.ui.constants.ColorConstants; +import com.fr.general.IOUtils; + +import javax.swing.Action; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import java.awt.Graphics; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/10/19 + */ +public class LoadingMenuItem extends UIMenuItem { + private boolean loading = false; + + private final Icon profileIcon = IOUtils.readIcon("/com/fr/design/form/images/loading.gif"); + + public LoadingMenuItem(Action action) { + super(action); + setOpaque(true); + setBackground(ColorConstants.BACKGROUND); + setUI(new SharedComponentActionMenuItemUI()); + } + + public void startLoading() { + loading = true; + setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 20)); + revalidate(); + repaint(); + } + + public void stopLoading() { + loading = false; + setBorder(BorderFactory.createEmptyBorder()); + revalidate(); + repaint(); + } + + public boolean isLoading() { + return loading; + } + + @Override + protected void paintBorder(Graphics g) { + super.paintBorder(g); + if (loading) { + profileIcon.paintIcon(this, g, getWidth() - 20, 0); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/SharedComponentActionMenuItemUI.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/SharedComponentActionMenuItemUI.java new file mode 100644 index 0000000000..a400ccf37b --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/actions/SharedComponentActionMenuItemUI.java @@ -0,0 +1,75 @@ +package com.fr.design.mainframe.share.ui.actions; + +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.imenu.UIMenuItemUI; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.mainframe.share.ui.constants.ColorConstants; +import com.fr.design.utils.gui.GUIPaintUtils; +import com.fr.stable.Constants; + +import javax.swing.ButtonModel; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.MenuSelectionManager; +import java.awt.Color; +import java.awt.Component; +import java.awt.Container; +import java.awt.Graphics; +import java.awt.Graphics2D; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/10/18 + */ +public class SharedComponentActionMenuItemUI extends UIMenuItemUI { + + @Override + protected void paintBackground(Graphics g, JMenuItem menuItem, Color bgColor) { + ButtonModel model = menuItem.getModel(); + Color oldColor = g.getColor(); + int menuWidth = menuItem.getWidth(); + int menuHeight = menuItem.getHeight(); + + g.setColor(ColorConstants.BACKGROUND); + g.fillRect(0, 0, menuWidth, menuHeight); + if (menuItem.isOpaque()) { + if (model.isArmed() || (menuItem instanceof JMenu && model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + } else { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, menuItem.getBackground(), 7); + } + g.setColor(oldColor); + } else if (model.isArmed() || (menuItem instanceof JMenu && + model.isSelected())) { + GUIPaintUtils.fillPaint((Graphics2D) g, 0, 0, menuWidth, menuHeight, true, Constants.NULL, UIConstants.FLESH_BLUE, 7); + g.setColor(oldColor); + } + } + + @Override + protected void doClick(MenuSelectionManager msm) { + if (hasLoadingMenuItem()) { + return; + } + + if (menuItem instanceof LoadingMenuItem) { + menuItem.doClick(0); + } else { + super.doClick(msm); + } + } + + private boolean hasLoadingMenuItem() { + Container parent = menuItem.getParent(); + if (parent instanceof UIPopupMenu) { + Component[] components = parent.getComponents(); + for (Component component: components) { + if (component instanceof LoadingMenuItem && ((LoadingMenuItem) component).isLoading()) { + return true; + } + } + } + return false; + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/AbstractWidgetPopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/AbstractWidgetPopupPreviewPane.java new file mode 100644 index 0000000000..12c2c33ffd --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/AbstractWidgetPopupPreviewPane.java @@ -0,0 +1,15 @@ +package com.fr.design.mainframe.share.ui.base; + +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; + +import javax.swing.JPopupMenu; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/15 + */ +public abstract class AbstractWidgetPopupPreviewPane extends JPopupMenu { + + public abstract void populateBean(PreviewWidgetBlock block); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LocalWidgetPopupPreviewPane.java similarity index 81% rename from designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java rename to designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LocalWidgetPopupPreviewPane.java index 91b1eae89e..f78dbf7014 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/PopupPreviewPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/base/LocalWidgetPopupPreviewPane.java @@ -1,6 +1,9 @@ package com.fr.design.mainframe.share.ui.base; import com.fr.design.constants.UIConstants; +import com.fr.design.mainframe.share.ui.block.LocalWidgetBlock; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.form.share.DefaultSharableWidget; import com.fr.general.IOUtils; import javax.swing.BorderFactory; @@ -17,17 +20,16 @@ import java.awt.Toolkit; /** * Created by kerry on 2020-06-23 */ -public class PopupPreviewPane extends JPopupMenu { - private Container contentPane; +public class LocalWidgetPopupPreviewPane extends AbstractWidgetPopupPreviewPane { private Image compImage; private static final int WIDTH = 400; private static final int STANDARD_DPI = 128; private static final int MAX_HEIGHT = 400; private static final int HEIGHT = 210; - public PopupPreviewPane() { + public LocalWidgetPopupPreviewPane() { setFocusable(false); - contentPane = new JPanel(); + Container contentPane = new JPanel(); contentPane.setBackground(Color.white); this.setLayout(new BorderLayout()); this.add(contentPane, BorderLayout.CENTER); @@ -36,9 +38,9 @@ public class PopupPreviewPane extends JPopupMenu { setBorder(BorderFactory.createLineBorder(UIConstants.LINE_COLOR)); } - public void setComp(Image compImage) { + public void populateBean(PreviewWidgetBlock block) { try { - this.compImage = compImage; + this.compImage = block.getPreviewImage(); this.updateSize(); } catch (Exception e) { e.printStackTrace(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java index 06e513b809..3be4f96b9a 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/AbstractOnlineWidgetBlock.java @@ -1,20 +1,28 @@ package com.fr.design.mainframe.share.ui.block; import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.mainframe.share.ui.actions.DownloadSuitableThemeAction; +import com.fr.design.mainframe.share.ui.actions.Jump2DetailAction; +import com.fr.design.mainframe.share.ui.constants.ColorConstants; import com.fr.design.mainframe.share.ui.online.OnlineResourceManager; import com.fr.design.mainframe.share.ui.online.OnlineWidgetSelectPane; import com.fr.design.mainframe.share.ui.online.ResourceLoader; +import com.fr.design.utils.gui.GUICoreUtils; import com.fr.form.share.bean.OnlineShareWidget; import com.fr.form.share.constants.ShareComponentConstants; import com.fr.log.FineLoggerFactory; import com.fr.stable.EncodeConstants; +import com.fr.stable.StringUtils; import com.fr.third.springframework.web.util.UriUtils; import org.jetbrains.annotations.NotNull; import javax.imageio.ImageIO; import javax.swing.ImageIcon; +import javax.swing.JPopupMenu; import java.awt.Dimension; import java.awt.Image; +import java.awt.event.MouseEvent; import java.io.IOException; import java.net.URL; @@ -41,10 +49,12 @@ public abstract class AbstractOnlineWidgetBlock extends PreviewWidgetBlock super.mouseClicked(e); if (e.getButton() == MouseEvent.BUTTON3 && !isEdit) { this.parentPane.hidePreviewPane(); - UIPopupMenu popupMenu = new UIPopupMenu(); - popupMenu.setOnlyText(true); - popupMenu.setBackground(UIConstants.DEFAULT_BG_RULER); - popupMenu.add(new PopupMenuItem(new MoveGroupAction())); - popupMenu.add(new PopupMenuItem(new RemoveAction())); - GUICoreUtils.showPopupMenu(popupMenu, this, e.getX(), e.getY()); + JPopupMenu rightClickPopupMenu = getRightClickPopupMenu(); + GUICoreUtils.showPopupMenu(rightClickPopupMenu, this, e.getX(), e.getY()); } } @@ -195,30 +197,36 @@ public class LocalWidgetBlock extends PreviewWidgetBlock hidePreview(); ComponentCollector.getInstance().collectPopupJump(); Object source = e.getSource(); - Widget creatorSource; - String shareId; if (source instanceof LocalWidgetBlock) { LocalWidgetBlock no = (LocalWidgetBlock) e.getSource(); if (no == null) { return; } - shareId = no.getBindInfo().getId(); - creatorSource = getGroup().getElCaseEditorById(shareId); - if (creatorSource == null) { - ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + XCreator xCreator= transformXCreator(no); + if (xCreator == null) { return; } - creatorSource.setWidgetID(UUID.randomUUID().toString()); - ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); - //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 - String suitableTemplateThemeName = no.getWidget().getSuitableTemplateThemeName(); - XCreator xCreator = ShareComponentUtils.createThemedXCreator(creatorSource, suitableTemplateThemeName, shareId, no.getBindInfo()); WidgetToolBarPane.getTarget().startDraggingBean(xCreator); lastPressEvent = null; this.setBorder(null); } } + public XCreator transformXCreator(LocalWidgetBlock block) { + String shareId = block.getBindInfo().getId(); + Widget creatorSource = getGroup().getElCaseEditorById(shareId); + if (creatorSource == null) { + ShareUIUtils.showErrorMessageDialog(Toolkit.i18nText("Fine-Design_Share_Drag_Error_Info")); + return null; + } + creatorSource.setWidgetID(UUID.randomUUID().toString()); + ((AbstractBorderStyleWidget) creatorSource).addWidgetAttrMark(new SharableAttrMark(true)); + //tab布局WCardMainBorderLayout通过反射出来的大小是960*480 + String suitableTemplateThemeName = block.getWidget().getSuitableTemplateThemeName(); + XCreator xCreator = ShareComponentUtils.createThemedXCreator(creatorSource, suitableTemplateThemeName, shareId, block.getBindInfo()); + return xCreator; + } + @Override public void paint(Graphics g) { super.paint(g); @@ -265,12 +273,34 @@ public class LocalWidgetBlock extends PreviewWidgetBlock return !WidgetSelectedManager.getInstance().isSelectEmpty(); } + @Override + public JPopupMenu createRightClickPopupMenu() { + + UIPopupMenu popupMenu = new UIPopupMenu(); + popupMenu.setOnlyText(true); + popupMenu.setOpaque(true); + popupMenu.setBackground(ColorConstants.BACKGROUND); + popupMenu.add(new MoveGroupAction().createMenuItem()); + popupMenu.add(new RemoveAction().createMenuItem()); + + return popupMenu; + } + private class MoveGroupAction extends UpdateAction { public MoveGroupAction() { this.putValue(Action.SMALL_ICON, null); this.setName(Toolkit.i18nText("Fine-Design_Share_Group_Move")); } + @Override + public UIMenuItem createMenuItem() { + UIMenuItem menuItem = super.createMenuItem(); + menuItem.setOpaque(true); + menuItem.setBackground(ColorConstants.BACKGROUND); + menuItem.setUI(new SharedComponentActionMenuItemUI()); + return menuItem; + } + @Override public void actionPerformed(ActionEvent e) { new GroupMoveDialog(DesignerContext.getDesignerFrame()) { @@ -297,6 +327,15 @@ public class LocalWidgetBlock extends PreviewWidgetBlock this.setName(Toolkit.i18nText("Fine-Design_Share_Remove")); } + @Override + public UIMenuItem createMenuItem() { + UIMenuItem menuItem = super.createMenuItem(); + menuItem.setOpaque(true); + menuItem.setBackground(ColorConstants.BACKGROUND); + menuItem.setUI(new SharedComponentActionMenuItemUI()); + return menuItem; + } + @Override public void actionPerformed(ActionEvent e) { int rv = FineJOptionPane.showConfirmDialog(DesignerContext.getDesignerFrame(), diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java index 8ad419b038..325e28afef 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetBlock.java @@ -35,8 +35,11 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.SwingConstants; import javax.swing.SwingWorker; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; import java.awt.AlphaComposite; import java.awt.BorderLayout; import java.awt.Color; @@ -89,6 +92,28 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { return southPane; } + @Override + public JPopupMenu createRightClickPopupMenu() { + JPopupMenu popupMenu = super.createRightClickPopupMenu(); + popupMenu.addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + OnlineWidgetBlock.this.repaint(); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + OnlineWidgetBlock.this.repaint(); + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + OnlineWidgetBlock.this.repaint(); + } + }); + return popupMenu; + } + @Override public void mouseEntered(MouseEvent e) { super.mouseEntered(e); @@ -112,7 +137,8 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { @Override public void mouseClicked(MouseEvent e) { super.mouseClicked(e); - if (!checkWidgetInstalled() && getDownloadIconRec().contains(e.getX(), e.getY())) { + boolean isLeftClickDownloadIcon = e.getButton() != MouseEvent.BUTTON3 && getDownloadIconRec().contains(e.getX(), e.getY()); + if (!isRightClickPopupMenuVisible() && isLeftClickDownloadIcon && !checkWidgetInstalled()) { downLoadWidget(); } } @@ -269,7 +295,7 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { return; } //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 - if (isMouseEnter || downloading) { + if (!isRightClickPopupMenuVisible() && (isMouseEnter || downloading)) { Graphics2D g2d = (Graphics2D) g; Composite oldComposite = g2d.getComposite(); //画白色的编辑层 @@ -298,7 +324,6 @@ public class OnlineWidgetBlock extends AbstractOnlineWidgetBlock { } } - class WidgetDownloadProcess implements com.fr.design.extra.Process { @Override diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java index 4b84585940..c3965f0da3 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/OnlineWidgetPackageBlock.java @@ -35,7 +35,7 @@ public class OnlineWidgetPackageBlock extends AbstractOnlineWidgetBlock { detailLabel.addMouseListener(new MouseClickListener() { @Override public void mouseClicked(MouseEvent e) { - parentPane.showWidgetDetailPane(widget.getId()); + parentPane.showWidgetDetailPane(widget); } }); southPane.add(detailLabel, BorderLayout.EAST); @@ -51,7 +51,6 @@ public class OnlineWidgetPackageBlock extends AbstractOnlineWidgetBlock { this.setPreferredSize(new Dimension(ShareComponentConstants.SHARE_PACKAGE_BLOCK_WIDTH, ShareComponentConstants.SHARE_PACKAGE_BLOCK_HEIGHT)); this.add(createSouthPane(widget, parentPane), BorderLayout.SOUTH); } - } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java index 8ad9e2b11c..65a4294586 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/block/PreviewWidgetBlock.java @@ -7,6 +7,7 @@ import org.jetbrains.annotations.NotNull; import javax.swing.ImageIcon; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; @@ -25,12 +26,14 @@ import java.io.Serializable; public abstract class PreviewWidgetBlock extends JPanel implements MouseListener, MouseMotionListener, Serializable { protected T widget; private boolean showing = false; + private final JPopupMenu rightClickPopupMenu; public PreviewWidgetBlock(T widget) { this.widget = widget; initPane(); this.addMouseListener(this); this.addMouseMotionListener(this); + rightClickPopupMenu = this.createRightClickPopupMenu(); } protected void initPane() { @@ -51,6 +54,18 @@ public abstract class PreviewWidgetBlock extends JPanel implements MouseListe return widget; } + protected JPopupMenu createRightClickPopupMenu() { + return null; + } + + public JPopupMenu getRightClickPopupMenu() { + return rightClickPopupMenu; + } + + protected boolean isRightClickPopupMenuVisible() { + return rightClickPopupMenu != null && rightClickPopupMenu.isVisible(); + } + @NotNull protected abstract Image getCoverImage(); @@ -116,10 +131,12 @@ public abstract class PreviewWidgetBlock extends JPanel implements MouseListe public void mouseMoved(MouseEvent e) { Dimension dimension = getCoverDimension(); Rectangle containerRec = new Rectangle(0, 0, dimension.width, dimension.height); - if (containerRec.contains(e.getX(), e.getY())) { - this.showPreviewPane(); - } else { - this.hidePreviewPane(); + if (!isRightClickPopupMenuVisible()) { + if (containerRec.contains(e.getX(), e.getY())) { + this.showPreviewPane(); + } else { + this.hidePreviewPane(); + } } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/constants/ColorConstants.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/constants/ColorConstants.java new file mode 100644 index 0000000000..6bd815142f --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/constants/ColorConstants.java @@ -0,0 +1,12 @@ +package com.fr.design.mainframe.share.ui.constants; + +import java.awt.Color; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/10/19 + */ +public class ColorConstants { + public static final Color BACKGROUND = new Color(0xF0F0F1); +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java index 05507a786f..1e9ca55a11 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/GroupPane.java @@ -40,7 +40,7 @@ import java.util.List; * @Author: Yuan.Wang * @Date: 2020/11/5 */ -class GroupPane extends JPanel { +public class GroupPane extends JPanel { private static final Icon downIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_down.png"); private static final Icon rightIcon = IOUtils.readIcon("/com/fr/base/images/share/arrow_right.png"); private static final int DEFAULT_HEIGHT = 24; diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java index 44bdd0fa5d..90f1f30c2e 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/local/LocalWidgetSelectPane.java @@ -1,6 +1,8 @@ package com.fr.design.mainframe.share.ui.local; import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; +import com.fr.design.mainframe.share.ui.base.LocalWidgetPopupPreviewPane; import com.fr.design.mainframe.share.ui.block.LocalWidgetBlock; import com.fr.form.share.DefaultSharableWidget; import com.fr.form.share.SharableWidgetProvider; @@ -22,7 +24,7 @@ import java.awt.event.MouseEvent; /** * created by Harrison on 2020/03/23 **/ -public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { +public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { private LocalWidgetBlock selectedBlock; private final Group group; @@ -105,6 +107,11 @@ public class LocalWidgetSelectPane extends AbstractWidgetSelectPane { return selectedBlock; } + @Override + protected AbstractWidgetPopupPreviewPane createPopupPreviewPane() { + return new LocalWidgetPopupPreviewPane(); + } + @Override protected Container getParentContainer() { return this.getParent().getParent(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetPopupPreviewPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetPopupPreviewPane.java new file mode 100644 index 0000000000..3113fd06ff --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetPopupPreviewPane.java @@ -0,0 +1,220 @@ +package com.fr.design.mainframe.share.ui.online; + +import com.fr.design.designer.IntervalConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; +import com.fr.design.mainframe.share.ui.block.PreviewWidgetBlock; +import com.fr.design.mainframe.share.ui.constants.ColorConstants; +import com.fr.form.share.bean.OnlineShareWidget; +import com.fr.general.FRFont; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; +import javax.swing.plaf.basic.BasicLabelUI; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Image; +import java.awt.Toolkit; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/14 + */ +public class OnlineWidgetPopupPreviewPane extends AbstractWidgetPopupPreviewPane { + private static final int POPUP_WIDTH = 412; + private static final int POPUP_TOP_HEIGHT = 28; + private static final int POPUP_BOTTOM_HEIGHT = 54; + + private PreviewImagePane previewImagePane; + private UILabel versionLabel; + private UILabel downloadsLabel; + private UILabel priceLabel; + + private final JPanel suitableThemeNamePane; + private UILabel suitableThemeNameLabel; + + public OnlineWidgetPopupPreviewPane() { + super(); + setPreferredSize(new Dimension(POPUP_WIDTH, getPreferredSize().height)); + setLayout(new BorderLayout(0, 0)); + setBorder(BorderFactory.createLineBorder(new Color(0xDADADD))); + setBorderPainted(true); + setOpaque(false); + setBackground(ColorConstants.BACKGROUND); + + suitableThemeNamePane = createSuitableThemeNamePane(); + JPanel previewImagePane = createPreviewImagePane(); + JPanel widgetInfoPane = createWidgetInfoPane(); + + addComponents(suitableThemeNamePane, previewImagePane, widgetInfoPane); + } + + private JPanel createSuitableThemeNamePane() { + suitableThemeNameLabel = new UILabel(); + suitableThemeNameLabel.setUI(new BasicLabelUI()); + suitableThemeNameLabel.setOpaque(false); + suitableThemeNameLabel.setBackground(null); + suitableThemeNameLabel.setIcon(IOUtils.readIcon("/com/fr/design/icon/icon_predefined_style.png")); + suitableThemeNameLabel.setIconTextGap(IntervalConstants.INTERVAL_L6); + + JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); + content.setPreferredSize(new Dimension(POPUP_WIDTH, POPUP_TOP_HEIGHT)); + content.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + content.setOpaque(true); + content.setBackground(new Color(0xF5F5F7)); + content.add(suitableThemeNameLabel, BorderLayout.CENTER); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(content, BorderLayout.CENTER); + + JSeparator separator = new JSeparator(); + separator.setPreferredSize(new Dimension(POPUP_WIDTH, 1)); + separator.setBackground(new Color(0xE8E8E9)); + container.add(separator, BorderLayout.SOUTH); + + return container; + } + + private JPanel createPreviewImagePane() { + previewImagePane = new PreviewImagePane(); + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 10)); + container.add(previewImagePane, BorderLayout.CENTER); + return container; + } + + private JPanel createWidgetInfoPane() { + versionLabel = new UILabel(); + versionLabel.setVerticalAlignment(SwingConstants.CENTER); + versionLabel.setFont(FRFont.getInstance(versionLabel.getFont()).deriveFont(12.0F)); + versionLabel.setForeground(new Color(0x333334)); + + downloadsLabel = new UILabel(); + downloadsLabel.setVerticalAlignment(SwingConstants.TOP); + downloadsLabel.setFont(FRFont.getInstance(downloadsLabel.getFont()).deriveFont(12.0F)); + downloadsLabel.setForeground(new Color(0x333334)); + + priceLabel = new UILabel(); + priceLabel.setVerticalAlignment(SwingConstants.CENTER); + priceLabel.setHorizontalAlignment(SwingConstants.RIGHT); + priceLabel.setFont(FRFont.getInstance(priceLabel.getFont()).deriveFont(14.0F)); + priceLabel.setForeground(new Color(0xE65251)); + + JPanel container = new JPanel(); + container.setPreferredSize(new Dimension(POPUP_WIDTH - 20, POPUP_BOTTOM_HEIGHT)); + container.setLayout(new GridBagLayout()); + container.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 10)); + + GridBagConstraints constraints = new GridBagConstraints(); + constraints.fill = GridBagConstraints.BOTH; + + constraints.gridx = 0; + constraints.gridy = 0; + constraints.gridwidth = 1; + constraints.gridheight = 1; + constraints.weightx = 1; + constraints.weighty = 1; + container.add(versionLabel, constraints); + + constraints.gridx = 0; + constraints.gridy = 1; + constraints.gridwidth = 1; + constraints.gridheight = 1; + constraints.weightx = 1; + constraints.weighty = 1; + container.add(downloadsLabel, constraints); + + constraints.gridx = 1; + constraints.gridy = 0; + constraints.gridwidth = 1; + constraints.gridheight = 2; + constraints.weightx = 1; + constraints.weighty = 2; + container.add(priceLabel, constraints); + + return container; + } + + private void addComponents(JComponent... components) { + if (components == null) { + return; + } + JComponent container = this; + for (int i = 0; i < components.length; i++) { + JComponent component = components[i]; + if (component != null) { + container.add(component, BorderLayout.NORTH); + if (i < components.length - 1) { + JPanel nextContainer = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(nextContainer, BorderLayout.CENTER); + container = nextContainer; + } + } + } + } + + @Override + public void populateBean(PreviewWidgetBlock block) { + OnlineShareWidget widget = block.getWidget(); + String themeName = widget.getThemeName(); + if (StringUtils.isNotEmpty(themeName)) { + suitableThemeNamePane.setVisible(true); + suitableThemeNameLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Suitable_Theme_Prefix") + themeName); + } else { + suitableThemeNamePane.setVisible(false); + } + + String priceText = "¥" + widget.getPrice(); + if (widget.getPrice() <= 0) { + priceText = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Price_Free"); + } + priceLabel.setText(priceText); + + versionLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Version") + ": " + widget.getDesignerVersion()); + downloadsLabel.setText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Share_Download_Times") + ": " + widget.getDownloadTimes()); + previewImagePane.setPreviewImage(block.getPreviewImage()); + + int height = (suitableThemeNamePane.isVisible() ? POPUP_TOP_HEIGHT : 0) + 10 + previewImagePane.getPreferredSize().height + POPUP_BOTTOM_HEIGHT; + setPreferredSize(new Dimension(POPUP_WIDTH, height)); + } + + private static class PreviewImagePane extends JPanel { + private static final Image DEFAULT_IMAGE = IOUtils.readImage("com/fr/base/images/share/component_error.png"); + private static final int PREVIEW_IMAGE_WIDTH = POPUP_WIDTH - 20; + private static final int STANDARD_DPI = 128; + + private Image previewImage; + + public void setPreviewImage(Image previewImage) { + this.previewImage = previewImage; + if (this.previewImage == null) { + this.previewImage = DEFAULT_IMAGE; + } + + int dpi = Toolkit.getDefaultToolkit().getScreenResolution(); + int imageWidth = this.previewImage.getWidth(null); + int imageHeight = this.previewImage.getHeight(null); + + double imageAspectRatio = (double) imageWidth / imageHeight; + int width = (PREVIEW_IMAGE_WIDTH * dpi) / STANDARD_DPI; + int height = (int) (width / imageAspectRatio); + setPreferredSize(new Dimension(width, height)); + } + + @Override + public void paint(Graphics g) { + g.drawImage(this.previewImage, 0, 0, getWidth(), getHeight(), null); + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java index c07485745d..2d8bcfdbef 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetRepoPane.java @@ -24,7 +24,6 @@ import java.awt.Cursor; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.MouseEvent; -import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; @@ -34,13 +33,29 @@ import java.util.concurrent.ExecutionException; */ public class OnlineWidgetRepoPane extends BasicPane { private static final String MARKET_URL = "https://market.fanruan.com/reuse"; + private static List[] sharableWidgets; private OnlineWidgetTabPane componentTabPane; private JPanel centerPane; private boolean isShowPackagePanel = false; private CardLayout cardLayout; + private Status currentStatus; + enum Status {LOADING, DISCONNECTED, NORMAL} + public static boolean loadWidgets() { + if (sharableWidgets != null){ + return true; + } + try{ + sharableWidgets = ShareUtils.getAllSharableWidgetsFromShop(); + return true; + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return false; + } + } + public static OnlineWidgetRepoPane getInstance() { return OnlineWidgetRepoPane.HOLDER.singleton; } @@ -77,7 +92,16 @@ public class OnlineWidgetRepoPane extends BasicPane { this.add(createInternetErrorPane(), Status.DISCONNECTED.name()); switchPane(Status.LOADING); - synchronizedLoadingContent(); + setContent(); + } + + private void setContent() { + if (sharableWidgets != null) { + initContentPane(); + addCenterPane(); + } else { + synchronizedLoadingContent(); + } } private void addCenterPane() { @@ -91,6 +115,7 @@ public class OnlineWidgetRepoPane extends BasicPane { } private void switchPane(Status status) { + this.currentStatus = status; cardLayout.show(this, status.name()); } @@ -100,7 +125,6 @@ public class OnlineWidgetRepoPane extends BasicPane { protected Boolean doInBackground() throws Exception { return initContentPane(); } - @Override protected void done() { try { @@ -118,24 +142,19 @@ public class OnlineWidgetRepoPane extends BasicPane { } private boolean initContentPane() { - List sharableWidgets = new ArrayList<>(); - List sharableWidgetPackage = new ArrayList<>(); - - try { - ShareUtils.getAllSharableWidgetsFromShop(sharableWidgets, sharableWidgetPackage); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + boolean loadWidgetsSuccess = loadWidgets(); + if (loadWidgetsSuccess) { + this.componentTabPane = new OnlineWidgetTabPane(sharableWidgets[0].toArray(new OnlineShareWidget[sharableWidgets[0].size()]), + sharableWidgets[1].toArray(new OnlineShareWidget[sharableWidgets[1].size()])); + } else { switchPane(Status.DISCONNECTED); - return false; } - this.componentTabPane = new OnlineWidgetTabPane(sharableWidgets.toArray(new OnlineShareWidget[sharableWidgets.size()]), - sharableWidgetPackage.toArray(new OnlineShareWidget[sharableWidgetPackage.size()])); - - return true; + return loadWidgetsSuccess; } private void reload() { this.removeAll(); + sharableWidgets = null; initPane(); this.validate(); this.repaint(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java index 61e3ced831..c1a556fc5f 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/OnlineWidgetSelectPane.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.share.ui.online; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.share.AbstractWidgetSelectPane; +import com.fr.design.mainframe.share.ui.base.AbstractWidgetPopupPreviewPane; import com.fr.design.mainframe.share.ui.base.LoadingPane; import com.fr.design.mainframe.share.ui.base.NoMatchPane; import com.fr.design.mainframe.share.ui.base.PagingFiledPane; @@ -30,7 +31,7 @@ import java.util.concurrent.ExecutionException; /** * Created by kerry on 2020-10-19 */ -public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { +public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { protected static final int H_GAP = 5; protected static final int V_GAP = 10; @@ -219,6 +220,11 @@ public class OnlineWidgetSelectPane extends AbstractWidgetSelectPane { } } + @Override + protected AbstractWidgetPopupPreviewPane createPopupPreviewPane() { + return new OnlineWidgetPopupPreviewPane(); + } + protected Container getParentContainer() { return this.getParent(); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java index 2271f0c89b..15b8804835 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackageSelectPane.java @@ -25,8 +25,8 @@ public class OnlineWidgetPackageSelectPane extends OnlineWidgetSelectPane { } - public void showWidgetDetailPane(String id) { - this.parentPane.showWidgetDetailPane(id); + public void showWidgetDetailPane(OnlineShareWidget widgetPackage) { + this.parentPane.showWidgetDetailPane(widgetPackage); } protected PreviewWidgetBlock createWidgetBlock(OnlineShareWidget provider) { diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java index 887b7c34a4..662df3d8d9 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/online/widgetpackage/OnlineWidgetPackagesShowPane.java @@ -150,10 +150,11 @@ public class OnlineWidgetPackagesShowPane extends AbstractOnlineWidgetShowPane { return onlineShareWidgets.toArray(new OnlineShareWidget[onlineShareWidgets.size()]); } - public void showWidgetDetailPane(final String id) { + public void showWidgetDetailPane(final OnlineShareWidget widgetPackage) { + String id = widgetPackage.getId(); currentPackageId = id; boolean containsCache = cachePanelMap.containsKey(id); - onlineWidgetSelectPane = containsCache ? cachePanelMap.get(id) : new OnlineWidgetSelectPane(() -> ShareUtils.getPackageWidgets(id), 50); + onlineWidgetSelectPane = containsCache ? cachePanelMap.get(id) : new OnlineWidgetSelectPane(() -> ShareUtils.getPackageWidgets(widgetPackage), 50); downloadLabel.setVisible(!containsCache); showWidgetDetailPane(onlineWidgetSelectPane); } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java index 4e8f9ffc5f..7623c2e0aa 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPane.java @@ -151,7 +151,7 @@ public class FilterPane extends JPanel { Point p = FilterPane.this.getLocationOnScreen(); popup = pf.getPopup(FilterPane.this, filterPopupPane, p.x, p.y + FilterPane.this.getHeight()); popup.show(); - filterPopupPane.setPreferredSize(new Dimension(228, filterPopupPane.getHeight())); + filterPopupPane.setPreferredSize(new Dimension(filterPopupPane.getWidth(), filterPopupPane.getHeight())); showPopup = true; arrowButton.setIcon(FILTER_COMBO_UP); firePopupStateChange(true); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java index e2bcd5344d..f0d3714c7d 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/ui/widgetfilter/FilterPopupPane.java @@ -31,6 +31,8 @@ public abstract class FilterPopupPane extends JPanel { private static final Color BORDER_COLOR = Color.decode("#D9DADD"); private static final String FILTER_ALL_ID = "0"; + public static final int CONTENT_WIDTH = 225; + FilterPane filterPane; private List filterList = new ArrayList<>(); private final List checkBoxList = new ArrayList<>(); @@ -101,7 +103,7 @@ public abstract class FilterPopupPane extends JPanel { jPanel.setBackground(Color.WHITE); UILabel titleLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Type")); titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); - titleLabel.setPreferredSize(new Dimension(226, 20)); + titleLabel.setPreferredSize(new Dimension(CONTENT_WIDTH - 2, 20)); titleLabel.setOpaque(true); titleLabel.setBackground(Color.decode("#EDEDEE")); jPanel.add(titleLabel, BorderLayout.NORTH); @@ -131,7 +133,7 @@ public abstract class FilterPopupPane extends JPanel { jPanel.setBackground(Color.WHITE); UILabel titleLabel = new UILabel(filterTypeInfo.getTitle()); titleLabel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 5)); - titleLabel.setPreferredSize(new Dimension(226, 20)); + titleLabel.setPreferredSize(new Dimension(CONTENT_WIDTH - 2, 20)); titleLabel.setOpaque(true); titleLabel.setBackground(Color.decode("#EDEDEE")); jPanel.add(titleLabel, BorderLayout.NORTH); @@ -150,7 +152,7 @@ public abstract class FilterPopupPane extends JPanel { } } int contentPaneHeight = ((displayCount + 1) / 2) * 27; - contentPane.setPreferredSize(new Dimension(228, contentPaneHeight)); + contentPane.setPreferredSize(new Dimension(CONTENT_WIDTH, contentPaneHeight)); for (final WidgetFilterInfo filterInfo : filterTypeInfo.getFilterItems()) { if (ComparatorUtils.equals(FILTER_ALL_ID, filterInfo.getId())) { continue; diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java index 96c2cc28c6..c5b90c7856 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/DownloadUtils.java @@ -1,5 +1,6 @@ package com.fr.design.mainframe.share.util; +import com.fr.base.theme.FormTheme; import com.fr.design.DesignerEnvManager; import com.fr.design.extra.PluginConstants; import com.fr.form.share.base.CancelCheck; @@ -9,6 +10,10 @@ import com.fr.general.CloudCenter; import com.fr.log.FineLoggerFactory; import com.fr.stable.ProductConstants; import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.xml.XMLPrintWriter; +import com.fr.stable.xml.XMLReaderHelper; +import com.fr.stable.xml.XMLableReader; import com.fr.third.org.apache.http.HttpEntity; import com.fr.third.org.apache.http.HttpException; import com.fr.third.org.apache.http.HttpStatus; @@ -23,9 +28,12 @@ import com.fr.third.org.apache.http.impl.client.HttpClients; import org.jetbrains.annotations.NotNull; import javax.crypto.Cipher; +import java.io.BufferedReader; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileOutputStream; import java.io.InputStream; +import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.security.KeyFactory; import java.security.interfaces.RSAPublicKey; @@ -130,6 +138,40 @@ public class DownloadUtils { } } + public static FormTheme downloadThemeFile(String themePath) { + try { + CloseableHttpResponse fileRes = getHttpResponse(themePath); + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_MOVED_TEMPORARILY) { + fileRes = getHttpResponse(fileRes.getHeaders("Location")[0].getValue()); + } + if (fileRes.getStatusLine().getStatusCode() == HttpStatus.SC_OK) { + HttpEntity entity = fileRes.getEntity(); + + BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(entity.getContent(), StandardCharsets.UTF_8)); + StringBuilder stringBuilder = new StringBuilder(); + String line; + while ((line = bufferedReader.readLine()) != null) { + stringBuilder.append(line); + } + + String content = stringBuilder.toString(); + XMLableReader reader = XMLReaderHelper.createXMLableReader(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)), XMLPrintWriter.XML_ENCODER); + + FormTheme theme = new FormTheme(); + reader.readXMLObject(theme); + if (StringUtils.isNotEmpty(theme.getName())) { + return theme; + } + } else { + FineLoggerFactory.getLogger().info("download theme {} failed", themePath); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + + return null; + } + private static CloseableHttpResponse getHttpResponse(String url, String id) throws Exception { //先登录一下。不然可能失败 CloseableHttpClient client = createClient(); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java index 8c88de20b1..b66c2458c7 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/InstallComponentHelper.java @@ -32,19 +32,23 @@ public class InstallComponentHelper { public static void installPreComponent() { if (needPreInstallComponent()) { - for (String componentPath : PRE_INSTALL_COMPONENTS) { - try { - InputStream inputStream = InstallComponentHelper.class.getResourceAsStream(StableUtils.pathJoin(PRE_INSTALL_PATH, componentPath)); - byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); - WorkContext.getWorkResource().write(StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), componentPath), data); - } catch (Exception e) { - FineLoggerFactory.getLogger().error("install Component filed" + e.getMessage(), e); - } - } + installShareComponents(PRE_INSTALL_PATH, PRE_INSTALL_COMPONENTS); } } + public static void installShareComponents(String resourcePath, String[] components) { + for (String componentPath : components) { + try { + InputStream inputStream = InstallComponentHelper.class.getResourceAsStream(StableUtils.pathJoin(resourcePath, componentPath)); + byte[] data = ResourceIOUtils.inputStream2Bytes(inputStream); + WorkContext.getWorkResource().write(StableUtils.pathJoin(ComponentPath.SHARE_PATH.path(), componentPath), data); + } catch (Exception e) { + FineLoggerFactory.getLogger().error("install Component filed" + e.getMessage(), e); + } + } + } + private static boolean needPreInstallComponent() { try { //老用户或者组件库里已有组件,不预装组件 diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java index 0dd613975e..c9da573914 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/util/ShareComponentUtils.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.share.util; import com.fr.base.io.IOFile; import com.fr.base.iofile.attr.ExtendSharableAttrMark; import com.fr.base.theme.FormTheme; +import com.fr.base.theme.FormThemeConfig; import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.TemplateThemeCompatible; import com.fr.design.designer.creator.XCreator; @@ -58,9 +59,11 @@ public class ShareComponentUtils { JTemplate template = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); TemplateTheme theme = template.getTemplateTheme(); if (theme instanceof FormTheme) { + String themeName4LegacyTemplate = FormThemeConfig.getInstance().getThemeName4LegacyTemplate(); boolean isCurrentUsingThemeSuitSharedComponent = StringUtils.isNotEmpty(theme.getName()) && StringUtils.isNotEmpty(suitableTemplateThemeName) && - StringUtils.equals(theme.getName(), suitableTemplateThemeName); + StringUtils.equals(theme.getName(), suitableTemplateThemeName) && + !StringUtils.equals(theme.getName(), themeName4LegacyTemplate); XCreatorUtils.setupTemplateTheme(creator, false, (FormTheme) theme, isCurrentUsingThemeSuitSharedComponent ? TemplateThemeCompatible.NONE : TemplateThemeCompatible.ABSENT); } return creator; diff --git a/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java b/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java index 5f45b57b09..62eebdf218 100644 --- a/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/parameter/RootDesignDefinePane.java @@ -10,6 +10,8 @@ import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.designer.properties.PropertyTab; import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.fit.common.TemplateTool; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.fun.ParameterExpandablePaneUIProvider; import com.fr.design.gui.ibutton.UIButtonGroup; @@ -20,8 +22,11 @@ import com.fr.design.gui.itextfield.UITextField; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.FormDesigner; +import com.fr.design.mainframe.FormSelection; import com.fr.design.mainframe.JTemplate; import com.fr.design.mainframe.widget.accessibles.AccessibleBackgroundEditor; +import com.fr.design.utils.gui.LayoutUtils; import com.fr.design.utils.gui.UIComponentUtils; import com.fr.design.widget.ui.designer.AbstractDataModify; import com.fr.design.widget.ui.designer.component.UIBoundSpinner; @@ -35,6 +40,7 @@ import javax.swing.Icon; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; +import java.awt.Rectangle; import java.util.Set; /** @@ -43,18 +49,19 @@ import java.util.Set; public class RootDesignDefinePane extends AbstractDataModify { private XWParameterLayout root; private UISpinner designerWidth; + private UISpinner paraHeight; private UICheckBox displayReport; private UICheckBox useParamsTemplate; private AccessibleBackgroundEditor background; private UIButtonGroup hAlignmentPane; private UITextField labelNameTextField; - /** - * 插件带来的额外属性 - */ + //是否是新设计模式下决策报表 + private boolean newForm; private PropertyGroupPane extraPropertyGroupPane; public RootDesignDefinePane(XCreator xCreator) { super(xCreator); + newForm = TemplateTool.getCurrentEditingNewJForm() != null && DesignerUIModeConfig.getInstance().newUIMode(); this.root = (XWParameterLayout) xCreator; initComponent(); } @@ -62,7 +69,11 @@ public class RootDesignDefinePane extends AbstractDataModify { public void initComponent() { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); + if (newForm) { + paraHeight = new UIBoundSpinner(0, Integer.MAX_VALUE, 1, 0); + } else { + designerWidth = new UIBoundSpinner(1, Integer.MAX_VALUE, 1); + } JPanel advancePane = createAdvancePane(); UIExpandablePane advanceExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Advanced"), 280, 20, advancePane); this.add(advanceExpandablePane, BorderLayout.NORTH); @@ -70,7 +81,6 @@ public class RootDesignDefinePane extends AbstractDataModify { UIExpandablePane layoutExpandablePane = new UIExpandablePane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Size"), 280, 20, layoutPane); this.add(layoutExpandablePane, BorderLayout.CENTER); this.addExtraUIExpandablePaneFromPlugin(); - } private void addExtraUIExpandablePaneFromPlugin() { @@ -92,9 +102,9 @@ public class RootDesignDefinePane extends AbstractDataModify { double[] rowSize = {p}; double[] columnSize = {p, f}; int[][] rowCount = {{1, 1}}; - Component[][] components = new Component[][]{ - new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Desin_Width")), designerWidth}, - }; + Component[] component = newForm ? new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Designer_Fit_Design_Height")), paraHeight} : + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Desin_Width")), designerWidth}; + Component[][] components = new Component[][]{component}; JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); panel.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); @@ -103,6 +113,21 @@ public class RootDesignDefinePane extends AbstractDataModify { } public JPanel createAdvancePane() { + if (newForm) { + return getNewFormAdvancePane(); + } else { + return getTemplateAdvancePane(); + } + } + + /** + * @Description: 获取的非新决策报表AdvancePane + * @param + * @return: + * @Author: Henry.Wang + * @date: 2020/11/05 15:36 + */ + private JPanel getTemplateAdvancePane() { JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); labelNameTextField = new UITextField(); displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); @@ -139,6 +164,40 @@ public class RootDesignDefinePane extends AbstractDataModify { return jPanel; } + /** + * @Description: 获取新决策报表的AdvancePane + * @param + * @return: + * @Author: Henry.Wang + * @date: 2020/11/05 15:36 + */ + private JPanel getNewFormAdvancePane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + labelNameTextField = new UITextField(); + displayReport = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Display_Nothing_Before_Query")); + UIComponentUtils.setLineWrap(displayReport); + useParamsTemplate = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Use_Params_Template")); + background = new AccessibleBackgroundEditor(); + + double f = TableLayout.FILL; + double p = TableLayout.PREFERRED; + double[] rowSize = {p, p, p, p}; + double[] columnSize = {p, f}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}}; + Component[][] components = new Component[][]{ + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, + new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Base_Background")), background}, + new Component[]{displayReport, null}, + new Component[]{useParamsTemplate, null} + }; + JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); + panel.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); + + jPanel.add(panel, BorderLayout.NORTH); + + return jPanel; + } + @Override public String title4PopupWindow() { return "parameter"; @@ -150,17 +209,37 @@ public class RootDesignDefinePane extends AbstractDataModify { background.setValue(ob.getBackground()); displayReport.setSelected(ob.isDelayDisplayContent()); useParamsTemplate.setSelected(ob.isUseParamsTemplate()); - designerWidth.setValue(ob.getDesignWidth()); - hAlignmentPane.setSelectedItem(ob.getPosition()); + if (newForm) { + FormDesigner designer = TemplateTool.getCurrentEditingNewJForm().getFormDesign(); + paraHeight.setValue(designer.getParaHeight()); + } else { + designerWidth.setValue(ob.getDesignWidth()); + hAlignmentPane.setSelectedItem(ob.getPosition()); - if (extraPropertyGroupPane != null) { - extraPropertyGroupPane.populate(ob); + if (extraPropertyGroupPane != null) { + extraPropertyGroupPane.populate(ob); + } } } @Override public WParameterLayout updateBean() { + if (newForm) { + return updateNewFormBean(); + } else { + return updateTemplateBean(); + } + } + + /** + * @Description: 更新非新决策报表的bean + * @param + * @return: + * @Author: Henry.Wang + * @date: 2020/11/05 15:36 + */ + private WParameterLayout updateTemplateBean() { WParameterLayout wParameterLayout = (WParameterLayout) creator.toData(); wParameterLayout.setLabelName(labelNameTextField.getText()); if (isCompsOutOfDesignerWidth((int) designerWidth.getValue())) { @@ -173,22 +252,56 @@ public class RootDesignDefinePane extends AbstractDataModify { JTemplate jTemplate = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); jTemplate.needAddTemplateIdAttr(useParamsTemplate.isSelected()); wParameterLayout.setBackground((Background) background.getValue()); - wParameterLayout.setPosition((int) hAlignmentPane.getSelectedItem()); + wParameterLayout.setPosition((Integer) hAlignmentPane.getSelectedItem()); return wParameterLayout; } - private boolean isCompsOutOfDesignerWidth(int designerWidth){ - for(int i=0; i designerWidth){ + if (comp.getX() + comp.getWidth() > designerWidth) { return true; } } return false; } + @Override public DataCreatorUI dataUI() { return null; } - } diff --git a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java b/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java index 908defcbb5..cb04f9345c 100644 --- a/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java +++ b/designer-form/src/main/java/com/fr/design/preview/DeveloperPreview.java @@ -43,8 +43,8 @@ public class DeveloperPreview extends AbstractPreviewProvider { @Override public void onClick(JTemplate jt) { - MutilTempalteTabPane.getInstance().closeCurrentTpl(); super.onClick(jt); + MutilTempalteTabPane.getInstance().closeCurrentTpl(); } diff --git a/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java b/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java index 9b1097d37a..7c8ae3c6be 100644 --- a/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java +++ b/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java @@ -49,6 +49,7 @@ import com.fr.form.ui.MultiFileEditor; import com.fr.form.ui.NameWidget; import com.fr.form.ui.NoneWidget; import com.fr.form.ui.NumberEditor; +import com.fr.form.ui.PageFixedRowComboBox; import com.fr.form.ui.Password; import com.fr.form.ui.Radio; import com.fr.form.ui.RadioGroup; @@ -98,6 +99,7 @@ public class FormWidgetDefinePaneFactoryBase { defineMap.put(TextEditor.class, new Appearance(TextFieldEditorDefinePane.class, WidgetConstants.TEXT + "")); defineMap.put(NameWidget.class, new Appearance(UserEditorDefinePane.class, "UserDefine")); defineMap.put(ComboBox.class, new Appearance(ComboBoxDefinePane.class, WidgetConstants.COMBOBOX + "")); + defineMap.put(PageFixedRowComboBox.class, new Appearance(ComboBoxDefinePane.class, WidgetConstants.COMBOBOX + "")); defineMap.put(RadioGroup.class, new Appearance(RadioGroupDefinePane.class, WidgetConstants.RADIOGROUP + "")); defineMap.put(CheckBoxGroup.class, new Appearance(CheckBoxGroupDefinePane.class, WidgetConstants.CHECKBOXGROUP + "")); diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/EmptyLayoutPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/EmptyLayoutPane.java new file mode 100644 index 0000000000..f17b258f90 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/EmptyLayoutPane.java @@ -0,0 +1,36 @@ +package com.fr.design.widget.ui.designer; + +import com.fr.base.svg.IconUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.stable.StringUtils; + +import javax.swing.BorderFactory; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; + +public class EmptyLayoutPane extends PredefinedLayoutPane { + public EmptyLayoutPane() { + this.setLayout(new BorderLayout()); + this.setPreferredSize(new Dimension(234, 1)); + this.setBackground(Color.WHITE); + UILabel newFormIcon = new UILabel(IconUtils.readIcon("/com/fr/design/form/images/new_form.png")); + newFormIcon.setBorder(BorderFactory.createCompoundBorder( + BorderFactory.createEmptyBorder(39, 105, 0, 105), + BorderFactory.createDashedBorder(Color.BLACK, 1.0f, 2.0f, 2.0f, true) + )); + UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_New_Empty_Template")); + label.setBorder(BorderFactory.createEmptyBorder(0, 78, 30, 0)); + + this.add(newFormIcon, BorderLayout.NORTH); + this.add(label, BorderLayout.CENTER); + + this.initListener(); + } + + @Override + public String getTemplatePath() { + return StringUtils.EMPTY; + } +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java index 45c2cd9686..4ee699e0fe 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/FieldEditorDefinePane.java @@ -1,9 +1,17 @@ package com.fr.design.widget.ui.designer; +import com.fr.design.ExtraDesignClassManager; +import com.fr.design.beans.ErrorMsgTextFieldAdapter; +import com.fr.design.beans.UITextFieldAdapter; import com.fr.design.constants.LayoutConstants; import com.fr.design.designer.IntervalConstants; -import com.fr.design.designer.creator.*; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; +import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.foldablepane.UIExpandablePane; +import com.fr.design.fun.TextFieldAdapterProvider; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.itextfield.UITextField; @@ -11,19 +19,19 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.widget.ui.designer.component.FontSizeComboPane; import com.fr.form.ui.FieldEditor; +import com.fr.log.FineLoggerFactory; - -import javax.swing.*; -import javax.swing.event.DocumentEvent; -import javax.swing.event.DocumentListener; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Component; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; public abstract class FieldEditorDefinePane extends AbstractDataModify { protected UICheckBox allowBlankCheckBox; // richer:错误信息,是所有控件共有的属性,所以放到这里来 - protected UITextField errorMsgTextField; + protected ErrorMsgTextFieldAdapter errorMsgTextField; protected JPanel validatePane; protected FontSizeComboPane fontSizePane; protected UITextField labelNameTextField; @@ -40,7 +48,6 @@ public abstract class FieldEditorDefinePane extends Abstr allowBlankCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Allow_Null")); allowBlankCheckBox.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); fontSizePane = new FontSizeComboPane(); - errorMsgTextField = new UITextField(); JPanel contentPane = this.setFirstContentPane(); JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); jPanel.add(contentPane, BorderLayout.CENTER); @@ -76,23 +83,17 @@ public abstract class FieldEditorDefinePane extends Abstr protected void initErrorMsgPane() { // 错误信息 - errorMsgTextField = new UITextField(); -// // richer:主要为了方便查看比较长的错误信息 - errorMsgTextField.getDocument().addDocumentListener(new DocumentListener() { - - public void changedUpdate(DocumentEvent e) { - errorMsgTextField.setToolTipText(errorMsgTextField.getText()); - } - - public void insertUpdate(DocumentEvent e) { - errorMsgTextField.setToolTipText(errorMsgTextField.getText()); - } - - public void removeUpdate(DocumentEvent e) { - errorMsgTextField.setToolTipText(errorMsgTextField.getText()); - } - }); - + TextFieldAdapterProvider provider = ExtraDesignClassManager.getInstance().getSingle(TextFieldAdapterProvider.XML_TAG); + if (provider == null) { + errorMsgTextField = new UITextFieldAdapter(); + return; + } + try { + errorMsgTextField = provider.createTextFieldAdapter(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + errorMsgTextField = new UITextFieldAdapter(); + } } @@ -111,7 +112,7 @@ public abstract class FieldEditorDefinePane extends Abstr validatePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); final UILabel uiLabel = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Widget_Error_Tip")); JPanel borderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); - final JPanel errorTipPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{uiLabel, errorMsgTextField}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_MEDIUM); + final JPanel errorTipPane = TableLayoutHelper.createGapTableLayoutPane(new Component[][]{new Component[]{uiLabel, errorMsgTextField.getErrorMsgTextField()}}, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_L1, LayoutConstants.VGAP_MEDIUM); errorTipPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L6, IntervalConstants.INTERVAL_L5, 0, 0)); borderPane.add(errorTipPane, BorderLayout.CENTER); allowBlankCheckBox.addItemListener(new ItemListener() { diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/NewFormPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/NewFormPane.java new file mode 100644 index 0000000000..5e55b692df --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/NewFormPane.java @@ -0,0 +1,349 @@ +package com.fr.design.widget.ui.designer; + +import com.fr.base.iofile.attr.TemplateLayoutIdAttrMark; +import com.fr.design.DesignerEnvManager; +import com.fr.design.border.UITitledMatteBorder; +import com.fr.design.designer.beans.PredefinedLayout; +import com.fr.design.designer.beans.models.NewFormModel; +import com.fr.design.dialog.BasicPane; +import com.fr.design.dialog.DialogActionListener; +import com.fr.design.dialog.UIDialog; +import com.fr.design.gui.ibutton.UIButtonGroup; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.BaseJForm; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.form.main.Form; +import com.fr.form.ui.Widget; +import com.fr.form.ui.container.OccupiedLayout; +import com.fr.form.ui.container.WAbsoluteLayout.BoundsWidget; +import com.fr.form.ui.container.WBorderLayout; +import com.fr.form.ui.container.WFitLayout; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.StringUtils; +import com.fr.stable.bridge.StableFactory; + +import javax.swing.BorderFactory; +import javax.swing.DefaultListCellRenderer; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListSelectionModel; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.ListSelectionEvent; +import javax.swing.event.ListSelectionListener; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +public class NewFormPane extends BasicPane { + private static final String EMPTY_FORM_LAYOUTID = "9ebf6aff-ad53-45a9-a175-9633f4162a3a"; + + private NewFormModel newFormModel; + private UIDialog dialog; + private PredefinedLayoutPane selectedLayoutPane = null; + private Map layoutPaneMap = new HashMap<>(); + private List layoutCards = new ArrayList<>(); + + public NewFormPane() { + newFormModel = NewFormModel.getInstance(); + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 0, 0)); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.add(createModuleListPane(), BorderLayout.WEST); + this.add(createTemplateManagePane(), BorderLayout.CENTER); + initWindow(); + } + + private void initWindow() { + dialog = new UIDialog(DesignerContext.getDesignerFrame(), this) { + @Override + public void checkValid() throws Exception { + + } + }; + dialog.setButtonEnabled(false); + dialog.addDialogActionListener(new DialogActionListener() { + @Override + public void doOk() { + createLayoutForm(); + } + + @Override + public void doCancel() { + + } + }); + dialog.setSize(new Dimension(900, 600)); + GUICoreUtils.centerWindow(dialog); + dialog.setTitle(this.title4PopupWindow()); + dialog.setResizable(false); + } + + public void createLayoutForm() { + if (selectedLayoutPane != null) { + NewFormPane.this.newForm(selectedLayoutPane.getTemplatePath()); + } + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_New_Template"); + } + + public UIDialog getWindow() { + return dialog; + } + + public void showWindow() { + dialog.setVisible(true); + } + + private JPanel createModuleListPane() { + JList list = new JList(); + list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); + list.setModel(initListModel()); + list.setSelectedIndex(0); + list.setCellRenderer(new DefaultListCellRenderer() { + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { + super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + this.setBorder(BorderFactory.createEmptyBorder(0, 8, 0, 0)); + return this; + } + }); + list.addListSelectionListener(new ListSelectionListener() { + @Override + public void valueChanged(ListSelectionEvent e) { + String value = list.getSelectedValue(); + int selectedIndex = list.getSelectedIndex(); + for (Map.Entry entry : layoutPaneMap.entrySet()) { + String moduleName = entry.getKey(); + JPanel module = entry.getValue(); + module.setVisible(selectedIndex == 0 || ComparatorUtils.equals(moduleName, value)); + } + } + }); + + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBackground(new Color(255, 255, 255)); + jPanel.setPreferredSize(new Dimension(138, 1)); + jPanel.add(new UIScrollPane(list), BorderLayout.CENTER); + return jPanel; + } + + private DefaultListModel initListModel() { + DefaultListModel model = new DefaultListModel<>(); + model.addElement(Toolkit.i18nText("Fine-Design_All_Template_Layout")); + Map> map = newFormModel.getConfig(); + for (String key : map.keySet()) { + model.addElement(key); + } + return model; + } + + private JPanel createTemplateManagePane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.add(createTemplateManageNorthPane(), BorderLayout.NORTH); + jPanel.add(createTemplateManageSouthPane(), BorderLayout.CENTER); + return jPanel; + } + + private JPanel createTemplateManageNorthPane() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + jPanel.setPreferredSize(new Dimension(1, 129)); + jPanel.add(createNewTemplatePane(), BorderLayout.WEST); + jPanel.add(createSwitchButtonPane(), BorderLayout.EAST); + return jPanel; + } + + private JPanel createNewTemplatePane() { + EmptyLayoutPane jPanel = new EmptyLayoutPane(); + jPanel.addClickListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setSelectedLayoutPane(jPanel); + dialog.setButtonEnabled(true); + } + }); + return jPanel; + } + + private JPanel createSwitchButtonPane() { + UIButtonGroup buttonGroup = new UIButtonGroup(new String[] { + Toolkit.i18nText("Fine-Design_Simple_Style_Template"), + Toolkit.i18nText("Fine-Design_Real_Style_Template") + }); + buttonGroup.setPreferredSize(new Dimension(140, 20)); + buttonGroup.setSelectedIndex(DesignerEnvManager.getEnvManager().getLayoutTemplateStyle()); + buttonGroup.addChangeListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + int selectedIndex = buttonGroup.getSelectedIndex(); + for (PredefinedLayoutPane layoutCard : layoutCards) { + DesignerEnvManager.getEnvManager().setLayoutTemplateStyle(selectedIndex); + layoutCard.showCard(); + } + } + }); + + JPanel switchButtonPane = new JPanel(new BorderLayout()); + switchButtonPane.add(buttonGroup, BorderLayout.CENTER); + + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10)); + jPanel.add(switchButtonPane, BorderLayout.NORTH); + return jPanel; + } + + private JPanel createTemplateManageSouthPane() { + List predefinedLayoutPanes = createPredefinedLayoutPanes(); + JPanel selectionsPane = createSelectionsPane(predefinedLayoutPanes); + + UIScrollPane selectionsScrollPane = new UIScrollPane(selectionsPane); + selectionsScrollPane.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + + JPanel titlePane = new JPanel(new BorderLayout()); + titlePane.setBorder(UITitledMatteBorder.createTitledBorder(Toolkit.i18nText("Fine-Design_Select_Template"), new Color(1, 159, 222))); + titlePane.add(selectionsScrollPane, BorderLayout.CENTER); + + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.setBorder(BorderFactory.createEmptyBorder(20, 0, 0, 0)); + jPanel.add(titlePane, BorderLayout.CENTER); + + return jPanel; + } + + private JPanel createSelectionsPane(List components) { + JPanel selectionsPane = new JPanel(); + JPanel container = new JPanel(new BorderLayout()); + for (int i = 0; i < components.size(); i++) { + JPanel component = components.get(i); + if (component != null) { + container.add(component, BorderLayout.NORTH); + JPanel nextContainer = new JPanel(new BorderLayout()); + container.add(nextContainer, BorderLayout.CENTER); + if (i == 0) { + selectionsPane = container; + } + container = nextContainer; + } + } + return selectionsPane; + } + + private List createPredefinedLayoutPanes() { + List jPanels = new ArrayList<>(); + Map> map = newFormModel.getConfig(); + for (Map.Entry> entry : map.entrySet()) { + String moduleName = entry.getKey(); + List layouts = entry.getValue(); + + JPanel module = createPredefinedLayoutPane(moduleName); + layoutPaneMap.put(moduleName, module); + for (PredefinedLayout layout : layouts) { + PredefinedLayoutPane predefinedLayoutPane = new PredefinedLayoutPane(layout); + predefinedLayoutPane.addClickListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + setSelectedLayoutPane(predefinedLayoutPane); + dialog.setButtonEnabled(true); + } + }); + module.add(predefinedLayoutPane); + layoutCards.add(predefinedLayoutPane); + } + jPanels.add(module); + } + return jPanels; + } + + private JPanel createPredefinedLayoutPane(String title) { + JPanel jp = new JPanel(); + UITitledMatteBorder explainBorder = UITitledMatteBorder.createTitledTopBorder(title, Color.BLACK); + jp.setBorder(explainBorder); + jp.setLayout(new GridLayout(0, 3, 5, 5)); + return jp; + } + + private void newForm(String path) { + BaseJForm jForm; + try { + Form form = Form.getEmptyBodyForm(); + initLayoutInfo(form, path); + jForm = StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, new Object[]{form}, BaseJForm.class); + DesignerContext.getDesignerFrame().addAndActivateJTemplate((JTemplate) jForm); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + + /** + * 通过布局文件的位置初始化Form对象的布局信息 + * + * @param form 新建的form对象 + * @param path 布局文件位置 + * @throws Exception + */ + private void initLayoutInfo(Form form, String path) throws Exception { + if (isNewEmptyForm(path)) { + initEmptyFormLayoutId(form); + } else { + Form layoutTemplate = new Form(); + layoutTemplate.readStream(NewFormPane.class.getResourceAsStream(path)); + + if (layoutTemplate.getBody() != null && layoutTemplate.getBody() instanceof WFitLayout) { + WFitLayout layoutTemplateBody = (WFitLayout) layoutTemplate.getBody(); + WFitLayout body = (WFitLayout) form.getBody(); + + body.setMargin(layoutTemplateBody.getMargin()); + body.setCompInterval(layoutTemplateBody.getCompInterval()); + for (int i = 0; i < layoutTemplateBody.getWidgetCount(); i++) { + Widget boundsWidget = layoutTemplateBody.getWidget(i); + if (boundsWidget != null && boundsWidget instanceof BoundsWidget) { + Widget widget = ((BoundsWidget) boundsWidget).getWidget(); + if (widget != null && widget instanceof OccupiedLayout) { + body.addWidget((Widget) boundsWidget.clone()); + } + } + } + + form.setLayoutId(layoutTemplate.getLayoutId()); + } + } + } + + private void initEmptyFormLayoutId(Form form) { + form.addAttrMark(new TemplateLayoutIdAttrMark(EMPTY_FORM_LAYOUTID)); + form.setLayoutId(EMPTY_FORM_LAYOUTID); + } + + private boolean isNewEmptyForm(String layoutTemplatePath) { + return StringUtils.isEmpty(layoutTemplatePath); + } + + private void setSelectedLayoutPane(PredefinedLayoutPane layoutPane) { + if (selectedLayoutPane != layoutPane) { + if (selectedLayoutPane != null) { + selectedLayoutPane.setSelected(false); + } + selectedLayoutPane = layoutPane; + if (selectedLayoutPane != null) { + selectedLayoutPane.setSelected(true); + } + } + } +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/PredefinedLayoutPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/PredefinedLayoutPane.java new file mode 100644 index 0000000000..097440f961 --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/PredefinedLayoutPane.java @@ -0,0 +1,129 @@ +package com.fr.design.widget.ui.designer; + +import com.fr.base.GraphHelper; +import com.fr.base.svg.IconUtils; +import com.fr.design.DesignerEnvManager; +import com.fr.design.designer.beans.PredefinedLayout; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.stable.Constants; +import com.fr.stable.StringUtils; + +import javax.swing.JPanel; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public class PredefinedLayoutPane extends JPanel { + private static final Color HOVERING_BORDER_COLOR = new Color(65, 155, 249); + private static final Color HOVERING_SHADOW_COLOR = new Color(65, 155, 249, 51); + private CardLayout cardLayout = new CardLayout(); + protected boolean hovering = false; + protected boolean selected = false; + protected MouseAdapter clickListener; + protected String templatePath = StringUtils.EMPTY; + + public PredefinedLayoutPane() { + + } + + public PredefinedLayoutPane(PredefinedLayout predefinedLayout) { + this.templatePath = predefinedLayout.getTemplate(); + UILabel simpleStyle = new UILabel(IconUtils.readIcon(predefinedLayout.getSimpleStyle())); + UILabel realStyle = new UILabel(IconUtils.readIcon(predefinedLayout.getRealStyle())); + + this.setLayout(cardLayout); + this.add(realStyle, 0); + this.add(simpleStyle, 1); + this.setPreferredSize(new Dimension(235, 134)); + this.initListener(); + this.showCard(); + } + + protected void initListener() { + this.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + if (clickListener != null) { + clickListener.mouseClicked(e); + } + } + + @Override + public void mouseEntered(MouseEvent e) { + hovering = true; + repaint(); + } + + @Override + public void mouseExited(MouseEvent e) { + hovering = false; + repaint(); + } + }); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + if (hovering) { + g.setColor(HOVERING_SHADOW_COLOR); + GraphHelper.fillRect(g, 1, 1, this.getWidth() - 2, this.getHeight() - 2); + } + + if (selected || hovering) { + g.setColor(HOVERING_BORDER_COLOR); + Rectangle rectangle = new Rectangle(1, 1, this.getWidth() - 2, this.getHeight() - 2); + GraphHelper.draw(g, rectangle, Constants.LINE_MEDIUM); + } + } + + public void addClickListener(MouseAdapter clickListener) { + this.clickListener = clickListener; + } + + public void showCard() { + if (DesignerEnvManager.getEnvManager().getLayoutTemplateStyle() == DesignerEnvManager.LAYOUT_TEMPLATE_SIMPLE_STYLE) { + showSimpleStyle(); + } else if (DesignerEnvManager.getEnvManager().getLayoutTemplateStyle() == DesignerEnvManager.LAYOUT_TEMPLATE_REAL_STYLE) { + showRealStyle(); + } + } + + public void showSimpleStyle() { + cardLayout.last(this); + } + + public void showRealStyle() { + cardLayout.first(this); + } + + public boolean isHovering() { + return hovering; + } + + public void setHovering(boolean hovering) { + this.hovering = hovering; + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + repaint(); + } + + public String getTemplatePath() { + return templatePath; + } + + public void setTemplatePath(String templatePath) { + this.templatePath = templatePath; + } +} diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java index 2baea973ce..6e6a2ff145 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/TextFieldEditorDefinePane.java @@ -1,7 +1,9 @@ package com.fr.design.widget.ui.designer; +import com.fr.design.ExtraDesignClassManager; import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; +import com.fr.design.fun.RegPaneProvider; import com.fr.design.gui.frpane.RegFieldPane; import com.fr.design.gui.frpane.RegPane; import com.fr.design.gui.ilable.UILabel; @@ -11,10 +13,12 @@ import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.design.widget.ui.designer.component.FormWidgetValuePane; import com.fr.form.ui.TextEditor; - +import com.fr.log.FineLoggerFactory; import com.fr.stable.StringUtils; -import javax.swing.*; -import java.awt.*; + +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.Component; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -65,27 +69,36 @@ public class TextFieldEditorDefinePane extends FieldEditorDefinePane widgetValueLabel.setVerticalAlignment(SwingConstants.TOP); Component[][] components = new Component[][]{ new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Label_Name")), labelNameTextField}, - new Component[]{widgetValueLabel, formWidgetValuePane}, + new Component[]{widgetValueLabel, formWidgetValuePane}, new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_WaterMark"), SwingConstants.LEFT), waterMarkDictPane}, new Component[]{new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Font_Size"), SwingConstants.LEFT), fontSizePane} }; double[] rowSize = {p, p, p, p, p, p}; - double[] columnSize = {p,f}; - int[][] rowCount = {{1, 1},{1, 3},{1, 1},{1, 1}}; - final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); + double[] columnSize = {p, f}; + int[][] rowCount = {{1, 1}, {1, 3}, {1, 1}, {1, 1}}; + final JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); JPanel boundsPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); boundsPane.add(panel); return boundsPane; } - public JPanel setValidatePane(){ + public JPanel setValidatePane() { return regPane; } - protected RegFieldPane createRegPane() { - return new RegFieldPane(); + RegPaneProvider provider = ExtraDesignClassManager.getInstance().getSingle(RegPaneProvider.XML_TAG); + if (provider == null) { + return new RegFieldPane(); + } + + try { + return provider.createRegPane(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + return new RegFieldPane(); + } } @Override @@ -102,7 +115,7 @@ public class TextFieldEditorDefinePane extends FieldEditorDefinePane @Override protected TextEditor updateSubFieldEditorBean() { - TextEditor ob = (TextEditor)creator.toData(); + TextEditor ob = (TextEditor) creator.toData(); this.regPane.update(ob); ob.setWaterMark(waterMarkDictPane.getText()); formWidgetValuePane.update(ob); diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java index 856ff6a0c8..a73104e283 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/PaddingBoundPane.java @@ -14,6 +14,7 @@ import com.fr.form.ui.RichStyleWidgetProvider; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.SwingConstants; +import javax.swing.SwingUtilities; import java.awt.BorderLayout; import java.awt.Component; @@ -37,10 +38,10 @@ public class PaddingBoundPane extends BasicPane { public void initBoundPane(int t, int b, int l, int r) { this.setLayout(FRGUIPaneFactory.createBorderLayout()); - top = new UISpinner(0, Integer.MAX_VALUE, 1, t); - bottom = new UISpinner(0, Integer.MAX_VALUE, 1, b); - left = new UISpinner(0, Integer.MAX_VALUE, 1, l); - right = new UISpinner(0, Integer.MAX_VALUE, 1, r); + top = new UISpinner(0, Integer.MAX_VALUE, 1, t, false); + bottom = new UISpinner(0, Integer.MAX_VALUE, 1, b, false); + left = new UISpinner(0, Integer.MAX_VALUE, 1, l, false); + right = new UISpinner(0, Integer.MAX_VALUE, 1, r, false); top.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate")); bottom.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate")); left.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate")); @@ -79,13 +80,32 @@ public class PaddingBoundPane extends BasicPane { } public void update(RichStyleWidgetProvider marginWidget) { - marginWidget.setMargin(updateBean()); + try { + marginWidget.setMargin(updateBean()); + } catch (UnsupportedOperationException e) { + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + populateBean(marginWidget.getMargin()); + } + }); + + } + } public PaddingMargin updateBean() { return new PaddingMargin((int) top.getValue(), (int) left.getValue(), (int) bottom.getValue(), (int) right.getValue()); } + @Override + public void setEnabled(boolean enabled) { + this.top.setEnabled(enabled); + this.left.setEnabled(enabled); + this.bottom.setEnabled(enabled); + this.right.setEnabled(enabled); + } + @Override protected String title4PopupWindow() { return "PaddingBoundPane"; diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java index 87c89f3cb4..9507248df3 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ElementEditorDefinePane.java @@ -5,6 +5,8 @@ import com.fr.base.theme.TemplateTheme; import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.*; +import com.fr.design.fit.DesignerUIModeConfig; +import com.fr.design.fit.attrpane.PcFitExpandablePane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.style.FollowingThemePane; import com.fr.design.layout.FRGUIPaneFactory; @@ -15,12 +17,15 @@ import com.fr.form.ui.ElementCaseEditor; import com.fr.form.ui.PaddingMargin; import com.fr.form.web.FormToolBarManager; import com.fr.general.ComparatorUtils; +import com.fr.report.fit.ReportFitAttr; import javax.swing.BorderFactory; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; +import java.util.ArrayList; +import java.util.List; /** * Created by ibm on 2017/8/7. @@ -29,6 +34,9 @@ public class ElementEditorDefinePane extends WTitleLayoutDefinePane 0) { + centerPane.add(extraPropertyGroupPane, BorderLayout.CENTER); + } + pcFitExpandablePane = new PcFitExpandablePane(this); + if (DesignerUIModeConfig.getInstance().newUIMode()) { + centerPane.add(pcFitExpandablePane, BorderLayout.SOUTH); + } + return centerPane; } + private CRPropertyDescriptor[] removeOldFitEditor(CRPropertyDescriptor[] extraTableEditor) { + if (!DesignerUIModeConfig.getInstance().newUIMode()) { + return extraTableEditor; + } + List list = new ArrayList(); + for (CRPropertyDescriptor crPropertyDescriptor : extraTableEditor) { + if (!ComparatorUtils.equals(FIT_STATE_PC, crPropertyDescriptor.getName())) { + list.add(crPropertyDescriptor); + } + } + return list.toArray(new CRPropertyDescriptor[list.size()]); + } + protected ElementCaseEditor updateSubBean() { ElementCaseEditor elementCaseEditor = (ElementCaseEditor) creator.toData(); if (themePane.isFollowingTheme() || ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { paddingBoundPane.update(elementCaseEditor); } elementCaseEditor.setToolBars((FormToolBarManager[]) elementCaseToolBarEditor.getValue()); - + if (DesignerUIModeConfig.getInstance().newUIMode()) { + ReportFitAttr fitAttr = pcFitExpandablePane.update(); + elementCaseEditor.setReportFitAttr(fitAttr); + } return elementCaseEditor; } + protected void populateSubBean(ElementCaseEditor ob) { paddingBoundPane.populate(ob); elementCaseToolBarEditor.setValue(ob.getToolBars()); extraPropertyGroupPane.populate(ob); + if (DesignerUIModeConfig.getInstance().newUIMode()) { + pcFitExpandablePane.populate(ob.getReportFitAttr()); + } } - } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java index bc8dc9be03..6db75c171b 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteBodyLayoutDefinePane.java @@ -4,13 +4,14 @@ import com.fr.base.io.IOFile; import com.fr.base.iofile.attr.WatermarkAttr; import com.fr.base.theme.FormTheme; import com.fr.base.theme.TemplateTheme; -import com.fr.base.theme.settings.ThemedComponentStyle; import com.fr.design.data.DataCreatorUI; import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.designer.properties.items.FRLayoutTypeItems; import com.fr.design.designer.properties.items.Item; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; @@ -19,6 +20,7 @@ import com.fr.design.gui.xpane.LayoutStylePane; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.design.mainframe.widget.accessibles.AccessibleBodyWatermarkEditor; import com.fr.design.widget.FRWidgetFactory; @@ -36,6 +38,9 @@ import javax.swing.DefaultComboBoxModel; import javax.swing.JPanel; import java.awt.BorderLayout; import java.awt.Component; +import static javax.swing.JOptionPane.OK_CANCEL_OPTION; +import static javax.swing.JOptionPane.OK_OPTION; +import static javax.swing.JOptionPane.WARNING_MESSAGE; /** * Created by ibm on 2017/8/2. @@ -60,8 +65,9 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane { initUIComboBox(); this.setLayout(FRGUIPaneFactory.createBorderLayout()); boundPane = new WidgetBoundPane(creator); - this.add(boundPane, BorderLayout.NORTH); - + if (!DesignerUIModeConfig.getInstance().newUIMode()){ + this.add(boundPane, BorderLayout.NORTH); + } JPanel panel1 = FRGUIPaneFactory.createBorderLayout_S_Pane(); this.add(panel1, BorderLayout.CENTER); @@ -118,12 +124,13 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane { UILabel layoutTypeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Attr_Layout_Type")); UILabel scaleModeLabel = FRWidgetFactory.createLineWrapLabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Scaling_Mode")); - - JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane( - new Component[][]{ - {layoutTypeLabel, layoutCombox}, - {scaleModeLabel, comboBox} - }, + Component[][] components = DesignerUIModeConfig.getInstance().newUIMode() ? new Component[][]{ + {layoutTypeLabel, layoutCombox} + } : new Component[][]{ + {layoutTypeLabel, layoutCombox}, + {scaleModeLabel, comboBox} + }; + JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W1, IntervalConstants.INTERVAL_L1); contentPane.setBorder(BorderFactory.createEmptyBorder(IntervalConstants.INTERVAL_L1, 0, IntervalConstants.INTERVAL_L1, 0)); @@ -173,12 +180,24 @@ public class FRAbsoluteBodyLayoutDefinePane extends FRAbsoluteLayoutDefinePane { ((XWFitLayout) creator.getBackupParent()).toData().resetStyle(); if (state == WBodyLayoutType.FIT.getTypeValue()) { XWFitLayout xwFitLayout = ((XWFitLayout)creator.getBackupParent()); - xwFitLayout.switch2FitBodyLayout(creator); - WFitLayout wFitLayout = xwFitLayout.toData(); - // 切换布局类型时,保留body背景样式 - if (wFitLayout != null) { - wFitLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme()); - wFitLayout.setBorderStyle(layout.getBorderStyle()); + int selVal = FineJOptionPane.showConfirmDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Form_Layout_Switch_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Alert"), + OK_CANCEL_OPTION, + WARNING_MESSAGE + ); + if(OK_OPTION == selVal){ + xwFitLayout.switch2FitBodyLayout(creator); + WFitLayout wFitLayout = xwFitLayout.toData(); + // 切换布局类型时,保留body背景样式 + if (wFitLayout != null) { + wFitLayout.setBorderStyleFollowingTheme(layout.isBorderStyleFollowingTheme()); + wFitLayout.setBorderStyle(layout.getBorderStyle()); + } + copyLayoutAttr(layout, xwFitLayout.toData()); + }else { + this.layoutCombox.setSelectedIndex(1); } copyLayoutAttr(layout, xwFitLayout.toData()); xwFitLayout.refreshStylePreviewEffect(); diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java index dff0e159a1..ef82a81b68 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/FRAbsoluteLayoutDefinePane.java @@ -5,6 +5,7 @@ import com.fr.design.designer.IntervalConstants; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.properties.items.FRAbsoluteConstraintsItems; import com.fr.design.designer.properties.items.Item; +import com.fr.design.fit.DesignerUIModeConfig; import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; @@ -39,7 +40,9 @@ public class FRAbsoluteLayoutDefinePane extends AbstractFRLayoutDefinePane 0 && ((XCreator) xCreator.getComponent(0)).shouldScaleCreator()) { - component = xCreator.getComponent(0); + Component component = xCreator.getComponent(0); component.setBounds(xCreator.getBounds()); } } - xwAbsoluteBodyLayout.add(component); + if (!xCreator.acceptType(XOccupiedLayout.class)){ + xwAbsoluteBodyLayout.add(xCreator); + } + } copyLayoutAttr(wFitLayout, xwAbsoluteBodyLayout.toData()); xWFitLayout.setBackupParent(xwAbsoluteBodyLayout); FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); formDesigner.getSelectionModel().setSelectedCreators( FormSelectionUtils.rebuildSelection(xWFitLayout, new Widget[]{wAbsoluteBodyLayout})); - if (xwAbsoluteBodyLayout.toData() != null) { xwAbsoluteBodyLayout.toData().setBorderStyleFollowingTheme(wAbsoluteBodyLayout.isBorderStyleFollowingTheme()); xwAbsoluteBodyLayout.toData().setBorderStyle(wAbsoluteBodyLayout.getBorderStyle()); @@ -254,6 +281,8 @@ public class FRFitLayoutDefinePane extends AbstractFRLayoutDefinePane + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/2.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/2.frm new file mode 100644 index 0000000000..0b04d5e7d4 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/2.frm @@ -0,0 +1,128 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/3.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/3.frm new file mode 100644 index 0000000000..43cc0b93b5 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/3.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/4.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/4.frm new file mode 100644 index 0000000000..d6b0ba42b1 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/4.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/5.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/5.frm new file mode 100644 index 0000000000..167db8fd20 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/5.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/6.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/6.frm new file mode 100644 index 0000000000..504bfbd124 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/2-4/6.frm @@ -0,0 +1,137 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/1.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/1.frm new file mode 100644 index 0000000000..24df43d5c7 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/1.frm @@ -0,0 +1,146 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/2.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/2.frm new file mode 100644 index 0000000000..17a624d7d7 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/2.frm @@ -0,0 +1,146 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/3.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/3.frm new file mode 100644 index 0000000000..1b1f1e1a4a --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/3.frm @@ -0,0 +1,155 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/4.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/4.frm new file mode 100644 index 0000000000..dcd003aa1c --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/4.frm @@ -0,0 +1,155 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/5.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/5.frm new file mode 100644 index 0000000000..98a3ac6f9a --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/5.frm @@ -0,0 +1,164 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/6.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/6.frm new file mode 100644 index 0000000000..34d579ed58 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/5-7/6.frm @@ -0,0 +1,164 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/1.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/1.frm new file mode 100644 index 0000000000..710ccc3bda --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/1.frm @@ -0,0 +1,173 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/2.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/2.frm new file mode 100644 index 0000000000..2bfe6c1987 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/2.frm @@ -0,0 +1,182 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/3.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/3.frm new file mode 100644 index 0000000000..e80cd4303f --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/3.frm @@ -0,0 +1,182 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/4.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/4.frm new file mode 100644 index 0000000000..c18a36d26a --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/4.frm @@ -0,0 +1,191 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/5.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/5.frm new file mode 100644 index 0000000000..21c56152f7 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/5.frm @@ -0,0 +1,191 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/6.frm b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/6.frm new file mode 100644 index 0000000000..a76dbdb6b9 --- /dev/null +++ b/designer-form/src/main/resources/com/fr/design/form/layouts/templates/multi/6.frm @@ -0,0 +1,209 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + + + + + + + + + + + + + + + + + + + diff --git a/designer-realize/src/main/java/com/fr/design/actions/insert/flot/FormulaFloatAction.java b/designer-realize/src/main/java/com/fr/design/actions/insert/flot/FormulaFloatAction.java index dbd9d4be6e..0251bf3d81 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/insert/flot/FormulaFloatAction.java +++ b/designer-realize/src/main/java/com/fr/design/actions/insert/flot/FormulaFloatAction.java @@ -5,7 +5,6 @@ package com.fr.design.actions.insert.flot; import com.fr.base.BaseFormula; import com.fr.base.DynamicUnitList; - import com.fr.design.actions.ElementCaseAction; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; @@ -16,7 +15,7 @@ import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.mainframe.theme.utils.DefaultThemedFloatElement; import com.fr.design.menu.MenuKeySet; - +import com.fr.design.utils.gui.AdjustWorkBookDefaultStyleUtils; import com.fr.grid.Grid; import com.fr.grid.selection.FloatSelection; import com.fr.report.ReportHelper; @@ -24,7 +23,7 @@ import com.fr.report.cell.FloatElement; import com.fr.report.elementcase.TemplateElementCase; import com.fr.stable.unit.FU; -import javax.swing.*; +import javax.swing.KeyStroke; /** * Insert formula. @@ -101,6 +100,7 @@ public class FormulaFloatAction extends ElementCaseAction { reportPane.stopEditing(); final FloatElement floatElement = DefaultThemedFloatElement.createInstance(); + AdjustWorkBookDefaultStyleUtils.adjustFloatElement(floatElement); final UIFormula formulaPane = FormulaFactory.createFormulaPane(); formulaPane.populate(BaseFormula.createFormulaBuilder().build()); diff --git a/designer-realize/src/main/java/com/fr/design/actions/insert/flot/TextBoxFloatAction.java b/designer-realize/src/main/java/com/fr/design/actions/insert/flot/TextBoxFloatAction.java index 26aad41e23..32723cffa6 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/insert/flot/TextBoxFloatAction.java +++ b/designer-realize/src/main/java/com/fr/design/actions/insert/flot/TextBoxFloatAction.java @@ -8,7 +8,7 @@ import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.mainframe.ElementCasePane; import com.fr.design.mainframe.theme.utils.DefaultThemedFloatElement; import com.fr.design.menu.MenuKeySet; - +import com.fr.design.utils.gui.AdjustWorkBookDefaultStyleUtils; import com.fr.grid.Grid; import com.fr.grid.selection.FloatSelection; import com.fr.report.ReportHelper; @@ -16,7 +16,7 @@ import com.fr.report.cell.FloatElement; import com.fr.report.elementcase.TemplateElementCase; import com.fr.stable.unit.FU; -import javax.swing.*; +import javax.swing.KeyStroke; import java.awt.event.ActionEvent; /** @@ -61,6 +61,7 @@ public class TextBoxFloatAction extends AbstractShapeAction { return; } FloatElement floatElement = DefaultThemedFloatElement.createInstance("Text"); + AdjustWorkBookDefaultStyleUtils.adjustFloatElement(floatElement); this.startDraw(floatElement); doWithDrawingFloatElement(); } diff --git a/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java b/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java index 8dd00d1703..4c7feab061 100644 --- a/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java +++ b/designer-realize/src/main/java/com/fr/design/actions/report/ReportEngineAttrAction.java @@ -1,14 +1,13 @@ package com.fr.design.actions.report; - -import com.fr.base.svg.IconUtils; import com.fr.design.actions.ReportComponentAction; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.WorkSheetDesigner; import com.fr.design.menu.KeySetUtils; -import com.fr.design.report.LayerReportPane; +import com.fr.design.report.ReportEnginePane; import com.fr.report.worksheet.WorkSheet; public class ReportEngineAttrAction extends ReportComponentAction { @@ -19,7 +18,7 @@ public class ReportEngineAttrAction extends ReportComponentAction { button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); - TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog<>(designerFrame, JWorkBook.this, ReportThemeConfig.getInstance()); + TemplateThemeUsingDialog dialog = new TemplateThemeUsingDialog(); dialog.setVisible(true); } }); @@ -716,8 +717,13 @@ public class JWorkBook extends JTemplate { } protected void addShortCut(MenuDef exportMenuDef, MenuDef excelExportMenuDef) { - exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), - new CSVExportAction(this), new TextExportAction(this), new EmbeddedExportExportAction(this)); + if (CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath())){ + exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), + new CSVExportAction(this), new TextExportAction(this)); + }else { + exportMenuDef.addShortCut(excelExportMenuDef, new PDFExportAction(this), new WordExportAction(this), new SVGExportAction(this), + new CSVExportAction(this), new TextExportAction(this), new EmbeddedExportExportAction(this)); + } } /** @@ -741,7 +747,8 @@ public class JWorkBook extends JTemplate { */ @Override public ShortCut[] shortcut4TemplateMenu() { - return ArrayUtils.addAll(new ShortCut[]{ + boolean enableNewEngine = CptAndCptxCompatibilityUtil.isEngineXEnable(this.getTarget(), getEditingFILE().getPath()); + ShortCut[] commonShortCut = ArrayUtils.addAll(new ShortCut[]{ new ReportWebAttrAction(this), new ReportExportAttrAction(this), new ReportParameterAction(this), @@ -751,8 +758,15 @@ public class JWorkBook extends JTemplate { new ReportWatermarkAction(this), new NameSeparator(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Utils_Current_Sheet")), }, this.reportComposite.getEditingReportComponent().shortcut4TemplateMenu()); + if (enableNewEngine){ + return ArraysUtil.insert(commonShortCut, new CalculateAttrAction(this), 5); + }else { + return commonShortCut; + } } + + /** * 模板的工具 * @@ -1232,7 +1246,6 @@ public class JWorkBook extends JTemplate { protected void addChooseFILEFilter(FILEChooserPane fileChooser) { String appName = ProductConstants.APP_NAME; fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPT, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); - fileChooser.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPTX, appName + Toolkit.i18nText("Fine-Design_Report_Template_File"))); addExtraChooseFILEFilter(fileChooser); } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java index b412d724d0..5fe5618293 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java @@ -34,7 +34,7 @@ public class ReportComponentComposite extends JComponent implements RemoveListen private static final int MAX = 400; private static final int HUND = 100; private static final int MIN = 10; - private static final int DIR = 10; + public static final int DIR = 10; private JWorkBook parent; private UIModeControlContainer parentContainer = null; @@ -66,17 +66,6 @@ public class ReportComponentComposite extends JComponent implements RemoveListen jSliderContainer.addValueChangeListener(showValSpinnerChangeListener); } - MouseWheelListener showValSpinnerMouseWheelListener = new MouseWheelListener() { - @Override - public void mouseWheelMoved(MouseWheelEvent e) { - if (InputEventBaseOnOS.isControlDown(e)) { - int dir = e.getWheelRotation(); - int old_resolution = jSliderContainer.getShowValue(); - jSliderContainer.setShowValue(old_resolution - (dir * DIR)); - } - } - }; - ChangeListener showValSpinnerChangeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { @@ -130,12 +119,12 @@ public class ReportComponentComposite extends JComponent implements RemoveListen } if (centerCardPane.editingComponet.elementCasePane == null) { - centerCardPane.getPolyDezi().polyArea.addMouseWheelListener(showValSpinnerMouseWheelListener); + centerCardPane.getPolyDezi().polyArea.addMouseWheelListener(new ReportComponentCompositeMouseWheelHandler(this)); return; } Grid grid = centerCardPane.editingComponet.elementCasePane.getGrid(); - this.centerCardPane.editingComponet.elementCasePane.getGrid().addMouseWheelListener(showValSpinnerMouseWheelListener); + this.centerCardPane.editingComponet.elementCasePane.getGrid().addMouseWheelListener(new ReportComponentCompositeMouseWheelHandler(this)); if (!grid.hasFocus() && grid.isRequestFocusEnabled()) { grid.requestFocus(); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java new file mode 100644 index 0000000000..e8b41afac5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java @@ -0,0 +1,75 @@ +package com.fr.design.mainframe; + +import com.fr.common.inputevent.InputEventBaseOnOS; + +import javax.swing.JScrollBar; +import javax.swing.JViewport; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; + +/** + * @author Starryi + * @version 1.0 + * Created by Starryi on 2021/9/24 + */ +public class ReportComponentCompositeMouseWheelHandler implements MouseWheelListener { + private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; + private final DesignerScaleMouseWheelHandler scaleMouseWheelHandler; + + public ReportComponentCompositeMouseWheelHandler(ReportComponentComposite componentComposite) { + translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new ScrollPaneAdapter(componentComposite)); + scaleMouseWheelHandler = new DesignerScaleMouseWheelHandler(new ScalePaneAdapter(componentComposite), ReportComponentComposite.DIR); + } + + @Override + public void mouseWheelMoved(MouseWheelEvent e) { + if (InputEventBaseOnOS.isControlDown(e)) { + scaleMouseWheelHandler.mouseWheelMoved(e); + } else { + translateMouseWheelHandler.mouseWheelMoved(e); + } + } + + private static class ScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { + private final ReportComponentComposite componentComposite; + private JViewport viewport; + + public ScrollPaneAdapter(ReportComponentComposite componentComposite) { + this.componentComposite = componentComposite; + this.viewport = new JViewport(); + } + + @Override + public boolean isWheelScrollingEnabled() { + return true; + } + + @Override + public JScrollBar getVerticalScrollBar() { + return componentComposite.getEditingReportComponent().getVerticalScrollBar(); + } + + @Override + public JScrollBar getHorizontalScrollBar() { + return componentComposite.getEditingReportComponent().getHorizontalScrollBar(); + } + + @Override + public JViewport getViewport() { + return viewport; + } + } + + private static class ScalePaneAdapter implements DesignerScaleMouseWheelHandler.ScalePane { + private final ReportComponentComposite componentComposite; + + public ScalePaneAdapter(ReportComponentComposite componentComposite) { + this.componentComposite = componentComposite; + } + + @Override + public JFormSliderPane getSlidePane() { + return componentComposite.getjSliderContainer(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java index e7612c0010..47c2e6c7e6 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java @@ -32,19 +32,17 @@ import com.fr.design.mainframe.alphafine.search.manager.impl.RecentSearchManager import com.fr.design.mainframe.alphafine.search.manager.impl.RecommendSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.SegmentationManager; import com.fr.design.mainframe.alphafine.search.manager.impl.SimilarSearchManager; -import com.fr.form.main.Form; -import com.fr.form.main.FormIO; import com.fr.general.ComparatorUtils; import com.fr.general.http.HttpClient; -import com.fr.io.TemplateWorkBookIO; -import com.fr.io.exporter.ImageExporter; import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; -import com.fr.main.impl.WorkBook; import com.fr.stable.CodeUtils; import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.exporter.LocalExportOperator; +import com.fr.workspace.server.exporter.TemplateExportOperator; import javax.imageio.ImageIO; import javax.swing.BorderFactory; import javax.swing.DefaultListModel; @@ -601,14 +599,15 @@ public class AlphaFineDialog extends UIDialog { checkWorker(); this.showWorker = new SwingWorker() { @Override - protected BufferedImage doInBackground() { - Form form = null; + protected BufferedImage doInBackground() throws Exception { + byte[] bytes = null; try { - form = FormIO.readForm(fileName); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportFormAsImageData(fileName); + } catch (Exception ignored) { + // 兼容下老版本 + bytes = new LocalExportOperator().exportFormAsImageData(fileName); } - return FormIO.exportFormAsImage(form); + return TemplateExportOperator.byteDataToImage(bytes); } @Override @@ -631,15 +630,15 @@ public class AlphaFineDialog extends UIDialog { checkWorker(); this.showWorker = new SwingWorker() { @Override - protected BufferedImage doInBackground() { - WorkBook workBook = null; + protected BufferedImage doInBackground() throws Exception { + byte[] bytes = null; try { - workBook = (WorkBook) TemplateWorkBookIO.readTemplateWorkBook(fileName); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportWorkBookAsImageData(fileName); + } catch (Exception ignored) { + // 兼容下老版本 + bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName); } - BufferedImage bufferedImage = new ImageExporter().exportToImage(workBook); - return bufferedImage; + return TemplateExportOperator.byteDataToImage(bytes); } @Override diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java b/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java index 286890303e..972df0cc8c 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/app/FormApp.java @@ -4,6 +4,7 @@ import com.fr.base.Parameter; import com.fr.base.chart.exception.ChartNotFoundException; import com.fr.base.io.XMLEncryptUtils; import com.fr.design.DesignerEnvManager; +import com.fr.design.fit.NewJForm; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.AbstractAppProvider; import com.fr.design.mainframe.BaseJForm; @@ -19,6 +20,7 @@ import com.fr.exception.TplLockedException; import com.fr.file.FILE; import com.fr.form.main.Form; import com.fr.form.ui.container.WBorderLayout; +import com.fr.form.ui.container.WFitLayout; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.report.util.ReadXmlType; @@ -58,36 +60,31 @@ class FormApp extends AbstractAppProvider { * @return */ private JTemplate compatibleForm(FILE tplFile, HashMap classType) { - if (ComparatorUtils.equals(StableFactory.getRegisteredClass(BaseJForm.XML_TAG), JForm.class)) { - classType.put(Constants.ARG_2, Parameter[].class); - JForm emptyForm = new JForm(new Form(new WBorderLayout("form")), tplFile); - OpenWorker> worker = new OpenWorker<>( - new Callable>() { - @Override - public OpenResult call() throws Exception { - Form form = getForm(tplFile); - return new OpenResult<>(form, form.getParameters()); - } - }, emptyForm); - worker.addCallBack(new Callable>() { - @Override - public JTemplate call() throws Exception { - OpenResult result = worker.getResult(); - return (JTemplate) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, - new Object[]{result.getBaseBook(), tplFile, result.getRef()}, classType, BaseJForm.class); - } - }); - worker.start(tplFile.getPath()); - OpenResult result = worker.getResult(); - if (result != null) { + classType.put(Constants.ARG_2, Parameter[].class); + NewJForm emptyForm = new NewJForm(Form.getEmptyBodyForm(), tplFile); + OpenWorker> worker = new OpenWorker<>( + new Callable>() { + @Override + public OpenResult call() throws Exception { + Form form = getForm(tplFile); + return new OpenResult<>(form, form.getParameters()); + } + }, emptyForm); + worker.addCallBack(new Callable>() { + @Override + public JTemplate call() throws Exception { + OpenResult result = worker.getResult(); return (JTemplate) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, - new Object[]{result.getBaseBook(), tplFile, new Parameter[0]}, classType, BaseJForm.class); + new Object[]{result.getBaseBook(), tplFile, result.getRef()}, classType, BaseJForm.class); } - return emptyForm; - } else { + }); + worker.start(tplFile.getPath()); + OpenResult result = worker.getResult(); + if (result != null) { return (JTemplate) StableFactory.getMarkedInstanceObjectFromClass(BaseJForm.XML_TAG, - new Object[]{getForm(tplFile), tplFile}, classType, BaseJForm.class); + new Object[]{result.getBaseBook(), tplFile, new Parameter[0]}, classType, BaseJForm.class); } + return emptyForm; } @Nullable diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java index 29180c09db..3ba44743df 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoLabel.java @@ -6,6 +6,7 @@ package com.fr.design.mainframe.bbs; import com.fr.design.DesignerEnvManager; import com.fr.design.bbs.BBSLoginUtils; import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.FineJOptionPane; import com.fr.design.extra.LoginContextListener; import com.fr.design.extra.UserLoginContext; import com.fr.design.gui.ilable.UILabel; @@ -14,6 +15,7 @@ import com.fr.design.gui.imenu.UIPopupMenu; import com.fr.design.locale.impl.BbsSpaceMark; import com.fr.design.login.DesignerLoginHelper; import com.fr.design.login.DesignerLoginSource; +import com.fr.design.login.service.DesignerPassportManager; import com.fr.design.login.utils.DesignerLoginUtils; import com.fr.design.mainframe.DesignerContext; import com.fr.design.os.impl.SupportOSImpl; @@ -29,6 +31,7 @@ import com.fr.general.locale.LocaleMark; import com.fr.log.FineLoggerFactory; import com.fr.stable.EncodeConstants; import com.fr.stable.StringUtils; +import javax.swing.JOptionPane; import javax.swing.SwingConstants; import java.awt.Cursor; import java.awt.Frame; @@ -120,8 +123,33 @@ public class UserInfoLabel extends UILabel { UserLoginContext.fireLoginContextListener(DesignerLoginSource.SWITCH_ACCOUNT); } }); + //退出登录 + UIMenuItem logout = new UIMenuItem(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Logout")); + logout.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + String[] options = new String[]{ + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Logout"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Button_Cancel") + }; + int rv = FineJOptionPane.showConfirmDialog( + DesignerLoginHelper.getDialog(), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_BBSLogin_Logout_Tip"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + JOptionPane.OK_CANCEL_OPTION, + JOptionPane.WARNING_MESSAGE, + null, + options, + options[1] + ); + if (rv == JOptionPane.YES_OPTION) { + DesignerPassportManager.getInstance().logout(); + } + } + }); menu.add(priviteMessage); menu.add(closeOther); + menu.add(logout); GUICoreUtils.showPopupMenu(menu, UserInfoLabel.this, 0, MENU_HEIGHT); } else { UserLoginContext.fireLoginContextListener(DesignerLoginSource.NORMAL); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java index e6ae079aa4..b3d6e35e5e 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/bbs/UserInfoPane.java @@ -86,6 +86,12 @@ public class UserInfoPane extends BasicPane { markSignIn(text); } }); + EventDispatcher.listen(CertificateEvent.LOGOUT, new Listener() { + @Override + public void on(Event event, String text) { + markUnSignIn(); + } + }); } public UserInfoLabel getUserInfoLabel() { diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/CellElementEditPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/CellElementEditPane.java index e54d03443e..4205ea152c 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/CellElementEditPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/CellElementEditPane.java @@ -7,9 +7,15 @@ import com.fr.design.gui.frpane.AttributeChangeListener; import com.fr.design.gui.ibutton.UIHeadGroup; import com.fr.design.gui.itabpane.TitleChangeListener; import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.mainframe.cell.settingpane.AbstractCellAttrPane; +import com.fr.design.mainframe.cell.settingpane.CellExpandAttrPane; +import com.fr.design.mainframe.cell.settingpane.CellOtherSetPane; +import com.fr.design.mainframe.cell.settingpane.CellPresentPane; +import com.fr.design.mainframe.cell.settingpane.CellStylePane; import com.fr.design.mainframe.cell.settingpane.*; import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase; import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.gui.AdjustWorkBookDefaultStyleUtils; import com.fr.general.ComparatorUtils; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; @@ -17,8 +23,11 @@ import com.fr.report.cell.CellElement; import com.fr.report.cell.TemplateCellElement; import com.fr.report.elementcase.TemplateElementCase; -import javax.swing.*; -import java.awt.*; +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Dimension; import java.util.ArrayList; import java.util.List; @@ -112,6 +121,7 @@ public class CellElementEditPane extends BasicPane { CellElement cellElement = elementCase.getCellElement(cs.getColumn(), cs.getRow()); if (cellElement == null) { cellElement = DefaultThemedTemplateCellElementCase.createInstance(cs.getColumn(), cs.getRow()); + AdjustWorkBookDefaultStyleUtils.adjustCellElement(cellElement); //默认选中的是A1单元格,所以若是A1单元格没有加到列表时要加上,否则在聚合报表时会出错 if (cs.isSelectedOneCell(elementCasePane) && (cs.getColumn() + cs.getRow() == 0)) { elementCase.addCellElement((TemplateCellElement) cellElement); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java index 1d02fde9cb..0ea7713ca9 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/CellOtherSetPane.java @@ -1,5 +1,6 @@ package com.fr.design.mainframe.cell.settingpane; +import com.fr.base.Style; import com.fr.design.constants.LayoutConstants; import com.fr.design.constants.UIConstants; import com.fr.design.editor.ValueEditorPane; @@ -21,13 +22,16 @@ import com.fr.design.mainframe.theme.utils.DefaultThemedTemplateCellElementCase; import com.fr.design.utils.gui.UIComponentUtils; import com.fr.design.widget.FRWidgetFactory; import com.fr.general.ComparatorUtils; +import com.fr.general.FRFont; import com.fr.report.cell.TemplateCellElement; import com.fr.report.cell.cellattr.CellGUIAttr; import com.fr.report.cell.cellattr.CellInsertPolicyAttr; import com.fr.report.cell.cellattr.CellPageAttr; import com.fr.report.elementcase.TemplateElementCase; +import com.fr.stable.Constants; import com.fr.stable.StringUtils; - +import com.fr.design.i18n.Toolkit; +import java.awt.Color; import javax.swing.BorderFactory; import javax.swing.ButtonGroup; import javax.swing.JPanel; @@ -75,6 +79,11 @@ public class CellOtherSetPane extends AbstractCellAttrPane { private UICheckBox canBreakOnPaginateCheckBox; private UICheckBox repeatCheckBox; + //固定行数分页 + private UICheckBox pageFixedRowDataCheckBox; + private UILabel currentPageFixedRowDataTipLabel; + private TemplateCellElement pageFixedRowDataCell; + // 自动调整 private UIRadioButton autoHeightRadioButton; // 自动调整行高 private UIRadioButton autoWidthRadioButton; // 自动调整列宽 @@ -90,6 +99,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane { private JPanel insertRowPolicyPane; private JPanel defaultValuePane; + private static final Color TIPS_FONT_COLOR = new Color(0x8f8f92); /** * 初始化 * @@ -263,8 +273,10 @@ public class CellOtherSetPane extends AbstractCellAttrPane { pageBeforeColumnCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Before_Column")); pageAfterColumnCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_After_Column")); - canBreakOnPaginateCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellPage_Can_Break_On_Paginate")); - repeatCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellPage_Repeat_Content_When_Paging")); + canBreakOnPaginateCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_CellPage_Can_Break_On_Paginate")); + repeatCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_CellPage_Repeat_Content_When_Paging")); + pageFixedRowDataCheckBox = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Fixed_Row_Cell")); + currentPageFixedRowDataTipLabel = new UILabel(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_No_Page_Fixed_Row_Cell") +")"); pageBeforeRowCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); pageAfterRowCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); @@ -272,11 +284,13 @@ public class CellOtherSetPane extends AbstractCellAttrPane { pageAfterColumnCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); canBreakOnPaginateCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); repeatCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); - + pageFixedRowDataCheckBox.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); + currentPageFixedRowDataTipLabel.setBorder(UIConstants.CELL_ATTR_ZEROBORDER); + currentPageFixedRowDataTipLabel.setForeground(TIPS_FONT_COLOR); double p = TableLayout.PREFERRED; - double[] rowSize = {p, p, p, p, p, p, p, p, p, p, p}; + double[] rowSize = {p, p, p, p, p, p, p, p, p, p, p,p}; double[] columnSize = {p}; - int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; + int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1},{1,1},{1,1}}; Component[][] components = new Component[][]{ new Component[]{null}, new Component[]{pageBeforeRowCheckBox}, @@ -287,6 +301,9 @@ public class CellOtherSetPane extends AbstractCellAttrPane { new Component[]{null}, new Component[]{canBreakOnPaginateCheckBox}, new Component[]{repeatCheckBox}, + new Component[]{null}, + new Component[]{pageFixedRowDataCheckBox}, + new Component[]{currentPageFixedRowDataTipLabel} }; return TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, LayoutConstants.VGAP_MEDIUM, LayoutConstants.VGAP_LARGE); @@ -313,13 +330,20 @@ public class CellOtherSetPane extends AbstractCellAttrPane { @Override public void itemStateChanged(ItemEvent e) { + Style elementStyle = cellElement.getStyle(); + FRFont frFont = elementStyle.getFRFont(); if (showContent.getSelectedIndex() == 3) { fileNamePane.setPreferredSize(new Dimension(100, 20)); fileNameLayout.show(fileNamePane, "content"); + frFont = frFont.applyForeground(Color.blue); + frFont = frFont.applyUnderline(Constants.LINE_THIN); } else { fileNameLayout.show(fileNamePane, "none"); fileNamePane.setPreferredSize(new Dimension(0, 0)); + frFont = frFont.applyForeground(Color.black); + frFont = frFont.applyUnderline(Constants.LINE_NONE); } + cellElement.setStyle(elementStyle.deriveFRFont(frFont)); } }); return fileNamePane; @@ -345,6 +369,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane { repeatCheckBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellPage_Repeat_Content_When_Paging")); insertRowPolicyButtonGroup.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy")); valueEditor.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy")); + pageFixedRowDataCheckBox.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Fixed_Row_Cell")); } @@ -356,6 +381,9 @@ public class CellOtherSetPane extends AbstractCellAttrPane { @Override protected void populateBean() { + this.currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_No_Page_Fixed_Row_Cell") + ")"); + this.pageFixedRowDataCell = null; + checkPageFixedRow(); CellGUIAttr cellGUIAttr = cellElement.getCellGUIAttr(); if (cellGUIAttr == null) { cellGUIAttr = CellGUIAttr.DEFAULT_CELLGUIATTR; @@ -411,6 +439,7 @@ public class CellOtherSetPane extends AbstractCellAttrPane { this.pageAfterColumnCheckBox.setSelected(cellPageAttr.isPageAfterColumn()); this.canBreakOnPaginateCheckBox.setSelected(cellPageAttr.isCanBreakOnPaginate()); this.repeatCheckBox.setSelected(cellPageAttr.isRepeat()); + this.pageFixedRowDataCheckBox.setSelected(cellPageAttr.isPageFixedRow()); CellInsertPolicyAttr cellInsertPolicyAttr = cellElement.getCellInsertPolicyAttr();// 插入 if (cellInsertPolicyAttr == null) { cellInsertPolicyAttr = new CellInsertPolicyAttr(); @@ -536,6 +565,20 @@ public class CellOtherSetPane extends AbstractCellAttrPane { cellPageAttr.setRepeat(this.repeatCheckBox.isSelected()); } + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_CellWrite_Page_Fixed_Row_Cell"))) { + cellPageAttr.setPageFixedRow(this.pageFixedRowDataCheckBox.isSelected()); + if (this.pageFixedRowDataCheckBox.isSelected()) { + if (pageFixedRowDataCell != null && pageFixedRowDataCell != cellElement) { + pageFixedRowDataCell.getCellPageAttr().setPageFixedRow(false); + } + pageFixedRowDataCell = cellElement; + currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_Current_Page_Fixed_Row_Cell") + cellElement.toString() + ")"); + } else { + if (pageFixedRowDataCell != null && pageFixedRowDataCell == cellElement) { + currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_No_Page_Fixed_Row_Cell") + ")"); + } + } + } cellElement.setCellPageAttr(cellPageAttr); if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_CellWrite_InsertRow_Policy"))) { @@ -579,6 +622,29 @@ public class CellOtherSetPane extends AbstractCellAttrPane { } } + private void checkPageFixedRow() { + TemplateElementCase elementCase = elementCasePane.getEditingElementCase(); + int rowCount = elementCase.getRowCount(); + int columnCount = elementCase.getColumnCount(); + boolean find = false; + for (int row = 0; row < rowCount; row++) { + for (int column = 0; column < columnCount; column++) { + TemplateCellElement cellElement = elementCase.getTemplateCellElement(column, row); + if (cellElement != null) { + if (cellElement.getCellPageAttr() != null && cellElement.getCellPageAttr().isPageFixedRow()) { + this.pageFixedRowDataCell = cellElement; + this.currentPageFixedRowDataTipLabel.setText(" (" + Toolkit.i18nText("Fine-Design_Report_CellWrite_Current_Page_Fixed_Row_Cell") + cellElement.toString() + ")"); + find = true; + break; + } + } + } + if (find) { + break; + } + } + } + /** * 返回界面的标题 * diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java index 268dbebe6a..cafbf7d549 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/cell/settingpane/style/CustomStylePane.java @@ -114,11 +114,10 @@ public class CustomStylePane extends MultiTabPane