diff --git a/designer-base/src/main/java/com/fr/design/PluginClassRefreshManager.java b/designer-base/src/main/java/com/fr/design/PluginClassRefreshManager.java index 4ff6beda24..9e1d57dfd9 100644 --- a/designer-base/src/main/java/com/fr/design/PluginClassRefreshManager.java +++ b/designer-base/src/main/java/com/fr/design/PluginClassRefreshManager.java @@ -27,6 +27,8 @@ public class PluginClassRefreshManager { private final PluginEventListener pluginAfterRunEventListener = new PluginEventListener() { @Override public void on(PluginEvent event) { + // 重载模版之前 触发下hide + HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().fireTabChange(); // 兼容之前版本特性 for (String tag : context) { if (event.getContext().contain(tag)) { @@ -51,6 +53,7 @@ public class PluginClassRefreshManager { public void on(PluginEvent event) { PluginListenerRegistration.getInstance().listen(PluginEventType.AfterRun, pluginAfterRunEventListener); if (DesignerLaunchStatus.getStatus() != DesignerLaunchStatus.WORKSPACE_INIT_COMPLETE) { + HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().fireTabChange(); HistoryTemplateListCache.getInstance().reloadAllEditingTemplate(); } } diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/FileTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/FileTableDataPane.java index 6eb802619f..5d9d4146d6 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/FileTableDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/FileTableDataPane.java @@ -26,6 +26,7 @@ import com.fr.design.gui.itableeditorpane.UITableEditorPane; import com.fr.design.gui.itextfield.UITextField; import com.fr.design.gui.itoolbar.UIToolbar; 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; @@ -612,7 +613,7 @@ public class FileTableDataPane extends AbstractTableDataPane { private void setTextField(FileTableData ob) { if (ob.getFilePath() != null) { - if (ob.getFilePath().indexOf("http") != -1) { + if (ob.getFilePath().contains("http")) { urlRadioSelectAction(); urlText.setText(ob.getFilePath()); } else { @@ -625,6 +626,15 @@ public class FileTableDataPane extends AbstractTableDataPane { @Override public FileTableData updateBean() { String filePath = getFilePathFromUrlOrLocal(); + // 安全要求禁止 file 协议访问本地磁盘 + if (FileTableData.isInvalidFilePath(filePath)) { + FineJOptionPane.showMessageDialog(this, + Toolkit.i18nText("Fine-Design_File_Table_Data_Path_Invalid"), + Toolkit.i18nText("Fine-Design_Basic_Widget_Error_Tip"), + JOptionPane.ERROR_MESSAGE); + // 阻止对话框关闭 + throw new RuntimeException(Toolkit.i18nText("Fine-Design_File_Table_Data_Path_Invalid")); + } if (StringUtils.isNotBlank(filePath)) { this.params = getEditorPaneParameter().length == 0 ? null : getEditorPaneParameter(); if (fileTypeComboBox.getSelectedIndex() == EXCEL) { @@ -786,6 +796,14 @@ public class FileTableDataPane extends AbstractTableDataPane { if (this.fileTableData == null) { return; } + String filePath = getFilePathFromUrlOrLocal(); + if (FileTableData.isInvalidFilePath(filePath)) { + FineJOptionPane.showMessageDialog(this, + Toolkit.i18nText("Fine-Design_File_Table_Data_Path_Invalid"), + Toolkit.i18nText("Fine-Design_Basic_Widget_Error_Tip"), + JOptionPane.ERROR_MESSAGE); + return; + } PreviewTablePane.previewTableData(this.updateBean()); } @@ -802,7 +820,7 @@ public class FileTableDataPane extends AbstractTableDataPane { xmlNodeTree = new XMLNodeTree(); this.add(new JScrollPane(xmlNodeTree)); - keyPointLaber = new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Key_Point") + ":"); + keyPointLaber = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Key_Point") + ":"); refreshAction = new RefreshParameterAction(); ToolBarDef toolbarDef = new ToolBarDef(); toolbarDef.addShortCut(refreshAction); @@ -820,7 +838,7 @@ public class FileTableDataPane extends AbstractTableDataPane { private class RefreshParameterAction extends UpdateAction { public RefreshParameterAction() { - this.setName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh")); + this.setName(Toolkit.i18nText("Fine-Design_Basic_Refresh")); this.setMnemonic('r'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/control/refresh.png")); } diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java index d0bc499a29..f1d2433dbe 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/ProcedureDataPane.java @@ -158,7 +158,7 @@ public class ProcedureDataPane extends AbstractTableDataPane imp private JToolBar creatToolBar() { ToolBarDef toolBarDef = new ToolBarDef(); - toolBarDef.addShortCut(new PreviewAction()); + toolBarDef.addShortCut(new PreviewAction(this)); toolBarDef.addShortCut(new RefreshAction()); toolBarDef.addShortCut(SeparatorDef.DEFAULT); isShareCheckBox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Is_Share_DBTableData")); @@ -243,7 +243,7 @@ public class ProcedureDataPane extends AbstractTableDataPane imp this.storeProcedureWorkerListener = null; } - + private StoreProcedure updateBeanWithOutExecute() { String dbName = connectionTableProcedurePane.getSelectedDatabaseConnnectonName(); @@ -266,16 +266,16 @@ public class ProcedureDataPane extends AbstractTableDataPane imp return sp; } - + @Override public StoreProcedure updateBean() { - + final StoreProcedure sp = updateBeanWithOutExecute(); if (updateWorker != null) { updateWorker.cancel(true); } updateWorker = new SwingWorker() { - + @Override protected Void doInBackground() throws Exception { DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER); @@ -284,7 +284,7 @@ public class ProcedureDataPane extends AbstractTableDataPane imp sp.refreshDataModelListAndResultNames(dataModels); return null; } - + @Override public void done() { DesignTableDataManager.setThreadLocal(DesignTableDataManager.NO_PARAMETER); @@ -293,7 +293,7 @@ public class ProcedureDataPane extends AbstractTableDataPane imp fireDSChanged(); } }; - + updateWorker.execute(); return sp; } @@ -359,17 +359,20 @@ public class ProcedureDataPane extends AbstractTableDataPane imp } private class PreviewAction extends UpdateAction { - public PreviewAction() { + ProcedureDataPane procedureDataPane; + + public PreviewAction(ProcedureDataPane procedureDataPane) { this.setName(PREVIEW_BUTTON); this.setMnemonic('P'); this.setSmallIcon(BaseUtils.readIcon("/com/fr/design/images/m_file/preview.png")); + this.procedureDataPane = procedureDataPane; } @Override public void actionPerformed(ActionEvent evt) { - StoreProcedure sp = updateBeanWithOutExecute(); - StoreProcedureDataWrapper storeProcedureDataWrappe = new StoreProcedureDataWrapper(sp, StringUtils.EMPTY, queryText.getText()); - storeProcedureDataWrappe.previewData(StoreProcedureDataWrapper.PREVIEW_ALL); + StoreProcedure sp = updateBeanWithOutExecute(); + StoreProcedureDataWrapper storeProcedureDataWrapper = new StoreProcedureDataWrapper(this.procedureDataPane, sp, StringUtils.EMPTY, queryText.getText()); + storeProcedureDataWrapper.previewData(StoreProcedureDataWrapper.PREVIEW_ALL); } } diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java index 17fbf57888..08274fd71d 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/wrapper/StoreProcedureDataWrapper.java @@ -18,6 +18,7 @@ import com.fr.log.FineLoggerFactory; import javax.swing.Icon; import javax.swing.JFrame; import javax.swing.SwingWorker; +import java.awt.Component; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -52,16 +53,25 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { private int previewModel; public StoreProcedureDataWrapper(StoreProcedure storeProcedure, String storeprocedureName, String dsName) { - this(storeProcedure, storeprocedureName, dsName, true); + this(null, storeProcedure, storeprocedureName, dsName, true); } + public StoreProcedureDataWrapper(StoreProcedure storeProcedure, String storeprocedureName, String dsName, boolean needLoad) { + this(null, storeProcedure, storeprocedureName, dsName, needLoad); + } + public StoreProcedureDataWrapper(Component component, StoreProcedure storeProcedure, String storeprocedureName, String dsName) { + this(component, storeProcedure, storeprocedureName, dsName, true); + } + /** - * @param dsName 存储过程一个返回数据集的名字 - * @param storeProcedure 存储过程 - * @param storeprocedureName 存储过程的名字(某些情况下可以为空) - */ - public StoreProcedureDataWrapper(StoreProcedure storeProcedure, String storeprocedureName, String dsName, boolean needLoad) { + * @param: component loadingBar的父弹框(如果不设置父弹框的话,可能出现loadingBar隐藏在一个弹框后的情况) + * @param: storeProcedure 存储过程 + * @param: storeprocedureName 存储过程的名字(某些情况下可以为空) + * @param: dsName 存储过程一个返回数据集的名字 + * @param: needLoad 是否要加载 + **/ + public StoreProcedureDataWrapper(Component component, StoreProcedure storeProcedure, String storeprocedureName, String dsName, boolean needLoad) { this.dsName = dsName; this.storeProcedure = storeProcedure; this.storeProcedure.setCalculating(false); @@ -69,7 +79,10 @@ public final class StoreProcedureDataWrapper implements TableDataWrapper { if (needLoad) { setWorker(); } - loadingBar = new AutoProgressBar(new JFrame(), Toolkit.i18nText("Fine-Design_Basic_Loading_Data"), "", 0, 100) { + if (component == null) { + component = new JFrame(); + } + loadingBar = new AutoProgressBar(component, Toolkit.i18nText("Fine-Design_Basic_Loading_Data"), "", 0, 100) { public void doMonitorCanceled() { getWorker().cancel(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 9d10da3a72..22f6cb246e 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 @@ -58,7 +58,7 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver * Spinner内的数字文本框长度 */ private int numberFieldColumns; - private boolean hasTextFieldFocus = false; + private boolean textFieldFocus = false; public UISpinner() { @@ -197,6 +197,10 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver this.nextButton.setEnabled(flag); } + public void setTextFieldFocus(boolean textFieldFocus) { + this.textFieldFocus = textFieldFocus; + } + @Override public Dimension getPreferredSize() { Dimension dim = super.getPreferredSize(); @@ -319,7 +323,7 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver @Override public void mouseWheelMoved(MouseWheelEvent e) { - if (hasTextFieldFocus && isEnabled() && e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { + if (textFieldFocus && isEnabled() && e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { setValue(value - e.getWheelRotation()); } } @@ -333,12 +337,12 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver textField.addFocusListener(new FocusAdapter() { @Override public void focusGained(FocusEvent e) { - hasTextFieldFocus = true; + textFieldFocus = true; } @Override public void focusLost(FocusEvent e) { - hasTextFieldFocus = false; + textFieldFocus = false; textField.getDocument().removeDocumentListener(docListener); textField.setValue(value); textField.getDocument().addDocumentListener(docListener); diff --git a/designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java b/designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java index 5da006fa76..2d2dd935d1 100644 --- a/designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java +++ b/designer-base/src/main/java/com/fr/design/login/DesignerLoginHelper.java @@ -6,6 +6,7 @@ import com.fr.design.extra.WebViewDlgHelper; import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.os.impl.SupportOSImpl; +import com.fr.design.plugin.DesignerPluginContext; import com.fr.design.update.ui.dialog.UpdateMainDialog; import com.fr.general.GeneralContext; import java.awt.Dialog; @@ -25,7 +26,7 @@ import javax.swing.WindowConstants; public class DesignerLoginHelper { private static final String MAIN_RESOURCE_PATH = "/com/fr/design/login/login.html"; - private static final String JXBROWSER = "com.teamdev.jxbrowser.chromium.Browser"; + private static final String JXBROWSER = "com.teamdev.jxbrowser.browser.Browser"; private static UIDialog dialog = null; @@ -91,6 +92,7 @@ public class DesignerLoginHelper { dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); dialog.setVisible(false); dialog = null; + DesignerPluginContext.setPluginDialog(null); } } diff --git a/designer-base/src/main/java/com/fr/design/login/DesignerLoginShowDialog.java b/designer-base/src/main/java/com/fr/design/login/DesignerLoginShowDialog.java index 031ec4941f..53e4556e4e 100644 --- a/designer-base/src/main/java/com/fr/design/login/DesignerLoginShowDialog.java +++ b/designer-base/src/main/java/com/fr/design/login/DesignerLoginShowDialog.java @@ -1,6 +1,7 @@ package com.fr.design.login; import com.fr.design.dialog.UIDialog; +import com.fr.design.plugin.DesignerPluginContext; import com.fr.design.utils.gui.GUICoreUtils; import java.awt.BorderLayout; import java.awt.Component; @@ -36,6 +37,7 @@ public class DesignerLoginShowDialog extends UIDialog { setSize(DEFAULT); GUICoreUtils.centerWindow(this); setResizable(false); + DesignerPluginContext.setPluginDialog(this); } @Override diff --git a/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java b/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java index 92e4171460..b3513bb6da 100644 --- a/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java +++ b/designer-base/src/main/java/com/fr/design/login/guide/DesignerGuideHelper.java @@ -22,7 +22,7 @@ import javax.swing.WindowConstants; public class DesignerGuideHelper { private static final String MAIN_RESOURCE_PATH = "/com/fr/design/login/guide.html"; - private static final String JXBROWSER = "com.teamdev.jxbrowser.chromium.Browser"; + private static final String JXBROWSER = "com.teamdev.jxbrowser.browser.Browser"; private static final long ONE_WEEK = 7 * 24 * 3600 * 1000L; private static final long ONE_MONTH = 30 * 24 * 3600 * 1000L; private static final long SIX_MONTH = 6 * ONE_MONTH; diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java index 890b6fa04b..b7bc518385 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java @@ -212,6 +212,12 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta } } + @Override + public void windowIconified(WindowEvent e) { + // 最小化时 hide工具栏 + HistoryTemplateListCache.getInstance().getCurrentEditingTemplate().fireTabChange(); + } + }; private JComponent closeButton = new JComponent() { 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 f540832d0d..f3afcacc98 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 @@ -56,6 +56,10 @@ public class DesktopCardPane extends BasicPane implements TargetModifiedListener } else if (!DesignModeContext.isVcsMode() && !DesignModeContext.isAuthorityEditing()) { DesignModeContext.switchTo(DesignerMode.NORMAL); } + // 切换时 + if (component != null) { + component.fireTabChange(); + } DesignerFrameFileDealerPane.getInstance().setCurrentEditingTemplate(jt); if (component != null) { layeredPane.remove(component); 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 9e8df6b85f..f1bc2cbafe 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 @@ -17,6 +17,7 @@ import com.fr.design.actions.file.SaveAsTemplateAction; import com.fr.design.actions.file.SaveTemplateAction; import com.fr.design.actions.file.WebPreviewUtils; import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.data.datapane.TableDataTreePane; import com.fr.design.designer.DesignerProxy; import com.fr.design.designer.TargetComponent; import com.fr.design.dialog.FineJOptionPane; @@ -94,7 +95,7 @@ import java.util.concurrent.Callable; /** * 报表设计和表单设计的编辑区域(设计器编辑的IO文件) */ -public abstract class JTemplate> extends TargetComponent implements ToolBarMenuDockPlus, DesignerProxy, JTemplateSave { +public abstract class JTemplate> extends TargetComponent implements ToolBarMenuDockPlus, DesignerProxy, JTemplateSave, TabChangeListener { // TODO ALEX_SEP editingFILE这个属性一定要吗?如果非要不可,有没有可能保证不为null private static final int PREFIX_NUM = 3000; protected FILE editingFILE = null; @@ -217,6 +218,11 @@ public abstract class JTemplate> } } + @Override + public void fireTabChange() { + // do nothing + } + protected void addPane(PropertyItemPaneProvider provider) { // do nothing } @@ -389,6 +395,8 @@ public abstract class JTemplate> addCenterPane(); refreshToolArea(); + + TableDataTreePane.getInstance(DesignModelAdapter.getCurrentModelAdapter()).refreshDockingView(); } }); diff --git a/designer-base/src/main/java/com/fr/design/mainframe/TabChangeListener.java b/designer-base/src/main/java/com/fr/design/mainframe/TabChangeListener.java new file mode 100644 index 0000000000..a69706c551 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/TabChangeListener.java @@ -0,0 +1,13 @@ +package com.fr.design.mainframe; + +/** + * tab切换时对当前打开的模版处理些事件 + * + * @author hades + * @version 10.0 + * Created by hades on 2021/7/22 + */ +public interface TabChangeListener { + + void fireTabChange(); +} diff --git a/designer-base/src/main/java/com/fr/design/parameter/ParameterArrayPane.java b/designer-base/src/main/java/com/fr/design/parameter/ParameterArrayPane.java index adb0e48472..2703a2a2b8 100644 --- a/designer-base/src/main/java/com/fr/design/parameter/ParameterArrayPane.java +++ b/designer-base/src/main/java/com/fr/design/parameter/ParameterArrayPane.java @@ -18,6 +18,9 @@ import java.util.Arrays; import java.util.List; public class ParameterArrayPane extends JListControlPane { + + private static final String DEFAULT_PARAMETER_NAME_PREFIX = "para"; + /** * Constructor. */ @@ -63,7 +66,7 @@ public class ParameterArrayPane extends JListControlPane { new NameableSelfCreator(Toolkit.i18nText("Fine-Design_Basic_Engine_Parameter_Name"), Parameter.class, ParameterPane.class) { public Parameter createNameable(UnrepeatedNameHelper helper) { // 返回参数设置面板. - return new Parameter(helper.createUnrepeatedName("p")); + return new Parameter(helper.createUnrepeatedName(DEFAULT_PARAMETER_NAME_PREFIX)); } @Override diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java b/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java index db0661b1f8..f3284c11e5 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmFinder.java @@ -15,7 +15,6 @@ import com.fr.event.Listener; import com.fr.general.GeneralContext; import com.fr.log.FineLoggerFactory; import com.fr.stable.StableUtils; -import com.fr.stable.os.OperatingSystem; import com.fr.workspace.Workspace; import com.fr.workspace.WorkspaceEvent; @@ -32,7 +31,7 @@ public class UpmFinder { private static final String UPM_DIR = "/upm"; private static final String MAIN_RESOURCE_PATH = UPM_DIR + "/plugin_design.html"; - private static final String JXBROWSER = OperatingSystem.isWindows() ? "com.teamdev.jxbrowser.browser.Browser" : "com.teamdev.jxbrowser.chromium.Browser"; + private static final String JXBROWSER = "com.teamdev.jxbrowser.browser.Browser"; public static String installHome = FRContext.getCommonOperator().getWebRootPath(); diff --git a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java index 045d54413f..24431cd957 100644 --- a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java +++ b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java @@ -26,6 +26,8 @@ import com.fr.plugin.manage.control.PluginTaskCallback; import com.fr.plugin.manage.control.PluginTaskResult; import com.fr.plugin.manage.control.ProgressCallback; import com.fr.report.ReportHelper; +import com.fr.rpc.ExceptionHandler; +import com.fr.rpc.RPCInvokerExceptionInfo; import com.fr.rpc.Result; import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; @@ -35,6 +37,7 @@ import com.fr.workspace.engine.base.FineObjectPool; import com.fr.workspace.engine.channel.http.FunctionalHttpRequest; import com.fr.workspace.engine.exception.WorkspaceConnectionException; import com.fr.workspace.engine.rpc.WorkspaceProxyPool; +import com.fr.workspace.server.check.VersionInfoOperator; import java.lang.reflect.Method; import java.text.ParsePosition; import java.text.SimpleDateFormat; @@ -87,23 +90,27 @@ public class VersionCheckUtils { public static void showVersionCheckDialog(String envName) { if (!VersionCheckUtils.versionCheck(envName)) { - NotificationDialog notificationDialog = new NotificationDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Prompt"), - false, NotificationDialog.WARNING_MESSAGE, Toolkit.i18nText("Fine-Design_Basic_Sync_Check_Brief_Info"), new NotificationDialogAction() { - @Override - public String name() { - return "VERSION_CHECK"; - } - - @Override - public void doClick() { - CheckServiceDialog checkServiceDialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), GeneralUtils.readFullBuildNO(), getRemoteBranch(envName),getNoExistServiceDescription(envName)); - checkServiceDialog.setVisible(true); - } - }); - notificationDialog.setVisible(true); + showNotificationDialog(envName); } } + private static void showNotificationDialog(String envName) { + NotificationDialog notificationDialog = new NotificationDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Prompt"), + false, NotificationDialog.WARNING_MESSAGE, Toolkit.i18nText("Fine-Design_Basic_Sync_Check_Brief_Info"), new NotificationDialogAction() { + @Override + public String name() { + return "VERSION_CHECK"; + } + + @Override + public void doClick() { + CheckServiceDialog checkServiceDialog = new CheckServiceDialog(DesignerContext.getDesignerFrame(), GeneralUtils.readFullBuildNO(), getRemoteBranch(envName), getNoExistServiceDescription(envName)); + checkServiceDialog.setVisible(true); + } + }); + notificationDialog.setVisible(true); + } + public static boolean checkLocalAndRemoteJartime(String envName) { DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); DesignerWorkspaceInfo selectedEnv = envManager.getWorkspaceInfo(envName); @@ -156,15 +163,22 @@ public class VersionCheckUtils { } public static String getRemoteBranch(DesignerWorkspaceInfo selectedEnv) { - String remoteBranch = StringUtils.EMPTY; - WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); - try { - remoteBranch = new FunctionalHttpRequest(connectionInfo).getServerBranch(); - } catch (WorkspaceConnectionException e) { - remoteBranch = Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old") + formatBranch(GeneralUtils.readFullBuildNO()); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } + String remoteBranch; + remoteBranch = WorkContext.getCurrent().get(VersionInfoOperator.class, new ExceptionHandler() { + @Override + public String callHandler(RPCInvokerExceptionInfo exceptionInfo) { + WorkspaceConnectionInfo connectionInfo = selectedEnv.getConnection(); + String remoteBranch = StringUtils.EMPTY; + try { + remoteBranch = new FunctionalHttpRequest(connectionInfo).getServerBranch(); + } catch (WorkspaceConnectionException e) { + remoteBranch = Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Branch_Is_Old") + formatBranch(GeneralUtils.readFullBuildNO()); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return remoteBranch; + } + }).getFullBuildNO(); return remoteBranch; } @@ -248,7 +262,7 @@ public class VersionCheckUtils { Map pluginsNameMap = ReportHelper.getPluginNameMap(); for (int i = 0; i < remotePlugins.size(); i++) { remotePlugin = remotePlugins.getJSONObject(i); - if (ComparatorUtils.equals(remotePlugin.getString("running"), "false")) { + if (ComparatorUtils.equals(remotePlugin.getString("running"), "false") || (remotePlugin.containsKey("sync") && !remotePlugin.getBoolean("sync"))) { continue; } String remotePluginID = remotePlugin.getString(ID); diff --git a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java index 441a1fdecd..a921a03229 100644 --- a/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java +++ b/designer-base/src/main/java/com/fr/env/CheckServiceDialog.java @@ -36,6 +36,8 @@ import java.awt.Component; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.io.File; import java.util.List; import javax.swing.BorderFactory; @@ -167,13 +169,15 @@ public class CheckServiceDialog extends JDialog implements ActionListener { centerPanel.add(detailsPane, BorderLayout.CENTER); JPanel buttonPanel = FRGUIPaneFactory.createBorderLayout_M_Pane(); buttonPanel.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 10)); - boolean Sync = false; - if (isOnline() && Sync) { + if (isOnline()) { ignoreButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_Ignore")); ignoreButton.addActionListener(this); syncButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Sync_To_Local")); syncButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Sync_To_Local_Tip")); - syncButton.addMouseListener(syncButtonClickListener); + syncButton.addActionListener(syncButtonActionListener); + if(jarConsistency && differentPlugins.isEmpty()){ + syncButton.setEnabled(false); + } progressBar = new JProgressBar(); progressBar.setUI(new MotifProgressBarUI()); progressBar.setForeground(UpdateConstants.BAR_COLOR); @@ -184,6 +188,10 @@ public class CheckServiceDialog extends JDialog implements ActionListener { buttonPanel.add(progressBar, BorderLayout.CENTER); buttonPanel.add(syncButton, BorderLayout.EAST); } else { + if (!(jarConsistency && differentPlugins.isEmpty())) { + UILabel adviceLabel = new UILabel(Toolkit.i18nText("Fine-Design_Basic_Sync_Suggestion")); + centerPanel.add(adviceLabel, BorderLayout.SOUTH); + } UIButton okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Remote_Design_Button_Confirm")); okButton.addActionListener(this); buttonPanel.add(okButton, BorderLayout.EAST); @@ -194,6 +202,12 @@ public class CheckServiceDialog extends JDialog implements ActionListener { this.add(centerPanel, BorderLayout.CENTER); this.add(buttonPanel, BorderLayout.SOUTH); this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 750 : 600, 500)); + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + close(); + } + }); GUICoreUtils.centerWindow(this); } @@ -304,82 +318,89 @@ public class CheckServiceDialog extends JDialog implements ActionListener { } }; - private MouseListener syncButtonClickListener = new MouseAdapter() { + private ActionListener syncButtonActionListener = new ActionListener() { @Override - public void mouseClicked(MouseEvent e) { - ignoreButton.setEnabled(false); - syncButton.setEnabled(false); - String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")}; - if (!jarConsistency) { - int a = FineJOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Basic_Sync_Info_Information"), - Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, IOUtils.readIcon("com/fr/design/icon/versioncheck/question.png"), option, 1); - if (0 == a) { - progressBar.setVisible(true); - progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message")); - syncButton.setEnabled(false); - deletePreviousPropertyFile(); - final String installLib = StableUtils.pathJoin(StableUtils.getInstallHome(), ProjectConstants.LOGS_NAME, UpdateConstants.INSTALL_LIB); - final JFrame frame = DesignerContext.getDesignerFrame(); - final RestartHelper helper = new RestartHelper(); - FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY); - SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(frame, JSONArray.create()); - new SyncFileProcess(progressBar, remoteBuildNo, syncFailedPluginsDialog) { - @Override - public void onDownloadSuccess() { - deleteForDesignerUpdate(installLib); - progressBar.setVisible(false); - syncFailedPluginsDialog.showDialog(); - if (!syncFailedPluginsDialog.restartClicked()) { - helper.restartForUpdate(frame); - } - } + public void actionPerformed(ActionEvent e) { + sync(); + } + }; - @Override - public void onDownloadFailed() { - progressBar.setVisible(false); - deleteForDesignerUpdate(installLib); - ErrorDialog errorDialog = new ErrorDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Fail")); - errorDialog.setVisible(true); + private void sync() { + ignoreButton.setEnabled(false); + syncButton.setEnabled(false); + String[] option = {Toolkit.i18nText("Fine-Design_Report_Yes"), Toolkit.i18nText("Fine-Design_Report_No")}; + if (!jarConsistency) { + int a = FineJOptionPane.showOptionDialog(getParent(), Toolkit.i18nText("Fine-Design_Basic_Sync_Info_Information"), + Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, QUESTION_MESSAGE, IOUtils.readIcon("com/fr/design/icon/versioncheck/question.png"), option, 1); + if (0 == a) { + progressBar.setVisible(true); + progressBar.setString(Toolkit.i18nText("Fine-Design_Update_Info_Wait_Message")); + syncButton.setEnabled(false); + deletePreviousPropertyFile(); + final String installLib = StableUtils.pathJoin(StableUtils.getInstallHome(), ProjectConstants.LOGS_NAME, UpdateConstants.INSTALL_LIB); + final JFrame frame = DesignerContext.getDesignerFrame(); + final RestartHelper helper = new RestartHelper(); + FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY); + SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(frame, JSONArray.create()); + new SyncFileProcess(progressBar, remoteBuildNo, syncFailedPluginsDialog) { + @Override + public void onDownloadSuccess() { + deleteForDesignerUpdate(installLib); + progressBar.setVisible(false); + syncFailedPluginsDialog.showDialog(); + if (!syncFailedPluginsDialog.restartClicked()) { helper.restartForUpdate(frame); } - }.execute(); - } - } else { - //到这边说明主jar是一致的,就只尝试同步插件 - new SwingWorker() { - - @Override - protected JSONArray doInBackground() { - progressBar.setVisible(true); - progressBar.setString(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugins")); - progressBar.setValue(0); - return VersionCheckUtils.syncPlugins(differentPlugins); } @Override - protected void done() { + public void onDownloadFailed() { progressBar.setVisible(false); - JSONArray syncFailedPlugins = null; - try { - syncFailedPlugins = get(); - } catch (Exception ex) { - FineLoggerFactory.getLogger().error(ex.getMessage(), ex); - } - if (syncFailedPlugins != null && syncFailedPlugins.size() > 0) { - SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(DesignerContext.getDesignerFrame(), syncFailedPlugins); - syncFailedPluginsDialog.setVisible(true); - } else { - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), - Toolkit.i18nText("Fine-Design_Basic_Sync_Success"), - Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), - FineJOptionPane.INFORMATION_MESSAGE); - } - close(); + deleteForDesignerUpdate(installLib); + ErrorDialog errorDialog = new ErrorDialog(DesignerContext.getDesignerFrame(), Toolkit.i18nText("Fine-Design_Basic_Sync_Fail")); + errorDialog.setVisible(true); + helper.restartForUpdate(frame); } }.execute(); + } else { + ignoreButton.setEnabled(true); + syncButton.setEnabled(true); } + } else { + //到这边说明主jar是一致的,就只尝试同步插件 + new SwingWorker() { + + @Override + protected JSONArray doInBackground() { + progressBar.setVisible(true); + progressBar.setString(Toolkit.i18nText("Fine-Design_Basic_Sync_Plugins")); + progressBar.setValue(0); + return VersionCheckUtils.syncPlugins(differentPlugins); + } + + @Override + protected void done() { + progressBar.setVisible(false); + JSONArray syncFailedPlugins = null; + try { + syncFailedPlugins = get(); + } catch (Exception ex) { + FineLoggerFactory.getLogger().error(ex.getMessage(), ex); + } + if (syncFailedPlugins != null && syncFailedPlugins.size() > 0) { + SyncFailedPluginsDialog syncFailedPluginsDialog = new SyncFailedPluginsDialog(DesignerContext.getDesignerFrame(), syncFailedPlugins); + syncFailedPluginsDialog.setVisible(true); + } else { + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Sync_Success"), + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + FineJOptionPane.INFORMATION_MESSAGE); + } + close(); + } + }.execute(); } - }; + } private boolean deletePreviousPropertyFile() { File moveFile = new File(RestartHelper.MOVE_FILE); 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 a93ea0460d..8117f87395 100644 --- a/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java +++ b/designer-base/src/main/java/com/fr/env/SyncFailedPluginsDialog.java @@ -21,6 +21,8 @@ import java.awt.Dimension; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; import java.util.Locale; import javax.swing.BorderFactory; import javax.swing.Icon; @@ -96,6 +98,12 @@ public class SyncFailedPluginsDialog extends JDialog { this.setResizable(false); this.add(body, BorderLayout.CENTER); this.setSize(new Dimension(GeneralContext.getLocale().equals(Locale.US) ? 400 : 380, 225)); + this.addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent e) { + hideDialog(); + } + }); GUICoreUtils.centerWindow(this); } diff --git a/designer-base/src/main/resources/com/fr/design/images/control/aspect_ratio_lock.png b/designer-base/src/main/resources/com/fr/design/images/control/aspect_ratio_lock.png new file mode 100644 index 0000000000..b54cbbb18f Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/aspect_ratio_lock.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/aspect_ratio_unlock.png b/designer-base/src/main/resources/com/fr/design/images/control/aspect_ratio_unlock.png new file mode 100644 index 0000000000..f80a3d073e Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/aspect_ratio_unlock.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_e.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_e.png new file mode 100644 index 0000000000..650567ee91 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_e.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_n.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_n.png new file mode 100644 index 0000000000..1085265c0d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_n.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_ne.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_ne.png new file mode 100644 index 0000000000..8f8163a6fe Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_ne.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_nw.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_nw.png new file mode 100644 index 0000000000..af33c873df Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_nw.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_s.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_s.png new file mode 100644 index 0000000000..1085265c0d Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_s.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_se.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_se.png new file mode 100644 index 0000000000..af33c873df Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_se.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_sw.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_sw.png new file mode 100644 index 0000000000..8f8163a6fe Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_sw.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_w.png b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_w.png new file mode 100644 index 0000000000..650567ee91 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/control/icon_cursor_drag_w.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/transparent_background.jpg b/designer-base/src/main/resources/com/fr/design/images/transparent_background.jpg deleted file mode 100644 index b04da96ea6..0000000000 Binary files a/designer-base/src/main/resources/com/fr/design/images/transparent_background.jpg and /dev/null differ diff --git a/designer-chart/src/main/java/com/fr/design/chart/gui/ChartComponent.java b/designer-chart/src/main/java/com/fr/design/chart/gui/ChartComponent.java index 1a5088a272..1ce2fbffd9 100644 --- a/designer-chart/src/main/java/com/fr/design/chart/gui/ChartComponent.java +++ b/designer-chart/src/main/java/com/fr/design/chart/gui/ChartComponent.java @@ -43,6 +43,7 @@ public class ChartComponent extends MiddleChartComponent implements MouseListene public ChartComponent() { super(); + setOpaque(true); addMouseListener(this); addMouseMotionListener(this); } @@ -148,11 +149,12 @@ public class ChartComponent extends MiddleChartComponent implements MouseListene chartCollection4Design.setPredefinedStyleName(getGlobalPredefinedStyleName(), false); Graphics2D g2d = (Graphics2D) g; - Paint oldPaint = g2d.getPaint(); - - g2d.setPaint(Color.WHITE); - g2d.fillRect(0, 0, this.getBounds().width, this.getBounds().height); - g2d.setPaint(oldPaint); + if (this.isOpaque()) { + Paint oldPaint = g2d.getPaint(); + g2d.setPaint(Color.WHITE); + g2d.fillRect(0, 0, this.getBounds().width, this.getBounds().height); + g2d.setPaint(oldPaint); + } g2d.translate(ChartConstants.PREGAP4BOUNDS/2, ChartConstants.PREGAP4BOUNDS/2); diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java index 4b3147c0ab..e4426f61ad 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/adapters/layout/FRAbsoluteLayoutAdapter.java @@ -9,6 +9,7 @@ import com.fr.design.designer.properties.BoundsGroupModel; import com.fr.design.designer.properties.FRAbsoluteLayoutPropertiesGroupModel; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; +import com.fr.form.ui.Widget; import com.fr.form.ui.container.WAbsoluteLayout; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; @@ -295,6 +296,12 @@ public class FRAbsoluteLayoutAdapter extends FRBodyLayoutAdapter { */ @Override public void fix(XCreator creator) { + Widget widget = creator.toData(); + Rectangle bounds = creator.getBounds(); + if (widget != null && widget.isAspectRatioLocked() && (bounds.width == 0 || bounds.height == 0)) { + widget.setAspectRatioLocked(false); + widget.setAspectRatioBackup(-1.0); + } WAbsoluteLayout wabs = (WAbsoluteLayout)container.toData(); fix(creator,creator.getX(),creator.getY()); wabs.setBounds(creator.toData(),creator.getBounds()); 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 a1c9f1ff9f..58f58c0758 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 @@ -86,9 +86,15 @@ public class DesignerEditor implements PropertyChangeListe int horizonMargin = marginLeft + marginRight; int verticalMargin = marginTop + marginBottom; - comp.setSize(new Dimension(size.width - 2 - horizonMargin, size.height - 2 - verticalMargin)); + int x = 1 + marginLeft; + int y = 1 + marginTop; + int width = size.width - 2 - horizonMargin; + int height = size.height - 2 - verticalMargin; + + comp.setSize(new Dimension(width, height)); LayoutUtils.layoutContainer(comp); - Graphics clipg = g.create(1 + marginLeft, 1 + marginTop, size.width, size.height); + comp.setBounds(comp.getX() + x - 1, comp.getY() + y - 1, width, height); + Graphics clipg = g.create(x, y, width, height); this.comp.paint(clipg); } } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XAutoChartCreator.java b/designer-form/src/main/java/com/fr/design/designer/creator/XAutoChartCreator.java index ec132a206d..4c5b669b48 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XAutoChartCreator.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XAutoChartCreator.java @@ -18,8 +18,7 @@ import com.fr.stable.bridge.StableFactory; import javax.swing.JComponent; import javax.swing.JPanel; -import java.awt.Dimension; -import java.awt.Graphics; +import java.awt.*; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; @@ -102,7 +101,8 @@ public class XAutoChartCreator extends XChartEditor { } - public void paint(Graphics g) { + @Override + public void paintForeground(Graphics2D g) { BufferedImage bufferedImage = IOUtils.readImage("com/fr/design/form/images/auto_chart_preview.png"); GraphHelper.paintImage( g, this.getWidth(), this.getHeight(), bufferedImage, @@ -110,7 +110,7 @@ public class XAutoChartCreator extends XChartEditor { 0, 0, -1, -1 ); - super.paint(g); + super.paintForeground(g); } private void initChart(BaseChartCollection chartCollection) { 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 fc40b1d123..645f38706e 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 @@ -194,13 +194,14 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ titleCreator.setBorder(new BottomLineBorder(color, thickness)); } - if (bodyXCreator instanceof XBorderStyleWidgetCreator) { - XBorderStyleWidgetCreator styledBodyXCreator = (XBorderStyleWidgetCreator) bodyXCreator; - Background background4Painting = styledBodyXCreator.getBackground4Painting(); - - styledBodyXCreator.setBackground4Painting(null); // body不绘制背景 - titleParent.setBackground4Painting(background4Painting); // 容器绘制完整背景 - } + // 主体背景的生效范围暂时保持原样,不作用于包含标题区域的整体范围内 +// if (bodyXCreator instanceof XBorderStyleWidgetCreator) { +// XBorderStyleWidgetCreator styledBodyXCreator = (XBorderStyleWidgetCreator) bodyXCreator; +// Background background4Painting = styledBodyXCreator.getBackground4Painting(); +// +// styledBodyXCreator.setBackground4Painting(null); // body不绘制背景 +// titleParent.setBackground4Painting(background4Painting); // 容器绘制完整背景 +// } } } } @@ -222,24 +223,27 @@ public class XBorderStyleWidgetCreator extends XWidgetCreator{ } // 设计器预览界面中绘制组件背景效果 - private void paintBackground(Graphics2D g2d) { + public void paintBackground(Graphics2D g2d) { Background background4Painting = getBackground4Painting(); if (background4Painting != null) { + BorderPacker style = toData().getBorderStyle(); + Composite oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, style.getAlpha())); background4Painting.paint(g2d, new Rectangle2D.Double(0, 0, getWidth(), getHeight())); + g2d.setComposite(oldComposite); } } - @Override - protected void paintComponent(Graphics g) { - this.paintBackground((Graphics2D) g); - super.paintComponent(g); + public void paintForeground(Graphics2D g2d) { + super.paint(g2d); + super.paintBorder(g2d); } @Override public void paint(Graphics g) { this.clipByRoundedBorder((Graphics2D) g); - super.paint(g); - paintBorder(g); + this.paintBackground((Graphics2D) g); + this.paintForeground((Graphics2D) g); } @Override 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 2e9b3e23a4..ad328b85e7 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 @@ -29,12 +29,8 @@ import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.SwingUtilities; +import java.awt.*; import java.beans.IntrospectionException; -import java.awt.Color; -import java.awt.Cursor; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Rectangle; import java.awt.event.MouseEvent; /** @@ -150,6 +146,9 @@ public class XChartEditor extends XBorderStyleWidgetCreator { if (isEditing) { g.setColor(OUTER_BORDER_COLOR); GraphHelper.draw(g, new Rectangle(bounds.x - BORDER_WIDTH, bounds.y - BORDER_WIDTH, bounds.width + BORDER_WIDTH + 1, bounds.height + BORDER_WIDTH + 1), Constants.LINE_LARGE); + + g.setColor(INNER_BORDER_COLOR); + GraphHelper.draw(g, new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height), Constants.LINE_MEDIUM); } else if (!isHovering) { super.paintBorder(g, bounds); } @@ -228,16 +227,19 @@ public class XChartEditor extends XBorderStyleWidgetCreator { /** * 渲染Painter */ - public void paint(Graphics g) { + @Override + public void paintForeground(Graphics2D g) { Dimension size = getSize(); PaddingMargin margin = toData().getMargin(); + designerEditor.paintEditor(g, size, margin); + if (coverPanel != null) { int horizonMargin = margin != null ? margin.getLeft() + margin.getRight() : 0; int verticalMargin = margin != null ? margin.getTop() + margin.getBottom() : 0; coverPanel.setSize(size.width - horizonMargin, size.height - verticalMargin); } - super.paint(g); + super.paintForeground(g); if (isEditing) { g.setColor(INNER_BORDER_COLOR); GraphHelper.draw(g, new Rectangle(0, 0, getWidth(), getHeight()), Constants.LINE_MEDIUM); @@ -289,6 +291,7 @@ public class XChartEditor extends XBorderStyleWidgetCreator { final MiddleChartComponent chartComponent = DesignModuleFactory.getChartComponent(((BaseChartEditor) data).getChartCollection()); if (chartComponent != null) { JComponent jChart = chartComponent; + chartComponent.setOpaque(false); jChart.setBorder(BorderFactory.createLineBorder(Color.lightGray)); designerEditor = new DesignerEditor(jChart); chartComponent.addStopEditingListener(designerEditor); 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 0983dded9b..dbc956c857 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 @@ -23,6 +23,7 @@ import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.NoSupportAuthorityEdit; import com.fr.design.mainframe.WidgetPropertyPane; +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; @@ -33,6 +34,7 @@ import com.fr.stable.StringUtils; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPanel; +import javax.swing.SwingUtilities; import javax.swing.border.Border; import java.awt.BorderLayout; import java.awt.Color; @@ -776,10 +778,23 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo } int extraX = (int) ((bounds.x + bounds.width + SelectedPopupDialog.OFFSET_X) * designer.getScale()); int extraY = (int) (bounds.y * designer.getScale()); - popup.setLocation(designer.getLocationOnScreen().x + designer.getPaintX() + extraX, designer.getLocationOnScreen().y + designer.getPaintY() + extraY); - popup.updatePane(designer); - popup.setVisible(selected && accept); - popup.setRelativeBounds(bounds); + // 放到事件尾部执行 + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + popup.setLocation(designer.getLocationOnScreen().x + designer.getPaintX() + extraX, designer.getLocationOnScreen().y + designer.getPaintY() + extraY); + popup.updatePane(designer); + popup.setVisible(selected && accept && popup.hasVisibleButtons() && popup.isCanVisible() && !isShowPluginDialog()); + popup.setRelativeBounds(bounds); + } + }); + } + + private boolean isShowPluginDialog() { + if (DesignerPluginContext.getPluginDialog() == null) { + return false; + } + return DesignerPluginContext.getPluginDialog().isVisible(); } /** @@ -830,4 +845,16 @@ public abstract class XCreator extends JPanel implements XComponent, XCreatorToo } } + public void hidePopup() { + if (popup != null) { + popup.setVisible(false); + } + } + + public void processPopup(boolean canVisible) { + if (popup != null) { + popup.setCanVisible(canVisible); + } + } + } 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 7ed22c52dd..b5cc813ae8 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 @@ -41,7 +41,7 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme static { try { - DEFAULT_BACKGROUND = BaseUtils.readImageWithCache("com/fr/base/images/report/elementcase.png"); + DEFAULT_BACKGROUND = BaseUtils.readImageWithCache("com/fr/base/images/report/elementcase_translucent.png"); } catch (Throwable e) { //IBM jdk 1.5.0_22 并发下读取图片有时会异常(EOFException), 这个图片反正只有设计器用到, 捕获住 DEFAULT_BACKGROUND = CoreGraphHelper.createBufferedImage(0, 0); @@ -183,7 +183,8 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme if (editor == null) { setBorder(DEFALUTBORDER); editor = new JPanel(); - editor.setBackground(null); + editor.setOpaque(false); + editor.setBackground(new Color(0, 0, 0, 0)); editor.setLayout(null); imageLable = initImageBackground(); @@ -218,7 +219,8 @@ public class XElementCase extends XBorderStyleWidgetCreator implements FormEleme private void setLabelBackground(Image image, UILabel imageLable) { ImageIcon icon = new ImageIcon(image); imageLable.setIcon(icon); - imageLable.setOpaque(true); + imageLable.setOpaque(false); + imageLable.setBackground(new Color(0, 0, 0, 0)); imageLable.setLayout(null); imageLable.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight()); } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java b/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java index 154091a296..13358f2b20 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XLabel.java @@ -19,6 +19,7 @@ import com.fr.form.ui.Label; import com.fr.form.ui.container.WParameterLayout; import com.fr.general.Background; +import com.fr.general.act.BorderPacker; import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; import com.fr.stable.core.PropertyChangeAdapter; @@ -91,8 +92,13 @@ public class XLabel extends XWidgetCreator { Label label = (Label) data; Dimension size = this.getSize(); //先画背景,再画标题 - if (toData().getBackground() != null) { - toData().getBackground().paint(g, new Rectangle2D.Double(0, 0, size.getWidth(), size.getHeight())); + Background background = label.getBackground(); + if (background != null) { + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, label.getBackgroundOpacity())); + background.paint(g, new Rectangle2D.Double(0, 0, size.getWidth(), size.getHeight())); + g2d.setComposite(oldComposite); } if (label.getWidgetValue() != null) { Graphics2D g2d = (Graphics2D) g.create(); 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 c6d0067c3a..44d1588dfa 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 @@ -386,7 +386,18 @@ public class XWAbsoluteLayout extends XLayoutContainer { if (!creator.acceptType(XWFitLayout.class)) { creator.setDirections(Direction.ALL); } - wabs.addWidget(new BoundsWidget(creator.toData(), creator.getBounds())); + Widget wgt = creator.toData(); + if (wgt != null && wgt.isAspectRatioLocked() && wgt.getAspectRatioBackup() <= 0) { + // 将比例锁定的组件重新移会绝对布局内时(如body修改绝对布局),尺寸比例可能失效,需要重新计算 + Rectangle bounds = creator.getBounds(); + if (bounds.width > 0 && bounds.height > 0) { + wgt.setAspectRatioBackup(1.0 * bounds.width / bounds.height); + } else { + wgt.setAspectRatioLocked(false); + wgt.setAspectRatioBackup(-1); + } + } + wabs.addWidget(new BoundsWidget(wgt, creator.getBounds())); } /** @@ -402,6 +413,11 @@ public class XWAbsoluteLayout extends XLayoutContainer { WAbsoluteLayout wlayout = this.toData(); XWidgetCreator xwc = ((XWidgetCreator) e.getChild()); Widget wgt = xwc.toData(); + + // 将比例锁定的组件重新移出绝对布局时(如body修改为自适应布局),锁定的尺寸比例失效 + if (wgt != null) { + wgt.setAspectRatioBackup(-1.0); + } BoundsWidget bw = new BoundsWidget(wgt, xwc.getBounds()); wlayout.removeWidget(bw); } @@ -447,10 +463,7 @@ public class XWAbsoluteLayout extends XLayoutContainer { super.paint(g); //如果鼠标移动到布局内且布局不可编辑,画出编辑蒙层 if (isMouseEnter && !this.editable) { - CoverReportPane.paintEditButton(g, this); - if (isShared()) { - CoverReportPane.paintShareButton(g, this); - } + CoverReportPane.paintCover(g, this); } } 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 896cbe37c5..cd0919d593 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 @@ -758,6 +758,11 @@ public class XWFitLayout extends XLayoutContainer { int[] veris = getVeris(true); int containerWidth = 0; int containerHeight = 0; + + PaddingMargin margin = toData().getMargin(); + int maxW = this.getWidth() - margin.getRight(); + int maxH = this.getHeight() - margin.getBottom(); + for (int index=0, n=this.getComponentCount(); index 0 && bounds.height > 0) { + widget.setAspectRatioLocked(true); + widget.setAspectRatioBackup(1.0 * bounds.width / bounds.height); + } else { + widget.setAspectRatioLocked(false); + widget.setAspectRatioBackup(-1.0); + } + } designer.getEditListenerTable().fireCreatorModified(creator, DesignerEvent.CREATOR_RESIZED); } }); @@ -139,7 +153,7 @@ public class PopupControlPanel extends JPanel { if (index > 0) { getComponent(2 * index - 1).setVisible(false); } - buttons.get(index).setVisible(true); + buttons.get(index).setVisible(visible); if (!visible) { // 如果当前按钮设置为不可见,且在当前按钮之前的其他按钮也不可见,则下一个可见按钮前无分割线 @@ -192,6 +206,7 @@ public class PopupControlPanel extends JPanel { } public void updatePane(FormDesigner designer) { + setButtonVisible(editButton, creator.acceptType(XWTitleLayout.class, XWCardMainBorderLayout.class) || creator.getClass().equals(XWAbsoluteLayout.class)); setButtonVisible(settingButton, creator.isShared()); setButtonVisible(toggleButton, AdapterBus.searchLayoutAdapter(designer, creator) instanceof FRAbsoluteLayoutAdapter); toggleButton.setSelected(creator.toData().isAspectRatioLocked()); @@ -199,6 +214,15 @@ public class PopupControlPanel extends JPanel { updateDimension(); } + public boolean hasVisibleButtons() { + for (int i = 0; i < buttons.size(); i++) { + if (buttons.get(i).isVisible()) { + return true; + } + } + return false; + } + private void updateDimension() { int height = 0; for (int i = 0; i < buttons.size(); i++) { diff --git a/designer-form/src/main/java/com/fr/design/designer/ui/SelectedPopupDialog.java b/designer-form/src/main/java/com/fr/design/designer/ui/SelectedPopupDialog.java index 6702fe7f42..44978ad667 100644 --- a/designer-form/src/main/java/com/fr/design/designer/ui/SelectedPopupDialog.java +++ b/designer-form/src/main/java/com/fr/design/designer/ui/SelectedPopupDialog.java @@ -3,8 +3,11 @@ package com.fr.design.designer.ui; import com.fr.design.designer.creator.XCreator; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.FormDesigner; +import com.fr.stable.os.OperatingSystem; + import java.awt.Rectangle; import javax.swing.JDialog; +import javax.swing.JFrame; /** * @author hades @@ -20,10 +23,13 @@ public class SelectedPopupDialog extends JDialog { private final PopupControlPanel controlPanel; + private boolean canVisible = true; + public SelectedPopupDialog(XCreator creator, FormDesigner designer) { - super(DesignerContext.getDesignerFrame()); + super(OperatingSystem.isMacos() ? new JFrame() : DesignerContext.getDesignerFrame()); this.setUndecorated(true); this.setModal(false); + this.setFocusableWindowState(false); controlPanel = new PopupControlPanel(creator, designer); this.getContentPane().add(controlPanel); this.setSize(controlPanel.getDefaultDimension()); @@ -34,8 +40,19 @@ public class SelectedPopupDialog extends JDialog { this.setSize(controlPanel.getDefaultDimension()); } + public boolean hasVisibleButtons() { + return controlPanel.hasVisibleButtons(); + } + public void setRelativeBounds(Rectangle rectangle) { this.controlPanel.setRelativeBounds(rectangle); } + public boolean isCanVisible() { + return canVisible; + } + + public void setCanVisible(boolean canVisible) { + this.canVisible = canVisible; + } } diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java index fcd9ed0103..324213bc3d 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/BorderLineAndImagePane.java @@ -37,18 +37,33 @@ import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.stable.project.ProjectConstants; -import javax.swing.*; +import javax.swing.BorderFactory; +import javax.swing.JComponent; +import javax.swing.JFileChooser; +import javax.swing.JPanel; +import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.plaf.basic.BasicButtonUI; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Desktop; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.FontMetrics; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Point; +import java.awt.Toolkit; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; +import java.awt.geom.Line2D; import java.awt.geom.RoundRectangle2D; -import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.net.URI; @@ -65,7 +80,7 @@ import java.util.Arrays; public class BorderLineAndImagePane extends JPanel implements UIObserver { private final int SETTING_LABEL_WIDTH = LayoutStylePane.SETTING_LABEL_WIDTH; private final Style DEFAULT_IMAGE_LAYOUT_STYLE = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_DEFAULT); - private final String TWEAK_NINE_POINT_HELP_URL = ""; + private final String TWEAK_NINE_POINT_HELP_URL = "https://help.fanruan.com/finereport/doc-view-4135.html"; private UIObserverListener uiObserverListener; @@ -415,18 +430,11 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { private void initComponents() { setLayout(new BorderLayout()); - setBorder(BorderFactory.createTitledBorder(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Border_Image_Config_Nine_Point_Fill_Preview"))); + setBorder(BorderFactory.createEmptyBorder()); + add(previewPane, BorderLayout.CENTER); - JPanel content = FRGUIPaneFactory.createBorderLayout_S_Pane(); - content.setBorder(BorderFactory.createEmptyBorder( - IntervalConstants.INTERVAL_W1, - IntervalConstants.INTERVAL_W1, - IntervalConstants.INTERVAL_W1, - IntervalConstants.INTERVAL_W1)); - content.add(previewPane); - previewPane.setPreferredSize(new Dimension(611, 457)); - - add(content, BorderLayout.CENTER); + previewPane.setPreferredSize(new Dimension(615, 462)); + previewPane.setBorder(BorderFactory.createEmptyBorder()); } @Override @@ -436,27 +444,61 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { } private class NinePointLinePreviewPane extends JPanel implements MouseMotionListener, MouseListener { - private final BufferedImage transparentImage = IOUtils.readImage("/com/fr/design/images/transparent_background.jpg"); - - public final Color PATCH_COLOR = new Color(0, 0, 0, 38); - public final Color DIVIDER_COLOR = new Color(250, 250, 250); - public final Color TEXT_COLOR = Color.WHITE; - public final int PADDING = 15; + public final Color BACKGROUND_PANE_COLOR = Color.WHITE; + public final Color BACKGROUND_IMG_COLOR = Color.lightGray; + public final Color DIVIDER_BACKGROUND_COLOR = new Color(235, 29, 31); + public final Color DIVIDER_FOREGROUND_COLOR = Color.WHITE; + public final Color HINT_BACKGROUND_COLOR = new Color(0, 215, 215); + public final Color HINT_FOREGROUND_COLOR = Color.WHITE; + public final int HINT_GAP = 5; + public final int PADDING = 20; + public final Cursor E_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_e.png"), + new Point(8, 8), "E_DRAG_CURSOR"); + public final Cursor S_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_s.png"), + new Point(8, 8), "S_DRAG_CURSOR"); + public final Cursor W_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_w.png"), + new Point(8, 8), "W_DRAG_CURSOR"); + public final Cursor N_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_n.png"), + new Point(8, 8), "N_DRAG_CURSOR"); + public final Cursor NE_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_ne.png"), + new Point(8, 8), "NE_DRAG_CURSOR"); + public final Cursor NW_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_nw.png"), + new Point(8, 8), "NW_DRAG_CURSOR"); + public final Cursor SE_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_se.png"), + new Point(8, 8), "SE_DRAG_CURSOR"); + public final Cursor SW_DRAG_CURSOR = Toolkit.getDefaultToolkit().createCustomCursor( + IOUtils.readImage("/com/fr/design/images/control/icon_cursor_drag_sw.png"), + new Point(8, 8), "SW_DRAG_CURSOR"); private int ninePointLeft = -1; private int ninePointTop = -1; private int ninePointRight = -1; private int ninePointBottom = -1; + private static final int MIN_NINE_POINT = 0; + private int imgWidth; private int imgHeight; private int scaleImgWidth; private int scaleImgHeight; private int scaleImgX; private int scaleImgY; - private double scale = 1.0; + private double imageScale = 1.0; + + private boolean draggingLeftDivider = false; + private boolean draggingRightDivider = false; + private boolean draggingTopDivider = false; + private boolean draggingBottomDivider = false; public NinePointLinePreviewPane() { + this.setLayout(null); this.addMouseMotionListener(this); this.addMouseListener(this); } @@ -466,7 +508,9 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g; - g2d.drawImage(transparentImage, 0, 0, getWidth(), getHeight(), null); + + g2d.setColor(BACKGROUND_PANE_COLOR); + g2d.fillRect(0, 0, getWidth(), getHeight()); Image image = imagePreviewPane.getImage(); @@ -482,49 +526,115 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { scaleImgHeight = (int) (1.0F * scaleImgWidth * imgHeight / imgWidth); scaleImgX = autoFixAreaX; scaleImgY = (autoFixAreaHeight - scaleImgHeight) / 2 + autoFixAreaY; // 垂直居中 - scale = 1.0 * scaleImgWidth / imgWidth; + imageScale = 1.0 * scaleImgWidth / imgWidth; } else { scaleImgHeight = autoFixAreaHeight; scaleImgWidth = (int) (1.0F * scaleImgHeight * imgWidth / imgHeight); scaleImgX = (autoFixAreaWidth - scaleImgWidth) / 2 + autoFixAreaX; // 水平居中 scaleImgY = autoFixAreaY; - scale = 1.0 * scaleImgHeight / imgHeight; + imageScale = 1.0 * scaleImgHeight / imgHeight; } + g2d.setColor(BACKGROUND_IMG_COLOR); + g2d.fillRect(scaleImgX, scaleImgY, scaleImgWidth, scaleImgHeight); g2d.drawImage(image, scaleImgX, scaleImgY, scaleImgWidth, scaleImgHeight, null); - int scaleLeft = (int) (ninePointLeft * scale); - int scaleTop = (int) (ninePointTop * scale); - int scaleRight = (int) (ninePointRight * scale); - int scaleBottom = (int) (ninePointBottom * scale); + int scaleLeft = (int) (ninePointLeft * imageScale); + int scaleTop = (int) (ninePointTop * imageScale); + int scaleRight = (int) (ninePointRight * imageScale); + int scaleBottom = (int) (ninePointBottom * imageScale); double topYInPane = scaleImgY + scaleTop; double bottomYInPane = scaleImgY + scaleImgHeight - scaleBottom; double leftXInPane = scaleImgX + scaleLeft; double rightXInPane = scaleImgX + scaleImgWidth - scaleRight; - g2d.setColor(PATCH_COLOR); - // draw horizontal patch - GraphDrawHelper.fillRect(g2d, 0, topYInPane, getWidth(), scaleImgHeight - scaleTop - scaleBottom); - // draw vertical patch - GraphDrawHelper.fillRect(g2d, scaleImgX + scaleLeft, 0,scaleImgWidth - scaleLeft - scaleRight, getHeight()); - - g2d.setColor(DIVIDER_COLOR); - // draw top divider - GraphDrawHelper.drawLine(g2d, 0, topYInPane, getWidth(), topYInPane); - // draw bottom divider - GraphDrawHelper.drawLine(g2d, 0, bottomYInPane, getWidth(), bottomYInPane); - // draw left divider - GraphDrawHelper.drawLine(g2d, leftXInPane, 0, leftXInPane, getHeight()); - // draw right divider - GraphDrawHelper.drawLine(g2d, rightXInPane, 0, rightXInPane, getHeight()); - - g2d.setColor(TEXT_COLOR); - // draw nine point info - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointTop), (leftXInPane + rightXInPane) / 2.0F, topYInPane / 2.0); - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointBottom), (leftXInPane + rightXInPane) / 2.0F, (bottomYInPane + getHeight()) / 2.0); - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointLeft), leftXInPane / 2.0, (topYInPane + bottomYInPane) / 2.0); - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointRight), (rightXInPane + getWidth()) / 2.0, (topYInPane + bottomYInPane) / 2.0); + // 顶部分割线 + drawDivider(g2d, scaleImgX, topYInPane, scaleImgX + scaleImgWidth, topYInPane, draggingTopDivider); + if (draggingTopDivider) { + // 顶部提示 + drawHint(g2d, ninePointTop + "px", leftXInPane, scaleImgY, scaleImgWidth - scaleLeft - scaleRight, scaleTop, false); + } + // 底部分割线 + drawDivider(g2d, scaleImgX, bottomYInPane, scaleImgX + scaleImgWidth, bottomYInPane, draggingBottomDivider); + if (draggingBottomDivider) { + // 底部提示 + drawHint(g2d, ninePointBottom + "px", leftXInPane, bottomYInPane, scaleImgWidth - scaleLeft - scaleRight, scaleBottom, false); + } + // 左侧分割线 + drawDivider(g2d, leftXInPane, scaleImgY, leftXInPane, scaleImgY + scaleImgHeight, draggingLeftDivider); + if (draggingLeftDivider) { + // 左侧提示 + drawHint(g2d, ninePointLeft + "px", scaleImgX, topYInPane, scaleLeft, scaleImgHeight - scaleTop - scaleBottom, true); + } + // 右侧分割线 + drawDivider(g2d, rightXInPane, scaleImgY, rightXInPane, scaleImgY + scaleImgHeight, draggingRightDivider); + if (draggingRightDivider) { + // 右侧提示 + drawHint(g2d, ninePointRight + "px", rightXInPane, topYInPane, scaleRight, scaleImgHeight - scaleTop - scaleBottom, true); + } + } + + private void drawHint(Graphics2D g2d, String hint, double x, double y, double width, double height, boolean horizontal) { + FontMetrics metrics = GraphDrawHelper.getFontMetrics(g2d.getFont()); + double hintTextHeight = Math.max(metrics.getAscent() + metrics.getDescent(), 16); + double hintTextWidth = Math.max(metrics.stringWidth(hint), metrics.stringWidth("123")); + double hintFrameRadius = hintTextHeight / 2; + double hintFrameHeight = hintTextHeight; + double hintFrameWidth = hintTextWidth + 2 * hintFrameRadius; + + double centerX = x + width / 2; + double centerY = y + height / 2; + + double indent = 1.0; + double shortLine = 4.0; + + if (horizontal) { + if (width > hintFrameWidth) { + g2d.setColor(HINT_BACKGROUND_COLOR); + GraphDrawHelper.draw(g2d, new Line2D.Double(x + indent, centerY, x + width - indent, centerY), Constants.LINE_THIN, 1.0F); + GraphDrawHelper.draw(g2d, new Line2D.Double(x + indent, centerY - shortLine, x + indent, centerY + shortLine), Constants.LINE_THIN, 1.0F); + GraphDrawHelper.draw(g2d, new Line2D.Double(x + width - indent, centerY - shortLine, x + width - indent, centerY + shortLine), Constants.LINE_THIN, 1.0F); + } + + double hintFrameX = centerX - hintFrameWidth / 2; + double hintFrameY = centerY + HINT_GAP; + + g2d.setColor(HINT_BACKGROUND_COLOR); + GraphDrawHelper.fill(g2d, new RoundRectangle2D.Double(hintFrameX, hintFrameY, hintFrameWidth, hintFrameHeight, hintFrameRadius * 2, hintFrameRadius * 2)); + + g2d.setColor(HINT_FOREGROUND_COLOR); + GraphDrawHelper.drawString(g2d, hint, hintFrameX + (hintFrameWidth - hintTextWidth) / 2, hintFrameY + (hintFrameHeight + hintTextHeight) / 2.0 - metrics.getDescent()); + } else { + if (height > hintFrameHeight) { + g2d.setColor(HINT_BACKGROUND_COLOR); + GraphDrawHelper.draw(g2d, new Line2D.Double(centerX, y + indent, centerX, y + height - indent), Constants.LINE_THIN, 1.0F); + GraphDrawHelper.draw(g2d, new Line2D.Double(centerX - shortLine, y + indent, centerX + shortLine, y + indent), Constants.LINE_THIN, 1.0F); + GraphDrawHelper.draw(g2d, new Line2D.Double(centerX - shortLine, y + height - indent, centerX + shortLine, y + height - indent), Constants.LINE_THIN, 1.0F); + } + + double hintFrameX = centerX + HINT_GAP; + double hintFrameY = centerY - hintFrameHeight / 2; + + g2d.setColor(HINT_BACKGROUND_COLOR); + GraphDrawHelper.fill(g2d, new RoundRectangle2D.Double(hintFrameX, hintFrameY, hintFrameWidth, hintFrameHeight, hintFrameRadius * 2, hintFrameRadius * 2)); + + g2d.setColor(HINT_FOREGROUND_COLOR); + GraphDrawHelper.drawString(g2d, hint, hintFrameX + (hintFrameWidth - hintTextWidth) / 2, hintFrameY + (hintFrameHeight + hintTextHeight) / 2.0 - metrics.getDescent()); + } + } + + private void drawDivider(Graphics2D g2d, double x1, double y1, double x2, double y2, boolean dragging) { + if (dragging) { + g2d.setColor(DIVIDER_BACKGROUND_COLOR); + GraphDrawHelper.draw(g2d, new Line2D.Double(x1, y1, x2, y2), Constants.LINE_THIN, 2.0F); + + g2d.setColor(DIVIDER_FOREGROUND_COLOR); + GraphDrawHelper.draw(g2d, new Line2D.Double(x1, y1, x2, y2), Constants.LINE_THIN, 1.0F); + } else { + g2d.setColor(DIVIDER_BACKGROUND_COLOR); + GraphDrawHelper.draw(g2d, new Line2D.Double(x1, y1, x2, y2), Constants.LINE_DASH, 1.0F); + } } @Override @@ -532,40 +642,22 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { int x = e.getX(); int y = e.getY(); - int cursorType = getCursor().getType(); + Cursor cursor = getCursor(); - switch (cursorType) { - case Cursor.W_RESIZE_CURSOR: { - int nextLeft = (int) ((x - scaleImgX) / scale); - if (1 <= nextLeft && nextLeft < imgWidth - ninePointRight) { - ninePointLeft = nextLeft; - repaint(); - } - return; - } - case Cursor.E_RESIZE_CURSOR: { - int nextRight = (int) ((scaleImgX + scaleImgWidth - x) / scale); - if (1 <= nextRight && nextRight < imgWidth - ninePointLeft) { - ninePointRight = nextRight; - repaint(); - } - return; - } - case Cursor.N_RESIZE_CURSOR: { - int nextTop = (int) ((y - scaleImgY) / scale); - if (1 <= nextTop && nextTop < imgHeight - ninePointBottom) { - ninePointTop = nextTop; - repaint(); - } - return; - } - case Cursor.S_RESIZE_CURSOR: { - int nextBottom = (int) ((scaleImgY + scaleImgHeight - y) / scale); - if (1 <= nextBottom && nextBottom < imgHeight - ninePointTop) { - ninePointBottom = nextBottom; - repaint(); - } - } + if (cursor == W_DRAG_CURSOR || cursor == NW_DRAG_CURSOR || cursor == SW_DRAG_CURSOR) { + int nextLeft = (int) ((x - scaleImgX) / imageScale); + this.onNinePointLeftChanged(nextLeft); + } else if (cursor == E_DRAG_CURSOR || cursor == NE_DRAG_CURSOR || cursor == SE_DRAG_CURSOR) { + int nextRight = (int) ((scaleImgX + scaleImgWidth - x) / imageScale); + this.onNinePointRightChanged(nextRight); + } + + if (cursor == N_DRAG_CURSOR || cursor == NE_DRAG_CURSOR || cursor == NW_DRAG_CURSOR) { + int nextTop = (int) ((y - scaleImgY) / imageScale); + this.onNinePointTopChanged(nextTop); + } else if (cursor == S_DRAG_CURSOR || cursor == SE_DRAG_CURSOR || cursor == SW_DRAG_CURSOR) { + int nextBottom = (int) ((scaleImgY + scaleImgHeight - y) / imageScale); + this.onNinePointBottomChanged(nextBottom); } } @@ -576,31 +668,51 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { int x = e.getX(); int y = e.getY(); - double scaleLeft = ninePointLeft * scale; - double scaleTop = ninePointTop * scale; - double scaleRight = ninePointRight * scale; - double scaleBottom = ninePointBottom * scale; + double scaleLeft = ninePointLeft * imageScale; + double scaleTop = ninePointTop * imageScale; + double scaleRight = ninePointRight * imageScale; + double scaleBottom = ninePointBottom * imageScale; // determine cursor - int cursorType = Cursor.DEFAULT_CURSOR; - - boolean hoveringLeftDivider = Math.abs(x - (scaleImgX + scaleLeft)) < 2; - boolean hoveringRightDivider = Math.abs(x - (scaleImgX + scaleImgWidth - scaleRight)) < 2; - boolean hoveringTopDivider = Math.abs(y - (scaleImgY + scaleTop)) < 2; - boolean hoveringBottomDivider = Math.abs(y - (scaleImgY + scaleImgHeight - scaleBottom)) < 2; + Cursor cursor = Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR); + + boolean hoveringLeftDivider = false; + boolean hoveringRightDivider = false; + boolean hoveringTopDivider = false; + boolean hoveringBottomDivider = false; + + if (scaleImgX - 2 <= x && x <= scaleImgX + scaleImgWidth + 2 && scaleImgY - 2 <= y && y <= scaleImgY + scaleImgHeight + 2) { + hoveringLeftDivider = Math.abs(x - (scaleImgX + scaleLeft)) < 2; + hoveringRightDivider = Math.abs(x - (scaleImgX + scaleImgWidth - scaleRight)) < 2; + hoveringTopDivider = Math.abs(y - (scaleImgY + scaleTop)) < 2; + hoveringBottomDivider = Math.abs(y - (scaleImgY + scaleImgHeight - scaleBottom)) < 2; + } - if (hoveringLeftDivider) { - cursorType = Cursor.W_RESIZE_CURSOR; + if (hoveringLeftDivider && hoveringTopDivider) { + cursor = NW_DRAG_CURSOR; + } else if (hoveringLeftDivider && hoveringBottomDivider) { + cursor = SW_DRAG_CURSOR; + } else if (hoveringRightDivider && hoveringTopDivider) { + cursor = NE_DRAG_CURSOR; + } else if (hoveringRightDivider && hoveringBottomDivider) { + cursor = SE_DRAG_CURSOR; + } else if (hoveringLeftDivider) { + cursor = W_DRAG_CURSOR; } else if (hoveringRightDivider) { - cursorType = Cursor.E_RESIZE_CURSOR; + cursor = E_DRAG_CURSOR; } else if (hoveringTopDivider) { - cursorType = Cursor.N_RESIZE_CURSOR; + cursor = N_DRAG_CURSOR; } else if (hoveringBottomDivider) { - cursorType = Cursor.S_RESIZE_CURSOR; + cursor = S_DRAG_CURSOR; } - needRepaint = getCursor().getType() != cursorType; - this.setCursor(Cursor.getPredefinedCursor(cursorType)); + draggingLeftDivider = hoveringLeftDivider; + draggingRightDivider = hoveringRightDivider; + draggingTopDivider = hoveringTopDivider; + draggingBottomDivider = hoveringBottomDivider; + + needRepaint = getCursor() != cursor; + this.setCursor(cursor); if (needRepaint) { repaint(); @@ -609,7 +721,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { @Override public void mouseClicked(MouseEvent e) { - + requestFocus(); } @Override @@ -620,6 +732,10 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { @Override public void mouseReleased(MouseEvent e) { this.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); + this.draggingLeftDivider = false; + this.draggingRightDivider = false; + this.draggingTopDivider = false; + this.draggingBottomDivider = false; repaint(); } @@ -634,6 +750,45 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { } + 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; + } + this.ninePointTop = value; + repaint(); + } + + 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; + } + this.ninePointBottom = value; + repaint(); + } + + 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; + } + this.ninePointLeft = value; + repaint(); + } + + 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; + } + this.ninePointRight = value; + repaint(); + } public void setNinePoint(int[] ninePoint) { ninePointLeft = ninePoint[0]; diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java index 81ce5fa7e1..c0ad60ad4f 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/LayoutStylePane.java @@ -1,10 +1,8 @@ package com.fr.design.gui.xpane; -import com.fr.base.GraphHelper; import com.fr.base.Utils; import com.fr.base.svg.IconUtils; import com.fr.design.beans.BasicBeanPane; -import com.fr.design.constants.UIConstants; import com.fr.design.designer.IntervalConstants; import com.fr.design.file.HistoryTemplateListCache; import com.fr.design.formula.TinyFormulaPane; @@ -13,7 +11,6 @@ import com.fr.design.gui.ibutton.UIButtonGroup; 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.LineComboBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ispinner.UISpinner; @@ -105,42 +102,46 @@ public class LayoutStylePane extends BasicBeanPane { boolean currentIsRootLayout = currentEditingTemplate != null && !currentEditingTemplate.isJWorkBook() && ((JForm)currentEditingTemplate).isSelectRootPane(); JPanel titlePane = createTitleStylePane(); + JPanel bodyContentPane = currentIsRootLayout ? createBodyContentPane4RootLayout() : createBodyContentPane(); + JPanel backgroundPane = createBackgroundStylePane(); + if (titlePane != null) { container.add(titlePane, BorderLayout.NORTH); if (currentIsRootLayout) { titlePane.setVisible(false); } } + JPanel nextContainerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.add(nextContainerPane, BorderLayout.CENTER); - //界面上表单主体只有背景和透明度可以设置 - JPanel mainStylePane = currentIsRootLayout ? createMainStylePane4RootLayout() : createMainStylePane4WidgetLayout(); - if (mainStylePane != null) { - container.add(mainStylePane, BorderLayout.CENTER); + if (bodyContentPane != null) { + //界面上表单主体只有背景和透明度可以设置 + nextContainerPane.add(bodyContentPane, BorderLayout.NORTH); + } + if (backgroundPane != null) { + nextContainerPane.add(backgroundPane, BorderLayout.CENTER); + if (currentIsRootLayout) { + backgroundPane.setVisible(false); + } } this.add(container, BorderLayout.CENTER); } - protected void initMainComponents() { + protected JPanel createBackgroundStylePane() { borderStyleCombo = new UIComboBox(BORDER_STYLE); borderLineAndImagePane = new BorderLineAndImagePane(); cornerSpinner = new UISpinner(0,1000,1,0); - backgroundPane = new LayoutBackgroundSpecialPane(); - backgroundOpacityPane = new UIPercentDragPane(); - } - protected JPanel createMainStylePane4WidgetLayout() { - initMainComponents(); double p = TableLayout.PREFERRED; double f = TableLayout.FILL; - double[] rowSize = {p, p, p, p, p}; + double[] rowSize = {p, p, p, p}; double[] columnSize = {SETTING_LABEL_WIDTH, f}; JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Frame_Style")), null}, + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Background_Style")), null}, {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Render_Style")), borderStyleCombo}, {this.borderLineAndImagePane, null}, - {this.createMainBackgroundAndOpacityPane(), null}, {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Radius")), cornerSpinner}, }, rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); @@ -153,16 +154,23 @@ public class LayoutStylePane extends BasicBeanPane { return container; } - protected JPanel createMainStylePane4RootLayout() { - initMainComponents(); + protected JPanel createBodyContentPane() { + backgroundPane = new LayoutBackgroundSpecialPane(); + backgroundOpacityPane = new UIPercentDragPane(); + double p = TableLayout.PREFERRED; double f = TableLayout.FILL; double[] rowSize = {p, p}; double[] columnSize = {SETTING_LABEL_WIDTH, f}; + JPanel bodyBackground = createBackgroundAndOpacityPane( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Fill"), + this.backgroundPane, + this.backgroundOpacityPane); + JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ - {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Style_Frame_Style")), null}, - {this.createMainBackgroundAndOpacityPane(), null}, + {new UILabel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Content")), null}, + {bodyBackground, null}, }, rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); @@ -174,11 +182,31 @@ public class LayoutStylePane extends BasicBeanPane { return container; } - protected JPanel createMainBackgroundAndOpacityPane() { - return createBackgroundAndOpacityPane( - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Background"), + protected JPanel createBodyContentPane4RootLayout() { + backgroundPane = new LayoutBackgroundSpecialPane(); + backgroundOpacityPane = new UIPercentDragPane(); + + double p = TableLayout.PREFERRED; + double f = TableLayout.FILL; + double[] rowSize = {p}; + double[] columnSize = {SETTING_LABEL_WIDTH, f}; + + JPanel bodyBackground = createBackgroundAndOpacityPane( + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget-Style_Body_Fill"), this.backgroundPane, this.backgroundOpacityPane); + + JPanel contentPane = TableLayoutHelper.createGapTableLayoutPane(new JComponent[][]{ + {bodyBackground, null}, + }, + rowSize, columnSize, IntervalConstants.INTERVAL_L1, IntervalConstants.INTERVAL_L1); + contentPane.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + + JPanel container = FRGUIPaneFactory.createBorderLayout_S_Pane(); + container.setBorder(new BottomLineBorder()); + container.add(contentPane, BorderLayout.NORTH); + + return container; } protected void initTitleComponents() { @@ -489,16 +517,25 @@ public class LayoutStylePane extends BasicBeanPane { protected static class BottomLineBorder extends LineBorder { public BottomLineBorder() { - super(Color.lightGray, 1); + super(new Color(217, 218, 221), 1); } @Override public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Graphics2D g2d = (Graphics2D) g; + Color oldColor = g2d.getColor(); - g2d.setColor(this.lineColor); - GraphHelper.drawLine(g, 0, height, width, height, 1); + 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); } } 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 134252487c..0c838b61ec 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 @@ -4,6 +4,9 @@ import com.fr.design.constants.UIConstants; 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.XWTitleLayout; +import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.treeview.ComponentTreeCellRenderer; import com.fr.design.designer.treeview.ComponentTreeModel; import com.fr.design.file.HistoryTemplateListCache; @@ -16,6 +19,7 @@ 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; import javax.swing.DropMode; import javax.swing.JPanel; @@ -349,6 +353,7 @@ public class ComponentTree extends JTree { private final class ComponetTreeMouseListener extends MouseAdapter { private final JTree tree; + private XCreator selectedCreator; private ComponetTreeMouseListener(JTree tree) { this.tree = tree; @@ -378,19 +383,59 @@ public class ComponentTree extends JTree { @Override public void mouseClicked(MouseEvent e) { - // 鼠标左键 双击 - if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 && !designer.isFormParaDesigner()) { - Point p = e.getPoint(); - // 解析组件树路径 获取选中的组件 - int selRow = tree.getRowForLocation(p.x, p.y); - TreePath path = tree.getPathForRow(selRow); - Rectangle bounds = tree.getPathBounds(path); - if (bounds != null) { - Point point = bounds.getLocation(); - SwingUtilities.convertPointToScreen(point, tree); - XCreator comp = (XCreator) path.getLastPathComponent(); - startEditing(comp, e); + onMouseEvent(e, new Consumer() { + @Override + public void accept(XCreator creator) { + if (e.getClickCount() == 2 && e.getButton() == MouseEvent.BUTTON1 && !designer.isFormParaDesigner()) { + startEditing(creator, e); + } } + }); + + } + + @Override + public void mousePressed(MouseEvent e) { + onMouseEvent(e, new Consumer() { + @Override + public void accept(XCreator creator) { + if (e.getButton() == MouseEvent.BUTTON1) { + selectedCreator = creator; + } + } + }); + } + + @Override + public void mouseReleased(MouseEvent e) { + if (e.getButton() == MouseEvent.BUTTON1 && selectedCreator != null) { + showSelectedPopup(selectedCreator); + } + } + + private void showSelectedPopup(XCreator comp) { + Rectangle rectangle = getRelativeBounds(comp); + comp.showSelectedPopup(designer, rectangle, comp.acceptType(XWTitleLayout.class, XWCardMainBorderLayout.class, XWAbsoluteLayout.class)); + comp.setSelected(true); + } + + /** + * 响应鼠标事件并解析选中的组件 + * + * @param e + * @param consumer + */ + private void onMouseEvent(final MouseEvent e, Consumer consumer) { + Point p = e.getPoint(); + // 解析组件树路径 获取选中的组件 + int selRow = tree.getRowForLocation(p.x, p.y); + TreePath path = tree.getPathForRow(selRow); + Rectangle bounds = tree.getPathBounds(path); + if (bounds != null) { + Point point = bounds.getLocation(); + SwingUtilities.convertPointToScreen(point, tree); + XCreator comp = (XCreator) path.getLastPathComponent(); + consumer.accept(comp); } } @@ -410,6 +455,20 @@ public class ComponentTree extends JTree { 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)); } + // 放到事件尾部执行 + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + //处理下tab块的选中 + if (comp.acceptType(XWCardMainBorderLayout.class)) { + XCreator xCreator = designer.getSelectionModel().getSelection().getSelectedCreator(); + if (xCreator != null) { + showSelectedPopup(xCreator); + } + } + } + }); + } /** diff --git a/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java b/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java index f63c430554..6bafb317f3 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/CoverPane.java @@ -42,9 +42,7 @@ public class CoverPane extends JComponent { Graphics2D g2d = (Graphics2D) g; Composite oldComposite = g2d.getComposite(); //画白色的编辑层 - g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); - g2d.setColor(XCreatorConstants.COVER_COLOR); - g2d.fillRect(x, y, w, h); + paintCover(g, component); //画编辑按钮所在框 FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); AlphaComposite alphaComposite = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, formDesigner.getCursor().getType() != Cursor.DEFAULT_CURSOR ? 0.9f : 0.7f); @@ -71,6 +69,21 @@ public class CoverPane extends JComponent { GraphHelper.draw(g, new Rectangle(BORDER_WIDTH, BORDER_WIDTH, w - BORDER_WIDTH * 2, h - BORDER_WIDTH * 2), Constants.LINE_MEDIUM); } + /** + * 绘制悬浮层 + * @param g + * @param component + */ + public static void paintCover(Graphics g, Component component) { + Graphics2D g2d = (Graphics2D) g; + Composite oldComposite = g2d.getComposite(); + //画白色的编辑层 + g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 50 / 100.0F)); + g2d.setColor(XCreatorConstants.COVER_COLOR); + g2d.fillRect(0, 0, component.getWidth(), component.getHeight()); + g2d.setComposite(oldComposite); + } + public CoverPane() { setBackground(null); setOpaque(false); @@ -87,6 +100,6 @@ public class CoverPane extends JComponent { public void paint(Graphics g) { super.paint(g); - paintEditButton(g, this); + paintCover(g, this); } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java b/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java index 14b8aed7a3..ba687f5255 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/CoverReportPane.java @@ -75,8 +75,5 @@ public class CoverReportPane extends CoverPane{ @Override public void paint(Graphics g) { super.paint(g); - if (isShared()) { - paintShareButton(g, this); - } } } 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 8a2bdcc6cc..c1d834fa94 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 @@ -18,7 +18,9 @@ import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XEditorHolder; import com.fr.design.designer.creator.XElementCase; import com.fr.design.designer.creator.XLayoutContainer; +import com.fr.design.designer.creator.XWAbsoluteLayout; import com.fr.design.designer.creator.XWFitLayout; +import com.fr.design.designer.creator.XWTitleLayout; import com.fr.design.designer.creator.cardlayout.XCardAddButton; import com.fr.design.designer.creator.cardlayout.XCardSwitchButton; import com.fr.design.designer.creator.cardlayout.XWCardLayout; @@ -34,6 +36,7 @@ import com.fr.design.utils.gui.LayoutUtils; import com.fr.general.ComparatorUtils; import com.fr.stable.Constants; +import java.util.LinkedList; import javax.swing.BorderFactory; import javax.swing.JComponent; import javax.swing.JPopupMenu; @@ -382,6 +385,14 @@ public class EditingMouseListener extends MouseInputAdapter { } private boolean isEditButton(MouseEvent e, XCreator component, Insets insets) { + // 不显示编辑按钮 鼠标格式 + if (component.getParent() instanceof XCreator) { + XCreator parent = (XCreator) component.getParent(); + if (parent.acceptType(XWTitleLayout.class) || component.acceptType(XWCardMainBorderLayout.class, XWAbsoluteLayout.class)) { + return false; + } + } + int innerWidth = component.getWidth() - insets.left - insets.right; int innerHeight = component.getHeight() - insets.top - insets.bottom; @@ -457,10 +468,7 @@ public class EditingMouseListener extends MouseInputAdapter { if (designer.getCursor().getType() == Cursor.HAND_CURSOR) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); } - if (isShareConfigButton(e, component, insets)) { - designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); - component.setHelpBtnOnFocus(true); - } else if (isEditButton(e, component, insets)) { + if (isEditButton(e, component, insets)) { designer.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } } @@ -613,6 +621,7 @@ public class EditingMouseListener extends MouseInputAdapter { int oldX = e.getX(); int oldY = e.getY(); offsetEventPoint(e); + selectionModel.getSelection().getTabList().clear(); XCreator creator = designer.getComponentAt(e); boolean isValidButton = e.getButton() == MouseEvent.BUTTON1 || e.getButton() == MouseEvent.BUTTON3; @@ -624,6 +633,8 @@ public class EditingMouseListener extends MouseInputAdapter { creator = processTopLayoutMouseClick(creator); if (creator != null) { + // tab块处于未编辑状态 + boolean uneditedTab = designer.getCursor().getType() != Cursor.HAND_CURSOR && creator.acceptType(XWCardMainBorderLayout.class) && !((XWCardMainBorderLayout) creator).isEditable(); // 点击不在tab块的button中 boolean clickedNonCardButton = !creator.acceptType(XCardAddButton.class, XCardSwitchButton.class); if (clickedNonCardButton && e.getClickCount() == 1 && designer.getCursor().getType() != Cursor.HAND_CURSOR) { @@ -631,10 +642,17 @@ public class EditingMouseListener extends MouseInputAdapter { selectionModel.selectACreatorAtMouseEvent(e); refreshTopXCreator(); XCreator[] xCreators = selectionModel.getSelection().getSelectedCreators(); - for (XCreator xCreator : xCreators) { - xCreator.setSelected(true); - } - } else if (clickedNonCardButton && responseTabLayout(oldCreator, e)) { + // 放到事件队尾执行 + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + for (XCreator xCreator : xCreators) { + xCreator.setSelected(!e.isShiftDown()); + } + } + }); + + } else if (clickedNonCardButton && uneditedTab && responseTabLayout(oldCreator, e)) { // do nothing } else { creator.respondClick(this, e); @@ -652,13 +670,36 @@ public class EditingMouseListener extends MouseInputAdapter { } private boolean responseTabLayout(XCreator creator, MouseEvent e) { - if (creator.acceptType(XWCardMainBorderLayout.class) ) { - creator.respondClick(this, e); + LinkedList list = selectionModel.getSelection().getTabList(); + if (creator.acceptType(XWCardMainBorderLayout.class)) { + list.add(creator); + } + while (creator.getParent() instanceof XCreator) { + creator = (XCreator) creator.getParent(); + if (creator.acceptType(XWCardMainBorderLayout.class)) { + list.add(creator); + } + } + // 至少存在一层以上tab块的嵌套 + if (list.size() > 1) { + XWCardMainBorderLayout firstCreator = (XWCardMainBorderLayout) list.getFirst(); + XWCardMainBorderLayout lastCreator = (XWCardMainBorderLayout) list.getLast(); + // 内层tab响应事件 + firstCreator.respondClick(this, e); + setCoverPaneNotDisplay(firstCreator, e, false); + final XCreator xCreator = selectionModel.getSelection().getSelectedCreator(); + SwingUtilities.invokeLater(new Runnable() { + @Override + public void run() { + xCreator.setSelected(true); + // 外层tab展示阴影边框效果 + lastCreator.setShowOuterShadowBorder(true); + } + }); return true; - } else if (creator.getParent() instanceof XCreator) { - return responseTabLayout((XCreator) creator.getParent(), e); + } else { + return false; } - return false; } 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 2fdbb5a29a..d1aa9fc56e 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 @@ -112,7 +112,12 @@ public class FormCreatorDropTarget extends DropTarget { if (addingXCreator.isShared()) { if (container.acceptType(XWAbsoluteLayout.class)) { // 绝对布局中新添加的共享组件默认锁定尺寸比例 - addingXCreator.toData().setAspectRatioLocked(true); + Rectangle bounds = new Rectangle(addingXCreator.getBounds()); + Widget addingWidget = addingXCreator.toData(); + if (addingWidget != null && bounds.width > 0 && bounds.height > 0) { + addingXCreator.toData().setAspectRatioLocked(true); + addingXCreator.toData().setAspectRatioBackup(1.0 * bounds.width / bounds.height); + } } String shareId = addingXCreator.getShareId(); @@ -335,4 +340,8 @@ public class FormCreatorDropTarget extends DropTarget { } } } + + public TabDragInner getTabDragInner() { + return this.tabDragInner; + } } 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 1d4fad8e34..1a6d24ec55 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 @@ -1743,4 +1743,18 @@ public class FormDesigner extends TargetComponent
implements TreeSelection return false; } + public void processPopup(boolean canVisible) { + XCreator creator = this.getSelectionModel().getSelection().getSelectedCreator(); + if (creator != null) { + creator.processPopup(canVisible); + } + } + + public void hidePopup() { + XCreator creator = this.getSelectionModel().getSelection().getSelectedCreator(); + if (creator != null) { + creator.hidePopup(); + } + } + } 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 c49902c8d9..a8ddce03c9 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 @@ -13,7 +13,7 @@ import com.fr.design.designer.beans.models.SelectionModel; 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.XWTitleLayout; +import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.form.util.XCreatorConstants; import com.fr.design.roleAuthority.ReportAndFSManagePane; import com.fr.design.utils.ComponentUtils; @@ -24,6 +24,7 @@ import com.fr.report.core.ReportUtils; import com.fr.stable.ArrayUtils; import com.fr.stable.Constants; +import java.awt.dnd.DropTarget; import javax.swing.*; import javax.swing.plaf.ComponentUI; import java.awt.AlphaComposite; @@ -94,6 +95,7 @@ public class FormDesignerUI extends ComponentUI { } paintBorder(g); paintSelection(g); + paintBorderShadow(g); if (DesignerMode.isAuthorityEditing()) { paintAuthorityDetails(g, designer.getRootComponent()); @@ -326,10 +328,41 @@ public class FormDesignerUI extends ComponentUI { } creator.paintBorder(g, creatorBounds); // 拖拽时不绘制 - creator.showSelectedPopup(designer, creatorBounds, !designer.getStateModel().isDragging() && creator.acceptType(XWTitleLayout.class)); + creator.showSelectedPopup(designer, creatorBounds, !designer.getStateModel().isDragging()); } } + /** + * 绘制tab块的阴影 + * + * @param g + */ + private void paintBorderShadow(Graphics g) { + // 绘制可拖拽进tab块之前的阴影 + DropTarget dropTarget = designer.getDropTarget(); + if (dropTarget instanceof FormCreatorDropTarget) { + FormCreatorDropTarget target = (FormCreatorDropTarget) dropTarget; + XLayoutContainer layoutContainer = target.getTabDragInner().getBelowXLayoutContainer(); + if (layoutContainer != null && layoutContainer.acceptType(XWCardMainBorderLayout.class)) { + XWCardMainBorderLayout cardMainBorderLayout = (XWCardMainBorderLayout) layoutContainer; + cardMainBorderLayout.paintShadowBorder(g, getCreatorBounds(layoutContainer)); + } + } + // 绘制嵌套tab块时的阴影 + if (designer.getSelectionModel().getSelection().getTabList().size() > 1) { + XLayoutContainer layoutContainer = (XLayoutContainer) designer.getSelectionModel().getSelection().getTabList().getLast(); + XWCardMainBorderLayout cardMainBorderLayout = (XWCardMainBorderLayout) layoutContainer; + cardMainBorderLayout.paintShadowBorder(g, getCreatorBounds(layoutContainer)); + } + } + + private Rectangle getCreatorBounds(XLayoutContainer layoutContainer) { + Rectangle creatorBounds = ComponentUtils.getRelativeBounds(layoutContainer); + creatorBounds.x -= designer.getHorizontalScaleValue(); + creatorBounds.y -= designer.getVerticalScaleValue(); + return creatorBounds; + } + /** * 初始为自适应时,处理选中的范围 * @param bound 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 5f48ce294d..c25d99b1ae 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 @@ -13,6 +13,7 @@ import com.fr.design.designer.creator.XWAbsoluteLayout; import com.fr.design.designer.creator.XWFitLayout; import com.fr.design.designer.creator.XWParameterLayout; import com.fr.design.designer.creator.XWTitleLayout; +import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; import com.fr.design.designer.creator.cardlayout.XWCardTagLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.file.HistoryTemplateListCache; @@ -25,12 +26,15 @@ import java.awt.Component; import java.awt.LayoutManager; import java.awt.Rectangle; import java.util.ArrayList; +import java.util.LinkedList; public class FormSelection { private ArrayList selection; private Rectangle backupBounds; private ArrayList recs = new ArrayList(); + // 选中的组件外层嵌套的tab块 head->tail 由内向外 + private LinkedList tabList = new LinkedList<>(); public FormSelection() { selection = new ArrayList(); @@ -43,6 +47,9 @@ public class FormSelection { for (XCreator xCreator : selection) { xCreator.setSelected(false); } + for (XCreator xCreator : tabList) { + ((XWCardMainBorderLayout) xCreator).setShowOuterShadowBorder(false); + } selection.clear(); } @@ -277,7 +284,9 @@ public class FormSelection { for (XCreator creator : selection) { LayoutAdapter layoutAdapter = AdapterBus.searchLayoutAdapter(designer, creator); if (layoutAdapter != null) { - if (creator.acceptType(XWAbsoluteLayout.class) && recs.size() > i) { + // 这里处理绝对画布块 仅局限于选中多个组件且其中包含了绝对画布块的情况 + boolean accept = creator.acceptType(XWAbsoluteLayout.class) && recs.size() > i && selection.size() > 1; + if (accept) { Rectangle rectangle = recs.get(i); check4ParaPane(rectangle); creator.setBackupBound(rectangle); @@ -402,4 +411,8 @@ public class FormSelection { } } } + + public LinkedList getTabList() { + return tabList; + } } 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 08969c91a0..8c9b1f2bc8 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 @@ -47,8 +47,6 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.form.FormECCompositeProvider; import com.fr.design.mainframe.form.FormECDesignerProvider; -import com.fr.design.mainframe.share.collect.ComponentCollector; -import com.fr.design.mainframe.share.util.ShareComponentUtils; import com.fr.design.mainframe.template.info.JFormProcessInfo; import com.fr.design.mainframe.template.info.TemplateProcessInfo; import com.fr.design.mainframe.toolbar.ToolBarMenuDock; @@ -79,10 +77,8 @@ import com.fr.form.ui.Widget; import com.fr.form.ui.container.WBorderLayout; import com.fr.form.ui.container.WLayout; import com.fr.general.ComparatorUtils; -import com.fr.json.JSONArray; import com.fr.log.FineLoggerFactory; import com.fr.page.PaperSettingProvider; -import com.fr.plugin.observer.PluginEventListener; import com.fr.report.cell.Elem; import com.fr.report.cell.cellattr.CellImage; import com.fr.report.worksheet.FormElementCase; @@ -135,8 +131,6 @@ public class JForm extends JTemplate implements BaseJForm implements BaseJForm definePane = rn.getDefinePane(); - JComponent jComponent = definePane.toSwingComponent(); + JComponent definePaneComponent = definePane.toSwingComponent(); + boolean isExtraWidget = FormWidgetDefinePaneFactoryBase.isExtraXWidget(creator.toData()); - attriCardPane.add(jComponent, BorderLayout.CENTER); + if (isExtraWidget) { + // REPORT-55603: 仅对于插件控件,将尺寸*位置面板放置在definePane下方,其余控件将尺寸*位置面板放置在definePane上方 + attriCardPane.add(definePaneComponent, BorderLayout.NORTH); + } else { + // 使用单独的JPane和BorderLayout.North进行包装,避免出现CENTER嵌套CENTER后,内容高度变大的情况 + JPanel definePaneWrapContent = FRGUIPaneFactory.createBorderLayout_S_Pane(); + definePaneWrapContent.add(definePaneComponent, BorderLayout.NORTH); + attriCardPane.add(definePaneWrapContent, BorderLayout.CENTER); + } currentEditorDefinePane = definePane; } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/UIBoundSpinner.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/UIBoundSpinner.java index 426d27f1ae..ea90f3f397 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/UIBoundSpinner.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/UIBoundSpinner.java @@ -23,8 +23,14 @@ public class UIBoundSpinner extends UISpinner{ @Override protected void initTextFiledListeners(){ this.getTextField().addFocusListener(new FocusAdapter() { + @Override + public void focusGained(FocusEvent e) { + setTextFieldFocus(true); + } + @Override public void focusLost(FocusEvent e) { + setTextFieldFocus(false); setTextFieldValue(getTextField().getValue()); setTextField(value); } diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java index d046a6a9e8..a462a8aed6 100644 --- a/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/component/WidgetBoundPane.java @@ -103,14 +103,11 @@ public class WidgetBoundPane extends BasicPane { } public void populate() { - Rectangle bounds = new Rectangle(creator.getBounds()); - if (ratioLockedButton != null) { - // 临时禁止尺寸比例锁定,关掉widthSpinner/heightSpinner之间的数值关联,以更新其高度和宽度值 - ratioLockedButton.setLocked(false); - } - width.setValue(bounds.width); - height.setValue(bounds.height); - if (ratioLockedButton != null) { + if (ratioLockedButton == null) { + Rectangle bounds = new Rectangle(creator.getBounds()); + width.setValue(bounds.width); + height.setValue(bounds.height); + } else { ratioLockedButton.populate(creator); } } @@ -213,8 +210,7 @@ public class WidgetBoundPane extends BasicPane { private final UISpinner mWidthSpinner; private final UISpinner mHeightSpinner; - protected double width4Backup = 0; - protected double height4Backup = 0; + protected double aspectRatioBackup = 0; public AspectRatioLockedButton(UISpinner widthSpinner, UISpinner heightSpinner) { setUI(new BasicButtonUI()); @@ -229,12 +225,16 @@ public class WidgetBoundPane extends BasicPane { addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - // 改变图标icon - setLocked(!isLocked()); - - if (isLocked() && isLockEnabled()) { - width4Backup = mWidthSpinner.getValue(); - height4Backup = mHeightSpinner.getValue(); + double width = mWidthSpinner.getValue(); + double height = mHeightSpinner.getValue(); + boolean nextLocked = !isLocked(); + + if (nextLocked && width > 0 && height > 0) { + setLocked(true); + aspectRatioBackup = width / height; + } else { + setLocked(false); + aspectRatioBackup = -1; } if (globalNameListener != null) { @@ -250,16 +250,28 @@ public class WidgetBoundPane extends BasicPane { mWidthSpinner.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { - if (isLockEnabled() && isLocked() && width4Backup > 0 && height4Backup > 0) { - mHeightSpinner.setValue(mWidthSpinner.getValue() * height4Backup / width4Backup, false); + if (isLockEnabled() && isLocked()) { + if (mWidthSpinner.getValue() == 0) { + setLocked(false); + aspectRatioBackup = -1; + } else if (aspectRatioBackup > 0) { + double value = mWidthSpinner.getValue() / aspectRatioBackup; + mHeightSpinner.setValue(Math.round(value), false); + } } } }); mHeightSpinner.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { - if (isLockEnabled() && isLocked() && width4Backup > 0 && height4Backup > 0) { - mWidthSpinner.setValue(mHeightSpinner.getValue() * width4Backup / height4Backup, false); + if (isLockEnabled() && isLocked()) { + if (mHeightSpinner.getValue() == 0) { + setLocked(false); + aspectRatioBackup = -1; + }else if (aspectRatioBackup > 0) { + double value = mHeightSpinner.getValue() * aspectRatioBackup; + mWidthSpinner.setValue(Math.round(value), false); + } } } }); @@ -301,14 +313,26 @@ public class WidgetBoundPane extends BasicPane { public void populate(XCreator creator) { Rectangle bounds = new Rectangle(creator.getBounds()); - width4Backup = bounds.width; - height4Backup = bounds.height; Widget widget = creator.toData(); + + aspectRatioBackup = widget.getAspectRatioBackup(); setLocked(widget.isAspectRatioLocked()); + + mWidthSpinner.setValue(bounds.width, false); + mHeightSpinner.setValue(bounds.height, false); } public void update(XCreator creator) { - creator.toData().setAspectRatioLocked(this.isLocked()); + Widget widget = creator.toData(); + if (widget != null) { + if (this.isLocked()) { + widget.setAspectRatioLocked(true); + widget.setAspectRatioBackup(this.aspectRatioBackup); + } else { + widget.setAspectRatioLocked(false); + widget.setAspectRatioBackup(-1.0); + } + } } @Override diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java index d43926e6a5..95d14be32a 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/JWorkBook.java @@ -198,6 +198,7 @@ public class JWorkBook extends JTemplate { centerPane = new UIModeControlContainer(parameterPane, reportComposite = new ReportComponentComposite(this)) { @Override protected void onModeChanged() { + processPopup(isUpMode()); refreshToolArea(); } @@ -1221,4 +1222,19 @@ public class JWorkBook extends JTemplate { super.whenClose(); reportComposite.doRemoveAction(); } + + protected void processPopup(boolean visible) { + FormDesigner designer = (FormDesigner) parameterPane.getParaDesigner(); + if (designer != null) { + designer.processPopup(visible); + } + } + + @Override + public void fireTabChange() { + FormDesigner designer = (FormDesigner) parameterPane.getParaDesigner(); + if (designer != null) { + designer.hidePopup(); + } + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java index 14895e90b3..b2892e7221 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/form/FormElementCaseDesigner.java @@ -30,6 +30,7 @@ import com.fr.design.selection.Selectedable; import com.fr.design.selection.SelectionListener; import com.fr.form.FormElementCaseProvider; import com.fr.form.main.Form; +import com.fr.grid.Grid; import com.fr.grid.selection.CellSelection; import com.fr.grid.selection.Selection; import com.fr.log.FineLoggerFactory; @@ -42,9 +43,9 @@ import javax.swing.JComponent; import javax.swing.JPanel; import javax.swing.JScrollBar; import java.awt.BorderLayout; -import java.awt.Color; import java.awt.Dimension; -import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Transparency; import java.awt.image.BufferedImage; /** @@ -128,17 +129,24 @@ public class FormElementCaseDesigner public BufferedImage getElementCaseImage(Dimension size) { BufferedImage image = null; try { - image = new java.awt.image.BufferedImage(size.width, size.height, - java.awt.image.BufferedImage.TYPE_INT_RGB); - Graphics g = image.getGraphics(); - - //填充白色背景, 不然有黑框 - Color oldColor = g.getColor(); - g.setColor(Color.WHITE); - g.fillRect(0, 0, size.width, size.height); - g.setColor(oldColor); - - this.elementCasePane.paintComponents(g); + int width = size.width; + int height = size.height; + + image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g2d = image.createGraphics(); + // 创建一个支持透明背景的buffer image + image = g2d.getDeviceConfiguration().createCompatibleImage(width, height, Transparency.TRANSLUCENT); + g2d.dispose(); + g2d = image.createGraphics(); + + Grid grid = this.elementCasePane != null ? this.elementCasePane.getGrid() : null; + if (grid != null) { + boolean oldTranslucent = grid.isTranslucent(); + // 截缩图图时grid需支持半透明,不能用默认白色填充画布,否则会遮挡组件样式背景 + grid.setTranslucent(true); + grid.paint(g2d); + grid.setTranslucent(oldTranslucent); + } } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java index 33b3b80f7d..157ce6f980 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java @@ -32,6 +32,8 @@ import javax.swing.*; import java.io.IOException; import java.net.URI; import java.net.URL; +import java.util.Timer; +import java.util.TimerTask; public class DesignerSocketIO { @@ -45,7 +47,7 @@ public class DesignerSocketIO { if (DesignerEnvManager.getEnvManager().isHttps()) { showConnectionLostDialog(); } - } + } }); } @@ -57,6 +59,8 @@ public class DesignerSocketIO { private static Socket socket = null; private static Status status = Status.Disconnected; + private static Timer disConnectHintTimer = null; + private static long disConnectHintTimerDelay = 3000; //维护一个当前工作环境的uri列表 private static String[] uri; //维护一个关于uri列表的计数器 @@ -87,18 +91,19 @@ public class DesignerSocketIO { createSocket(); } - private static void createSocket(){ + private static void createSocket() { //根据uri和计数器建立连接,并注册监听 try { - if(count 0 && height > 0 && (width > MAX_WIDTH || height > MAX_HEIGHT)) { + double aspectRatio = width / height; + if (width / height > MAX_WIDTH / MAX_HEIGHT) { + info.setWidth((int) MAX_WIDTH); + info.setHeight((int) (MAX_WIDTH / aspectRatio)); + } else { + info.setHeight((int) MAX_HEIGHT); + info.setWidth((int) (MAX_HEIGHT * aspectRatio)); + } + } + } } diff --git a/designer-realize/src/main/java/com/fr/grid/Grid.java b/designer-realize/src/main/java/com/fr/grid/Grid.java index abbd60928a..b55f60bb53 100644 --- a/designer-realize/src/main/java/com/fr/grid/Grid.java +++ b/designer-realize/src/main/java/com/fr/grid/Grid.java @@ -134,6 +134,9 @@ public class Grid extends BaseGridComponent { private boolean needRequestFocus = true; + // 截取缩略图时需透明(不能用默认白色填充),否则会遮挡组件样式的背景,其余情况的绘制可以用白色等默认颜色填充 + private boolean isTranslucent = false; + public Grid(int resolution) { this.resolution = resolution; // 能触发processEvent,不管是否给component增加listener @@ -1458,4 +1461,12 @@ public class Grid extends BaseGridComponent { this.paginateLineShowType = paginateLineShowType; this.getElementCasePane().repaint(); } + + public boolean isTranslucent() { + return isTranslucent; + } + + public void setTranslucent(boolean translucent) { + isTranslucent = translucent; + } } diff --git a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java index 0ae21bf4d5..1cb3e6242a 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java +++ b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java @@ -408,11 +408,11 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous int currentWidth = currentRight - currentLeft; int currentHeight = currentBottom - currentTop; - int backupWidth= resizingBackupBounds[2]; - int backupHeight= resizingBackupBounds[3]; - if (cursorType == Cursor.NW_RESIZE_CURSOR || cursorType == Cursor.NE_RESIZE_CURSOR || cursorType == Cursor.SE_RESIZE_CURSOR || cursorType == Cursor.SW_RESIZE_CURSOR) { - if (aspectRatio) { + if (aspectRatio && resizingBackupBounds != null) { + int backupWidth= resizingBackupBounds[2]; + int backupHeight= resizingBackupBounds[3]; + double currentDiagonal = Math.pow(currentWidth, 2) + Math.pow(currentHeight, 2); double backupDiagonal = Math.pow(backupWidth, 2) + Math.pow(backupHeight, 2); @@ -452,7 +452,10 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous floatElement.setTopDistance(topDistance); floatElement.setHeight(FU.valueOfPix(currentBottom, resolution).subtract(floatY1_fu)); - if (aspectRatio) { + if (aspectRatio && resizingBackupBounds != null) { + int backupWidth= resizingBackupBounds[2]; + int backupHeight= resizingBackupBounds[3]; + currentWidth = backupWidth * currentHeight / backupHeight; currentRight = currentLeft + currentWidth; FU floatX1_fu = FU.valueOfPix(currentLeft, resolution); @@ -465,7 +468,10 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous floatElement.setLeftDistance(leftDistance); floatElement.setWidth(FU.valueOfPix(currentRight, resolution).subtract(floatX1_fu)); - if (aspectRatio) { + if (aspectRatio && resizingBackupBounds != null) { + int backupWidth= resizingBackupBounds[2]; + int backupHeight= resizingBackupBounds[3]; + currentHeight = backupHeight * currentWidth / backupWidth; currentBottom = currentTop + currentHeight; FU floatY1_fu = FU.valueOfPix(currentTop, resolution); diff --git a/designer-realize/src/main/java/com/fr/grid/GridUI.java b/designer-realize/src/main/java/com/fr/grid/GridUI.java index 711ecee832..10934a7cc4 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridUI.java +++ b/designer-realize/src/main/java/com/fr/grid/GridUI.java @@ -1128,8 +1128,10 @@ public class GridUI extends ComponentUI { double realWidth = gridSize.getWidth();// 宽度 double realHeight = gridSize.getHeight();// 高度 - // 画背景 - this.paintBackground(g2d, grid, elementCase, resolution); + if (!grid.isTranslucent()) { + // 画背景 + this.paintBackground(g2d, grid, elementCase, resolution); + } // 画Grid Line this.paintGridLine(g2d, grid, elementCase, realWidth, realHeight, resolution); diff --git a/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java b/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java index 28b09fef79..bbf91f6409 100644 --- a/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java +++ b/designer-realize/src/main/java/com/fr/poly/creator/ECBlockPane.java @@ -18,6 +18,7 @@ import com.fr.design.actions.edit.HyperlinkAction; import com.fr.design.actions.edit.merge.MergeCellAction; import com.fr.design.actions.edit.merge.UnmergeCellAction; import com.fr.design.actions.utils.DeprecatedActionManager; +import com.fr.design.base.mode.DesignModeContext; import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; import com.fr.design.file.HistoryTemplateListPane; @@ -55,10 +56,10 @@ public class ECBlockPane extends PolyElementCasePane { @Override public void selectionChanged(SelectionEvent e) { - if (!isEditable()) { + if (!isEditable() && !DesignModeContext.isAuthorityEditing()) { return; } - if (DesignerMode.isAuthorityEditing()) { + if (DesignModeContext.isAuthorityEditing()) { if (designer.getSelection().getEditingElementCasePane() == null) { EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.AUTHORITY_EDITION_DISABLED); EastRegionContainerPane.getInstance().replaceAuthorityEditionPane(new NoSupportAuthorityEdit());