diff --git a/build.gradle b/build.gradle index cbc6d696c..804f1ad0f 100644 --- a/build.gradle +++ b/build.gradle @@ -60,10 +60,10 @@ allprojects { implementation 'com.fr.third:jxbrowser:6.23' implementation 'com.fr.third:jxbrowser-mac:6.23' implementation 'com.fr.third:jxbrowser-win64:6.23' - implementation 'com.fr.third:jxbrowser-v7:7.5' - implementation 'com.fr.third:jxbrowser-mac-v7:7.5' - implementation 'com.fr.third:jxbrowser-win64-v7:7.5' - implementation 'com.fr.third:jxbrowser-swing:7.5' + implementation 'com.fr.third:jxbrowser-v7:7.7' + implementation 'com.fr.third:jxbrowser-mac-v7:7.7' + implementation 'com.fr.third:jxbrowser-win64-v7:7.7' + implementation 'com.fr.third:jxbrowser-swing-v7:7.7' implementation 'com.fr.third.server:servlet-api:3.0' implementation 'org.swingexplorer:swexpl:2.0.1' implementation 'org.swingexplorer:swag:1.0' diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java index 58a021812..f65b6dc12 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/DBCPAttrPane.java @@ -42,6 +42,7 @@ public class DBCPAttrPane extends BasicPane { private static final int ORACLE_DEFAULT_FETCHSIZE = 128; private static final int DB2_DEFAULT_FETCHSIZE = 50; private static final int POSTGRE_DEFAULT_FETCHSIZE = 10000; + private static final int EMPTY_FETCHSIZE = -2; // carl:DBCP的一些属性 private IntegerEditor DBCP_INITIAL_SIZE = new IntegerEditor(); private IntegerEditor DBCP_MAX_ACTIVE = new IntegerEditor(); @@ -125,7 +126,11 @@ public class DBCPAttrPane extends BasicPane { this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.setValue(dbcpAttr.getTimeBetweenEvictionRunsMillis()); Integer fetchSize = DEFAULT_FETCHSIZE_MAP.get(JDBCConnectionDef.getInstance().getDatabaseName()); if (fetchSize != null) { - this.FETCHSIZE.setText(jdbcDatabase.getFetchSize() == -1 ? String.valueOf(fetchSize) : String.valueOf(jdbcDatabase.getFetchSize())); + if (jdbcDatabase.getFetchSize() == EMPTY_FETCHSIZE) { + this.FETCHSIZE.setText(StringUtils.EMPTY); + } else { + this.FETCHSIZE.setText(jdbcDatabase.getFetchSize() == -1 ? String.valueOf(fetchSize) : String.valueOf(jdbcDatabase.getFetchSize())); + } } } @@ -149,7 +154,11 @@ public class DBCPAttrPane extends BasicPane { dbcpAttr.setTimeBetweenEvictionRunsMillis(((Number) this.DBCP_TIMEBETWEENEVICTIONRUNSMILLS.getValue()).intValue()); Integer fetchSize = DEFAULT_FETCHSIZE_MAP.get(JDBCConnectionDef.getInstance().getDatabaseName()); if (fetchSize != null) { - jdbcDatabase.setFetchSize(Integer.parseInt(this.FETCHSIZE.getText())); + if (StringUtils.isEmpty(this.FETCHSIZE.getText())) { + jdbcDatabase.setFetchSize(EMPTY_FETCHSIZE); + } else { + jdbcDatabase.setFetchSize(Integer.parseInt(this.FETCHSIZE.getText())); + } } } diff --git a/designer-base/src/main/java/com/fr/design/gui/frpane/UIPercentDragPane.java b/designer-base/src/main/java/com/fr/design/gui/frpane/UIPercentDragPane.java index 1dd96de00..a375420b0 100644 --- a/designer-base/src/main/java/com/fr/design/gui/frpane/UIPercentDragPane.java +++ b/designer-base/src/main/java/com/fr/design/gui/frpane/UIPercentDragPane.java @@ -25,6 +25,6 @@ public class UIPercentDragPane extends JPanel { } public double updateBean() { - return dragPane.updateBean() * 100; + return dragPane.updateBean() / 100.0; } } diff --git a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java index 084820a13..8c7ed5ac5 100644 --- a/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java +++ b/designer-base/src/main/java/com/fr/design/ui/ModernUIPane.java @@ -5,8 +5,10 @@ import com.fr.design.dialog.BasicPane; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.i18n.Toolkit; +import com.fr.design.ui.compatible.BuilderDiff; import com.fr.design.utils.gui.GUICoreUtils; import com.fr.web.struct.AssembleComponent; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; import com.teamdev.jxbrowser.chromium.Browser; import com.teamdev.jxbrowser.chromium.BrowserType; import com.teamdev.jxbrowser.chromium.JSValue; @@ -42,6 +44,10 @@ public class ModernUIPane extends BasicPane { initialize(browserType); } + protected ModernUIPane() { + + } + private void initialize(BrowserType browserType) { if (browser == null) { setLayout(new BorderLayout()); @@ -151,7 +157,7 @@ public class ModernUIPane extends BasicPane { return null; } - public static class Builder { + public static class Builder implements BuilderDiff { private ModernUIPane pane; @@ -271,6 +277,22 @@ public class ModernUIPane extends BasicPane { return this; } + @Override + public Builder prepareForV6(ScriptContextListener contextListener) { + return prepare(contextListener); + } + + @Override + public Builder prepareForV6(LoadListener loadListener) { + return prepare(loadListener); + } + + @Override + public Builder prepareForV7(InjectJsCallback callback) { + // do nothing + return this; + } + public ModernUIPane build() { return pane; } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java b/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java new file mode 100644 index 000000000..33c817c94 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/BuilderDiff.java @@ -0,0 +1,24 @@ +package com.fr.design.ui.compatible; + +import com.fr.design.ui.ModernUIPane; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; +import com.teamdev.jxbrowser.chromium.events.LoadListener; +import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; + +/** + * 封装jxbrwoser v6/v7的构建方式的差异 + * + * @author hades + * @version 10.0 + * Created by hades on 2021/6/13 + */ +public interface BuilderDiff { + + ModernUIPane.Builder prepareForV6(ScriptContextListener contextListener); + + ModernUIPane.Builder prepareForV6(LoadListener loadListener); + + ModernUIPane.Builder prepareForV7(InjectJsCallback callback); + + +} diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java b/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java new file mode 100644 index 000000000..8616b647b --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/ModernUIPaneFactory.java @@ -0,0 +1,20 @@ +package com.fr.design.ui.compatible; + +import com.fr.design.ui.ModernUIPane; +import com.fr.stable.os.OperatingSystem; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2021/6/13 + */ +public class ModernUIPaneFactory { + + public static ModernUIPane.Builder modernUIPaneBuilder() { + if (OperatingSystem.isWindows()) { + return new NewModernUIPane.Builder<>(); + } else { + return new ModernUIPane.Builder<>(); + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java new file mode 100644 index 000000000..ab883516c --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/NewModernUIPane.java @@ -0,0 +1,301 @@ +package com.fr.design.ui.compatible; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.itoolbar.UIToolbar; +import com.fr.design.i18n.Toolkit; +import com.fr.design.ui.ModernUIConstants; +import com.fr.design.ui.ModernUIPane; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.web.struct.AssembleComponent; +import com.teamdev.jxbrowser.browser.Browser; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; +import com.teamdev.jxbrowser.chromium.events.LoadListener; +import com.teamdev.jxbrowser.chromium.events.ScriptContextListener; +import com.teamdev.jxbrowser.engine.Engine; +import com.teamdev.jxbrowser.engine.EngineOptions; +import com.teamdev.jxbrowser.engine.RenderingMode; +import com.teamdev.jxbrowser.js.JsObject; +import com.teamdev.jxbrowser.net.Network; +import com.teamdev.jxbrowser.net.callback.InterceptRequestCallback; +import com.teamdev.jxbrowser.view.swing.BrowserView; + + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.util.Map; +import java.util.Optional; +import javax.swing.JDialog; +import javax.swing.SwingUtilities; +import javax.swing.WindowConstants; + +/** + * 基于v7 jxbrowser实现 + * + * @author richie + * @version 10.0 + * Created by richie on 2019-03-04 + * 用于加载html5的Swing容器,可以在设计选项设置中打开调试窗口,示例可查看:com.fr.design.ui.ModernUIPaneTest + */ +public class NewModernUIPane extends ModernUIPane { + + private Browser browser; + private String namespace = "Pool"; + private String variable = "data"; + private String expression = "update()"; + + private NewModernUIPane() { + super(); + initialize(); + } + + private void initialize() { + setLayout(new BorderLayout()); + if (browser == null) { + if (DesignerEnvManager.getEnvManager().isOpenDebug()) { + UIToolbar toolbar = new UIToolbar(); + add(toolbar, BorderLayout.NORTH); + UIButton openDebugButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Open_Debug_Window")); + toolbar.add(openDebugButton); + UIButton reloadButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Reload")); + toolbar.add(reloadButton); + UIButton closeButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Close_Window")); + toolbar.add(closeButton); + + openDebugButton.addActionListener(e -> showDebuggerDialog()); + + reloadButton.addActionListener(e -> browser.navigation().reloadIgnoringCache()); + + closeButton.addActionListener(e -> SwingUtilities.getWindowAncestor( + NewModernUIPane.this).setVisible(false)); + initializeBrowser(); + add(BrowserView.newInstance(browser), BorderLayout.CENTER); + } else { + initializeBrowser(); + add(BrowserView.newInstance(browser), BorderLayout.CENTER); + } + } + } + + private void showDebuggerDialog() { + JDialog dialog = new JDialog(SwingUtilities.getWindowAncestor(this)); + Engine engine = Engine.newInstance( + EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED) + .addSwitch("--disable-google-traffic") + .remoteDebuggingPort(9222).build()); + Browser debugger = engine.newBrowser(); + BrowserView debuggerView = BrowserView.newInstance(debugger); + dialog.add(debuggerView, BorderLayout.CENTER); + dialog.setSize(new Dimension(800, 400)); + GUICoreUtils.centerWindow(dialog); + dialog.setVisible(true); + dialog.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); + browser.devTools().remoteDebuggingUrl().ifPresent(url -> { + debugger.navigation().loadUrl(url); + }); + } + + private void initializeBrowser() { + Engine engine = Engine.newInstance(EngineOptions.newBuilder(RenderingMode.HARDWARE_ACCELERATED).addSwitch("--disable-google-traffic").build()); + browser = engine.newBrowser(); + + // 初始化的时候,就把命名空间对象初始化好,确保window.a.b.c("a.b.c"为命名空间)对象都是初始化过的 + browser.set(InjectJsCallback.class, params -> { + params.frame().executeJavaScript(String.format(ModernUIConstants.SCRIPT_INIT_NAME_SPACE, namespace)); + return InjectJsCallback.Response.proceed(); + }); + } + + /** + * 转向一个新的地址,相当于重新加载 + * + * @param url 新的地址 + */ + @Override + public void redirect(String url) { + browser.navigation().loadUrl(url); + } + + /** + * 转向一个新的地址,相当于重新加载 + * + * @param url 新的地址 + * @param map 初始化参数 + */ + @Override + public void redirect(String url, Map map) { + Network network = browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map)); + browser.navigation().loadUrl(url); + } + + @Override + protected String title4PopupWindow() { + return "Modern"; + } + + @Override + public void populate(final T t) { + browser.set(InjectJsCallback.class, params -> { + JsObject ns = params.frame().executeJavaScript("window." + namespace); + if (ns != null) { + ns.putProperty(variable, t); + } + return InjectJsCallback.Response.proceed(); + }); + } + + @Override + public T update() { + if (browser.mainFrame().isPresent()) { + return browser.mainFrame().get().executeJavaScript("window." + namespace + "." + expression); + } + return null; + } + + public static class Builder extends ModernUIPane.Builder { + + private NewModernUIPane pane = new NewModernUIPane<>(); + + public NewModernUIPane.Builder prepare(InjectJsCallback callback) { + pane.browser.set(InjectJsCallback.class, callback); + return this; + } + + /** + * 加载jar包中的资源 + * + * @param path 资源路径 + */ + @Override + public NewModernUIPane.Builder withEMB(final String path) { + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, null)); + pane.browser.navigation().loadUrl("emb:" + path); + return this; + } + + /** + * 加载url指向的资源 + * + * @param url 文件的地址 + */ + @Override + public NewModernUIPane.Builder withURL(final String url) { + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network)); + pane.browser.navigation().loadUrl(url); + return this; + } + + /** + * 加载url指向的资源 + * + * @param url 文件的地址 + */ + @Override + public NewModernUIPane.Builder withURL(final String url, Map map) { + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network, map)); + pane.browser.navigation().loadUrl(url); + return this; + } + + /** + * 加载Atom组件 + * + * @param component Atom组件 + */ + @Override + public NewModernUIPane.Builder withComponent(AssembleComponent component) { + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component)); + pane.browser.navigation().loadUrl("emb:dynamic"); + return this; + } + + /** + * 加载Atom组件 + * + * @param component Atom组件 + */ + @Override + public NewModernUIPane.Builder withComponent(AssembleComponent component, Map map) { + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxComplexInterceptRequestCallback(network, component, map)); + pane.browser.navigation().loadUrl("emb:dynamic"); + return this; + } + + + /** + * 加载html文本内容 + * + * @param html 要加载html文本内容 + */ + @Override + public NewModernUIPane.Builder withHTML(String html) { + Network network = pane.browser.engine().network(); + network.set(InterceptRequestCallback.class, new NxInterceptRequestCallback(network)); + pane.browser.mainFrame().ifPresent(frame -> { + frame.loadHtml(html); + }); + return this; + } + + /** + * 设置该前端页面做数据交换所使用的对象 + * + * @param namespace 对象名 + */ + @Override + public NewModernUIPane.Builder namespace(String namespace) { + pane.namespace = namespace; + return this; + } + + /** + * java端往js端传数据时使用的变量名字 + * + * @param name 变量的名字 + */ + @Override + public NewModernUIPane.Builder variable(String name) { + pane.variable = name; + return this; + } + + /** + * js端往java端传数据时执行的函数表达式 + * + * @param expression 函数表达式 + */ + @Override + public NewModernUIPane.Builder expression(String expression) { + pane.expression = expression; + return this; + } + + @Override + public NewModernUIPane.Builder prepareForV6(ScriptContextListener contextListener) { + // do nothing + return this; + } + + @Override + public NewModernUIPane.Builder prepareForV6(LoadListener loadListener) { + // do nothing + return this; + } + + @Override + public NewModernUIPane.Builder prepareForV7(InjectJsCallback callback) { + return prepare(callback); + } + + @Override + public NewModernUIPane build() { + return pane; + } + } +} diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java b/designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java index 2c430bd34..f3147b652 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/NxComplexInterceptRequestCallback.java @@ -49,6 +49,9 @@ public class NxComplexInterceptRequestCallback extends NxInterceptRequestCallbac path = path.substring(4); } InputStream inputStream = IOUtils.readResource(path); + if (inputStream == null) { + return Response.proceed(); + } return InterceptRequestCallback.Response.intercept(generateBasicUrlRequestJob(urlRequest, getMimeType(path), IOUtils.inputStream2Bytes(inputStream))); } } diff --git a/designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java b/designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java index 7b4977e77..e2ab7ad93 100644 --- a/designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java +++ b/designer-base/src/main/java/com/fr/design/ui/compatible/NxInterceptRequestCallback.java @@ -100,6 +100,11 @@ public class NxInterceptRequestCallback implements InterceptRequestCallback { } String getMimeType(String path) { + // 去除 xxx?xxx 后面部分 + int index = path.indexOf("?"); + if (index != -1) { + path = path.substring(0, path.indexOf("?")); + } if (StringUtils.isBlank(path)) { return "text/html"; } @@ -124,6 +129,15 @@ public class NxInterceptRequestCallback implements InterceptRequestCallback { if (path.endsWith(".gif")) { return "image/gif"; } + if (path.endsWith(".woff")) { + return "font/woff"; + } + if (path.endsWith(".ttf")) { + return "truetype"; + } + if (path.endsWith(".eot")) { + return "embedded-opentype"; + } Path file = new File(path).toPath(); try { return Files.probeContentType(file); diff --git a/designer-base/src/main/java/com/fr/design/upm/NewUpmBridge.java b/designer-base/src/main/java/com/fr/design/upm/NewUpmBridge.java new file mode 100644 index 000000000..6b9f1f85f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/upm/NewUpmBridge.java @@ -0,0 +1,502 @@ +package com.fr.design.upm; + +import com.fr.decision.webservice.v10.plugin.helper.category.impl.UpmResourceLoader; +import com.fr.design.DesignerEnvManager; +import com.fr.design.bridge.exec.JSBridge; +import com.fr.design.bridge.exec.JSCallback; +import com.fr.design.extra.PluginOperateUtils; +import com.fr.design.extra.PluginUtils; +import com.fr.design.extra.exe.GetInstalledPluginsExecutor; +import com.fr.design.extra.exe.GetPluginCategoriesExecutor; +import com.fr.design.extra.exe.GetPluginFromStoreExecutor; +import com.fr.design.extra.exe.GetPluginPrefixExecutor; +import com.fr.design.extra.exe.PluginLoginExecutor; +import com.fr.design.extra.exe.ReadUpdateOnlineExecutor; +import com.fr.design.extra.exe.SearchOnlineExecutor; +import com.fr.design.i18n.Toolkit; +import com.fr.design.upm.event.CertificateEvent; +import com.fr.design.upm.event.DownloadEvent; +import com.fr.design.upm.exec.NewUpmBrowserExecutor; +import com.fr.design.upm.task.UpmTaskWorker; +import com.fr.event.EventDispatcher; +import com.fr.general.GeneralUtils; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import com.fr.plugin.context.PluginMarker; +import com.fr.stable.ArrayUtils; +import com.fr.stable.StringUtils; +import com.teamdev.jxbrowser.js.JsAccessible; +import com.teamdev.jxbrowser.js.JsFunction; +import com.teamdev.jxbrowser.js.JsObject; + +import javax.swing.JFileChooser; +import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; +import javax.swing.filechooser.FileNameExtensionFilter; +import java.io.File; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.FutureTask; +import java.util.concurrent.RunnableFuture; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-04-12 + * 桥接Java和JavaScript的类 + */ +public class NewUpmBridge extends UpmBridge { + + public static NewUpmBridge getBridge(JsObject jsObject) { + return new NewUpmBridge(jsObject); + } + + private JsObject jsObject; + + private NewUpmBridge(JsObject jsObject) { + this.jsObject = jsObject; + } + + /** + * 更新插件管理中心资源文件,这个方法仅仅是为了语义上的作用(更新) + * + * @param callback 安装完成后的回调函数 + */ + @JSBridge + @JsAccessible + public void update(final JsFunction callback) { + callback.invoke(jsObject, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); + try { + UpmResourceLoader.INSTANCE.download(); + UpmResourceLoader.INSTANCE.install(); + callback.invoke(jsObject, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); + EventDispatcher.fire(DownloadEvent.UPDATE, "success"); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + callback.invoke(jsObject, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); + } + } + + /** + * 下载并安装插件管理中心的资源文件 + * + * @param callback 安装完成后的回调函数 + */ + @JSBridge + @JsAccessible + public void startDownload(final JsFunction callback) { + callback.invoke(jsObject, "start", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Start")); + new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + UpmResourceLoader.INSTANCE.download(); + UpmResourceLoader.INSTANCE.install(); + return null; + } + + @Override + protected void done() { + try { + get(); + callback.invoke(jsObject, "success", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Success")); + EventDispatcher.fire(DownloadEvent.SUCCESS, "success"); + } catch (Exception e) { + callback.invoke(jsObject, "error", Toolkit.i18nText("Fine-Design_Basic_Update_Plugin_Manager_Download_Error")); + FineLoggerFactory.getLogger().error(e.getMessage(), e); + EventDispatcher.fire(DownloadEvent.ERROR, "error"); + } + } + }.execute(); + } + + /** + * 获取upm的版本信息 + * + * @return 版本信息 + */ + @JSBridge + @JsAccessible + @Override + public String getVersion() { + return super.getVersion(); + } + + @JSBridge + @JsAccessible + @Override + public String i18nText(String key) { + return super.i18nText(key); + } + + @JSBridge + @JsAccessible + @Override + public void closeWindow() { + super.closeWindow(); + } + + @JSBridge + @JsAccessible + @Override + public boolean isDesigner() { + return super.isDesigner(); + } + + @JSBridge + @JsAccessible + public void getPackInfo(final JsFunction callback) { + callback.invoke(jsObject, StringUtils.EMPTY); + } + + @JSBridge + @JsAccessible + public void getPluginPrefix(final JsFunction callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetPluginPrefixExecutor()); + task.execute(); + } + + /** + * 在线获取插件分类 + * + * @param callback 回调函数 + */ + @JSBridge + @JsAccessible + public void getPluginCategories(final JsFunction callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetPluginCategoriesExecutor()); + task.execute(); + } + + /** + * 根据条件获取在线插件 + * + * @param info 插件信息 + * @param callback 回调函数 + */ + @JSBridge + @JsAccessible + public void getPluginFromStoreNew(String info, final JsFunction callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetPluginFromStoreExecutor(new JSONObject(info))); + task.execute(); + } + + /** + * 已安装插件检查更新 + */ + @JSBridge + @JsAccessible + public void readUpdateOnline(final JsFunction callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new ReadUpdateOnlineExecutor()); + task.execute(); + } + + /** + * 获取已经安装的插件的数组 + */ + @JSBridge + @JsAccessible + public void getInstalledPlugins(final JsFunction callback) { + UpmTaskWorker task = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new GetInstalledPluginsExecutor()); + task.execute(); + } + + /** + * 从插件服务器上更新选中的插件 + * + * @param pluginIDs 插件集合 + */ + @JSBridge + @JsAccessible + public void updatePluginOnline(JsObject pluginIDs, final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + List pluginMarkerList = new ArrayList<>(); + for (String key : pluginIDs.propertyNames()) { + pluginIDs.property(key).ifPresent(v -> { + pluginMarkerList.add(PluginUtils.createPluginMarker(GeneralUtils.objectToString(v))); + }); + } + PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback); + } + + @JSBridge + @JsAccessible + public void updatePluginOnline(String pluginID, final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + List pluginMarkerList = new ArrayList<>(); + pluginMarkerList.add(PluginUtils.createPluginMarker(pluginID)); + PluginOperateUtils.updatePluginOnline(pluginMarkerList, jsCallback); + } + + /** + * 搜索在线插件 + * + * @param keyword 关键字 + */ + @JSBridge + @JsAccessible + public void searchPlugin(String keyword, final JsFunction callback) { + UpmTaskWorker worker = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new SearchOnlineExecutor(keyword)); + worker.execute(); + } + + /** + * 从磁盘上选择插件安装包进行安装 + * + * @param filePath 插件包的路径 + */ + @JSBridge + @JsAccessible + public void installPluginFromDisk(final String filePath, final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + File file = new File(filePath); + PluginOperateUtils.installPluginFromDisk(file, jsCallback); + } + + /** + * 卸载当前选中的插件 + * + * @param pluginInfo 插件信息 + */ + @JSBridge + @JsAccessible + public void uninstallPlugin(final String pluginInfo, final boolean isForce, final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + PluginOperateUtils.uninstallPlugin(pluginInfo, isForce, jsCallback); + } + + /** + * 从插件服务器上安装插件 + * + * @param pluginInfo 插件的ID + * @param callback 回调函数 + */ + @JSBridge + @JsAccessible + public void installPluginOnline(final String pluginInfo, final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + PluginMarker pluginMarker = PluginUtils.createPluginMarker(pluginInfo); + PluginOperateUtils.installPluginOnline(pluginMarker, jsCallback); + } + + /** + * 从磁盘上选择插件安装包进行插件升级 + * + * @param filePath 插件包的路径 + */ + @JSBridge + @JsAccessible + public void updatePluginFromDisk(String filePath, final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + File file = new File(filePath); + PluginOperateUtils.updatePluginFromDisk(file, jsCallback); + } + + /** + * 修改选中的插件的活跃状态 + * + * @param pluginID 插件ID + */ + @JSBridge + @JsAccessible + public void setPluginActive(String pluginID, final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + PluginOperateUtils.setPluginActive(pluginID, jsCallback); + } + + /** + * 选择文件对话框 + * + * @return 选择的文件的路径 + */ + @JSBridge + @JsAccessible + @Override + public String showFileChooser() { + return super.showFileChooser(); + } + + /** + * 选择文件对话框 + * + * @param des 过滤文件描述 + * @param filter 文件的后缀 + * @return 选择的文件的路径 + * 这里换用JFileChooser会卡死,不知道为什么 + */ + @JSBridge + @JsAccessible + @Override + public String showFileChooserWithFilter(final String des, final String filter) { + return super.showFileChooserWithFilter(des, filter); + } + + /** + * 选择文件对话框 + * + * @param des 过滤文件描述 + * @param args 文件的后缀 + * @return 选择的文件的路径 + */ + @JSBridge + @JsAccessible + public String showFileChooserWithFilters(final String des, final String args) { + RunnableFuture future = new FutureTask<>(() -> { + JFileChooser fileChooser = new JFileChooser(); + List filterList = new ArrayList<>(); + filterList.add(args); + String[] filters = filterList.toArray(new String[0]); + if (ArrayUtils.isNotEmpty(filters)) { + FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters)); + fileChooser.setFileFilter(filter); + } + int result = fileChooser.showOpenDialog(UpmFinder.getDialog()); + if (result == JFileChooser.APPROVE_OPTION) { + return fileChooser.getSelectedFile().getAbsolutePath(); + } + return null; + }); + SwingUtilities.invokeLater(future); + try { + return future.get(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return null; + } + + /** + * 选择文件对话框 + * + * @param des 过滤文件描述 + * @param args 文件的后缀 + * @return 选择的文件的路径 + */ + @JSBridge + @JsAccessible + public String showFileChooserWithFilters(final String des, final JsObject args) { + RunnableFuture future = new FutureTask<>(() -> { + JFileChooser fileChooser = new JFileChooser(); + List filterList = new ArrayList<>(); + for (String key : args.propertyNames()) { + args.property(key).ifPresent(v -> { + filterList.add(GeneralUtils.objectToString(v)); + }); + } + String[] filters = filterList.toArray(new String[0]); + if (ArrayUtils.isNotEmpty(filters)) { + FileNameExtensionFilter filter = new FileNameExtensionFilter(des, UpmUtils.findMatchedExtension(filters)); + fileChooser.setFileFilter(filter); + } + int result = fileChooser.showOpenDialog(UpmFinder.getDialog()); + if (result == JFileChooser.APPROVE_OPTION) { + return fileChooser.getSelectedFile().getAbsolutePath(); + } + return null; + }); + SwingUtilities.invokeLater(future); + try { + return future.get(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return null; + } + + ////////登录相关/////// + + /** + * 获取系统登录的用户名 + */ + @JSBridge + @JsAccessible + public String getLoginInfo(final JsFunction callback) { + registerLoginInfo(callback); + return DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); + } + + /** + * 系统登录注册 + * + * @param callback 回调函数 + */ + @JSBridge + @JsAccessible + public void registerLoginInfo(final JsFunction callback) { + JSCallback jsCallback = new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)); + String username = DesignerEnvManager.getEnvManager().getDesignerLoginUsername(); + if (StringUtils.isEmpty(username)) { + jsCallback.execute(StringUtils.EMPTY); + EventDispatcher.fire(CertificateEvent.LOGOUT, StringUtils.EMPTY); + } else { + jsCallback.execute(username); + EventDispatcher.fire(CertificateEvent.LOGIN, username); + } + } + + + /** + * 设计器端的用户登录 + * + * @param username 用户名 + * @param password 密码 + * @param callback 回调函数 + */ + @JSBridge + @JsAccessible + public void defaultLogin(String username, String password, final JsFunction callback) { + UpmTaskWorker worker = new UpmTaskWorker<>(new JSCallback(NewUpmBrowserExecutor.create(jsObject, callback)), new PluginLoginExecutor(username, password)); + worker.execute(); + } + + /** + * 清除用户信息 + */ + @JsAccessible + @JSBridge + @Override + public void clearUserInfo() { + super.clearUserInfo(); + } + + /** + * 打开论坛消息界面 + */ + @JSBridge + @JsAccessible + @Override + public void getPriviteMessage() { + super.getPriviteMessage(); + } + + /** + * 忘记密码 + */ + @JSBridge + @JsAccessible + @Override + public void forgetHref() { + super.forgetHref(); + } + + /** + * 立即注册 + */ + @JSBridge + @JsAccessible + @Override + public void registerHref() { + super.registerHref(); + } + + /** + * 使用系统浏览器打开网页 + * + * @param url 要打开的网页 + */ + @JSBridge + @JsAccessible + @Override + public void openShopUrlAtWebBrowser(String url) { + super.openShopUrlAtWebBrowser(url); + } +} diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java b/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java index ad933d7d2..fb40d5434 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmBridge.java @@ -66,6 +66,10 @@ public class UpmBridge { this.window = browser.executeJavaScriptAndReturnValue("window").asObject(); } + protected UpmBridge() { + + } + /** * 更新插件管理中心资源文件,这个方法仅仅是为了语义上的作用(更新) * @param callback 安装完成后的回调函数 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 2ea539faf..db0661b1f 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,6 +15,7 @@ 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; @@ -31,7 +32,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 = "com.teamdev.jxbrowser.chromium.Browser"; + private static final String JXBROWSER = OperatingSystem.isWindows() ? "com.teamdev.jxbrowser.browser.Browser" : "com.teamdev.jxbrowser.chromium.Browser"; public static String installHome = FRContext.getCommonOperator().getWebRootPath(); diff --git a/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java b/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java index 1bc4b9e94..0384b5c29 100644 --- a/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java +++ b/designer-base/src/main/java/com/fr/design/upm/UpmShowPane.java @@ -2,14 +2,17 @@ package com.fr.design.upm; import com.fr.design.dialog.BasicPane; import com.fr.design.ui.ModernUIPane; +import com.fr.design.ui.compatible.ModernUIPaneFactory; import com.fr.design.upm.event.DownloadEvent; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; +import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; import com.teamdev.jxbrowser.chromium.JSValue; import com.teamdev.jxbrowser.chromium.events.ScriptContextAdapter; import com.teamdev.jxbrowser.chromium.events.ScriptContextEvent; +import com.teamdev.jxbrowser.js.JsObject; import java.awt.*; /** @@ -29,16 +32,23 @@ public class UpmShowPane extends BasicPane { UpmShowPane() { setLayout(new BorderLayout()); -// 先屏蔽掉这个判断,后续可能修改交互 -// if (UpmFinder.checkUPMResourcesExist()) { - modernUIPane = new ModernUIPane.Builder<>() - .prepare(new ScriptContextAdapter() { + modernUIPane = ModernUIPaneFactory.modernUIPaneBuilder() + .prepareForV6(new ScriptContextAdapter() { @Override public void onScriptContextCreated(ScriptContextEvent event) { + // 6.x JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser())); } }) + .prepareForV7(params -> { + // 7.x + JsObject window = params.frame().executeJavaScript("window"); + if (window != null) { + window.putProperty("PluginHelper", NewUpmBridge.getBridge(window)); + } + return InjectJsCallback.Response.proceed(); + }) .withURL(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()) .build(); EventDispatcher.listen(DownloadEvent.UPDATE, new Listener() { @@ -47,23 +57,6 @@ public class UpmShowPane extends BasicPane { modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()); } }); -// } else { -// modernUIPane = new ModernUIPane.Builder<>() -// .withComponent(WarnComponent.KEY) -// .prepare(new ScriptContextAdapter() { -// @Override -// public void onScriptContextCreated(ScriptContextEvent event) { -// JSValue window = event.getBrowser().executeJavaScriptAndReturnValue("window"); -// window.asObject().setProperty("PluginHelper", UpmBridge.getBridge(event.getBrowser())); -// } -// }).build(); -// EventDispatcher.listen(DownloadEvent.SUCCESS, new Listener() { -// @Override -// public void on(Event event, String param) { -// modernUIPane.redirect(UpmFinder.getMainResourcePath(), UpmUtils.renderMap()); -// } -// }); -// } add(modernUIPane, BorderLayout.CENTER); } } diff --git a/designer-base/src/main/java/com/fr/design/upm/exec/NewUpmBrowserExecutor.java b/designer-base/src/main/java/com/fr/design/upm/exec/NewUpmBrowserExecutor.java new file mode 100644 index 000000000..04ab5620f --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/upm/exec/NewUpmBrowserExecutor.java @@ -0,0 +1,30 @@ +package com.fr.design.upm.exec; + +import com.fr.design.bridge.exec.JSExecutor; +import com.teamdev.jxbrowser.js.JsFunction; +import com.teamdev.jxbrowser.js.JsObject; + +/** + * @author richie + * @version 10.0 + * Created by richie on 2019-04-18 + */ +public class NewUpmBrowserExecutor implements JSExecutor { + + public static NewUpmBrowserExecutor create(JsObject window, JsFunction callback) { + return new NewUpmBrowserExecutor(window, callback); + } + + private final JsFunction callback; + private final JsObject window; + + private NewUpmBrowserExecutor(JsObject window, JsFunction callback) { + this.window = window; + this.callback = callback; + } + + @Override + public void executor(String newValue) { + callback.invoke(window, newValue); + } +} diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java b/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java index 4ceeab548..3b7613093 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/PlotFactory.java @@ -423,7 +423,7 @@ public class PlotFactory { //大数据模式 恢复用注释。删除下面2个方法 largeDataModel lineMapLargeModel。 public static boolean largeDataModel(Plot plot) { - return plot != null && plot.getDataProcessor().getMark() == LargeDataModel.MARK; + return plot != null && plot.isLargeDataModel(); } public static boolean lineMapLargeModel(Plot plot) { 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 1bb2cea52..a1c9f1ff9 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 @@ -1,5 +1,6 @@ package com.fr.design.designer.beans.events; +import com.fr.form.ui.PaddingMargin; import com.fr.stable.core.PropertyChangeAdapter; import com.fr.stable.core.PropertyChangeListener; import com.fr.design.utils.gui.LayoutUtils; @@ -76,6 +77,22 @@ public class DesignerEditor implements PropertyChangeListe } } + public void paintEditor(Graphics g, Dimension size, PaddingMargin margin) { + if (this.comp != null) { + int marginLeft = margin != null ? margin.getLeft() : 0; + int marginTop = margin != null ? margin.getTop() : 0; + int marginRight = margin != null ? margin.getRight() : 0; + int marginBottom = margin != null ? margin.getBottom() : 0; + int horizonMargin = marginLeft + marginRight; + int verticalMargin = marginTop + marginBottom; + + comp.setSize(new Dimension(size.width - 2 - horizonMargin, size.height - 2 - verticalMargin)); + LayoutUtils.layoutContainer(comp); + Graphics clipg = g.create(1 + marginLeft, 1 + marginTop, size.width, size.height); + this.comp.paint(clipg); + } + } + public T getEditorTarget() { return comp; } 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 bbd2f52d9..2e9b3e23a 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 @@ -20,6 +20,7 @@ import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.widget.editors.WLayoutBorderStyleEditor; import com.fr.design.module.DesignModuleFactory; import com.fr.form.ui.BaseChartEditor; +import com.fr.form.ui.PaddingMargin; import com.fr.form.ui.Widget; import com.fr.stable.Constants; import com.fr.stable.core.PropertyChangeAdapter; @@ -228,9 +229,13 @@ public class XChartEditor extends XBorderStyleWidgetCreator { * 渲染Painter */ public void paint(Graphics g) { - designerEditor.paintEditor(g, this.getSize()); + Dimension size = getSize(); + PaddingMargin margin = toData().getMargin(); + designerEditor.paintEditor(g, size, margin); if (coverPanel != null) { - coverPanel.setSize(this.getSize()); + 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); if (isEditing) { 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 80bf1b51d..0983dded9 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 @@ -777,6 +777,7 @@ 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); } 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 72bb2cb03..c6d0067c3 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 @@ -204,7 +204,8 @@ public class XWAbsoluteLayout extends XLayoutContainer { for (int index = 0, n = this.getComponentCount(); index < n; index++) { XCreator creator = (XCreator) this.getComponent(index); if (creator.toData().isAspectRatioLocked()) { - double percent = Math.min(percentW, percentH); + // 因为percentW/H是旧尺寸与新尺寸之间的比例,所以实现组件选择宽度和高度中较小的缩放比例的规则,需要使用Math.max + double percent = Math.max(percentW, percentH); percentW = percentH = percent; } BoundsWidget wgt = (BoundsWidget) layout.getBoundsWidget(creator.toData()); 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 6d7aa5d9f..896cbe37c 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 @@ -780,6 +780,17 @@ public class XWFitLayout extends XLayoutContainer { tabLayout.updateBoundsWidget(); } } + } + layout.setContainerHeight(containerHeight); + layout.setContainerWidth(containerWidth); + addCompInterval(getAcualInterval()); + + // REPORT-54410: 决策报表,模板中其他组件的宽高修改会影响绝对画布块中组件的宽高和位置 + // 绝对布局内的组件尺寸调整需要在绝对布局的bound排除GAP后进行,否则计算出的 + // 组件尺寸缩放比例会有问题 + for (int index = 0, n = this.getComponentCount(); index < n; index++) { + XCreator creator = (XCreator) this.getComponent(index); + BoundsWidget wgt = (BoundsWidget) layout.getBoundsWidget(creator.toData()); //如果子组件是绝对布局,则内部的widget也要更新 if (creator.acceptType(XWAbsoluteLayout.class)){ //更新的时候一定要带上backupBound @@ -790,9 +801,6 @@ public class XWFitLayout extends XLayoutContainer { creator.setBackupBound(creator.getBounds()); } } - layout.setContainerHeight(containerHeight); - layout.setContainerWidth(containerWidth); - addCompInterval(getAcualInterval()); } private Rectangle recalculateWidgetBounds(Rectangle rec, int[] hors, int[] veris) { diff --git a/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java index b8133d3da..ee0db4571 100644 --- a/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java +++ b/designer-form/src/main/java/com/fr/design/designer/ui/PopupControlPanel.java @@ -1,35 +1,27 @@ package com.fr.design.designer.ui; +import com.fr.design.designer.beans.AdapterBus; +import com.fr.design.designer.beans.adapters.layout.FRAbsoluteLayoutAdapter; +import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XCreator; import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.VerticalFlowLayout; import com.fr.design.mainframe.CoverReportPane; import com.fr.design.mainframe.EditingMouseListener; import com.fr.design.mainframe.FormDesigner; import com.fr.general.IOUtils; import com.fr.stable.ArrayUtils; -import java.awt.Color; -import java.awt.Component; -import java.awt.Container; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.Insets; -import java.awt.LayoutManager; -import java.awt.Rectangle; -import java.awt.RenderingHints; + +import javax.swing.*; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; -import javax.swing.AbstractButton; -import javax.swing.Icon; -import javax.swing.JButton; -import javax.swing.JPanel; -import javax.swing.JToggleButton; -import javax.swing.event.ChangeEvent; -import javax.swing.event.ChangeListener; +import java.util.ArrayList; +import java.util.List; /** * @author hades @@ -40,25 +32,39 @@ public class PopupControlPanel extends JPanel { private static final int ARC_VALUE = 4; private static final Color FILLED_COLOR = new Color(60, 63, 65); - private static final int V_GAP = 10; - private static final int H_GAP = 2; + private static final int BUTTON_SIZE = 16; + private static final int BUTTON_MARGIN = 4; + private static final int PANE_WIDTH = BUTTON_SIZE + BUTTON_MARGIN * 2; // 24 - private Dimension defaultDimension = new Dimension(20, 60); + private final Dimension defaultDimension = new Dimension(PANE_WIDTH, 0); private Rectangle rectangle; + + private final List buttons = new ArrayList<>(); private final JButton editButton; private final JButton settingButton; private final JToggleButton toggleButton; private final XCreator creator; - private final UILabel firstLabel; - private final UILabel secondLabel; public PopupControlPanel(XCreator creator, FormDesigner designer) { - if (creator.isShared()) { - defaultDimension = new Dimension(20, 85); - } - setLayout(getCustomLayout()); + setLayout(new VerticalFlowLayout(VerticalFlowLayout.TOP, 0, 0)); + setBorder(BorderFactory.createEmptyBorder()); this.creator = creator; - editButton = createNormalButton(IOUtils.readIcon("/com/fr/design/images/control/show_edit.png"), Toolkit.i18nText("Fine-Design_Form_Edit_Widget")); + + editButton = createEditButton(designer); + toggleButton = createAspectRatioLockedButton(designer); + settingButton = createSettingButton(); + + addButton(editButton, 0); + addButton(toggleButton, 1); + addButton(settingButton, 2); + + setButtonVisible(editButton, true); + setButtonVisible(toggleButton, false); + setButtonVisible(settingButton, false); + } + + private JButton createEditButton(FormDesigner designer) { + JButton editButton = createNormalButton(IOUtils.readIcon("/com/fr/design/images/control/show_edit.png"), Toolkit.i18nText("Fine-Design_Form_Edit_Widget")); editButton.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { @@ -71,102 +77,99 @@ public class PopupControlPanel extends JPanel { } } }); - settingButton = createNormalButton(IOUtils.readIcon("/com/fr/design/images/control/show_setting.png"), Toolkit.i18nText("Fine-Design_Share_Help_Settings")); + return editButton; + } - settingButton.addActionListener(new ActionListener() { + private JToggleButton createAspectRatioLockedButton(FormDesigner designer) { + JToggleButton button = new JToggleButton(IOUtils.readIcon("/com/fr/design/images/control/edit_unlock.png")); + initButtonStyle(button); + button.setSelectedIcon(IOUtils.readIcon("com/fr/design/images/control/edit_lock.png")); + button.setToolTipText(Toolkit.i18nText("Fine-Design_Form_UnLock_Widget_Ratio")); + button.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - CoverReportPane.showShareConfig(creator.toData()); - } - }); - toggleButton = new JToggleButton(IOUtils.readIcon("/com/fr/design/images/control/edit_lock.png")); - initButtonStyle(toggleButton); - toggleButton.setSelectedIcon(IOUtils.readIcon("com/fr/design/images/control/edit_unlock.png")); - toggleButton.setToolTipText(Toolkit.i18nText("Fine-Design_Form_Lock_Widget_Ratio")); - toggleButton.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { JToggleButton toggleBtn = (JToggleButton) e.getSource(); - String toolTipText = toggleBtn.isSelected() ? Toolkit.i18nText("Fine-Design_Form_UnLock_Widget_Ratio") : Toolkit.i18nText("Fine-Design_Form_Lock_Widget_Ratio"); + String toolTipText = toggleBtn.isSelected() ? Toolkit.i18nText("Fine-Design_Form_Lock_Widget_Ratio") : Toolkit.i18nText("Fine-Design_Form_UnLock_Widget_Ratio"); toggleBtn.setToolTipText(toolTipText); + creator.toData().setAspectRatioLocked(toggleBtn.isSelected()); + designer.getEditListenerTable().fireCreatorModified(creator, DesignerEvent.CREATOR_RESIZED); } }); - - firstLabel = createLabel(); - secondLabel = createLabel(); - - add(editButton); - add(toggleButton); - add(settingButton); - add(firstLabel); - add(secondLabel); + return button; } - protected LayoutManager getCustomLayout() { - return new LayoutManager() { + private JButton createSettingButton() { + JButton settingButton = createNormalButton(IOUtils.readIcon("/com/fr/design/images/control/show_setting.png"), Toolkit.i18nText("Fine-Design_Share_Help_Settings")); + settingButton.addActionListener(new ActionListener() { @Override - public void removeLayoutComponent(Component comp) { + public void actionPerformed(ActionEvent e) { + CoverReportPane.showShareConfig(creator.toData()); } + }); + return settingButton; + } - @Override - public Dimension preferredLayoutSize(Container parent) { - return defaultDimension; - } + private void addButton(JComponent component, int index) { + buttons.add(index, component); + if (index > 0) { + this.add(new SeparatorLabel(), index * 2 - 1); + } + this.add(component, index * 2); + } - @Override - public Dimension minimumLayoutSize(Container parent) { - return null; - } + private void setButtonVisible(JComponent component, boolean visible) { + int index = buttons.indexOf(component); - @Override - public void layoutContainer(Container parent) { - int width = parent.getPreferredSize().width; - int buttonWidth = editButton.getPreferredSize().width; - int buttonHeight = editButton.getPreferredSize().height; - int x = (width - buttonWidth) / 2; - editButton.setBounds(x, V_GAP, buttonWidth, buttonHeight); - firstLabel.setBounds(x, V_GAP + editButton.getHeight() + V_GAP / 2, buttonWidth, buttonHeight); - toggleButton.setBounds(x, V_GAP * 2 + editButton.getHeight(), buttonWidth, buttonHeight); - if (creator.isShared()) { - secondLabel.setBounds(x, V_GAP * 2 + editButton.getHeight() + toggleButton.getHeight() + V_GAP / 2, buttonWidth, buttonHeight); - settingButton.setBounds(x, V_GAP * 3 + editButton.getHeight() + toggleButton.getHeight(), buttonWidth, buttonHeight); - } + boolean hasVisibleButtonBeforeCurrent = false; + for (int i = 0; i < index; i++) { + if (buttons.get(i).isVisible()) { + hasVisibleButtonBeforeCurrent = true; + break; } + } - @Override - public void addLayoutComponent(String name, Component comp) { + if (hasVisibleButtonBeforeCurrent) { + buttons.get(index).setVisible(visible); + getComponent(2 * index - 1).setVisible(visible); + return; + } + + // 在当前按钮之前没有可见的按钮了 + if (index > 0) { + getComponent(2 * index - 1).setVisible(false); + } + buttons.get(index).setVisible(true); + + if (!visible) { + // 如果当前按钮设置为不可见,且在当前按钮之前的其他按钮也不可见,则下一个可见按钮前无分割线 + for (int i = index + 1; i < buttons.size(); i++) { + if (buttons.get(i).isVisible()) { + if (i > 0) { + getComponent(2 * i - 1).setVisible(false); + } + break; + } } - }; + } } private JButton createNormalButton(Icon icon, String toolTipText) { JButton button = new JButton(icon); + button.setPreferredSize(new Dimension(BUTTON_SIZE + 2 * BUTTON_MARGIN, BUTTON_SIZE + 2 * BUTTON_MARGIN)); + button.setBorder(BorderFactory.createEmptyBorder(BUTTON_MARGIN, BUTTON_MARGIN, BUTTON_MARGIN, BUTTON_MARGIN)); initButtonStyle(button); button.setToolTipText(toolTipText); return button; } private void initButtonStyle(AbstractButton button) { + button.setPreferredSize(new Dimension(BUTTON_SIZE + 2 * BUTTON_MARGIN, BUTTON_SIZE + 2 * BUTTON_MARGIN)); + button.setBorder(BorderFactory.createEmptyBorder(BUTTON_MARGIN, BUTTON_MARGIN, BUTTON_MARGIN, BUTTON_MARGIN)); button.setBorderPainted(false); - button.setBorder(null); - button.setMargin(new Insets(0, 0, 0, 0)); button.setContentAreaFilled(false); } - private UILabel createLabel() { - return new UILabel() { - @Override - public void paint(Graphics g) { - super.paint(g); - Graphics2D g2d = (Graphics2D) g; - g2d.setColor(Color.WHITE); - g2d.drawLine(H_GAP, 0, toggleButton.getWidth() - H_GAP, 0); - - } - }; - } - @Override protected void paintComponent(Graphics g) { super.paintComponent(g); @@ -188,4 +191,41 @@ public class PopupControlPanel extends JPanel { this.rectangle = rectangle; } + public void updatePane(FormDesigner designer) { + setButtonVisible(settingButton, creator.isShared()); + setButtonVisible(toggleButton, AdapterBus.searchLayoutAdapter(designer, creator) instanceof FRAbsoluteLayoutAdapter); + toggleButton.setSelected(creator.toData().isAspectRatioLocked()); + + updateDimension(); + } + + private void updateDimension() { + int height = 0; + for (int i = 0; i < buttons.size(); i++) { + JComponent component = buttons.get(i); + if (component.isVisible()) { + if (i > 0) { + height += 1; + } + height += component.getHeight(); + } + } + height += 2; + + defaultDimension.height = height; + } + + private static class SeparatorLabel extends UILabel { + public SeparatorLabel() { + setPreferredSize(new Dimension(PANE_WIDTH, 1)); + } + + @Override + public void paint(Graphics g) { + super.paint(g); + Graphics2D g2d = (Graphics2D) g; + g2d.setColor(Color.WHITE); + g2d.drawLine(BUTTON_MARGIN, 0, getWidth() - BUTTON_MARGIN, 0); + } + } } 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 e7de92679..6702fe7f4 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 @@ -29,6 +29,11 @@ public class SelectedPopupDialog extends JDialog { this.setSize(controlPanel.getDefaultDimension()); } + public void updatePane(FormDesigner designer) { + controlPanel.updatePane(designer); + this.setSize(controlPanel.getDefaultDimension()); + } + public void setRelativeBounds(Rectangle rectangle) { this.controlPanel.setRelativeBounds(rectangle); } 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 27c045459..fcd9ed010 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 @@ -53,6 +53,7 @@ import java.io.File; import java.io.IOException; import java.net.URI; import java.net.URISyntaxException; +import java.util.Arrays; /** * @author Starryi @@ -79,10 +80,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { private NinePointImageTweakDialogPane tweakPane; private ImageFileChooser imageFileChooser; - private int ninePointLeft = -1; - private int ninePointTop = -1; - private int ninePointRight = -1; - private int ninePointBottom = -1; + private int[] ninePoint = new int[] {-1, -1, -1, -1}; public BorderLineAndImagePane() { this.initComponents(); @@ -146,7 +144,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { private JPanel createBorderImageComposePane() { double p = TableLayout.PREFERRED; double f = TableLayout.FILL; - double[] rowSize = {p, p, p}; + double[] rowSize = {p, p, p, p, p}; double[] columnSize = {SETTING_LABEL_WIDTH, f}; JPanel borderedImagePreviewPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); @@ -219,6 +217,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { } if (!borderLineCombo.isSelectedBorderImage()) { imagePreviewPane.setImageWithSuffix(null); + tweakNinePointButton.setEnabled(false); } fireStateChanged(); @@ -241,9 +240,13 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { @Override public void stateChanged(ChangeEvent e) { Image image = imagePreviewPane.getImage(); - ninePointLeft = ninePointRight = (image != null ? image.getWidth(null) / 3 : -1); - ninePointTop = ninePointBottom = (image != null ? image.getHeight(null) / 3 : -1); + ninePoint = new int[4]; + ninePoint[0] = ninePoint[2] = (image != null ? image.getWidth(null) / 3 : -1); + ninePoint[1] = ninePoint[3] = (image != null ? image.getHeight(null) / 3 : -1); borderImageOpacityPane.populateBean(1.0); + if (image != null) { + tweakNinePointButton.setEnabled(true); + } fireStateChanged(); } @@ -256,10 +259,12 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { initNinePointTweakPaneIfNotExist(); if (imagePreviewPane.getImage() != null) { + tweakPane.previewPane.setNinePoint(ninePoint); BasicDialog dialog = tweakPane.showWindow(SwingUtilities.getWindowAncestor(BorderLineAndImagePane.this)); dialog.addDialogActionListener(new DialogActionAdapter() { @Override public void doOk() { + ninePoint = Arrays.copyOf(tweakPane.previewPane.getNinePoint(), 4); fireStateChanged(); } }); @@ -285,15 +290,14 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { if (image != null) { this.borderLineCombo.selectBorderImage(); this.imagePreviewPane.setImageWithSuffix(((ImageBackground) borderImage).getImageWithSuffix()); + this.tweakNinePointButton.setEnabled(true); this.borderImageOpacityPane.populateBean(style.getBorderImageOpacity()); if (ninePoint != null && ninePoint.length == 4 && ninePoint[0] > 0 && ninePoint[1] > 0 && ninePoint[2] > 0 && ninePoint[3] > 0) { - ninePointLeft = ninePoint[0]; - ninePointTop = ninePoint[1]; - ninePointRight = ninePoint[2]; - ninePointBottom = ninePoint[3]; + this.ninePoint = Arrays.copyOf(ninePoint, 4); } else { - ninePointLeft = ninePointRight = image.getWidth(null) / 3; - ninePointTop = ninePointBottom = image.getHeight(null) / 3; + this.ninePoint = new int[4]; + this.ninePoint[0] = this.ninePoint[2] = image.getWidth(null) / 3; + this.ninePoint[1] = this.ninePoint[3] = image.getHeight(null) / 3; } getComponent(1).setVisible(false); @@ -326,7 +330,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { Image image = this.imagePreviewPane.getImage(); if (image != null) { ImageBackground newImageBackground = new ImageFileBackground(this.imagePreviewPane.getImageWithSuffix(), Constants.IMAGE_EXTEND); - newImageBackground.setNinePoint(new int[] { ninePointLeft, ninePointTop, ninePointRight, ninePointBottom }); + newImageBackground.setNinePoint(Arrays.copyOf(ninePoint, 4)); style.setBorderImage(newImageBackground); style.setBorderImageOpacity((float)borderImageOpacityPane.updateBean()); } @@ -403,7 +407,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { } private class NinePointImageTweakDialogPane extends BasicPane { - private final NinePointLinePreviewPane previewPane = new NinePointLinePreviewPane(); + public final NinePointLinePreviewPane previewPane = new NinePointLinePreviewPane(); public NinePointImageTweakDialogPane() { this.initComponents(); @@ -439,6 +443,11 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { public final Color TEXT_COLOR = Color.WHITE; public final int PADDING = 15; + private int ninePointLeft = -1; + private int ninePointTop = -1; + private int ninePointRight = -1; + private int ninePointBottom = -1; + private int imgWidth; private int imgHeight; private int scaleImgWidth; @@ -468,7 +477,7 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { int autoFixAreaX = PADDING; int autoFixAreaY = PADDING; - if (imgWidth / imgHeight > autoFixAreaWidth / autoFixAreaHeight) { + if ((imgWidth * 1.0F / imgHeight) > (autoFixAreaWidth * 1.0F / autoFixAreaHeight)) { scaleImgWidth = autoFixAreaWidth; scaleImgHeight = (int) (1.0F * scaleImgWidth * imgHeight / imgWidth); scaleImgX = autoFixAreaX; @@ -489,28 +498,33 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { int scaleRight = (int) (ninePointRight * scale); int scaleBottom = (int) (ninePointBottom * scale); + 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, scaleImgY + scaleTop, getWidth(), scaleImgHeight - scaleTop - scaleBottom); + 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, scaleImgY + scaleTop, getWidth(), scaleImgY + scaleTop); + GraphDrawHelper.drawLine(g2d, 0, topYInPane, getWidth(), topYInPane); // draw bottom divider - GraphDrawHelper.drawLine(g2d, 0, scaleImgY + scaleImgHeight - scaleBottom, getWidth(), scaleImgY + scaleImgHeight - scaleBottom); + GraphDrawHelper.drawLine(g2d, 0, bottomYInPane, getWidth(), bottomYInPane); // draw left divider - GraphDrawHelper.drawLine(g2d, scaleImgX + scaleLeft, 0, scaleImgX + scaleLeft, getHeight()); + GraphDrawHelper.drawLine(g2d, leftXInPane, 0, leftXInPane, getHeight()); // draw right divider - GraphDrawHelper.drawLine(g2d, scaleImgX + scaleImgWidth - scaleRight, 0, scaleImgX + scaleImgWidth - scaleRight, getHeight()); + GraphDrawHelper.drawLine(g2d, rightXInPane, 0, rightXInPane, getHeight()); g2d.setColor(TEXT_COLOR); // draw nine point info - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointTop), scaleImgX + (scaleImgWidth + scaleLeft - scaleRight) / 2.0, (scaleImgY + scaleTop) / 2.0); - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointBottom), scaleImgX + scaleLeft + (scaleImgWidth - scaleLeft - scaleRight) / 2.0, scaleImgY + scaleImgHeight - (scaleBottom - PADDING) / 2.0); - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointLeft), (scaleImgX + scaleLeft) / 2.0, scaleImgY + (scaleImgHeight + scaleTop - scaleBottom) / 2.0); - GraphDrawHelper.drawString(g2d, Integer.toString(ninePointRight), scaleImgX + scaleImgWidth - (scaleRight - PADDING) / 2.0, scaleImgY + (scaleImgHeight + scaleTop - scaleBottom) / 2.0); + 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); } @Override @@ -619,5 +633,17 @@ public class BorderLineAndImagePane extends JPanel implements UIObserver { public void mouseExited(MouseEvent e) { } + + + public void setNinePoint(int[] ninePoint) { + ninePointLeft = ninePoint[0]; + ninePointTop = ninePoint[1]; + ninePointRight = ninePoint[2]; + ninePointBottom = ninePoint[3]; + } + + public int[] getNinePoint() { + return new int[] { ninePointLeft, ninePointTop, ninePointRight, ninePointBottom }; + } } } 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 ee1de8f7e..81ce5fa7e 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 @@ -81,7 +81,7 @@ public class LayoutStylePane extends BasicBeanPane { private UIToggleButton titleFontBoldButton; private UIToggleButton titleFontItalicButton; private UIToggleButton titleFontUnderlineButton; - private LineComboBox titleFontUnderlineCombo; +// private LineComboBox titleFontUnderlineCombo; // 目前前端仅支持短横线类型的下划线,因此设计器端暂时就不展示线型选择框了,待后续优化 // 标题图文混排 protected TitleInsetImagePane titleInsetImagePane; //对齐方式 @@ -211,8 +211,8 @@ public class LayoutStylePane extends BasicBeanPane { titleFontUnderlineButton.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline")); titleFontUnderlineButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Underline")); - titleFontUnderlineCombo = new LineComboBox(UIConstants.BORDER_LINE_STYLE_ARRAY); - titleFontUnderlineCombo.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Line_Style")); +// titleFontUnderlineCombo = new LineComboBox(UIConstants.BORDER_LINE_STYLE_ARRAY); +// titleFontUnderlineCombo.setGlobalName(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_FRFont_Line_Style")); titleInsetImagePane = new TitleInsetImagePane(); @@ -294,15 +294,15 @@ public class LayoutStylePane extends BasicBeanPane { JPanel containerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); containerPane.add(buttonPane, BorderLayout.NORTH); - containerPane.add(titleFontUnderlineCombo, BorderLayout.CENTER); +// containerPane.add(titleFontUnderlineCombo, BorderLayout.CENTER); - titleFontUnderlineCombo.setVisible(false); - titleFontUnderlineButton.addChangeListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - titleFontUnderlineCombo.setVisible(titleFontUnderlineButton.isSelected()); - } - }); +// titleFontUnderlineCombo.setVisible(false); +// titleFontUnderlineButton.addChangeListener(new ChangeListener() { +// @Override +// public void stateChanged(ChangeEvent e) { +// titleFontUnderlineCombo.setVisible(titleFontUnderlineButton.isSelected()); +// } +// }); return containerPane; } @@ -349,7 +349,8 @@ public class LayoutStylePane extends BasicBeanPane { frFont = frFont.applyName(titleFontFamilyComboBox.getSelectedItem().toString()); frFont = frFont.applyForeground(titleFontColorSelectPane.getColor()); frFont = updateTitleFontItalicBold(frFont); - int line = titleFontUnderlineButton.isSelected() ? this.titleFontUnderlineCombo.getSelectedLineStyle() : Constants.LINE_NONE; +// int line = titleFontUnderlineButton.isSelected() ? this.titleFontUnderlineCombo.getSelectedLineStyle() : Constants.LINE_NONE; + int line = titleFontUnderlineButton.isSelected() ? Constants.LINE_THIN : Constants.LINE_NONE; frFont = frFont.applyUnderline(line); title.setFrFont(frFont); title.setPosition((Integer) titleAlignPane.getSelectedItem()); @@ -425,11 +426,11 @@ public class LayoutStylePane extends BasicBeanPane { int line = frFont.getUnderline(); if (line == Constants.LINE_NONE) { titleFontUnderlineButton.setSelected(false); - titleFontUnderlineCombo.setVisible(false); +// titleFontUnderlineCombo.setVisible(false); } else { titleFontUnderlineButton.setSelected(true); - titleFontUnderlineCombo.setVisible(true); - this.titleFontUnderlineCombo.setSelectedLineStyle(line); +// titleFontUnderlineCombo.setVisible(true); +// this.titleFontUnderlineCombo.setSelectedLineStyle(line); } titleAlignPane.setSelectedItem(widgetTitle.getPosition()); diff --git a/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java b/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java index b7161cbfb..6b5391fb1 100644 --- a/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java +++ b/designer-form/src/main/java/com/fr/design/gui/xpane/TitleInsetImagePane.java @@ -47,6 +47,7 @@ public class TitleInsetImagePane extends JPanel implements UIObserver { private final int SETTING_LABEL_WIDTH = LayoutStylePane.SETTING_LABEL_WIDTH; private final int DELETE_BUTTON_SIZE = 24; private final int IMAGE_PREVIEW_SIZE = 145; + private final Color IMAGE_PREVIEW_OVERLAY_COLOR = new Color(255, 255, 255, 51); private final Style DEFAULT_IMAGE_LAYOUT_STYLE = Style.DEFAULT_STYLE.deriveImageLayout(Constants.IMAGE_DEFAULT); private final int DEFAULT_INSET_LOCATION_INDEX = 0; private final int DEFAULT_INSET_PADDING = 10; @@ -88,17 +89,24 @@ public class TitleInsetImagePane extends JPanel implements UIObserver { deletableImagePreviewPane.setLayout(null); deletableImagePreviewPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, 5)); deletableImagePreviewPane.setPreferredSize(new Dimension(IMAGE_PREVIEW_SIZE, IMAGE_PREVIEW_SIZE)); + JPanel overlayPane = new JPanel(); + overlayPane.setPreferredSize(new Dimension(IMAGE_PREVIEW_SIZE - 2, IMAGE_PREVIEW_SIZE - 2)); + overlayPane.setBackground(IMAGE_PREVIEW_OVERLAY_COLOR); imagePreviewPane.setBounds(0, 0, IMAGE_PREVIEW_SIZE, IMAGE_PREVIEW_SIZE); + overlayPane.setBounds(1, 1, IMAGE_PREVIEW_SIZE - 2, IMAGE_PREVIEW_SIZE - 2); imageDeleteButton.setBounds(IMAGE_PREVIEW_SIZE - DELETE_BUTTON_SIZE, 0, DELETE_BUTTON_SIZE, DELETE_BUTTON_SIZE); deletableImagePreviewPane.add(imageDeleteButton, 0); - deletableImagePreviewPane.add(imagePreviewPane, 1); + deletableImagePreviewPane.add(overlayPane, 1); + deletableImagePreviewPane.add(imagePreviewPane, 2); + overlayPane.setVisible(false); imageDeleteButton.setVisible(false); imageDeleteButton.setEnabled(false); deletableImagePreviewPane.addMouseListener(new MouseAdapter() { @Override public void mouseEntered(MouseEvent e) { super.mouseEntered(e); + overlayPane.setVisible(true); imageDeleteButton.setVisible(true); imageDeleteButton.setEnabled(true); } @@ -109,6 +117,7 @@ public class TitleInsetImagePane extends JPanel implements UIObserver { int x = e.getX(); int y = e.getY(); if (x <= 0 || getWidth() <= x || y <= 0 || y >= getHeight()) { + overlayPane.setVisible(false); imageDeleteButton.setVisible(false); imageDeleteButton.setEnabled(false); } 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 00ba360bb..8a2bdcc6c 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 @@ -19,6 +19,7 @@ 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.XWFitLayout; +import com.fr.design.designer.creator.cardlayout.XCardAddButton; import com.fr.design.designer.creator.cardlayout.XCardSwitchButton; import com.fr.design.designer.creator.cardlayout.XWCardLayout; import com.fr.design.designer.creator.cardlayout.XWCardMainBorderLayout; @@ -623,7 +624,9 @@ public class EditingMouseListener extends MouseInputAdapter { creator = processTopLayoutMouseClick(creator); if (creator != null) { - if (e.getClickCount() == 1 && designer.getCursor().getType() != Cursor.HAND_CURSOR) { + // 点击不在tab块的button中 + boolean clickedNonCardButton = !creator.acceptType(XCardAddButton.class, XCardSwitchButton.class); + if (clickedNonCardButton && e.getClickCount() == 1 && designer.getCursor().getType() != Cursor.HAND_CURSOR) { setCoverPaneNotDisplay(creator, e, false); selectionModel.selectACreatorAtMouseEvent(e); refreshTopXCreator(); @@ -631,7 +634,7 @@ public class EditingMouseListener extends MouseInputAdapter { for (XCreator xCreator : xCreators) { xCreator.setSelected(true); } - } else if (responseTabLayout(oldCreator, e)) { + } else if (clickedNonCardButton && responseTabLayout(oldCreator, e)) { // do nothing } else { creator.respondClick(this, e); 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 30b941818..2fdbb5a29 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 @@ -110,6 +110,11 @@ public class FormCreatorDropTarget extends DropTarget { //图表埋点 dealChartBuryingPoint(widget); if (addingXCreator.isShared()) { + if (container.acceptType(XWAbsoluteLayout.class)) { + // 绝对布局中新添加的共享组件默认锁定尺寸比例 + addingXCreator.toData().setAspectRatioLocked(true); + } + String shareId = addingXCreator.getShareId(); SharableEditorProvider sharableEditor = ShareLoader.getLoader().getSharedElCaseEditorById(shareId); SharableWidgetProvider bindInfo = ShareLoader.getLoader().getElCaseBindInfoById(shareId); diff --git a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java index 3b9ee9ab4..a5189e66f 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/widget/ui/FormWidgetCardPane.java @@ -19,6 +19,7 @@ import com.fr.design.foldablepane.UIExpandablePane; import com.fr.design.gui.frpane.AbstractAttrNoScrollPane; import com.fr.design.gui.frpane.AttributeChangeListener; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.EastRegionContainerPane; @@ -31,12 +32,12 @@ import com.fr.design.widget.Operator; import com.fr.design.widget.ui.designer.component.WidgetAbsoluteBoundPane; import com.fr.design.widget.ui.designer.component.WidgetBoundPane; import com.fr.design.widget.ui.designer.component.WidgetCardTagBoundPane; +import com.fr.form.ui.ChartEditor; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WScaleLayout; import com.fr.form.ui.container.WTitleLayout; import com.fr.form.ui.widget.CRBoundsWidget; import com.fr.general.ComparatorUtils; - import com.fr.general.IOUtils; import com.fr.stable.StringUtils; @@ -229,17 +230,26 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane { public void updateCreator() { currentEditorDefinePane.setGlobalName(getGlobalName()); Widget widget = currentEditorDefinePane.updateBean(); - if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Basic")) && widgetPropertyPane != null) { + if (ComparatorUtils.equals(getGlobalName(), Toolkit.i18nText("Fine-Design_Report_Basic")) && widgetPropertyPane != null) { UITextField widgetNameField = widgetPropertyPane.getWidgetNameField(); String toSetWidgetName = widgetNameField.getText(); String currentWidgetName = widget.getWidgetName(); - boolean exist = designer.getTarget().isNameExist(toSetWidgetName, widget) && !ComparatorUtils.equals(toSetWidgetName, currentWidgetName); if (toSetWidgetName.isEmpty()) { widgetNameField.setText(currentWidgetName); return; - } else if (exist) { + } + + boolean exist = designer.getTarget().isNameExist(toSetWidgetName, widget) && !ComparatorUtils.equals(toSetWidgetName, currentWidgetName); + if (exist) { widgetNameField.setText(currentWidgetName); - JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Widget_Rename_Failure"), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Joption_News"), JOptionPane.ERROR_MESSAGE, IOUtils.readIcon("com/fr/design/form/images/joption_failure.png")); + showNameInvalidDialog(Toolkit.i18nText("Fine-Design_Form_Widget_Rename_Failure")); + return; + } + + //图表名称的合法性检查 + if (widget instanceof ChartEditor && toSetWidgetName.startsWith("Chart")) { + widgetNameField.setText(currentWidgetName); + showNameInvalidDialog(Toolkit.i18nText("Fine-Design_Form_Chart_Widget_Rename_Failure")); return; } widgetPropertyPane.update(widget); @@ -252,6 +262,10 @@ public class FormWidgetCardPane extends AbstractAttrNoScrollPane { fireValueChanged(); } + private void showNameInvalidDialog(String message) { + JOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), message, Toolkit.i18nText("Fine-Design_Form_Joption_News"), JOptionPane.ERROR_MESSAGE, IOUtils.readIcon("com/fr/design/form/images/joption_failure.png")); + } + public void updateWidgetBound() { if (widgetBoundPane != null && ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Coords_And_Size"))) { widgetBoundPane.update(); diff --git a/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java b/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java index 1947e9ec4..e6217dbf0 100644 --- a/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java +++ b/designer-form/src/main/java/com/fr/design/widget/FormWidgetDefinePaneFactoryBase.java @@ -24,7 +24,7 @@ import com.fr.design.widget.ui.designer.TreeComboBoxEditorDefinePane; import com.fr.design.widget.ui.designer.TreeEditorDefinePane; import com.fr.design.widget.ui.designer.UserEditorDefinePane; import com.fr.design.widget.ui.designer.WidgetDefinePane; -import com.fr.design.widget.ui.designer.layout.BorderStyleWidgetDefinePane; +import com.fr.design.widget.ui.designer.layout.ChartEditorDefinePane; import com.fr.design.widget.ui.designer.layout.ElementEditorDefinePane; import com.fr.design.widget.ui.designer.layout.FRAbsoluteBodyLayoutDefinePane; import com.fr.design.widget.ui.designer.layout.FRAbsoluteLayoutDefinePane; @@ -107,7 +107,7 @@ public class FormWidgetDefinePaneFactoryBase { defineMap.put(FormSubmitButton.class, new Appearance(FreeButtonDefinePane.class, WidgetConstants.BUTTON + "")); defineMap.put(WFitLayout.class, new Appearance(FRFitLayoutDefinePane.class, "wFitLayout")); if (StableFactory.getMarkedClass(BridgeMark.CHART_EDITOR, AbstractBorderStyleWidget.class) != null) { - defineMap.put(StableFactory.getMarkedClass(BridgeMark.CHART_EDITOR, AbstractBorderStyleWidget.class), new Appearance(BorderStyleWidgetDefinePane.class, "chartEditor")); + defineMap.put(StableFactory.getMarkedClass(BridgeMark.CHART_EDITOR, AbstractBorderStyleWidget.class), new Appearance(ChartEditorDefinePane.class, "chartEditor")); } defineMap.put(WAbsoluteLayout.class, new Appearance(FRAbsoluteLayoutDefinePane.class, "wAbsoluteLayout")); 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 bfcaeb60e..d046a6a9e 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 @@ -251,7 +251,7 @@ public class WidgetBoundPane extends BasicPane { @Override public void stateChanged(ChangeEvent e) { if (isLockEnabled() && isLocked() && width4Backup > 0 && height4Backup > 0) { - mHeightSpinner.setValue(mWidthSpinner.getValue() * width4Backup / height4Backup, false); + mHeightSpinner.setValue(mWidthSpinner.getValue() * height4Backup / width4Backup, false); } } }); @@ -259,7 +259,7 @@ public class WidgetBoundPane extends BasicPane { @Override public void stateChanged(ChangeEvent e) { if (isLockEnabled() && isLocked() && width4Backup > 0 && height4Backup > 0) { - mWidthSpinner.setValue(mHeightSpinner.getValue() * height4Backup / width4Backup, false); + mWidthSpinner.setValue(mHeightSpinner.getValue() * width4Backup / height4Backup, false); } } }); diff --git a/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ChartEditorDefinePane.java b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ChartEditorDefinePane.java new file mode 100644 index 000000000..fdb3efc9d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/widget/ui/designer/layout/ChartEditorDefinePane.java @@ -0,0 +1,57 @@ +package com.fr.design.widget.ui.designer.layout; + +import com.fr.design.designer.IntervalConstants; +import com.fr.design.designer.creator.CRPropertyDescriptor; +import com.fr.design.designer.creator.PropertyGroupPane; +import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XElementCase; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.TableLayoutHelper; +import com.fr.design.mainframe.widget.accessibles.AccessibleElementCaseToolBarEditor; +import com.fr.design.widget.ui.designer.component.PaddingBoundPane; +import com.fr.form.ui.ChartEditor; +import com.fr.form.ui.ElementCaseEditor; +import com.fr.form.web.FormToolBarManager; +import com.fr.general.ComparatorUtils; + +import javax.swing.*; +import java.awt.*; + +/** + * Created by ibm on 2017/8/7. + */ +public class ChartEditorDefinePane extends WTitleLayoutDefinePane { + private PaddingBoundPane paddingBoundPane; + + public ChartEditorDefinePane(XCreator xCreator) { + super(xCreator); + + } + + protected JPanel createCenterPane() { + JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + paddingBoundPane = new PaddingBoundPane(); + Component[][] components = new Component[][]{ + new Component[]{paddingBoundPane, null}, + }; + JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, TableLayoutHelper.FILL_LASTCOLUMN, IntervalConstants.INTERVAL_W0, IntervalConstants.INTERVAL_L1); + panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 10, 0)); + centerPane.add(panel, BorderLayout.NORTH); + return centerPane; + } + + protected ChartEditor updateSubBean() { + ChartEditor chartEditor = (ChartEditor) creator.toData(); + if (ComparatorUtils.equals(getGlobalName(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_Padding_Duplicate"))) { + paddingBoundPane.update(chartEditor); + } + + return chartEditor; + } + + protected void populateSubBean(ChartEditor ob) { + paddingBoundPane.populate(ob); + } + +} 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 0f1ced379..d43926e6a 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 @@ -1019,6 +1019,9 @@ public class JWorkBook extends JTemplate { // EastRegionContainerPane.getInstance().replaceDownPane(new JPanel()); QuickEditorRegion.getInstance().populate(QuickEditor.DEFAULT_EDITOR); } else { + if (polyDesigner.getSelectionType() == PolyDesigner.SelectionType.INNER) { + EastRegionContainerPane.getInstance().switchMode(EastRegionContainerPane.PropertyMode.REPORT); + } EastRegionContainerPane.getInstance().replaceDownPane(CellElementPropertyPane.getInstance()); } EastRegionContainerPane.getInstance().replaceUpPane(QuickEditorRegion.getInstance()); 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 b6dc8bc4a..0ae21bf4d 100644 --- a/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java +++ b/designer-realize/src/main/java/com/fr/grid/GridMouseAdapter.java @@ -501,54 +501,59 @@ public class GridMouseAdapter implements MouseListener, MouseWheelListener, Mous private void doWithCellElementDragged(int evtX, int evtY, CellSelection cs) { ElementCasePane reportPane = grid.getElementCasePane(); - java.awt.Rectangle cellRectangle = cs.toRectangle(); + java.awt.Rectangle startRec = cs.toRectangle(); - ColumnRow selectedCellPoint = GridUtils.getAdjustEventColumnRow_withresolution(reportPane, evtX, evtY, resolution); - if (cellRectangle.contains(selectedCellPoint.getColumn(), selectedCellPoint.getRow())) { - grid.getDragRectangle().setBounds(cellRectangle); + ColumnRow currentMouseCell = GridUtils.getAdjustEventColumnRow_withresolution(reportPane, evtX, evtY, resolution); + if (isOutECBlockPane(evtX, evtY)) { + return; + } + int xDistance = evtX - this.oldEvtX; + int yDistance = evtY - this.oldEvtY; + boolean isHorizontal = isHorizontal(xDistance, yDistance); + Rectangle endRec = calculateEndRec(currentMouseCell, startRec, isHorizontal); + grid.getDragRectangle().setBounds(calculateDragRectangle(startRec, endRec)); + + reportPane.ensureColumnRowVisible(currentMouseCell.getColumn() + 1, currentMouseCell.getRow() + 1); + } + + private boolean isHorizontal(int xDistance, int yDistance) { + return Math.abs(yDistance) <= Math.abs(xDistance); + } + + /** + * 计算拖拽的结尾矩形 + * @param currentMouseCell 当前鼠标所在的格子 + * @param startRec 起始格子 + * @param isHorizontal 拖拽方向 水平or垂直 + * @return 计算拖拽的结尾矩形 + */ + private Rectangle calculateEndRec(ColumnRow currentMouseCell, Rectangle startRec, boolean isHorizontal) { + if (isHorizontal) { + return new Rectangle(currentMouseCell.column, startRec.y, 1, 1); } else { - int xDistance = evtX - this.oldEvtX; - int yDistance = evtY - this.oldEvtY; - if (Math.abs(yDistance) > Math.abs(xDistance)) { - grid.getDragRectangle().x = cellRectangle.x; - grid.getDragRectangle().width = cellRectangle.width; - if (yDistance >= 0) { - // 聚合报表要求拖拽的时候要在本块的内部进行 不能无限往下拖 - if (reportPane instanceof ECBlockPane && evtY > reportPane.getBounds().height - ECBlockGap) { - return; - } - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = selectedCellPoint.getRow() - cellRectangle.y + 1; - } else { - if (selectedCellPoint.getRow() >= cellRectangle.y && selectedCellPoint.getRow() < cellRectangle.y + cellRectangle.height) { - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = cellRectangle.height; - } else { - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = cellRectangle.y - selectedCellPoint.getRow() + cellRectangle.height; - } - } - } else { - grid.getDragRectangle().y = cellRectangle.y; - grid.getDragRectangle().height = cellRectangle.height; - if (xDistance >= 0) { - if (reportPane instanceof ECBlockPane && evtX > reportPane.getBounds().width - ECBlockGap) { - return; - } - grid.getDragRectangle().x = cellRectangle.x; - grid.getDragRectangle().width = selectedCellPoint.getColumn() - cellRectangle.x + 1; - } else { - if (selectedCellPoint.getColumn() >= cellRectangle.x && selectedCellPoint.getColumn() < cellRectangle.x + cellRectangle.width) { - grid.getDragRectangle().x = cellRectangle.x; - grid.getDragRectangle().width = cellRectangle.width; - } else { - grid.getDragRectangle().x = selectedCellPoint.getColumn(); - grid.getDragRectangle().width = cellRectangle.x - selectedCellPoint.getColumn() + cellRectangle.width; - } - } - } + return new Rectangle(startRec.x, currentMouseCell.row, 1, 1); } - reportPane.ensureColumnRowVisible(selectedCellPoint.getColumn() + 1, selectedCellPoint.getRow() + 1); + } + + /** + * 计算拖拽的边框,传俩矩形确认出一个大矩形,就是所要的结果 + * @param startRec 起始格子矩形 + * @param endRec 结尾格子矩形 + * @return 拖拽的边框 + */ + private Rectangle calculateDragRectangle(Rectangle startRec, Rectangle endRec) { + Rectangle rectangle = new Rectangle(); + int x = Math.min(startRec.x, endRec.x); + int y = Math.min(startRec.y, endRec.y); + int rightBottomX = Math.max(startRec.x + startRec.width, endRec.x + endRec.width); + int rightBottomY = Math.max(startRec.y + startRec.height, endRec.y + endRec.height); + rectangle.setBounds(x, y, rightBottomX - x, rightBottomY - y); + return rectangle; + } + + private boolean isOutECBlockPane(int evtX, int evtY) { + ElementCasePane reportPane = grid.getElementCasePane(); + return reportPane instanceof ECBlockPane && ((evtY > reportPane.getBounds().height - ECBlockGap) || (evtX > reportPane.getBounds().width - ECBlockGap)); } private void doShiftSelectCell(double evtX, double evtY) { diff --git a/designer-realize/src/main/java/com/fr/grid/IntelliElements.java b/designer-realize/src/main/java/com/fr/grid/IntelliElements.java index ca1ed55d8..e53e8b952 100644 --- a/designer-realize/src/main/java/com/fr/grid/IntelliElements.java +++ b/designer-realize/src/main/java/com/fr/grid/IntelliElements.java @@ -183,42 +183,40 @@ public class IntelliElements { } - public void doIntelliAction() { - for (int colIndex = getStartColumnIndex(), colEnd = getEndColumnIndex(); colIndex < colEnd; colIndex++) { - for (int rowIndex = getStartRowIndex(), rowEnd = getEndRowIndex(); rowIndex < rowEnd; rowIndex++) { - TemplateCellElement sourceCellElement = getSourceCellElementByColumnRow(colIndex, rowIndex); + public abstract void doIntelliAction(); - if (sourceCellElement == null) { - sourceCellElement = new DefaultTemplateCellElement(); - } - TemplateCellElement newCellElement = new DefaultTemplateCellElement(colIndex, rowIndex); - applyStyle(newCellElement, sourceCellElement);//style - if (sourceCellElement.getValue() instanceof DSColumn) { - try{ - DSColumn dsColumn = (DSColumn)((DSColumn) sourceCellElement.getValue()).clone(); - newCellElement.setValue(dsColumn); - }catch (CloneNotSupportedException e){ - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - newCellElement.setCellExpandAttr(sourceCellElement.getCellExpandAttr()); - } else if (sourceCellElement.getValue() instanceof Number) { - newCellElement.setValue(processNumber((Number) sourceCellElement.getValue())); - } else if (sourceCellElement.getValue() instanceof BaseFormula) { - BaseFormula formula = (BaseFormula) sourceCellElement.getValue(); - formula = this.generateSimpleFormula(formula, 1); - newCellElement.setValue(formula); - } else { - try { - //richer:不改变原单元格 - newCellElement.setValue(BaseUtils.cloneObject(sourceCellElement.getValue())); - } catch (CloneNotSupportedException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - } + public void expandCellValue(int colIndex, int rowIndex) { + TemplateCellElement sourceCellElement = getSourceCellElementByColumnRow(colIndex, rowIndex); - report.addCellElement(newCellElement); + if (sourceCellElement == null) { + sourceCellElement = new DefaultTemplateCellElement(); + } + TemplateCellElement newCellElement = new DefaultTemplateCellElement(colIndex, rowIndex); + applyStyle(newCellElement, sourceCellElement);//style + if (sourceCellElement.getValue() instanceof DSColumn) { + try{ + DSColumn dsColumn = (DSColumn)((DSColumn) sourceCellElement.getValue()).clone(); + newCellElement.setValue(dsColumn); + }catch (CloneNotSupportedException e){ + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + newCellElement.setCellExpandAttr(sourceCellElement.getCellExpandAttr()); + } else if (sourceCellElement.getValue() instanceof Number) { + newCellElement.setValue(processNumber((Number) sourceCellElement.getValue())); + } else if (sourceCellElement.getValue() instanceof BaseFormula) { + BaseFormula formula = (BaseFormula) sourceCellElement.getValue(); + formula = this.generateSimpleFormula(formula, 1); + newCellElement.setValue(formula); + } else { + try { + //richer:不改变原单元格 + newCellElement.setValue(BaseUtils.cloneObject(sourceCellElement.getValue())); + } catch (CloneNotSupportedException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); } } + + report.addCellElement(newCellElement); } protected abstract int getStartColumnIndex(); @@ -328,6 +326,15 @@ public class IntelliElements { }; } + @Override + public void doIntelliAction() { + for (int colIndex = getStartColumnIndex(), colEnd = getEndColumnIndex(); colIndex < colEnd; colIndex ++) { + for (int rowIndex = getStartRowIndex(), rowEnd = getEndRowIndex(); rowIndex < rowEnd; rowIndex ++) { + expandCellValue(colIndex, rowIndex); + } + } + } + @Override public boolean havetoModify() { return IntelliElements.this.dragCellRectangle.width > IntelliElements.this.oldCellRectangle.width; @@ -397,39 +404,48 @@ public class IntelliElements { }; } + @Override + public void doIntelliAction() { + for (int colIndex = getStartColumnIndex(), colEnd = getEndColumnIndex(); colIndex > colEnd; colIndex --) { + for (int rowIndex = getStartRowIndex(), rowEnd = getEndRowIndex(); rowIndex < rowEnd; rowIndex ++) { + expandCellValue(colIndex, rowIndex); + } + } + } + @Override public boolean havetoModify() { return true; } @Override - public int getStartRowIndex() { + public int getStartRowIndex() { return IntelliElements.this.oldCellRectangle.y; } @Override - public int getEndRowIndex() { + public int getEndRowIndex() { return IntelliElements.this.oldCellRectangle.y + IntelliElements.this.oldCellRectangle.height; } @Override - public int getStartColumnIndex() { - return IntelliElements.this.dragCellRectangle.x; + public int getStartColumnIndex() { + return IntelliElements.this.oldCellRectangle.x - 1; } @Override - public int getEndColumnIndex() { - return IntelliElements.this.oldCellRectangle.x; + public int getEndColumnIndex() { + return IntelliElements.this.dragCellRectangle.x - 1; } @Override public TemplateCellElement getSourceCellElementByColumnRow(int columnIndex, int rowIndex) { - return report.getTemplateCellElement(IntelliElements.this.oldCellRectangle.x + (columnIndex - IntelliElements.this.dragCellRectangle.x) % (IntelliElements.this.oldCellRectangle.width), rowIndex); + return report.getTemplateCellElement(columnIndex + IntelliElements.this.oldCellRectangle.width, rowIndex); } @Override protected Number processNumber(Number i) { - return i; + return FunctionHelper.asNumber(i.doubleValue() - 1); } @Override @@ -465,6 +481,15 @@ public class IntelliElements { }; } + @Override + public void doIntelliAction() { + for (int colIndex = getStartColumnIndex(), colEnd = getEndColumnIndex(); colIndex < colEnd; colIndex ++) { + for (int rowIndex = getStartRowIndex(), rowEnd = getEndRowIndex(); rowIndex < rowEnd; rowIndex ++) { + expandCellValue(colIndex, rowIndex); + } + } + } + @Override public boolean havetoModify() { return IntelliElements.this.dragCellRectangle.height > IntelliElements.this.oldCellRectangle.height; @@ -534,38 +559,47 @@ public class IntelliElements { } @Override - public boolean havetoModify() { + public void doIntelliAction() { + for (int colIndex = getStartColumnIndex(), colEnd = getEndColumnIndex(); colIndex < colEnd; colIndex++) { + for (int rowIndex = getStartRowIndex(), rowEnd = getEndRowIndex(); rowIndex > rowEnd; rowIndex--) { + expandCellValue(colIndex, rowIndex); + } + } + } + + @Override + public boolean havetoModify() { return true; } @Override - public int getStartRowIndex() { - return IntelliElements.this.dragCellRectangle.y; + public int getStartRowIndex() { + return IntelliElements.this.oldCellRectangle.y - 1; } @Override - public int getEndRowIndex() { - return IntelliElements.this.oldCellRectangle.y; + public int getEndRowIndex() { + return IntelliElements.this.dragCellRectangle.y - 1; } @Override - public int getStartColumnIndex() { + public int getStartColumnIndex() { return IntelliElements.this.oldCellRectangle.x; } @Override - public int getEndColumnIndex() { + public int getEndColumnIndex() { return IntelliElements.this.oldCellRectangle.x + IntelliElements.this.oldCellRectangle.width; } @Override public TemplateCellElement getSourceCellElementByColumnRow(int columnIndex, int rowIndex) { - return report.getTemplateCellElement(columnIndex, IntelliElements.this.oldCellRectangle.y + (rowIndex - IntelliElements.this.dragCellRectangle.y) % (IntelliElements.this.oldCellRectangle.height)); + return report.getTemplateCellElement(columnIndex, rowIndex + IntelliElements.this.oldCellRectangle.height); } @Override protected Number processNumber(Number i) { - return i; + return FunctionHelper.asNumber(i.doubleValue() - 1); } @Override