From e9e97d907a6bdb0d9dac8af085dae6cb04fc5e8d Mon Sep 17 00:00:00 2001 From: rinoux Date: Tue, 29 Mar 2022 16:24:01 +0800 Subject: [PATCH 01/55] =?UTF-8?q?REPORT-68607=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E9=85=8D=E7=BD=AE=E6=93=8D=E4=BD=9C=E6=94=BE?= =?UTF-8?q?=E4=BA=8B=E5=8A=A1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datapane/connect/ConnectionListPane.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index c0d23ed46..1913ee880 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -20,6 +20,8 @@ import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; +import com.fr.transaction.Configurations; +import com.fr.transaction.WorkerFacade; import javax.swing.SwingUtilities; import java.util.ArrayList; @@ -163,18 +165,29 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh Map updatedMap = new LinkedHashMap<>(); Arrays.stream(res).map(n -> (NameObject) n).forEach(no -> updatedMap.put(no.getName(), (Connection) no.getObject())); + List removedConnNames = new ArrayList<>(); + Map addedOrUpdatedConnections = new LinkedHashMap<>(); MapCompareUtils.contrastMapEntries(populatedConnectionsSnapshot, updatedMap, (entryEventKind, s, connection) -> { switch (entryEventKind) { case REMOVED: - connectionConfig.removeConnection(s); + removedConnNames.add(s); break; case ADDED: case UPDATED: - connectionConfig.addConnection(s, connection); + addedOrUpdatedConnections.put(s, connection); default: break; } }); + + // 之前丢有可能是因为没有放事务里吧 + Configurations.modify(new WorkerFacade(ConnectionConfig.class) { + @Override + public void run() { + removedConnNames.forEach(n -> ConnectionConfig.getInstance().removeConnection(n)); + addedOrUpdatedConnections.forEach((name, conn) -> ConnectionConfig.getInstance().addConnection(name, conn)); + } + }); } @Override From 26c3c48f3f578ab8eff16c2b02ed4ffc0e109153 Mon Sep 17 00:00:00 2001 From: hades Date: Sat, 7 May 2022 17:02:03 +0800 Subject: [PATCH 02/55] =?UTF-8?q?REPORT-70605=20=E6=8E=A7=E4=BB=B6-?= =?UTF-8?q?=E6=96=B0=E5=BB=BA=E6=95=B0=E6=8D=AE=E9=9B=86=E5=90=8E=EF=BC=8C?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E7=9A=84=E6=95=B0=E6=8D=AE=E5=AD=97=E5=85=B8?= =?UTF-8?q?=E9=80=89=E9=A1=B9=20=E5=88=87=E6=8D=A2=E7=84=A6=E7=82=B9?= =?UTF-8?q?=E5=90=8E=E6=89=8D=20=E5=88=B7=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/common/listener/ManageDsListenerRegisterListener.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/designer-base/src/main/java/com/fr/common/listener/ManageDsListenerRegisterListener.java b/designer-base/src/main/java/com/fr/common/listener/ManageDsListenerRegisterListener.java index 6baa2e86b..966f3daf1 100644 --- a/designer-base/src/main/java/com/fr/common/listener/ManageDsListenerRegisterListener.java +++ b/designer-base/src/main/java/com/fr/common/listener/ManageDsListenerRegisterListener.java @@ -35,6 +35,8 @@ public class ManageDsListenerRegisterListener implements AncestorListener { @Override public void ancestorAdded(AncestorEvent event) { DesignTableDataManager.addDsChangeListener(changeListener); + // 添加后 fire一下 更新数据 + changeListener.stateChanged(null); } @Override From f8a3043edae0781255f3ecadce139eaa5ad46d90 Mon Sep 17 00:00:00 2001 From: rinoux Date: Thu, 12 May 2022 10:19:11 +0800 Subject: [PATCH 03/55] =?UTF-8?q?REPORT-69285=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=AE=89=E5=85=A8=E5=85=B3=E9=94=AE=E5=AD=97?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datapane/connect/ConnectionListPane.java | 34 +++++++++++++------ .../connect/ConnectionManagerPane.java | 7 ++-- .../datapane/connect/ConnectionShowPane.java | 2 +- 3 files changed, 28 insertions(+), 15 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 1913ee880..0336c1ce0 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -1,5 +1,6 @@ package com.fr.design.data.datapane.connect; +import com.fr.data.core.db.JDBCSecurityChecker; import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; @@ -20,10 +21,9 @@ import com.fr.stable.ArrayUtils; import com.fr.stable.Nameable; import com.fr.stable.StringUtils; import com.fr.stable.core.PropertyChangeAdapter; -import com.fr.transaction.Configurations; -import com.fr.transaction.WorkerFacade; import javax.swing.SwingUtilities; +import java.sql.SQLException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; @@ -159,7 +159,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh /** * Update. */ - public void update(ConnectionConfig connectionConfig) { + public void update(ConnectionConfig connectionConfig) throws Exception { // Nameable[]居然不能强转成NameObject[],一定要这么写... Nameable[] res = this.update(); Map updatedMap = new LinkedHashMap<>(); @@ -180,14 +180,28 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh } }); - // 之前丢有可能是因为没有放事务里吧 - Configurations.modify(new WorkerFacade(ConnectionConfig.class) { - @Override - public void run() { - removedConnNames.forEach(n -> ConnectionConfig.getInstance().removeConnection(n)); - addedOrUpdatedConnections.forEach((name, conn) -> ConnectionConfig.getInstance().addConnection(name, conn)); + this.checkSecurity(addedOrUpdatedConnections); + alterConnections(removedConnNames, addedOrUpdatedConnections); + } + + private void alterConnections(List removedConnNames, Map addedOrUpdatedConnections) { + removedConnNames.forEach(n -> ConnectionConfig.getInstance().removeConnection(n)); + addedOrUpdatedConnections.forEach((name, conn) -> ConnectionConfig.getInstance().addConnection(name, conn)); + } + + private void checkSecurity(Map addedOrUpdatedConnections) throws Exception { + + for (Map.Entry entry : addedOrUpdatedConnections.entrySet()) { + Connection connection = entry.getValue(); + if (connection instanceof JDBCDatabaseConnection) { + try { + JDBCSecurityChecker.checkURL(((JDBCDatabaseConnection) connection).getURL()); + JDBCSecurityChecker.checkValidationQuery(((JDBCDatabaseConnection) connection).getDbcpAttr().getValidationQuery()); + } catch (SQLException e) { + throw new SQLException(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Invalid_Config", entry.getKey()) + ", " + e.getMessage(), e.getCause()); + } } - }); + } } @Override diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java index 6c768145f..eadf456e0 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionManagerPane.java @@ -4,9 +4,8 @@ import com.fr.design.gui.frpane.LoadingBasicPane; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.file.ConnectionConfig; - -import javax.swing.*; -import java.awt.*; +import javax.swing.JPanel; +import java.awt.BorderLayout; import java.util.HashMap; public class ConnectionManagerPane extends LoadingBasicPane implements ConnectionShowPane { @@ -39,7 +38,7 @@ public class ConnectionManagerPane extends LoadingBasicPane implements Connectio this.connectionListPane.populate(datasourceManager); } - public void update(ConnectionConfig datasourceManager) { + public void update(ConnectionConfig datasourceManager) throws Exception { this.connectionListPane.update(datasourceManager); } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionShowPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionShowPane.java index b5ae09be8..2b74ddcf9 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionShowPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionShowPane.java @@ -7,7 +7,7 @@ import com.fr.file.ConnectionConfig; * 数据链接显示面板 */ public interface ConnectionShowPane { - void update(ConnectionConfig connectionConfig); + void update(ConnectionConfig connectionConfig) throws Exception; void populate(ConnectionConfig connectionConfig); From 06346c31cd43bbde5d575c71242e53f74fed0494 Mon Sep 17 00:00:00 2001 From: rinoux Date: Thu, 12 May 2022 11:09:28 +0800 Subject: [PATCH 04/55] =?UTF-8?q?REPORT-69285=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=AE=89=E5=85=A8=E5=85=B3=E9=94=AE=E5=AD=97?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/os/impl/DatabaseDialogAction.java | 28 +++++++++++++++---- 1 file changed, 23 insertions(+), 5 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java b/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java index 057b561fa..669ef6ef4 100644 --- a/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java +++ b/designer-base/src/main/java/com/fr/design/os/impl/DatabaseDialogAction.java @@ -3,19 +3,26 @@ package com.fr.design.os.impl; import com.fr.design.data.datapane.connect.ConnectionManagerPane; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; import com.fr.design.editlock.EditLockUtils; +import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.DesignerFrame; import com.fr.file.ConnectionConfig; +import com.fr.report.LockItem; import com.fr.stable.os.support.OSBasedAction; import com.fr.transaction.CallBackAdaptor; import com.fr.transaction.Configurations; import com.fr.transaction.WorkerFacade; -import com.fr.report.LockItem; + +import javax.swing.JOptionPane; +import java.util.concurrent.atomic.AtomicBoolean; + import static com.fr.design.actions.server.ConnectionListAction.doWithDatasourceManager; /** * 数据连接窗口 + * * @author pengda * @date 2019/10/9 */ @@ -52,10 +59,17 @@ public class DatabaseDialogAction implements OSBasedAction { databaseListDialog.setDoOKSucceed(false); return; } + + AtomicBoolean saved = new AtomicBoolean(true); Configurations.modify(new WorkerFacade(ConnectionConfig.class) { @Override public void run() { - databaseManagerPane.update(datasourceManager); + try { + databaseManagerPane.update(datasourceManager); + } catch (Exception e) { + saved.set(false); + FineJOptionPane.showMessageDialog(databaseManagerPane, e.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE); + } } }.addCallBack(new CallBackAdaptor() { @Override @@ -66,9 +80,13 @@ public class DatabaseDialogAction implements OSBasedAction { @Override public void afterCommit() { - DesignerContext.getDesignerBean("databasename").refreshBeanElement(); - // 定义数据连接弹窗关闭后,解锁 - EditLockUtils.unlock(LockItem.CONNECTION); + if (saved.get()) { + DesignerContext.getDesignerBean("databasename").refreshBeanElement(); + // 定义数据连接弹窗关闭后,解锁 + EditLockUtils.unlock(LockItem.CONNECTION); + } else { + databaseListDialog.setDoOKSucceed(false); + } } })); } From 6a9c978a391e10b76d87cd5953e285ce2ed502c5 Mon Sep 17 00:00:00 2001 From: rinoux Date: Thu, 12 May 2022 11:09:34 +0800 Subject: [PATCH 05/55] =?UTF-8?q?REPORT-69285=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E5=AE=89=E5=85=A8=E5=85=B3=E9=94=AE=E5=AD=97?= =?UTF-8?q?=E6=A3=80=E6=9F=A5=E6=8B=A6=E6=88=AA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../connect/ConnectionComboBoxPanel.java | 22 +++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java index 5ee6654d4..c0e8ef023 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java @@ -8,10 +8,12 @@ import com.fr.design.DesignerEnvManager; import com.fr.design.actions.server.ConnectionListAction; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.DialogActionAdapter; +import com.fr.design.dialog.FineJOptionPane; import com.fr.design.editlock.ConnectionLockChangeChecker; import com.fr.design.editlock.EditLockUtils; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UILockButton; +import com.fr.design.i18n.Toolkit; import com.fr.design.mainframe.DesignerContext; import com.fr.file.ConnectionConfig; import com.fr.report.LockItem; @@ -22,6 +24,7 @@ import com.fr.transaction.WorkerFacade; import com.fr.workspace.WorkContext; import com.fr.workspace.server.connection.DBConnectAuth; +import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import java.awt.Dimension; import java.awt.event.ActionEvent; @@ -32,6 +35,7 @@ import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.concurrent.atomic.AtomicBoolean; /** * 选择数据连接的下拉框 @@ -145,10 +149,16 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { connectionListDialog.setDoOKSucceed(false); return; } + AtomicBoolean saved = new AtomicBoolean(true); Configurations.modify(new WorkerFacade(ConnectionConfig.class) { @Override public void run() { - connectionListPane.update(connectionConfig); + try { + connectionListPane.update(connectionConfig); + } catch (Exception e) { + saved.set(false); + FineJOptionPane.showMessageDialog(connectionListPane, e.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE); + } } }.addCallBack(new CallBackAdaptor() { @Override @@ -159,9 +169,13 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { @Override public void afterCommit() { - DesignerContext.getDesignerBean("databasename").refreshBeanElement(); - // 关闭定义数据连接页面,为其解锁 - EditLockUtils.unlock(LockItem.CONNECTION); + if (saved.get()) { + DesignerContext.getDesignerBean("databasename").refreshBeanElement(); + // 定义数据连接弹窗关闭后,解锁 + EditLockUtils.unlock(LockItem.CONNECTION); + } else { + connectionListDialog.setDoOKSucceed(false); + } } })); From 527618f35a6891c8cfe7406f4e93b11224d44c17 Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 12 May 2022 16:08:48 +0800 Subject: [PATCH 06/55] =?UTF-8?q?REPORT-71425=20websocket=E6=96=AD?= =?UTF-8?q?=E5=BC=80=E4=BC=98=E5=8C=96=20=E5=90=8C=E6=AD=A5=E5=88=B010.0.1?= =?UTF-8?q?9.13?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mainframe/toast/DesignerToastMsgUtil.java | 22 ++- .../mainframe/toast/ToastMsgDialog.java | 24 ++- .../mainframe/socketio/DesignerSocketIO.java | 138 +++++++++++++----- 3 files changed, 137 insertions(+), 47 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java b/designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java index 4e69c34c5..fc326c60e 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toast/DesignerToastMsgUtil.java @@ -6,17 +6,17 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.stable.Constants; -import java.awt.Dialog; -import java.awt.Frame; -import java.awt.Window; import javax.swing.BorderFactory; import javax.swing.Icon; import javax.swing.JEditorPane; import javax.swing.JPanel; import javax.swing.SwingConstants; import java.awt.BorderLayout; +import java.awt.Dialog; import java.awt.Dimension; import java.awt.Font; +import java.awt.Frame; +import java.awt.Window; /** * Created by kerry on 5/6/21 @@ -31,6 +31,13 @@ public class DesignerToastMsgUtil { } + public static ToastMsgDialog createPromptDialog(String text) { + return createDialog(PROMPT_ICON, toastPane(text), DesignerContext.getDesignerFrame()); + } + + public static ToastMsgDialog createPromptDialog(JPanel contentPane) { + return createDialog(PROMPT_ICON, contentPane, DesignerContext.getDesignerFrame()); + } public static void toastPrompt(JPanel contendPane) { toastPane(PROMPT_ICON, contendPane, DesignerContext.getDesignerFrame()); @@ -69,6 +76,11 @@ public class DesignerToastMsgUtil { } private static void toastPane(Icon icon, JPanel contendPane, Window parent) { + ToastMsgDialog dialog = createDialog(icon, contendPane, parent); + dialog.setVisible(true); + } + + private static ToastMsgDialog createDialog(Icon icon, JPanel contendPane, Window parent) { JPanel pane = FRGUIPaneFactory.createBorderLayout_S_Pane(); UILabel uiLabel = new UILabel(icon); uiLabel.setVerticalAlignment(SwingConstants.TOP); @@ -83,7 +95,7 @@ public class DesignerToastMsgUtil { } else { dialog = new ToastMsgDialog((Frame) parent, pane); } - dialog.setVisible(true); + return dialog; } @@ -118,4 +130,4 @@ public class DesignerToastMsgUtil { .toString(); } -} +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java b/designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java index 00f4f95ea..83cd84e9c 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toast/ToastMsgDialog.java @@ -3,10 +3,11 @@ package com.fr.design.mainframe.toast; import com.fr.concurrent.NamedThreadFactory; import com.fr.design.dialog.UIDialog; import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; import com.fr.module.ModuleContext; -import java.awt.Dialog; import javax.swing.JPanel; +import java.awt.Dialog; import java.awt.Dimension; import java.awt.Frame; import java.awt.Point; @@ -24,6 +25,7 @@ public class ToastMsgDialog extends UIDialog { private ScheduledExecutorService TIMER; private int hide_height = 0; private JPanel contentPane; + private boolean show = false; public ToastMsgDialog(Frame parent, JPanel panel) { super(parent); @@ -50,12 +52,16 @@ public class ToastMsgDialog extends UIDialog { hide_height = dimension.height; setSize(new Dimension(dimension.width, 0)); contentPane.setSize(dimension); - setLocationRelativeTo(DesignerContext.getDesignerFrame().getContentFrame()); - int positionY = DesignerContext.getDesignerFrame().getContentFrame().getLocationOnScreen().y + 10; - setLocation((DesignerContext.getDesignerFrame().getWidth() - dimension.width) / 2, positionY); + setRelativeLocation(dimension); addMouseEvent(contentPane); } + private void setRelativeLocation(Dimension dimension) { + DesignerFrame designerFrame = DesignerContext.getDesignerFrame(); + int positionX = designerFrame.getLocationOnScreen().x + (designerFrame.getWidth() - dimension.width) / 2; + int positionY = designerFrame.getContentFrame().getLocationOnScreen().y + 10; + this.setLocation(positionX, positionY); + } private Dimension calculatePreferSize() { Dimension contentDimension = contentPane.getPreferredSize(); @@ -65,6 +71,7 @@ public class ToastMsgDialog extends UIDialog { public void display(JPanel outerJPanel) { + show = true; outerJPanel.setLocation(0, -hide_height); ScheduledExecutorService TIP_TOOL_TIMER = createToastScheduleExecutorService(); TIP_TOOL_TIMER.scheduleAtFixedRate(new Runnable() { @@ -98,12 +105,13 @@ public class ToastMsgDialog extends UIDialog { TIP_TOOL_TIMER.shutdown(); ToastMsgDialog.this.setVisible(false); ToastMsgDialog.this.dispose(); + ToastMsgDialog.this.show = false; } outerJPanel.setLocation(point.x, point.y - 5); Dimension dimension = ToastMsgDialog.this.getSize(); ToastMsgDialog.this.setSize(new Dimension(dimension.width, dimension.height - 5)); } - }, 0,50, TimeUnit.MILLISECONDS); + }, 0, 50, TimeUnit.MILLISECONDS); } }, 5000, TimeUnit.MILLISECONDS); @@ -159,5 +167,7 @@ public class ToastMsgDialog extends UIDialog { super.dispose(); } - -} + public boolean isShow() { + return show; + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java index 97e8692dc..4d27dcf3d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/socketio/DesignerSocketIO.java @@ -7,20 +7,33 @@ import com.fr.design.EnvChangeEntrance; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.env.DesignerWorkspaceInfo; import com.fr.design.env.DesignerWorkspaceInfoContext; +import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.loghandler.DesignerLogger; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.design.mainframe.toast.DesignerToastMsgUtil; +import com.fr.design.mainframe.toast.ToastMsgDialog; import com.fr.design.ui.util.UIUtil; +import com.fr.design.utils.BrowseUtils; import com.fr.event.EventDispatcher; +import com.fr.general.CloudCenter; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.report.RemoteDesignConstants; import com.fr.serialization.SerializerHelper; import com.fr.stable.ArrayUtils; +import com.fr.stable.StableUtils; import com.fr.stable.StringUtils; import com.fr.third.apache.log4j.spi.LoggingEvent; +import com.fr.third.org.apache.http.client.config.RequestConfig; +import com.fr.third.org.apache.http.client.methods.CloseableHttpResponse; +import com.fr.third.org.apache.http.client.methods.HttpGet; import com.fr.third.org.apache.http.conn.ssl.NoopHostnameVerifier; import com.fr.third.org.apache.http.conn.ssl.TrustSelfSignedStrategy; +import com.fr.third.org.apache.http.impl.client.CloseableHttpClient; +import com.fr.third.org.apache.http.impl.client.HttpClients; import com.fr.third.org.apache.http.ssl.SSLContexts; import com.fr.web.WebSocketConfig; import com.fr.web.socketio.WebSocketProtocol; @@ -29,7 +42,6 @@ import com.fr.workspace.Workspace; import com.fr.workspace.base.WorkspaceConstants; import com.fr.workspace.connect.WorkspaceConnection; import com.fr.workspace.connect.WorkspaceConnectionInfo; -import com.fr.workspace.server.socket.SocketInfoOperator; import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; @@ -38,15 +50,21 @@ import io.socket.engineio.client.transports.Polling; import io.socket.engineio.client.transports.WebSocket; import java.io.File; import java.io.FileInputStream; +import java.net.URL; import java.security.KeyStore; import java.util.Arrays; import javax.net.ssl.SSLContext; -import javax.swing.*; +import javax.swing.BorderFactory; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.UIManager; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.event.MouseEvent; import java.io.IOException; import java.net.URI; -import java.net.URL; import java.util.Timer; -import java.util.TimerTask; public class DesignerSocketIO { @@ -56,18 +74,21 @@ public class DesignerSocketIO { Disconnecting } + private static final String WEBSOCKET_HELP_DOC = CloudCenter.getInstance().acquireUrlByKind("websocketConnect", "https://help.fanruan.com/finereport/doc-view-2512.html"); private static final String HTTPS = "https"; private static final String HTTP = "http"; private static Socket socket = null; private static Status status = Status.Disconnected; private static Timer disConnectHintTimer = null; private static long disConnectHintTimerDelay = 3000; + private static final int TIMEOUT = 5000; //维护一个当前工作环境的uri列表 private static String[] uri; //维护一个关于uri列表的计数器 private static int count; // 当前webSocket选择的协议 private static String currentProtocol; + private static ToastMsgDialog dialog = null; public static void close() { @@ -109,6 +130,7 @@ public class DesignerSocketIO { } else { //表示所有的uri都连接不成功 FineLoggerFactory.getLogger().warn("All uris failed to connect"); + showSocketDisconnectToast(); } } catch (Exception e) { FineLoggerFactory.getLogger().error(e.getMessage(), e); @@ -227,41 +249,35 @@ public class DesignerSocketIO { @Override public void call(Object... objects) { FineLoggerFactory.getLogger().info("start disConnectHintTimer"); - disConnectHintTimer = new Timer(); - disConnectHintTimer.schedule(new TimerTask() { - @Override - public void run() { - try { - /* - * todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上,切换成心跳断开之后进行提醒, - * socket 只用推日志和通知配置变更 - */ - printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}"); - if (status != Status.Disconnecting) { - showConnectionLostDialog(); - } - status = Status.Disconnected; - } finally { - disConnectHintTimer.cancel(); - disConnectHintTimer = null; - } - } - }, disConnectHintTimerDelay); + /* + * todo 远程心跳断开不一定 socket 断开 和远程紧密相关的业务都绑定在心跳上,切换成心跳断开之后进行提醒, + * socket 只用推日志和通知配置变更 + */ + printLog(objects, PrintEventLogImpl.ERROR, "disConnected args: {}"); + if (status != Status.Disconnecting) { + dealWithSocketDisconnect(); + } + status = Status.Disconnected; } }; - private static void showConnectionLostDialog() { + private static void dealWithSocketDisconnect() { + if (checkRPCConnect()) { + showSocketDisconnectToast(); + } else { + showRPCDisconnectDialog(); + } + } + + private static void showSocketDisconnectToast() { try { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - FineJOptionPane.showMessageDialog( - DesignerContext.getDesignerFrame(), - Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"), - UIManager.getString("OptionPane.messageDialogTitle"), - JOptionPane.ERROR_MESSAGE, - UIManager.getIcon("OptionPane.errorIcon")); - EnvChangeEntrance.getInstance().chooseEnv(); + if (dialog == null || !dialog.isShow()) { + dialog = DesignerToastMsgUtil.createPromptDialog(createDialogContent()); + dialog.setVisible(true); + } } }); } catch (Exception e) { @@ -269,6 +285,57 @@ public class DesignerSocketIO { } } + private static JPanel createDialogContent() { + JPanel jPanel = FRGUIPaneFactory.createBorderLayout_S_Pane(); + jPanel.add(new UILabel(Toolkit.i18nText("Fine-Design_WebSocket_Lost_Tip")), BorderLayout.WEST); + UILabel hyperLinkLabel = new UILabel(Toolkit.i18nText("Fine-Design_WebSocket_Lost_Tip_HyperLink_Text")); + hyperLinkLabel.addMouseListener(new MouseClickListener() { + @Override + public void mouseClicked(MouseEvent e) { + BrowseUtils.browser(WEBSOCKET_HELP_DOC); + } + }); + hyperLinkLabel.setBorder(BorderFactory.createEmptyBorder(0, 3, 0, 0)); + hyperLinkLabel.setForeground(Color.BLUE); + hyperLinkLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + jPanel.add(hyperLinkLabel, BorderLayout.CENTER); + return jPanel; + } + + private static void showRPCDisconnectDialog() { + UIUtil.invokeLaterIfNeeded(new Runnable() { + @Override + public void run() { + FineJOptionPane.showMessageDialog( + DesignerContext.getDesignerFrame(), + Toolkit.i18nText("Fine-Design_Basic_Remote_Disconnected"), + UIManager.getString("OptionPane.messageDialogTitle"), + JOptionPane.ERROR_MESSAGE, + UIManager.getIcon("OptionPane.errorIcon")); + EnvChangeEntrance.getInstance().chooseEnv(); + } + }); + } + + private static boolean checkRPCConnect() { + CloseableHttpClient httpclient = HttpClients.createDefault(); + WorkspaceConnectionInfo info = getConnectionInfo(); + HttpGet httpGet = new HttpGet(StableUtils.pathJoin(info.getUrl(), WorkspaceConstants.CONTROLLER_PREFIX, WorkspaceConstants.VT)); + RequestConfig requestConfig = RequestConfig + .custom() + .setConnectTimeout(TIMEOUT) + .setConnectionRequestTimeout(TIMEOUT) + .build(); + httpGet.setConfig(requestConfig); + try { + CloseableHttpResponse response = httpclient.execute(httpGet); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e, e.getMessage()); + return false; + } + return true; + } + //配置变更监听器 private static final Emitter.Listener modifyConfig = new Emitter.Listener() { @Override @@ -282,7 +349,7 @@ public class DesignerSocketIO { private static void printLog(Object[] objects, PrintEventLog printEventLog, String prefix) { for (Object object : objects) { if (object instanceof Throwable) { - Throwable throwable = (Throwable) object; + Throwable throwable = (Throwable) object; printEventLog.printThrowable(throwable); } else { printEventLog.print(prefix, object); @@ -292,7 +359,8 @@ public class DesignerSocketIO { interface PrintEventLog { void printThrowable(Throwable throwable); - void print(String s, Object ...object); + + void print(String s, Object... object); } enum PrintEventLogImpl implements PrintEventLog { @@ -321,4 +389,4 @@ public class DesignerSocketIO { }; } -} +} \ No newline at end of file From cc5d9910dcfa20da59ed7c8382e73a5584024683 Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 12 May 2022 18:01:12 +0800 Subject: [PATCH 07/55] =?UTF-8?q?REPORT-67417=20=E8=BF=90=E8=90=A5?= =?UTF-8?q?=E4=BA=A7=E5=93=81v1.0=20=E5=90=8C=E6=AD=A5=E4=B8=80=E4=BB=BD?= =?UTF-8?q?=E5=88=B010.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alphafine/AlphaFineConfigManager.java | 47 +- .../help/alphafine/AlphaFineConfigPane.java | 55 +- .../help/alphafine/AlphaFineShortCutUtil.java | 44 + .../actions/help/alphafine/SizedStack.java | 30 + .../design/dialog/link/MessageWithLink.java | 15 +- .../com/fr/design/utils/SvgPaintUtils.java | 28 + .../alphafine/AlphaFineConstants.java | 57 ++ .../mainframe/alphafine/AlphaFineHelper.java | 23 +- .../mainframe/alphafine/AlphaFineUtil.java | 76 ++ .../design/mainframe/alphafine/CellType.java | 50 +- .../alphafine/component/AlphaFineDialog.java | 6 +- .../alphafine/component/AlphaFineFrame.java | 784 ++++++++++++++++++ .../alphafine/component/AlphaFineList.java | 76 ++ .../alphafine/component/AlphaFinePane.java | 2 +- .../component/AlphaFineTextField.java | 19 +- .../AlphaFineToolTipContentCellRender.java | 68 ++ .../component/AlphaFineToolTipList.java | 42 + .../component/AlphaSearchTooltipPane.java | 62 ++ .../alphafine/component/LineCellRender.java | 32 + .../ProductNewsContentCellRender.java | 100 +++ .../component/ProductNewsImagePanel.java | 79 ++ .../alphafine/component/ProductNewsList.java | 78 ++ .../ProductNewsSearchResultPane.java | 36 + .../alphafine/component/SearchListModel.java | 126 +++ .../SearchResultContentCellRender.java | 83 ++ .../alphafine/component/SearchResultPane.java | 51 ++ .../component/SearchTooltipPopup.java | 58 ++ .../alphafine/component/SelectedLabel.java | 81 ++ .../exception/AlphaFineNetworkException.java | 14 + .../alphafine/model/ProductNews.java | 200 +++++ .../preview/DefaultProductNewsPane.java | 121 +++ .../preview/HelpDocumentNoResultPane.java | 167 ++++ .../preview/LoadingRightSearchResultPane.java | 167 ++++ .../alphafine/preview/NetWorkFailedPane.java | 69 ++ .../alphafine/preview/NoResultPane.java | 23 +- .../preview/NoResultWithLinkPane.java | 63 ++ .../alphafine/preview/ResultShowPane.java | 14 + .../alphafine/preview/SearchLoadingPane.java | 27 + .../preview/SimpleRightSearchResultPane.java | 32 + .../alphafine/question/QuestionPane.java | 59 ++ .../alphafine/question/QuestionWindow.java | 84 ++ .../ProductNewsSearchWorkerManager.java | 127 +++ .../alphafine/search/SearchManager.java | 17 + .../alphafine/search/SearchTextBean.java | 37 + .../alphafine/search/SearchWorkerManager.java | 146 ++++ .../manager/fun/AlphaFineSearchProvider.java | 12 + .../manager/impl/ActionSearchManager.java | 7 + .../manager/impl/DocumentSearchManager.java | 13 +- .../manager/impl/FileSearchManager.java | 7 + .../manager/impl/PluginSearchManager.java | 11 +- .../impl/ProductNewsSearchManager.java | 123 +++ .../fr/start/module/DesignerActivator.java | 26 + .../mainframe/alphafine/images/blue_bulb.svg | 4 + .../mainframe/alphafine/images/bulb.svg | 4 + .../mainframe/alphafine/images/clear.svg | 4 + .../mainframe/alphafine/images/close.svg | 3 + .../mainframe/alphafine/images/group.svg | 4 + .../mainframe/alphafine/images/group_new.svg | 4 + .../alphafine/images/groupbackgroud.svg | 3 + .../alphafine/images/history_search.svg | 4 + .../mainframe/alphafine/images/hot_search.svg | 3 + .../mainframe/alphafine/images/minimize.svg | 3 + 62 files changed, 3728 insertions(+), 82 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineShortCutUtil.java create mode 100644 designer-base/src/main/java/com/fr/design/actions/help/alphafine/SizedStack.java create mode 100644 designer-base/src/main/java/com/fr/design/utils/SvgPaintUtils.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipContentCellRender.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipList.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaSearchTooltipPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/LineCellRender.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsContentCellRender.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsImagePanel.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsSearchResultPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchListModel.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultContentCellRender.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchTooltipPopup.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SelectedLabel.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/exception/AlphaFineNetworkException.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/DefaultProductNewsPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/HelpDocumentNoResultPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/LoadingRightSearchResultPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NetWorkFailedPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultWithLinkPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/ResultShowPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SearchLoadingPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SimpleRightSearchResultPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionWindow.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/ProductNewsSearchWorkerManager.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchManager.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchTextBean.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchWorkerManager.java create mode 100644 designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/blue_bulb.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bulb.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/clear.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/close.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group_new.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/history_search.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/hot_search.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/minimize.svg diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java index 029632709..a8970f9d1 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java @@ -1,5 +1,6 @@ package com.fr.design.actions.help.alphafine; +import com.fr.design.DesignerEnvManager; import com.fr.general.ComparatorUtils; import com.fr.license.function.VT4FR; import com.fr.stable.OperatingSystem; @@ -8,6 +9,12 @@ import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.XMLReadable; import com.fr.stable.xml.XMLable; import com.fr.stable.xml.XMLableReader; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Set; +import java.util.Stack; import org.jetbrains.annotations.NotNull; import javax.swing.*; @@ -82,9 +89,29 @@ public class AlphaFineConfigManager implements XMLable { */ private boolean needRemind = true; + /** + * 产品动态 + */ + private boolean productDynamics = true; + private Map actionSearchTextCache = new HashMap<>(8); private String cacheBuildNO; + + + // todo 暂不持久化 方便测试 + /** + * key: 登录的bbs用户 + * value: alphaFine历史搜索记录 + */ + private Map> historySearchMap = new LinkedHashMap<>(); + + /** + * key: 登录的bbs用户 + * value: 已读的cid的集合 + */ + private Map> readSetMap = new LinkedHashMap<>(); + /** * 直接操作菜单次数 */ @@ -120,6 +147,7 @@ public class AlphaFineConfigManager implements XMLable { this.setContainFileContent(reader.getAttrAsBoolean("isContainFileContent", false)); this.setNeedSegmentationCheckbox(reader.getAttrAsBoolean("needSegmentationCheckbox", true)); this.setNeedIntelligentCustomerService(reader.getAttrAsBoolean("needIntelligentCustomerService", true)); + this.setProductDynamics(reader.getAttrAsBoolean("productDynamics", true)); this.setShortcuts(reader.getAttrAsString("shortcuts", getDefaultShortCuts())); this.setNeedRemind(reader.getAttrAsBoolean("isNeedRemind", true)); this.setOperateCount(reader.getAttrAsInt("operateCount", 0)); @@ -167,7 +195,8 @@ public class AlphaFineConfigManager implements XMLable { .attr("isNeedRemind", this.isNeedRemind()) .attr("operateCount", this.getOperateCount()) .attr("needSegmentationCheckbox", this.isNeedSegmentationCheckbox()) - .attr("needIntelligentCustomerService", this.isNeedIntelligentCustomerService()); + .attr("needIntelligentCustomerService", this.isNeedIntelligentCustomerService()) + .attr("productDynamics", this.isProductDynamics()); writeActionSearchTextCacheXML(writer); writer.end(); } @@ -335,4 +364,20 @@ public class AlphaFineConfigManager implements XMLable { public void setCacheBuildNO(@NotNull String cacheBuildNO) { this.cacheBuildNO = cacheBuildNO; } + + public Stack getHistorySearch() { + return historySearchMap.computeIfAbsent(DesignerEnvManager.getEnvManager().getDesignerLoginUsername(), k -> new SizedStack<>(3)); + } + + public Set getReadSet() { + return readSetMap.computeIfAbsent(DesignerEnvManager.getEnvManager().getDesignerLoginUsername(), k -> new HashSet<>()); + } + + public boolean isProductDynamics() { + return productDynamics; + } + + public void setProductDynamics(boolean productDynamics) { + this.productDynamics = productDynamics; + } } diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java index 5bf0214e0..55d467e88 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigPane.java @@ -25,37 +25,12 @@ import java.awt.event.MouseEvent; public class AlphaFineConfigPane extends BasicPane { private static final String TYPE = "pressed"; private static final String DISPLAY_TYPE = "+"; - private static final String BACK_SLASH = "BACK_SLASH"; - private static final String DISPLAY_BACK_SLASH = "\\"; - private static final String SLASH = "SLASH"; - private static final String DISPLAY_SLASH = "/"; - private static final String CONTROL = "CONTROL"; - private static final String DISPLAY_CONTROL = "ctrl"; - private static final String OPEN_BRACKET = "OPEN_BRACKET"; - private static final String DISPLAY_OPEN_BRACKET = "{"; - private static final String CLOSE_BRACKET = "CLOSE_BRACKET"; - private static final String DISPLAY_CLOSE_BRACKET = "}"; - private static final String COMMA = "COMMA"; - private static final String DISPLAY_COMMA = ","; - private static final String PERIOD = "PERIOD"; - private static final String DISPLAY_PERIOD = "."; - private static final String SEMICOLON = "SEMICOLON"; - private static final String DISPLAY_SEMICOLON = ";"; - private static final String QUOTE = "QUOTE"; - private static final String DISPLAY_QUOTE = "'"; - private static final String EQUALS = "EQUALS"; - private static final String DISPLAY_EQUALS = "+"; - private static final String MINUS = "MINUS"; - private static final String DISPLAY_MINUS = "-"; - private static final String COMMAND = "META"; - private static final String SMALL_COMMAND = "meta"; - private static final String DISPLAY_COMMAND = "\u2318"; private static final double COLUMN_GAP = 180; private static final double ROW_GAP = 25; private KeyStroke shortCutKeyStore = null; - private UICheckBox enabledCheckbox, searchOnlineCheckbox, needSegmentationCheckbox, needIntelligentCustomerService, containRecommendCheckbox, containActionCheckbox, containDocumentCheckbox, containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox; + private UICheckBox enabledCheckbox, searchOnlineCheckbox, needSegmentationCheckbox, needIntelligentCustomerService, productDynamicsCheckbox, containActionCheckbox, containDocumentCheckbox, containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox; private UITextField shortcutsField; public AlphaFineConfigPane() { @@ -75,9 +50,8 @@ public class AlphaFineConfigPane extends BasicPane { private Component[][] initSearchRangeComponents() { Component[][] components = new Component[][]{ - new Component[]{containRecommendCheckbox, containActionCheckbox, containDocumentCheckbox}, + new Component[]{productDynamicsCheckbox, containActionCheckbox, containDocumentCheckbox}, new Component[]{containTemplateCheckbox, containPluginCheckbox, containFileContentCheckbox}, - new Component[]{needIntelligentCustomerService, null, null} }; return components; } @@ -95,7 +69,7 @@ public class AlphaFineConfigPane extends BasicPane { double[] columnSize = {COLUMN_GAP, COLUMN_GAP, COLUMN_GAP}; JPanel northPane = FRGUIPaneFactory.createTitledBorderPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_Search_Range")); - containRecommendCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_AlphaFine_Recommend")); + productDynamicsCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_Dynamics")); containActionCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set")); containPluginCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon")); containDocumentCheckbox = new UICheckBox(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help")); @@ -139,7 +113,7 @@ public class AlphaFineConfigPane extends BasicPane { int keyCode = e.getKeyCode(); shortCutKeyStore = KeyStroke.getKeyStroke(keyCode, modifier); String str = shortCutKeyStore.toString(); - shortcutsField.setText(getDisplayShortCut(str)); + shortcutsField.setText(AlphaFineShortCutUtil.getDisplayShortCut(str)); shortcutsField.selectAll(); } }); @@ -153,16 +127,16 @@ public class AlphaFineConfigPane extends BasicPane { @Override public void actionPerformed(ActionEvent e) { if (!searchOnlineCheckbox.isSelected()) { - containRecommendCheckbox.setEnabled(false); + productDynamicsCheckbox.setEnabled(false); containPluginCheckbox.setEnabled(false); containDocumentCheckbox.setEnabled(false); needIntelligentCustomerService.setEnabled(false); - containRecommendCheckbox.setSelected(false); + productDynamicsCheckbox.setSelected(false); containPluginCheckbox.setSelected(false); containDocumentCheckbox.setSelected(false); needIntelligentCustomerService.setSelected(false); } else { - containRecommendCheckbox.setEnabled(true); + productDynamicsCheckbox.setEnabled(true); containPluginCheckbox.setEnabled(true); containDocumentCheckbox.setEnabled(true); needIntelligentCustomerService.setEnabled(true); @@ -207,10 +181,10 @@ public class AlphaFineConfigPane extends BasicPane { this.containPluginCheckbox.setSelected(alphaFineConfigManager.isContainPlugin() && enabled4Locale); this.containPluginCheckbox.setEnabled(enabled4Locale); - this.containRecommendCheckbox.setSelected(alphaFineConfigManager.isContainRecommend() && enabled4Locale); - this.containRecommendCheckbox.setEnabled(enabled4Locale); + this.productDynamicsCheckbox.setSelected(alphaFineConfigManager.isProductDynamics() && enabled4Locale); + this.productDynamicsCheckbox.setEnabled(enabled4Locale); - this.shortcutsField.setText(getDisplayShortCut(alphaFineConfigManager.getShortcuts())); + this.shortcutsField.setText(AlphaFineShortCutUtil.getDisplayShortCut(alphaFineConfigManager.getShortcuts())); this.needSegmentationCheckbox.setSelected(alphaFineConfigManager.isNeedSegmentationCheckbox()); @@ -226,7 +200,7 @@ public class AlphaFineConfigPane extends BasicPane { alphaFineConfigManager.setContainPlugin(this.containPluginCheckbox.isSelected()); alphaFineConfigManager.setContainAction(this.containActionCheckbox.isSelected()); alphaFineConfigManager.setContainDocument(this.containDocumentCheckbox.isSelected()); - alphaFineConfigManager.setContainRecommend(this.containRecommendCheckbox.isSelected()); + alphaFineConfigManager.setProductDynamics(this.productDynamicsCheckbox.isSelected()); alphaFineConfigManager.setEnabled(this.enabledCheckbox.isSelected()); alphaFineConfigManager.setSearchOnLine(this.searchOnlineCheckbox.isSelected()); alphaFineConfigManager.setContainTemplate(this.containTemplateCheckbox.isSelected()); @@ -245,13 +219,6 @@ public class AlphaFineConfigPane extends BasicPane { } - private String getDisplayShortCut(String shortCut) { - return shortCut.replace(TYPE, DISPLAY_TYPE).replace(BACK_SLASH, DISPLAY_BACK_SLASH).replace(SLASH, DISPLAY_SLASH) - .replace(CONTROL, DISPLAY_CONTROL).replace(OPEN_BRACKET, DISPLAY_OPEN_BRACKET).replace(CLOSE_BRACKET, DISPLAY_CLOSE_BRACKET) - .replace(COMMA, DISPLAY_COMMA).replace(PERIOD, DISPLAY_PERIOD).replace(SEMICOLON, DISPLAY_SEMICOLON).replace(QUOTE, DISPLAY_QUOTE) - .replace(EQUALS, DISPLAY_EQUALS).replace(MINUS, DISPLAY_MINUS).replace(COMMAND, DISPLAY_COMMAND).replace(SMALL_COMMAND, DISPLAY_COMMAND); - } - private KeyStroke convert2KeyStroke(String ks) { return KeyStroke.getKeyStroke(ks.replace(DISPLAY_TYPE, TYPE)); diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineShortCutUtil.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineShortCutUtil.java new file mode 100644 index 000000000..e21fc84ee --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineShortCutUtil.java @@ -0,0 +1,44 @@ +package com.fr.design.actions.help.alphafine; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/26 + */ +public class AlphaFineShortCutUtil { + + private static final String TYPE = "pressed"; + private static final String DISPLAY_TYPE = "+"; + private static final String BACK_SLASH = "BACK_SLASH"; + private static final String DISPLAY_BACK_SLASH = "\\"; + private static final String SLASH = "SLASH"; + private static final String DISPLAY_SLASH = "/"; + private static final String CONTROL = "CONTROL"; + private static final String DISPLAY_CONTROL = "ctrl"; + private static final String OPEN_BRACKET = "OPEN_BRACKET"; + private static final String DISPLAY_OPEN_BRACKET = "{"; + private static final String CLOSE_BRACKET = "CLOSE_BRACKET"; + private static final String DISPLAY_CLOSE_BRACKET = "}"; + private static final String COMMA = "COMMA"; + private static final String DISPLAY_COMMA = ","; + private static final String PERIOD = "PERIOD"; + private static final String DISPLAY_PERIOD = "."; + private static final String SEMICOLON = "SEMICOLON"; + private static final String DISPLAY_SEMICOLON = ";"; + private static final String QUOTE = "QUOTE"; + private static final String DISPLAY_QUOTE = "'"; + private static final String EQUALS = "EQUALS"; + private static final String DISPLAY_EQUALS = "+"; + private static final String MINUS = "MINUS"; + private static final String DISPLAY_MINUS = "-"; + private static final String COMMAND = "META"; + private static final String SMALL_COMMAND = "meta"; + private static final String DISPLAY_COMMAND = "\u2318"; + + public static String getDisplayShortCut(String shortCut) { + return shortCut.replace(TYPE, DISPLAY_TYPE).replace(BACK_SLASH, DISPLAY_BACK_SLASH).replace(SLASH, DISPLAY_SLASH) + .replace(CONTROL, DISPLAY_CONTROL).replace(OPEN_BRACKET, DISPLAY_OPEN_BRACKET).replace(CLOSE_BRACKET, DISPLAY_CLOSE_BRACKET) + .replace(COMMA, DISPLAY_COMMA).replace(PERIOD, DISPLAY_PERIOD).replace(SEMICOLON, DISPLAY_SEMICOLON).replace(QUOTE, DISPLAY_QUOTE) + .replace(EQUALS, DISPLAY_EQUALS).replace(MINUS, DISPLAY_MINUS).replace(COMMAND, DISPLAY_COMMAND).replace(SMALL_COMMAND, DISPLAY_COMMAND); + } +} diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/SizedStack.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/SizedStack.java new file mode 100644 index 000000000..fbc6eca00 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/SizedStack.java @@ -0,0 +1,30 @@ +package com.fr.design.actions.help.alphafine; + +import java.util.Stack; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/23 + */ +public class SizedStack extends Stack { + + private final int maxSize; + + public SizedStack(int size) { + super(); + this.maxSize = size; + } + + @Override + public T push(T object) { + while (this.size() >= maxSize) { + this.remove(0); + } + // 不重复 + if (this.contains(object)) { + return object; + } + return super.push(object); + } +} \ No newline at end of file diff --git a/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java index f73ec77df..2e839d27c 100644 --- a/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java +++ b/designer-base/src/main/java/com/fr/design/dialog/link/MessageWithLink.java @@ -37,15 +37,19 @@ public class MessageWithLink extends JEditorPane { } public MessageWithLink(String frontMessage, String linkName, String link, String backMessage) { - this(frontMessage, linkName, link, backMessage, LABEL.getBackground(), LABEL.getFont()); + this(frontMessage, linkName, link, backMessage, LABEL.getBackground(), LABEL.getFont(), LABEL.getForeground()); } public MessageWithLink(String message, String linkName, String link, Color color, Font font) { - this(message, linkName, link, StringUtils.EMPTY, color, font); + this(message, linkName, link, StringUtils.EMPTY, color, font, LABEL.getForeground()); } public MessageWithLink(String frontMessage, String linkName, String link, String backMessage, Color color, Font font) { - super("text/html", "" + frontMessage + "" + linkName + "" + backMessage + ""); + this(frontMessage, linkName, link, backMessage, color, font, LABEL.getForeground()); + } + + public MessageWithLink(String frontMessage, String linkName, String link, String backMessage, Color backgroundColor, Font font, Color fontColor) { + super("text/html", "" + frontMessage + "" + linkName + "" + backMessage + ""); initListener(link); setEditable(false); setBorder(null); @@ -66,12 +70,13 @@ public class MessageWithLink extends JEditorPane { }); } - private static StringBuilder generateStyle(Color color, Font font) { + private static StringBuilder generateStyle(Color backgroundColor, Font font, Color fontColor) { // 构建相同风格样式 StringBuilder style = new StringBuilder("font-family:" + font.getFamily() + ";"); style.append("font-weight:").append(font.isBold() ? "bold" : "normal").append(";"); style.append("font-size:").append(font.getSize()).append("pt;"); - style.append("background-color: rgb(").append(color.getRed()).append(",").append(color.getGreen()).append(",").append(color.getBlue()).append(");"); + style.append("color:rgb(").append(fontColor.getRed()).append(",").append(fontColor.getGreen()).append(",").append(fontColor.getBlue()).append(");"); + style.append("background-color: rgb(").append(backgroundColor.getRed()).append(",").append(backgroundColor.getGreen()).append(",").append(backgroundColor.getBlue()).append(");"); return style; } diff --git a/designer-base/src/main/java/com/fr/design/utils/SvgPaintUtils.java b/designer-base/src/main/java/com/fr/design/utils/SvgPaintUtils.java new file mode 100644 index 000000000..9f3dd0c46 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/utils/SvgPaintUtils.java @@ -0,0 +1,28 @@ +package com.fr.design.utils; + +import com.fr.base.svg.SVGIcon; +import com.fr.base.svg.SystemScaleUtils; +import java.awt.Graphics2D; + +/** + * 用于绘制svg图片缩放(高分屏下) + * + * @author hades + * @version 11.0 + * Created by hades on 2022/5/6 + */ +public class SvgPaintUtils { + + public static void beforePaint(Graphics2D g2) { + if (SystemScaleUtils.isJreHiDPIEnabled()) { + g2.scale(1 / SVGIcon.SYSTEM_SCALE, 1 / SVGIcon.SYSTEM_SCALE); + } + } + + public static void afterPaint(Graphics2D g2) { + if (SystemScaleUtils.isJreHiDPIEnabled()) { + g2.scale(SVGIcon.SYSTEM_SCALE, SVGIcon.SYSTEM_SCALE); + } + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java index 3946c9cbc..f4440fb5c 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java @@ -1,13 +1,20 @@ package com.fr.design.mainframe.alphafine; import com.fr.base.extension.FileExtension; +import com.fr.base.svg.IconUtils; +import com.fr.design.i18n.Toolkit; import com.fr.design.utils.DesignUtils; import com.fr.general.CloudCenter; +import com.fr.general.IOUtils; import java.awt.Color; import java.awt.Dimension; import java.awt.Font; import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedHashSet; +import java.util.Set; +import javax.swing.Icon; /** @@ -54,6 +61,11 @@ public class AlphaFineConstants { public static final Dimension HOT_ISSUES_JAPNEL_SIZE = new Dimension(213, 182); + /** + * 展示面板的尺寸 + */ + public static final Dimension PREVIEW_SIZE = new Dimension(680, 305); + public static final Dimension CLOSE_BUTTON_SIZE = new Dimension(40, 40); public static final Color WHITE = new Color(0xf9f9f9); @@ -131,6 +143,12 @@ public class AlphaFineConstants { public static final String ALPHA_PREVIEW = CloudCenter.getInstance().acquireUrlByKind("af.preview"); + public static final String ALPHA_CID = CloudCenter.getInstance().acquireUrlByKind("af.cid", "https://cid.fanruan.com/api/nav/alphafine"); + + private static final String DEFAULT_RECOMMEND = "[ { \"name\":\"快速入门指南\", \"link\":\"https://help.fanruan.com/finereport/doc-view-1335.html?source=3\" }, { \"name\":\"报表应用学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-1336.html?source=3\" }, { \"name\":\"参数应用学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4219.html?source=3\" }, { \"name\":\"填报学习路径\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4103.html?source=3\" }, { \"name\":\"API接口汇总\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4327.html?source=3\" }, { \"name\":\"文档月刊\", \"link\":\"https://help.fanruan.com/finereport/doc-view-4613.html?source=3\" } ]"; + + public static final String ALPHA_HELP_RECOMMEND = CloudCenter.getInstance().acquireUrlByKind("af.recommend", DEFAULT_RECOMMEND); + public static final String JAVASCRIPT_PREFIX = "javascript:SendJava"; public static final String CHINESE_CHARACTERS = "[\\u4e00-\\u9fa5]"; @@ -143,10 +161,49 @@ public class AlphaFineConstants { public static final String BACK_ICON_NAME = "back@1x.png"; + public static final Icon NO_RESULT_ICON = IOUtils.readIcon(AlphaFineConstants.IMAGE_URL + "noresult.png"); + + public static final Color SUSPENDED_COLOR = new Color(84, 165, 249); + + public static final Color FOREGROUND_COLOR = new Color(51, 51, 52); + + /** + * 后面数字代表透明度 80% + */ + public static final Color FOREGROUND_COLOR_8 = new Color(51, 51, 52, 204); + + public static final Color FOREGROUND_COLOR_6 = new Color(51, 51, 52, 153); + + public static final Color FOREGROUND_COLOR_5 = new Color(51, 51, 52, 128); + + public static final Color BACKGROUND_COLOR = new Color(245, 245, 247); + + public static final Icon BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/bulb.svg"); + + public static final Icon BLUE_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/blue_bulb.svg"); + + public static final String HOT_SEARCH = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search"); + + public static final Set HOT_SEARCH_SET = new LinkedHashSet<>( + Arrays.asList( + Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search_TOP_ONE"), + Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search_TOP_TWO"), + Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search_TOP_THREE") + ) + ); + + public static final ArrayList CONJUNCTION = new ArrayList() {{ add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Conjunction_HE")); add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Conjunction_YU")); add(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Conjunction_DE")); }}; + public static final String LOADING = "loading"; + + public static final String NETWORK_ERROR = "network error"; + + public static final String TITLE = "AlphaFine"; + + public static final int DEFAULT_CLICK_COUNT = 1; } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineHelper.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineHelper.java index dd5a01349..441bd03ac 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineHelper.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineHelper.java @@ -2,12 +2,11 @@ package com.fr.design.mainframe.alphafine; import com.fr.design.DesignerEnvManager; import com.fr.design.actions.help.alphafine.AlphaFineConfigManager; -import com.fr.design.mainframe.DesignerContext; import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; import com.fr.design.mainframe.alphafine.cell.model.MoreModel; import com.fr.design.mainframe.alphafine.cell.model.NoResultModel; import com.fr.design.mainframe.alphafine.cell.model.RobotModel; -import com.fr.design.mainframe.alphafine.component.AlphaFineDialog; +import com.fr.design.mainframe.alphafine.component.AlphaFineFrame; import com.fr.design.mainframe.alphafine.model.SearchResult; import com.fr.design.mainframe.alphafine.search.manager.impl.DocumentSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.HotIssuesManager; @@ -25,6 +24,7 @@ import com.fr.json.JSONFactory; import com.fr.json.JSONObject; import com.fr.stable.StringUtils; +import java.awt.Frame; import java.util.List; /** @@ -32,7 +32,7 @@ import java.util.List; */ public class AlphaFineHelper { public static final NoResultModel NO_CONNECTION_MODEL = new NoResultModel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Connection_Failed")); - private static AlphaFineDialog alphaFineDialog; + private static AlphaFineFrame alphaFineDialog; private static final String URL_FOR_TEST_NETWORK = "https://www.baidu.com"; private AlphaFineHelper() { @@ -62,17 +62,30 @@ public class AlphaFineHelper { return; } if (alphaFineDialog == null) { - alphaFineDialog = new AlphaFineDialog(DesignerContext.getDesignerFrame(), forceOpen); + alphaFineDialog = new AlphaFineFrame(); alphaFineDialog.setVisible(true); final AlphaFineConfigManager manager = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager(); manager.setNeedRemind(false); } else { - alphaFineDialog.setVisible(!alphaFineDialog.isVisible()); + alphaFineDialog.setVisible(true); + // check 如果最小化 点击悬浮按钮后 恢复 + if ((alphaFineDialog.getExtendedState() & Frame.ICONIFIED) != 0) { + // 从最小化恢复 + alphaFineDialog.setExtendedState(Frame.NORMAL); + } + alphaFineDialog.toFront(); } } + public static void resetAlphaFineDialog() { + alphaFineDialog = null; + } + + public static AlphaFineFrame getAlphaFineDialog() { + return alphaFineDialog; + } /** * 获取文件名上级目录 diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java new file mode 100644 index 000000000..12ff5a9d6 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java @@ -0,0 +1,76 @@ +package com.fr.design.mainframe.alphafine; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; +import com.fr.stable.StringUtils; +import java.util.Set; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/20 + */ +public class AlphaFineUtil { + + public static String highLightModelName(String modelName, String[] strings) { + if (strings == null) { + return modelName; + } + for (String string : strings) { + String primaryStr = getReplacedString(modelName, string); +// modelName = escapeExprSpecialWord(modelName); + if (StringUtils.isNotEmpty(primaryStr)) { +// primaryStr = escapeExprSpecialWord(primaryStr); + modelName = modelName.replaceAll("(?i)" + primaryStr, "|" + primaryStr + "|"); + } + } + modelName = "" + modelName.replaceAll("\\|", StringUtils.EMPTY) + ""; + return modelName; + } + + + private static String getReplacedString(String modelName, String string) { + //需要考虑modelName有空格的情况 + //比如现在是work boo k 搜索词是workb,应该要替换的部分是work b + //先去掉已经匹配替换过的部分,因为考虑到分词的情况,可能会进行多次替换 + final String regex = "\\|\\|"; + modelName = modelName.replaceAll(regex, StringUtils.EMPTY); + //再去掉空格进行匹配 + String noBlackName = modelName.replaceAll(StringUtils.BLANK, StringUtils.EMPTY).toLowerCase(); + int index = noBlackName.indexOf(string.toLowerCase()); + if (index == -1) { + return StringUtils.EMPTY; + } + StringBuilder result = new StringBuilder(); + int count = 0; + while (count < string.length()) { + char pos = noBlackName.charAt(index++); + result.append(pos); + count += pos == ' ' ? 0 : 1; + } + return result.toString(); + } + + public static String escapeExprSpecialWord(String keyword) { + if (StringUtils.isNotBlank(keyword)) { + String[] fbsArr = { "\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|" }; + for (String key : fbsArr) { + if (keyword.contains(key)) { + keyword = keyword.replace(key, "\\" + key); + } + } + } + return keyword; + } + + + public static boolean unread() { + Set readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet(); + Set idSet = ProductNewsSearchManager.getInstance().getIdSet(); + return !idSet.isEmpty() && !readSet.containsAll(idSet); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java index 3d533e47b..c558ee584 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/CellType.java @@ -1,15 +1,49 @@ package com.fr.design.mainframe.alphafine; +import com.fr.stable.StringUtils; + /** * Created by XiaXiang on 2017/4/27. */ public enum CellType { - RECOMMEND(0), ACTION(1), DOCUMENT(2), FILE(3), PLUGIN(4), REUSE(5), NO_RESULT(6), MORE(7), RECOMMEND_ROBOT(8), BOTTOM(9), ROBOT(10); + RECOMMEND(0), + ACTION(1, "action", "actionResult", false), + DOCUMENT(2, "document", "documentResult", true), + FILE(3, "file", "fileResult", false), + PLUGIN(4, "plugin", "pluginResult", true), + REUSE(5), + NO_RESULT(6, "noResult", StringUtils.EMPTY, false), + MORE(7), + RECOMMEND_ROBOT(8), + BOTTOM(9), + ROBOT(10), + PRODUCT_NEWS(11, "productNews", "productNewsResult", true); private int typeValue; - CellType(int type) { + /** + * 标志位 索引无搜索结果面板 + * + * 空字符表示不涉及索引该项 + */ + private String flagStr4None; + + /** + * 标志位 索引有搜索结果面板 + */ + private String flagStr4Result; + + private boolean needNetWork = true; + + CellType(int type, String flagStr4None, String flagStr4Result, boolean needNetWork) { this.typeValue = type; + this.flagStr4None = flagStr4None; + this.flagStr4Result = flagStr4Result; + this.needNetWork = needNetWork; + } + + CellType(int type) { + this(type, StringUtils.EMPTY, StringUtils.EMPTY, true); } public static CellType parse(int typeValue) { @@ -29,5 +63,17 @@ public enum CellType { public void setTypeValue(int typeValue) { this.typeValue = typeValue; } + + public String getFlagStr4None() { + return flagStr4None; + } + + public String getFlagStr4Result() { + return flagStr4Result; + } + + public boolean isNeedNetWork() { + return needNetWork; + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java index 47c2e6c7e..4a55d973f 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineDialog.java @@ -435,7 +435,7 @@ public class AlphaFineDialog extends UIDialog { */ private void removeLeftPane() { if (searchListModel.isEmpty() && defaultPane == null) { - defaultPane = new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result"), AlphaFineConstants.IMAGE_URL + "no_result.png"); + defaultPane = new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result"), AlphaFineConstants.NO_RESULT_ICON); searchResultPane.remove(leftSearchResultPane); searchResultPane.add(defaultPane, BorderLayout.WEST); refreshContainer(); @@ -636,7 +636,7 @@ public class AlphaFineDialog extends UIDialog { bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportWorkBookAsImageData(fileName); } catch (Exception ignored) { // 兼容下老版本 - bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName); + bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName); } return TemplateExportOperator.byteDataToImage(bytes); } @@ -661,7 +661,7 @@ public class AlphaFineDialog extends UIDialog { break; case ACTION: rightSearchResultPane.removeAll(); - rightSearchResultPane.add(new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result"), AlphaFineConstants.IMAGE_URL + "noresult.png")); + rightSearchResultPane.add(new NoResultPane(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result"), AlphaFineConstants.NO_RESULT_ICON)); validate(); repaint(); break; diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java new file mode 100644 index 000000000..d97710ef1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java @@ -0,0 +1,784 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.base.svg.IconUtils; +import com.fr.base.svg.SVGLoader; +import com.fr.design.DesignerEnvManager; +import com.fr.design.actions.help.alphafine.AlphaFineConfigManager; +import com.fr.design.actions.help.alphafine.AlphaFineShortCutUtil; +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.borders.UITextFieldBorder; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.CellType; +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import com.fr.design.mainframe.alphafine.model.ProductNews; +import com.fr.design.mainframe.alphafine.preview.DefaultProductNewsPane; +import com.fr.design.mainframe.alphafine.preview.HelpDocumentNoResultPane; +import com.fr.design.mainframe.alphafine.preview.LoadingRightSearchResultPane; +import com.fr.design.mainframe.alphafine.preview.NetWorkFailedPane; +import com.fr.design.mainframe.alphafine.preview.NoResultPane; +import com.fr.design.mainframe.alphafine.preview.NoResultWithLinkPane; +import com.fr.design.mainframe.alphafine.preview.SearchLoadingPane; +import com.fr.design.mainframe.alphafine.preview.SimpleRightSearchResultPane; +import com.fr.design.mainframe.alphafine.question.QuestionWindow; +import com.fr.design.mainframe.alphafine.search.ProductNewsSearchWorkerManager; +import com.fr.design.mainframe.alphafine.search.SearchTextBean; +import com.fr.design.mainframe.alphafine.search.SearchWorkerManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.ActionSearchManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.DocumentSearchManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.FileSearchManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.PluginSearchManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; +import com.fr.design.mainframe.alphafine.search.manager.impl.SegmentationManager; +import com.fr.design.utils.DesignUtils; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; +import java.awt.BorderLayout; +import java.awt.CardLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.Insets; +import java.awt.RenderingHints; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.ArrayList; +import java.util.List; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JButton; +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import javax.swing.Timer; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/04/06 + */ +public class AlphaFineFrame extends JFrame { + + private static final String ADVANCED_SEARCH_MARK = "k:"; + + private static final int TIMER_DELAY = 300; + + private static final String PLACE_HOLDER = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine"); + + private static final String SETTING = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Set"); + + private static final String NO_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_No_Result"); + + private static final String SKILLS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Skills"); + + private static final String SEARCH_TERM = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Search_Term"); + + private static final String SEARCH = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Search"); + + private static final String GO_FORUM = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Go_Forum"); + + private static final String TEMPLATES = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Templates"); + + public static final String PRODUCT_NEWS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_News"); + + private static final String HELP = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help"); + + private static final String PLUGIN = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon"); + + private static final String ONE_CLICK_READ = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_One_Click_Read"); + + private static final String NO_SEARCH_RESULT = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_NO_Result"); + + private static final String PRODUCT_DYNAMICS = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Product_Dynamics"); + + private static final Image SEARCH_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/search.svg"); + + private static final Color BORDER_COLOR = new Color(232, 232, 233); + + private final CardLayout cardLayout = new CardLayout(); + + private final JPanel resultPane = new JPanel(cardLayout); + + private String storeText; + + private String[] segmentationResult; + + private UILabel useTipLabel; + + private UILabel tipIconLabel; + + private AlphaFineTextField searchTextField; + + private AlphaFineList searchResultList; + + private SearchLoadingPane searchLoadingPane; + + private JPanel searchTextFieldWrapperPane; + + private UILabel clearLabel; + + private CellType selectedType; + + private String beforeSearchStr = StringUtils.EMPTY; + + private SearchWorkerManager settingSearchWorkerManager; + + private SearchWorkerManager fileSearchWorkerManager; + + private SearchWorkerManager documentWorkerManager; + + private SearchWorkerManager pluginSearchWorkerManager; + + private SearchWorkerManager currentSearchWorkerManager; + + private ProductNewsSearchWorkerManager productNewsSearchWorkerManager; + + public AlphaFineFrame() { + this.setTitle(AlphaFineConstants.TITLE); + setUndecorated(true); + setSize(AlphaFineConstants.FIELD_SIZE); + initComponents(); + centerWindow(this); + initSearchManager(); + } + + private void initSearchManager() { + + this.productNewsSearchWorkerManager = new ProductNewsSearchWorkerManager( + CellType.PRODUCT_NEWS, + searchTextBean -> { + return ProductNewsSearchManager.getInstance().getSearchResult(searchTextBean.getSegmentation()); + }, + this + ); + + this.settingSearchWorkerManager = new SearchWorkerManager( + CellType.ACTION, + searchTextBean -> ActionSearchManager.getInstance().getSearchResult(searchTextBean), + this, + new SimpleRightSearchResultPane(new NoResultPane(NO_RESULT, AlphaFineConstants.NO_RESULT_ICON)) + ); + fileSearchWorkerManager = new SearchWorkerManager( + CellType.FILE, + searchTextBean -> FileSearchManager.getInstance().getSearchResult(searchTextBean), + this, + new LoadingRightSearchResultPane() + ); + documentWorkerManager = new SearchWorkerManager( + CellType.DOCUMENT, + searchTextBean -> DocumentSearchManager.getInstance().getSearchResult(searchTextBean), + this, + new SimpleRightSearchResultPane(new JPanel()) + ); + + pluginSearchWorkerManager = new SearchWorkerManager( + CellType.PLUGIN, + searchTextBean -> PluginSearchManager.getInstance().getSearchResult(searchTextBean), + this, + new LoadingRightSearchResultPane() + ); + + } + + /** + * 初始化全部组件 + */ + private void initComponents() { + + add(createTopPane(), BorderLayout.NORTH); + initSearchTextField(); + add(createSearchPane(), BorderLayout.CENTER); + add(createShowPane(), BorderLayout.SOUTH); + this.getContentPane().setBackground(Color.WHITE); + this.setIconImage(SEARCH_IMAGE); + this.setSize(AlphaFineConstants.FULL_SIZE); + } + + private JPanel createTopPane() { + JPanel topPane = new JPanel(new BorderLayout()); + topPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + topPane.setBackground(Color.WHITE); + JPanel topLeftPane = new JPanel(new FlowLayout(FlowLayout.LEFT)); + topLeftPane.setBackground(Color.WHITE); + UILabel alphaFineLabel = new UILabel(AlphaFineConstants.TITLE); + alphaFineLabel.setFont(new Font("Arial Black", Font.PLAIN, 20)); + alphaFineLabel.setForeground(UIConstants.FLESH_BLUE); + topLeftPane.add(alphaFineLabel); + topPane.add(topLeftPane, BorderLayout.WEST); + + JPanel topRightPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 10)); + topRightPane.setBackground(Color.WHITE); + JPanel tipPane = new JPanel(new BorderLayout()); + tipPane.setBackground(Color.WHITE); + String toolTip = AlphaFineShortCutUtil.getDisplayShortCut(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Short_Cut", DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getShortcuts())); + tipIconLabel = new UILabel(AlphaFineConstants.BULB_ICON); + tipIconLabel.addMouseListener(tipMouseListener); + tipIconLabel.setToolTipText(toolTip); + useTipLabel = new UILabel(SKILLS); + useTipLabel.addMouseListener(tipMouseListener); + useTipLabel.setToolTipText(toolTip); + useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); + tipPane.add(tipIconLabel, BorderLayout.WEST); + tipPane.add(useTipLabel, BorderLayout.CENTER); + topRightPane.add(tipPane); + UIButton minimizeButton = createButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/minimize.svg")); + minimizeButton.addActionListener(e -> AlphaFineFrame.this.setExtendedState(JFrame.ICONIFIED)); + topRightPane.add(minimizeButton); + UIButton closeButton = createButton(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/close.svg")); + closeButton.addActionListener(e -> AlphaFineFrame.this.dispose()); + topRightPane.add(closeButton); + topPane.add(topRightPane, BorderLayout.EAST); + return topPane; + } + + private MouseAdapter tipMouseListener = new MouseAdapter() { + + @Override + public void mouseEntered(MouseEvent e) { + useTipLabel.setForeground(UIConstants.FLESH_BLUE); + tipIconLabel.setIcon(AlphaFineConstants.BLUE_BULB_ICON); + } + + @Override + public void mouseExited(MouseEvent e) { + useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); + tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON); + } + }; + + private JPanel createSearchPane() { + JPanel searchPane = new JPanel(new BorderLayout()); + searchPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20)); + searchTextFieldWrapperPane = new JPanel(new BorderLayout()) { + @Override + protected void paintBorder(Graphics g) { + g.setColor(BORDER_COLOR); + g.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 5, 5); + } + }; + searchTextFieldWrapperPane.setBorder(new UITextFieldBorder(new Insets(2, 3, 2, 3))); + searchTextFieldWrapperPane.setBackground(Color.WHITE); + searchTextFieldWrapperPane.add(searchTextField, BorderLayout.CENTER); + clearLabel = new UILabel(IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/clear.svg")); + clearLabel.setVisible(false); + clearLabel.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + searchTextField.setText(StringUtils.EMPTY); + clearLabel.setVisible(false); + } + }); + searchTextFieldWrapperPane.add(clearLabel, BorderLayout.EAST); + searchPane.add(searchTextFieldWrapperPane, BorderLayout.CENTER); + JButton searchButton = new JButton(SEARCH) { + @Override + public void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2d.setColor(UIConstants.FLESH_BLUE); + g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 4, 4); + super.paintComponent(g2d); + } + }; + searchButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + fireSearch(); + } + }); + searchButton.setPreferredSize(new Dimension(70, 60)); + searchButton.setForeground(Color.WHITE); + searchButton.setBorderPainted(false); + searchButton.setContentAreaFilled(false); + searchPane.add(searchButton, BorderLayout.EAST); + searchPane.setBackground(Color.WHITE); + return searchPane; + } + + private JPanel createShowPane() { + JPanel showPane = new JPanel(new BorderLayout()); + resultPane.add(new DefaultProductNewsPane(), CellType.PRODUCT_NEWS.getFlagStr4None()); + resultPane.add(new NoResultWithLinkPane(GO_FORUM, AlphaFineConstants.NO_RESULT_ICON), CellType.NO_RESULT.getFlagStr4None()); + resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.ACTION.getFlagStr4None()); + resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.FILE.getFlagStr4None()); + resultPane.add(new NoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.PLUGIN.getFlagStr4None()); + resultPane.add(new HelpDocumentNoResultPane(SEARCH_TERM, AlphaFineConstants.NO_RESULT_ICON), CellType.DOCUMENT.getFlagStr4None()); + resultPane.add(new NetWorkFailedPane(this::reSearch), AlphaFineConstants.NETWORK_ERROR); + + JPanel labelPane = new JPanel(new BorderLayout()); + labelPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20)); + labelPane.setBackground(Color.WHITE); + JPanel labelContentPane = new JPanel(new BorderLayout()); + UILabel tabLabel = new UILabel(PRODUCT_DYNAMICS); + tabLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); + tabLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + tabLabel.setPreferredSize(new Dimension(100, 30)); + JPanel westPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + westPane.add(tabLabel); + labelContentPane.add(westPane, BorderLayout.WEST); + JPanel eastPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 0, 0)); + UILabel readLabel = new UILabel(ONE_CLICK_READ); + readLabel.setHorizontalAlignment(SwingConstants.RIGHT); + readLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));; + readLabel.setPreferredSize(new Dimension(100, 30)); + readLabel.setForeground(UIConstants.FLESH_BLUE); + readLabel.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + fireOneClickRead(); + showPane.repaint(); + } + }); + eastPane.add(readLabel); + labelContentPane.add(eastPane, BorderLayout.EAST); + labelContentPane.setBackground(new Color(245, 245, 247)); + labelPane.add(labelContentPane); + labelPane.setPreferredSize(new Dimension(AlphaFineConstants.FULL_SIZE.width, 30)); + + JPanel tabPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); + tabPane.setBackground(Color.WHITE); + List selectedLabelList = new ArrayList<>(); + AlphaFineConfigManager alphaFineConfigManager = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager(); + if (alphaFineConfigManager.isProductDynamics()) { + selectedLabelList.add(new SelectedLabel(PRODUCT_NEWS, CellType.PRODUCT_NEWS, true)); + } + if (alphaFineConfigManager.isContainAction()) { + selectedLabelList.add(new SelectedLabel(SETTING, CellType.ACTION)); + } + if (alphaFineConfigManager.isContainFileContent() || alphaFineConfigManager.isContainTemplate()) { + selectedLabelList.add(new SelectedLabel(TEMPLATES, CellType.FILE)); + } + if (alphaFineConfigManager.isContainDocument()) { + selectedLabelList.add(new SelectedLabel(HELP, CellType.DOCUMENT)); + } + if (alphaFineConfigManager.isContainPlugin()) { + selectedLabelList.add(new SelectedLabel(PLUGIN, CellType.PLUGIN)); + } + selectedType = selectedLabelList.get(0).getCellType(); + for (SelectedLabel selectedLabel : selectedLabelList) { + + selectedLabel.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + for (SelectedLabel label : selectedLabelList) { + label.setSelected(false); + label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); + } + selectedLabel.setSelected(true); + // 处理产品动态 tab与下方文字展示不一致 + if (ComparatorUtils.equals(selectedLabel.getText().trim(), PRODUCT_NEWS)) { + tabLabel.setText(PRODUCT_DYNAMICS); + } else { + tabLabel.setText(selectedLabel.getText()); + } + readLabel.setVisible(false); + tabPane.repaint(); + switch (selectedLabel.getCellType()) { + case PRODUCT_NEWS: + readLabel.setVisible(true); + switchType(CellType.PRODUCT_NEWS); + break; + case ACTION: + currentSearchWorkerManager = settingSearchWorkerManager; + switchType(CellType.ACTION); + break; + case FILE: + currentSearchWorkerManager = fileSearchWorkerManager; + switchType(CellType.FILE); + break; + case DOCUMENT: + currentSearchWorkerManager = documentWorkerManager; + switchType(CellType.DOCUMENT); + break; + case PLUGIN: + currentSearchWorkerManager = pluginSearchWorkerManager; + switchType(CellType.PLUGIN); + break; + } + if (currentSearchWorkerManager != null) { + AlphaFineList alphaFineList = currentSearchWorkerManager.getSearchResultList(); + if (alphaFineList != null) { + alphaFineList.setSelectedIndex(0); + } + } + } + + private Color defaultColor; + + @Override + public void mouseEntered(MouseEvent e) { + defaultColor = selectedLabel.getForeground(); + selectedLabel.setForeground(AlphaFineConstants.SUSPENDED_COLOR); + } + + @Override + public void mouseExited(MouseEvent e) { + selectedLabel.setForeground(defaultColor); + } + }); + tabPane.add(selectedLabel); + } + showPane.add(tabPane, BorderLayout.NORTH); + showPane.add(labelPane, BorderLayout.CENTER); + showPane.add(resultPane, BorderLayout.SOUTH); + return showPane; + } + + private void fireOneClickRead() { + List productNewsList = ProductNewsSearchManager.getInstance().getCachedProductNewsList(); + Set readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet(); + for (ProductNews productNews : productNewsList) { + readSet.add(productNews.getId()); + } + } + + private void switchType(CellType cellType) { + this.selectedType = cellType; + if (StringUtils.isEmpty(searchTextField.getText())) { + cardLayout.show(resultPane, cellType.getFlagStr4None()); + } else { + // 当前搜索未结束 不切换loading + if (!checkSearchLoading()) { + return; + } + // 所有都搜索都结束 移除loading + if (isAllSearchOver()) { + resultPane.remove(searchLoadingPane); + } + + // 网络异常 + if (checkNetworkError()) { + return; + } + + cardLayout.show(resultPane, cellType.getFlagStr4Result()); + checkSearchResult(); + } + + } + + private boolean checkNetworkError() { + boolean networkError; + if (selectedType == CellType.PRODUCT_NEWS) { + networkError = productNewsSearchWorkerManager.isNetWorkError(); + } else { + networkError = currentSearchWorkerManager.isNetWorkError(); + } + cardLayout.show(resultPane, AlphaFineConstants.NETWORK_ERROR); + return networkError; + } + + private boolean checkSearchLoading() { + boolean searchOver; + if (selectedType == CellType.PRODUCT_NEWS) { + searchOver = productNewsSearchWorkerManager.isSearchOver(); + } else { + searchOver = currentSearchWorkerManager.isSearchOver(); + } + cardLayout.show(resultPane, AlphaFineConstants.LOADING); + return searchOver; + } + + private boolean isAllSearchOver() { + return productNewsSearchWorkerManager.isSearchOver() + && pluginSearchWorkerManager.isSearchOver() + && fileSearchWorkerManager.isSearchOver() + && settingSearchWorkerManager.isSearchOver() + && documentWorkerManager.isSearchOver(); + } + + private void checkSearchResult() { + if (currentSearchWorkerManager == null) { + return; + } + searchResultList = currentSearchWorkerManager.getSearchResultList(); + if (searchResultList != null) { + searchResultList.requestFocus(); + } + boolean hasSearchResult = true; + if (selectedType == CellType.PRODUCT_NEWS) { + hasSearchResult = productNewsSearchWorkerManager.hasSearchResult(); + } else { + hasSearchResult = currentSearchWorkerManager.hasSearchResult(); + } + + if (!hasSearchResult) { + cardLayout.show(resultPane, CellType.NO_RESULT.getFlagStr4None()); + } + + } + + private void initSearchTextField() { + searchTextField = new AlphaFineTextField(PLACE_HOLDER); + initTextFieldListener(); + searchTextField.setFont(DesignUtils.getDefaultGUIFont().applySize(14)); + searchTextField.setBackground(Color.WHITE); + searchTextField.setPreferredSize(new Dimension(300, 60)); + searchTextField.setBorder(null); + } + + + private void initTextFieldListener() { + searchTextField.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + // 搜索提示框 + if (StringUtils.isNotEmpty(searchTextField.getText())) { + clearLabel.setVisible(true); + SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); + } + AlphaFineToolTipList alphaFineToolTipList = SearchTooltipPopup.getInstance().getAlphaFineToolTipList(); + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + if (!alphaFineToolTipList.isSelectionEmpty()) { + fireSearch(alphaFineToolTipList.getSelectedValue()); + return; + } + fireSearch(); + } else if (e.getKeyCode() == KeyEvent.VK_DOWN) { + if (alphaFineToolTipList.getSelectedIndex() == alphaFineToolTipList.getModel().getSize() - 1) { + alphaFineToolTipList.setSelectedIndex(0); + } + alphaFineToolTipList.setSelectedIndex(alphaFineToolTipList.getSelectedIndex() + 1); + } else if (e.getKeyCode() == KeyEvent.VK_UP) { + alphaFineToolTipList.setSelectedIndex(alphaFineToolTipList.getSelectedIndex() - 1); + } + + } + }); + + searchTextField.addFocusListener(new FocusListener() { + @Override + public void focusGained(FocusEvent e) { + if (StringUtils.isNotEmpty(searchTextField.getText())) { + SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); + } + } + + @Override + public void focusLost(FocusEvent e) { + if (e.getOppositeComponent() != SearchTooltipPopup.getInstance().getAlphaFineToolTipList()) { + SearchTooltipPopup.getInstance().hide(); + } + } + }); + + startSearchTextFieldTimer(); + + } + + private void startSearchTextFieldTimer() { + Timer timer = new Timer(TIMER_DELAY, e -> { + // 坑 isShowing返回false 即使textField有内容 getText返回的也是空 + if (searchTextField.isShowing() && StringUtils.isEmpty(searchTextField.getText())) { + SearchTooltipPopup.getInstance().hide(); + clearLabel.setVisible(false); + switchType(selectedType); + } else if (searchTextField.hasFocus()) { + clearLabel.setVisible(true); + SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); + } + + }); + timer.start(); + } + + public void fireSearch(String text) { + searchTextField.setText(text); + fireSearch(); + } + + private void fireSearch() { + // 焦点转移 + AlphaFineFrame.this.requestFocus(); + if (ComparatorUtils.equals(beforeSearchStr, searchTextField.getText())) { + return; + } + if (StringUtils.isEmpty(searchTextField.getText())) { + beforeSearchStr = StringUtils.EMPTY; + return; + } + if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isNeedSegmentationCheckbox()) { + //是高级搜索 + if (searchTextField.getText().toLowerCase().startsWith(ADVANCED_SEARCH_MARK)) { + segmentationResult = SegmentationManager.getInstance().startSegmentation(getStoreText(searchTextField.getText().toLowerCase())); + } + //是普通搜索 + else { + segmentationResult = SegmentationManager.getInstance().startSegmentation(searchTextField.getText().toLowerCase()); + } + } else { + if (StringUtils.isEmpty(getRealSearchText(searchTextField.getText()))) { + segmentationResult = null; + } else { + segmentationResult = new String[]{getRealSearchText(searchTextField.getText())}; + } + } + DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getHistorySearch().push(searchTextField.getText()); + doSearch(searchTextField.getText().toLowerCase()); + beforeSearchStr = searchTextField.getText(); + SearchTooltipPopup.getInstance().hide(); + } + + private void dealWithSearchResult() { + final AlphaCellModel model = searchResultList.getSelectedValue(); + if (model != null) { + model.doAction(); + } + } + + public void showResult(String flag) { + cardLayout.show(resultPane, flag); + } + + public void addResult(JPanel panel, String flag) { + resultPane.add(panel, flag); + } + + public void removeSearchResultPane(JPanel panel) { + resultPane.remove(panel); + } + + + + private void doSearch(String text) { + initSearchLoadingPane(); + SearchTextBean searchTextBean = new SearchTextBean(text, segmentationResult); + this.productNewsSearchWorkerManager.doSearch(searchTextBean); + this.settingSearchWorkerManager.doSearch(searchTextBean); + this.fileSearchWorkerManager.doSearch(searchTextBean); + this.documentWorkerManager.doSearch(searchTextBean); + this.pluginSearchWorkerManager.doSearch(searchTextBean); + } + + /** + * 仅搜索依赖网络的搜索项 + * + */ + private void reSearch() { + String text = this.searchTextField.getText().toLowerCase(); + if (StringUtils.isEmpty(text)) { + return; + } + searchLoadingPane = new SearchLoadingPane(); + SearchTextBean searchTextBean = new SearchTextBean(text, segmentationResult); + this.productNewsSearchWorkerManager.doSearch(searchTextBean); + this.documentWorkerManager.doSearch(searchTextBean); + this.pluginSearchWorkerManager.doSearch(searchTextBean); + } + + private void initSearchLoadingPane() { + if (searchLoadingPane == null) { + searchLoadingPane = new SearchLoadingPane(); + } + resultPane.add(searchLoadingPane, AlphaFineConstants.LOADING); + cardLayout.show(resultPane, AlphaFineConstants.LOADING); + } + + public String getSearchText() { + return searchTextField.getText(); + } + + + public CellType getSelectedType() { + return selectedType; + } + + public void setStoreText(String storeText) { + this.storeText = storeText; + } + + /** + * 截取字符串中关键词 + * + * @param searchText + * @return + */ + private String getStoreText(String searchText) { + //这里也需要先做一个去除不需要空格的处理 + setStoreText((searchText.substring(searchText.indexOf(StringUtils.BLANK) + 1)).replaceAll(StringUtils.BLANK, StringUtils.EMPTY)); + return storeText; + } + + + /** + * 去除特殊字符,空格等 + */ + private String getRealSearchText(String searchText) { + searchText = searchText.toLowerCase(); + Pattern p = Pattern.compile(AlphaFineConstants.SPECIAL_CHARACTER_REGEX); + Matcher m = p.matcher(searchText); + searchText = m.replaceAll(StringUtils.EMPTY).trim().replaceAll(StringUtils.BLANK, StringUtils.EMPTY); + if (searchText.length() == 0) { + return null; + } + return searchText; + } + + private UIButton createButton(Icon icon) { + UIButton button = new UIButton() { + @Override + public void paintComponent(Graphics g) { + g.setColor(Color.WHITE); + g.fillRect(0, 0, getSize().width, getSize().height); + super.paintComponent(g); + } + }; + button.setPreferredSize(new Dimension(20, 20)); + button.setIcon(icon); + button.set4ToolbarButton(); + button.setBorderPainted(false); + button.setRolloverEnabled(false); + return button; + } + + /** + * 设置面板位置 + * + * @param win + */ + private void centerWindow(Window win) { + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + + Dimension winSize = win.getSize(); + + if (winSize.height > screenSize.height) { + winSize.height = screenSize.height; + } + if (winSize.width > screenSize.width) { + winSize.width = screenSize.width; + } + //这里设置位置:水平居中,竖直偏上 + win.setLocation((screenSize.width - winSize.width) / 2, (screenSize.height - winSize.height) / AlphaFineConstants.SHOW_SIZE); + } + + @Override + public void setVisible(boolean b) { + super.setVisible(b); + QuestionWindow.getInstance().setVisible(!b); + } + + @Override + public void dispose() { + super.dispose(); + AlphaFineHelper.resetAlphaFineDialog(); + QuestionWindow.getInstance().setVisible(true); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java new file mode 100644 index 000000000..b58a3e51b --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java @@ -0,0 +1,76 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import com.fr.design.mainframe.alphafine.preview.ResultShowPane; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JList; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/18 + */ +public class AlphaFineList extends JList { + + private ResultShowPane resultShowPane; + + public AlphaFineList() { + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + AlphaCellModel selectedValue = getSelectedValue(); + if (e.getClickCount() == AlphaFineConstants.DEFAULT_CLICK_COUNT && selectedValue.hasAction()) { + // 点击搜索结果 主页面移动到后面 + AlphaFineHelper.getAlphaFineDialog().toBack(); + dealWithSearchResult(); + } + } + }); + + addListSelectionListener(e -> { + if (!e.getValueIsAdjusting() && getSelectedValue() != null) { + if (resultShowPane != null) { + resultShowPane.showResult(getSelectedValue()); + } + } + }); + + + addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + dealWithSearchResult(); + } + } + }); + } + + public void setResultShowPane(ResultShowPane resultShowPane) { + this.resultShowPane = resultShowPane; + } + + @Override + public void setSelectedIndex(int index) { + super.setSelectedIndex(index); + AlphaCellModel alphaCellModel = getSelectedValue(); + if (resultShowPane != null && alphaCellModel != null) { + resultShowPane.showResult(getSelectedValue()); + } + ensureIndexIsVisible(getSelectedIndex()); + } + + private void dealWithSearchResult() { + final AlphaCellModel model = this.getSelectedValue(); + if (model != null) { + model.doAction(); + } + } + + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFinePane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFinePane.java index 74c4d6d34..06c9ff0c1 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFinePane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFinePane.java @@ -31,7 +31,7 @@ public class AlphaFinePane extends BasicPane { setLayout(new BorderLayout()); UIButton refreshButton = new UIButton(); refreshButton.setIcon(IOUtils.readIcon(("/com/fr/design/mainframe/alphafine/images/smallsearch.png"))); - refreshButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine")); + refreshButton.setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Learn_More_About")); refreshButton.set4ToolbarButton(); refreshButton.setRolloverEnabled(false); this.add(refreshButton); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineTextField.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineTextField.java index ba4d279fb..b745b0de9 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineTextField.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineTextField.java @@ -1,8 +1,7 @@ package com.fr.design.mainframe.alphafine.component; import com.fr.design.gui.itextfield.UITextField; -import com.fr.report.web.button.Image; - +import com.fr.design.mainframe.alphafine.AlphaFineConstants; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; @@ -13,9 +12,10 @@ import java.awt.RenderingHints; */ public class AlphaFineTextField extends UITextField { + private static final int PLACE_HOLDER_GAP = 3; + private String placeHolder; - private Image image; public AlphaFineTextField(String placeHolder) { this.placeHolder = placeHolder; @@ -36,16 +36,13 @@ public class AlphaFineTextField extends UITextField { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - g2.setColor(super.getDisabledTextColor()); - g2.drawString(placeHolder, getInsets().left, g.getFontMetrics().getMaxAscent() + getInsets().top + 15); + g2.setColor(AlphaFineConstants.FOREGROUND_COLOR_5); + g2.drawString(placeHolder, getInsets().left, g.getFontMetrics().getMaxAscent() + getInsets().top + PLACE_HOLDER_GAP); } - public Image getImage() { - return image; - } - - public void setImage(Image image) { - this.image = image; + @Override + protected void paintBorder(Graphics g) { + // do nothing } public String getPlaceHolder() { diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipContentCellRender.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipContentCellRender.java new file mode 100644 index 000000000..1b439f1a8 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipContentCellRender.java @@ -0,0 +1,68 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.base.svg.IconUtils; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineUtil; +import com.fr.general.ComparatorUtils; +import com.fr.stable.StringUtils; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public class AlphaFineToolTipContentCellRender implements ListCellRenderer { + + private static final Color SELECTED_COLOR = new Color(65, 155, 249, 26); + + private static final Icon HOT_SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/hot_search.svg"); + + private static final Icon SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/search.svg"); + + private static final Icon HISTORY_SEARCH_ICON = IconUtils.readIcon("/com/fr/design/mainframe/alphafine/images/history_search.svg"); + + + @Override + public Component getListCellRendererComponent(JList list, String value, int index, + boolean isSelected, boolean cellHasFocus) { + + if (StringUtils.isEmpty(value)) { + return new LineCellRender().getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); + } + + JPanel panel = new JPanel(new BorderLayout()); + panel.setBackground(null); + + UILabel iconLabel = new UILabel(); + iconLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 5, 0)); + iconLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); + iconLabel.setText(value); + if (ComparatorUtils.equals(value, AlphaFineConstants.HOT_SEARCH)) { + iconLabel.setIcon(HOT_SEARCH_ICON); + } else if (AlphaFineConstants.HOT_SEARCH_SET.contains(value)) { + iconLabel.setIcon(SEARCH_ICON); + } else { + iconLabel.setIcon(HISTORY_SEARCH_ICON); + } + + if (isSelected && !ComparatorUtils.equals(value, AlphaFineConstants.HOT_SEARCH)) { + iconLabel.setText(AlphaFineUtil.highLightModelName(value, new String[]{value})); + panel.setBackground(SELECTED_COLOR); + } + panel.add(iconLabel, BorderLayout.WEST); + panel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0)); + panel.setPreferredSize(new Dimension(640, 32)); + + return panel; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipList.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipList.java new file mode 100644 index 000000000..3d3333772 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineToolTipList.java @@ -0,0 +1,42 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.general.ComparatorUtils; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import javax.swing.JList; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public class AlphaFineToolTipList extends JList { + + public AlphaFineToolTipList() { + addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + AlphaFineHelper.getAlphaFineDialog().fireSearch(getSelectedValue()); + } + } + }); + + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == 2) { + if (ComparatorUtils.equals(getSelectedValue(), AlphaFineConstants.HOT_SEARCH)) { + return; + } + AlphaFineHelper.getAlphaFineDialog().fireSearch(getSelectedValue()); + } + } + }); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaSearchTooltipPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaSearchTooltipPane.java new file mode 100644 index 000000000..e803b647b --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaSearchTooltipPane.java @@ -0,0 +1,62 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import java.awt.Color; +import java.awt.Dimension; +import java.util.Stack; +import javax.swing.DefaultListModel; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public class AlphaSearchTooltipPane extends JPanel { + + private AlphaFineToolTipList alphaFineToolTipList; + + public AlphaSearchTooltipPane() { + alphaFineToolTipList = new AlphaFineToolTipList(); + alphaFineToolTipList.setCellRenderer(new AlphaFineToolTipContentCellRender()); + alphaFineToolTipList.setModel(getDefaultListModel()); + UIScrollPane scrollPane = new UIScrollPane(alphaFineToolTipList); + scrollPane.setBorder(null); + scrollPane.setBackground(Color.WHITE); + this.add(scrollPane); + this.setPreferredSize(new Dimension(640, 250)); + this.setBackground(Color.WHITE); + } + + public AlphaFineToolTipList getAlphaFineToolTipList() { + return alphaFineToolTipList; + } + + private DefaultListModel getDefaultListModel() { + DefaultListModel defaultListModel = new DefaultListModel<>(); + defaultListModel.addElement(AlphaFineConstants.HOT_SEARCH); + for (String content : AlphaFineConstants.HOT_SEARCH_SET) { + defaultListModel.addElement(content); + } + return defaultListModel; + } + + public void refreshHistory() { + Stack stack = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getHistorySearch(); + if (stack.isEmpty()) { + return; + } + DefaultListModel defaultListModel = new DefaultListModel<>(); + for (int i = stack.size() - 1; i >= 0; i--) { + defaultListModel.addElement(stack.get(i)); + } +// defaultListModel.addElement(StringUtils.EMPTY); + defaultListModel.addElement(AlphaFineConstants.HOT_SEARCH); + for (String content : AlphaFineConstants.HOT_SEARCH_SET) { + defaultListModel.addElement(content); + } + alphaFineToolTipList.setModel(defaultListModel); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/LineCellRender.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/LineCellRender.java new file mode 100644 index 000000000..9158cb045 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/LineCellRender.java @@ -0,0 +1,32 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ilable.UILabel; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; +import javax.swing.BorderFactory; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public class LineCellRender implements ListCellRenderer { + + @Override + public Component getListCellRendererComponent(JList list, String value, int index, + boolean isSelected, boolean cellHasFocus) { + JPanel panel = new JPanel(new BorderLayout()); + UILabel splitLabel = new UILabel(); + panel.setBackground(null); + splitLabel.setBackground(UIConstants.BARNOMAL); + splitLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 5,0)); + panel.setPreferredSize(new Dimension(640, 1)); + panel.add(splitLabel); + return panel; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsContentCellRender.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsContentCellRender.java new file mode 100644 index 000000000..c6b5983d6 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsContentCellRender.java @@ -0,0 +1,100 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineUtil; +import com.fr.design.mainframe.alphafine.model.ProductNews; +import com.fr.design.utils.DesignUtils; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.Graphics; +import java.text.SimpleDateFormat; +import javax.swing.BorderFactory; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/19 + */ +public class ProductNewsContentCellRender implements ListCellRenderer { + + private static final String FINE_REPORT = "FineReport"; + + private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy/MM/dd"); + + /** + * 透明灰色背景 Y方向偏移 + */ + private static final int GRAY_BACKGROUND_Y_GAP = 39; + + /** + * 透明灰色背景 高度 + */ + private static final int GRAY_BACKGROUND_HEIGHT = 23; + + /** + * 单行产品动态的高度与宽度尺寸 + */ + private static final Dimension DEFAULT_DIMENSION = new Dimension(500, 100); + + private String[] segmentationResult; + + private ProductNewsList productNewsList; + + public ProductNewsContentCellRender(String[] segmentationResult, ProductNewsList productNewsList) { + this.segmentationResult = segmentationResult; + this.productNewsList = productNewsList; + } + + public ProductNewsContentCellRender(ProductNewsList productNewsList) { + this(null, productNewsList); + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, + boolean cellHasFocus) { + ProductNews productNews = (ProductNews) value; + JPanel panel = new JPanel(new BorderLayout()); + panel.setBorder(BorderFactory.createEmptyBorder(0, 0, 10, 0)); + panel.setBackground(Color.WHITE); + + panel.add(new ProductNewsImagePanel(productNews), BorderLayout.WEST); + JPanel textPane = new JPanel(new BorderLayout()); + textPane.setBorder(BorderFactory.createEmptyBorder(0, 10, 10, 0)); + UILabel titleLabel = new UILabel(AlphaFineUtil.highLightModelName(productNews.getTitle(), segmentationResult)); + titleLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(20)); + if (productNewsList.getHoverIndex() == index) { + titleLabel.setForeground(UIConstants.FLESH_BLUE); + } + + textPane.add(titleLabel, BorderLayout.NORTH); + JPanel infoPane = new JPanel(new BorderLayout()); + UILabel productLabel = new UILabel(FINE_REPORT) { + @Override + protected void paintComponent(Graphics g) { + g.setColor(AlphaFineConstants.BACKGROUND_COLOR); + g.fillRect(0, getHeight() - GRAY_BACKGROUND_Y_GAP, getWidth(), GRAY_BACKGROUND_HEIGHT); + super.paintComponent(g); + } + }; + productLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); + infoPane.add(productLabel, BorderLayout.WEST); + + UILabel dateLabel = new UILabel(DATE_FORMAT.format(productNews.getPushDate())); + dateLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); + dateLabel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + infoPane.setBackground(Color.WHITE); + infoPane.add(dateLabel, BorderLayout.CENTER); + textPane.setBackground(Color.WHITE); + textPane.add(infoPane, BorderLayout.CENTER); + panel.add(textPane, BorderLayout.CENTER); + panel.setPreferredSize(DEFAULT_DIMENSION); + return panel; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsImagePanel.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsImagePanel.java new file mode 100644 index 000000000..b7afc0f78 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsImagePanel.java @@ -0,0 +1,79 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.base.GraphHelper; +import com.fr.base.svg.SVGLoader; +import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.alphafine.model.ProductNews; +import com.fr.design.utils.SvgPaintUtils; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; + +import java.awt.RenderingHints; +import java.util.Set; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/15 + */ +public class ProductNewsImagePanel extends JPanel { + + private static final Image NEW_TIP_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/new_tip.svg"); + + private static final int BACKGROUND_HEIGHT = 20; + + private static final Color BACKGROUND_COLOR = new Color(116, 181, 249); + + private static final Color COVER_COLOR = new Color(116, 181, 249, 26); + + private ProductNews productNews; + + private int width = 200; + private int height = 150; + + public ProductNewsImagePanel(ProductNews productNews) { + this.productNews = productNews; + } + + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR); + Color defaultColor = g2.getColor(); + + Image image = productNews.getImage(); + if (image != null) { + g2.drawImage(productNews.getImage(), 0, 0, getWidth(), getHeight(), this); + } else { + g2.setColor(COVER_COLOR); + g2.fillRect(0, 0, getWidth(), getHeight()); + } + Set readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet(); + if (!readSet.contains(productNews.getId())) { + SvgPaintUtils.beforePaint(g2); + g2.drawImage(NEW_TIP_IMAGE, 0, 0, this); + SvgPaintUtils.afterPaint(g2); + } + + g2.setColor(BACKGROUND_COLOR); + g2.fillRect(0, getHeight() - BACKGROUND_HEIGHT, getWidth(), BACKGROUND_HEIGHT); + g2.setColor(Color.WHITE); + int x = (getWidth() - GraphHelper.getWidth(productNews.getTag().getDesc(), g2.getFont())) / 2; + g2.drawString(productNews.getTag().getDesc(), x, getHeight() - 5); + g2.setColor(defaultColor); + } + + @Override + public Dimension getPreferredSize() { + return new Dimension(width, height); + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java new file mode 100644 index 000000000..9e4d1c402 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsList.java @@ -0,0 +1,78 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.model.ProductNews; +import com.fr.log.FineLoggerFactory; + +import java.awt.Cursor; +import java.awt.Desktop; +import java.awt.Point; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.net.URI; +import javax.swing.DefaultListModel; +import javax.swing.JList; +import javax.swing.ListModel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/21 + */ +public class ProductNewsList extends JList { + + private int hoverIndex = -1; + + public ProductNewsList(ListModel dataModel) { + super(dataModel); + addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (e.getClickCount() == AlphaFineConstants.DEFAULT_CLICK_COUNT) { + dealWithClick(); + } + } + + @Override + public void mouseExited(MouseEvent e) { + hoverIndex = -1; + ProductNewsList.this.repaint(); + } + }); + + addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + Point p = new Point(e.getX(), e.getY()); + int index = ProductNewsList.this.locationToIndex(p); + setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + if (index != hoverIndex) { + hoverIndex = index; + ProductNewsList.this.repaint(); + } + } + }); + } + + public ProductNewsList() { + this(new DefaultListModel<>()); + } + + private void dealWithClick() { + ProductNews productNews = getSelectedValue(); + try { + Desktop.getDesktop().browse(new URI(productNews.getUrl())); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet().add(productNews.getId()); + AlphaFineHelper.getAlphaFineDialog().repaint(); + } + + public int getHoverIndex() { + return hoverIndex; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsSearchResultPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsSearchResultPane.java new file mode 100644 index 000000000..3efba5fd1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/ProductNewsSearchResultPane.java @@ -0,0 +1,36 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; + +import java.awt.BorderLayout; +import java.awt.Color; +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/21 + */ +public class ProductNewsSearchResultPane extends JPanel { + + private ProductNewsList productNewsList; + + public ProductNewsSearchResultPane(String[] segmentationResult) { + + productNewsList = new ProductNewsList(); + UIScrollPane scrollPane = new UIScrollPane(productNewsList); + scrollPane.setBackground(Color.WHITE); + scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 20)); + productNewsList.setCellRenderer(new ProductNewsContentCellRender(segmentationResult, productNewsList)); + this.setLayout(new BorderLayout()); + this.setBackground(Color.WHITE); + this.add(scrollPane); + this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); + } + + public ProductNewsList getProductNewsList() { + return productNewsList; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchListModel.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchListModel.java new file mode 100644 index 000000000..f6948a57d --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchListModel.java @@ -0,0 +1,126 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import com.fr.design.mainframe.alphafine.model.SearchResult; +import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/18 + */ +public class SearchListModel extends DefaultListModel { + + private static final int MAX_SHOW_SIZE = 12; + private static final long serialVersionUID = 7230585307439551228L; + + + private SearchResult myDelegate; + + /** + * 第一有效的项是否被选中 + */ + private boolean isValidSelected; + + private UIScrollPane leftSearchResultPane; + + private AlphaFineList searchResultList; + + public SearchListModel(SearchResult searchResult, AlphaFineList searchResultList, UIScrollPane leftSearchResultPane) { + this.myDelegate = searchResult; + this.searchResultList = searchResultList; + this.leftSearchResultPane = leftSearchResultPane; + } + + @Override + public void addElement(AlphaCellModel element) { + AlphaFineHelper.checkCancel(); + int index = myDelegate.size(); + myDelegate.add(element); + fireContentsChanged(this, index, index); + fireSelectedStateChanged(element, index); + + } + + @Override + protected void fireContentsChanged(Object source, int index0, int index1) { + if (myDelegate.size() > MAX_SHOW_SIZE) { + leftSearchResultPane.getVerticalScrollBar().setBorder(BorderFactory.createEmptyBorder(0, 2, 0, 0)); + leftSearchResultPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 2)); + } else { + leftSearchResultPane.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + } + super.fireContentsChanged(source, index0, index1); + } + + /** + * 触发选中第一有效的项 + * + * @param element + * @param index + */ + private void fireSelectedStateChanged(AlphaCellModel element, int index) { + if (element.hasAction() && !isValidSelected()) { + searchResultList.setSelectedIndex(index); + setValidSelected(true); + } + } + + @Override + public AlphaCellModel getElementAt(int index) { + return myDelegate.get(index); + } + + @Override + public void add(int index, AlphaCellModel element) { + myDelegate.add(index, element); + fireIntervalAdded(this, index, index); + } + + @Override + public AlphaCellModel remove(int index) { + AlphaCellModel object = myDelegate.get(index); + myDelegate.remove(object); + fireContentsChanged(this, index, index); + return object; + } + + @Override + public int getSize() { + return this.myDelegate.size(); + } + + @Override + public void removeAllElements() { + this.myDelegate.clear(); + } + + /** + * 重置选中状态 + */ + public void resetSelectedState() { + setValidSelected(false); + } + + private boolean isValidSelected() { + return isValidSelected; + } + + private void setValidSelected(boolean selected) { + isValidSelected = selected; + } + + @Override + public boolean isEmpty() { + return myDelegate.isEmpty(); + } + + public void resetState() { + for (int i = 0; i < getSize(); i++) { + getElementAt(i).resetState(); + } + } +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultContentCellRender.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultContentCellRender.java new file mode 100644 index 000000000..dd65d36a2 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultContentCellRender.java @@ -0,0 +1,83 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineUtil; +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +import java.awt.Dimension; +import javax.swing.BorderFactory; +import javax.swing.JList; +import javax.swing.JPanel; +import javax.swing.ListCellRenderer; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/19 + */ +public class SearchResultContentCellRender implements ListCellRenderer { + + private static final int OFFSET = 45; + private static final String SELECTED_PATH = AlphaFineConstants.IMAGE_URL + "selected"; + private static final String CELL_PATH = AlphaFineConstants.IMAGE_URL + "alphafine"; + private static final String SUFFIX = ".png"; + + private String[] segmentationResult; + + public SearchResultContentCellRender(String[] segmentationResult) { + this.segmentationResult = segmentationResult; + } + + @Override + public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, + boolean cellHasFocus) { + + + AlphaCellModel model = (AlphaCellModel) value; + JPanel panel = new JPanel(new BorderLayout()); + panel.setBackground(null); + panel.setBorder(BorderFactory.createEmptyBorder(0, 10, 0, 0)); + // 图标icon 样式 + UILabel iconLabel = new UILabel(); + if (isSelected) { + iconLabel.setText(StringUtils.BLANK + model.getName()); + String iconUrl = SELECTED_PATH + model.getType().getTypeValue() + SUFFIX; + panel.setBackground(AlphaFineConstants.BLUE); + iconLabel.setForeground(Color.WHITE); + iconLabel.setIcon(IOUtils.readIcon(iconUrl)); + } else { + iconLabel.setText(AlphaFineUtil.highLightModelName(model.getName(), segmentationResult)); + String iconUrl = CELL_PATH + model.getType().getTypeValue() + SUFFIX; + iconLabel.setIcon(IOUtils.readIcon(iconUrl)); + } + iconLabel.setFont(AlphaFineConstants.MEDIUM_FONT); + + + // 内容详情label 样式 + UILabel detailLabel = new UILabel(); + String description = model.getDescription(); + if (StringUtils.isNotBlank(description)) { + detailLabel.setText("-" + description); + detailLabel.setForeground(AlphaFineConstants.LIGHT_GRAY); + panel.add(detailLabel, BorderLayout.CENTER); + int width = (int) (iconLabel.getPreferredSize().getWidth() + detailLabel.getPreferredSize().getWidth()); + if (width > AlphaFineConstants.LEFT_WIDTH - OFFSET) { + int nameWidth = (int) (AlphaFineConstants.LEFT_WIDTH - detailLabel.getPreferredSize().getWidth() - OFFSET); + iconLabel.setPreferredSize(new Dimension(nameWidth, AlphaFineConstants.CELL_HEIGHT)); + } + } else { + iconLabel.setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH - OFFSET, AlphaFineConstants.CELL_HEIGHT)); + } + + panel.add(iconLabel, BorderLayout.WEST); + panel.setPreferredSize(new Dimension(list.getFixedCellWidth(), AlphaFineConstants.CELL_HEIGHT)); + return panel; + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultPane.java new file mode 100644 index 000000000..d4f6c1802 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchResultPane.java @@ -0,0 +1,51 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.model.SearchResult; +import com.fr.design.mainframe.alphafine.preview.ResultShowPane; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public class SearchResultPane extends JPanel { + + private AlphaFineList searchResultList; + + private SearchListModel searchListModel; + + private UIScrollPane leftSearchResultPane; + + + public SearchResultPane(String[] segmentationResult, ResultShowPane rightSearchResultPane) { + searchResultList = new AlphaFineList(); + searchResultList.setFixedCellHeight(AlphaFineConstants.CELL_HEIGHT); + leftSearchResultPane = new UIScrollPane(searchResultList); + leftSearchResultPane.setBorder(null); + leftSearchResultPane.setBackground(Color.WHITE); + leftSearchResultPane.setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH, AlphaFineConstants.CONTENT_HEIGHT)); + searchListModel = new SearchListModel(new SearchResult(), searchResultList, leftSearchResultPane); + searchResultList.setModel(searchListModel); + searchResultList.setCellRenderer(new SearchResultContentCellRender(segmentationResult)); + searchResultList.setResultShowPane(rightSearchResultPane); + this.setPreferredSize(AlphaFineConstants.CONTENT_SIZE); + this.setLayout(new BorderLayout()); + this.add(leftSearchResultPane, BorderLayout.WEST); + this.add(rightSearchResultPane, BorderLayout.EAST); + this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); + } + + public AlphaFineList getSearchResultList() { + return searchResultList; + } + + public UIScrollPane getLeftSearchResultPane() { + return leftSearchResultPane; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchTooltipPopup.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchTooltipPopup.java new file mode 100644 index 000000000..b3aaa8170 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SearchTooltipPopup.java @@ -0,0 +1,58 @@ +package com.fr.design.mainframe.alphafine.component; + +import java.awt.Component; +import java.awt.Point; +import javax.swing.Popup; +import javax.swing.PopupFactory; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public class SearchTooltipPopup { + + private static final SearchTooltipPopup INSTANCE = new SearchTooltipPopup(); + + public static SearchTooltipPopup getInstance() { + return INSTANCE; + } + + private AlphaSearchTooltipPane alphaSearchTooltipPane; + + private SearchTooltipPopup() { + alphaSearchTooltipPane = new AlphaSearchTooltipPane(); + } + + private boolean showPopup; + + private Popup popup; + + public void show(Component owner) { + if (popup == null || !showPopup) { + PopupFactory pf = PopupFactory.getSharedInstance(); + Point point = owner.getLocationOnScreen(); + alphaSearchTooltipPane.refreshHistory(); + popup = pf.getPopup(owner, alphaSearchTooltipPane, point.x, point.y + owner.getHeight()); + } + if (!showPopup) { + alphaSearchTooltipPane.repaint(); + popup.show(); + getAlphaFineToolTipList().clearSelection(); + showPopup = true; + } + } + + public AlphaFineToolTipList getAlphaFineToolTipList() { + return alphaSearchTooltipPane.getAlphaFineToolTipList(); + } + + public void hide() { + if (popup != null) { + popup.hide(); + } + showPopup = false; + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SelectedLabel.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SelectedLabel.java new file mode 100644 index 000000000..9bf151adc --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/SelectedLabel.java @@ -0,0 +1,81 @@ +package com.fr.design.mainframe.alphafine.component; + +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineUtil; +import com.fr.design.mainframe.alphafine.CellType; + +import javax.swing.BorderFactory; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.RenderingHints; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/07 + */ +public class SelectedLabel extends UILabel { + + private static final int WIDTH = 4; + private static final int HEIGHT = 4; + private static final int GAP = 0; + private static final int BORDER_RIGHT = 5; + private static final int BORDER_TOP = 2; + + private boolean selected; + private CellType cellType; + + public SelectedLabel(String text, CellType cellType, boolean selected) { + super(text); + this.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); + this.setBorder(BorderFactory.createEmptyBorder(BORDER_TOP, 0, 0, BORDER_RIGHT)); + this.selected = selected; + this.cellType = cellType; + } + + public SelectedLabel(String text, CellType cellType) { + this(text, cellType, false); + } + + @Override + public void paintComponent(Graphics g) { + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, + RenderingHints.VALUE_ANTIALIAS_ON); + if (selected) { + g2d.setColor(UIConstants.FLESH_BLUE); + setForeground(UIConstants.FLESH_BLUE); + g2d.drawLine(0, this.getHeight() - 1, this.getWidth() - BORDER_RIGHT, this.getHeight() - 1); + } + super.paintComponent(g); + } + + + @Override + protected void paintBorder(Graphics g) { + super.paintBorder(g); + Graphics2D g2d = (Graphics2D) g; + g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); + if (cellType == CellType.PRODUCT_NEWS && AlphaFineUtil.unread()) { + Color oldColor = g.getColor(); + g2d.setColor(Color.RED); + g2d.fillOval(getWidth() - WIDTH, GAP, WIDTH, HEIGHT); + g2d.setColor(oldColor); + } + } + + public boolean isSelected() { + return selected; + } + + public void setSelected(boolean selected) { + this.selected = selected; + } + + public CellType getCellType() { + return cellType; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/exception/AlphaFineNetworkException.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/exception/AlphaFineNetworkException.java new file mode 100644 index 000000000..c8fec04e0 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/exception/AlphaFineNetworkException.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.alphafine.exception; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/27 + */ +public class AlphaFineNetworkException extends RuntimeException { + + public AlphaFineNetworkException() { + super("NetWork Error"); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java new file mode 100644 index 000000000..aea152da2 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/model/ProductNews.java @@ -0,0 +1,200 @@ +package com.fr.design.mainframe.alphafine.model; + +import com.fr.design.i18n.Toolkit; +import java.awt.Image; +import java.util.Date; + +/** + * 产品动态 + * + * @author hades + * @version 11.0 + * Created by hades on 2022/4/05 + */ +public class ProductNews { + + private long id; + private String title; + + private Tag tag; + private Target target; + + private Status status; + private String url; + private Image image; + + + private Date pushDate; + + /** + * 创建cid的用户 + */ + private int creator; + + public long getId() { + return id; + } + + public ProductNews setId(long id) { + this.id = id; + return this; + } + + public String getTitle() { + return title; + } + + public ProductNews setTitle(String title) { + this.title = title; + return this; + } + + public Tag getTag() { + return tag; + } + + public ProductNews setTag(Tag tag) { + this.tag = tag; + return this; + } + + public Target getTarget() { + return target; + } + + public ProductNews setTarget(Target target) { + this.target = target; + return this; + } + + public Status getStatus() { + return status; + } + + public ProductNews setStatus(Status status) { + this.status = status; + return this; + } + + public String getUrl() { + return url; + } + + public ProductNews setUrl(String url) { + this.url = url; + return this; + } + + public Image getImage() { + return image; + } + + public ProductNews setImage(Image image) { + this.image = image; + return this; + } + + public Date getPushDate() { + return pushDate; + } + + public ProductNews setPushDate(Date pushDate) { + this.pushDate = pushDate; + return this; + } + + public int getCreator() { + return creator; + } + + public ProductNews setCreator(int creator) { + this.creator = creator; + return this; + } + + interface CodeParser { + int getCode(); + } + + public enum Status implements CodeParser { + STOP(0), START(1); + + private final int code; + + Status(int code) { + this.code = code; + } + + @Override + public int getCode() { + return code; + } + + public static Status parseCode(int code) { + for (Status status : values()) { + if (code == status.code) { + return status; + } + } + throw new IllegalArgumentException(); + } + } + + public enum Tag { + SOLUTION(1, Toolkit.i18nText("Fine-Design_Report_AlphaFine_Solution")), + MATERIAL(2, Toolkit.i18nText("Fine-Design_Report_AlphaFine_Material")), + NEW_PRODUCT(3, Toolkit.i18nText("Fine-Design_Report_AlphaFine_New_Product")); + + private final int code; + + private final String desc; + + Tag(int code, String desc) { + this.code = code; + this.desc = desc; + } + + public static Tag parseCode(int code) { + for (Tag tag :values()) { + if (tag.code == code) { + return tag; + } + } + throw new IllegalArgumentException(); + } + + public int getCode() { + return code; + } + + public String getDesc() { + return desc; + } + } + + public enum Target { + ALL_USER(0); + + private final int code; + + Target(int code) { + this.code = code; + } + + public int getCode() { + return code; + } + + public static Target parseCode(int code) { + for (Target target : values()) { + if (target.code == code) { + return target; + } + } + throw new IllegalArgumentException(); + } + + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/DefaultProductNewsPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/DefaultProductNewsPane.java new file mode 100644 index 000000000..d70e37ec0 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/DefaultProductNewsPane.java @@ -0,0 +1,121 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.gui.icontainer.UIScrollPane; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.component.ProductNewsContentCellRender; +import com.fr.design.mainframe.alphafine.component.ProductNewsList; +import com.fr.design.mainframe.alphafine.exception.AlphaFineNetworkException; +import com.fr.design.mainframe.alphafine.model.ProductNews; +import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; +import com.fr.design.utils.DesignUtils; +import com.fr.log.FineLoggerFactory; +import java.awt.BorderLayout; +import java.awt.Color; +import java.util.List; +import javax.swing.BorderFactory; +import javax.swing.DefaultListModel; +import javax.swing.ImageIcon; +import javax.swing.JPanel; +import javax.swing.SwingWorker; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/14 + */ +public class DefaultProductNewsPane extends JPanel { + + + private static final String LOADING = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Loading"); + private static final ImageIcon LOADING_ICON = new ImageIcon(DefaultProductNewsPane.class.getResource("/com/fr/web/images/loading-local.gif")); + + private SwingWorker, Void> worker; + + public DefaultProductNewsPane() { + + setLayout(new BorderLayout()); + this.add(createLoadingPane()); + this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); + this.worker = createWorker(); + this.worker.execute(); + } + + + private JPanel createLoadingPane() { + JPanel loadingPane = new JPanel(new BorderLayout()); + UILabel loadingLabel = new UILabel(LOADING); + loadingLabel.setForeground(AlphaFineConstants.MEDIUM_GRAY); + loadingLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(14)); + loadingLabel.setBorder(BorderFactory.createEmptyBorder(0, 280, 0, 0)); + UILabel loadingIconLabel = new UILabel(LOADING_ICON); + loadingIconLabel.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); + loadingPane.add(loadingIconLabel, BorderLayout.NORTH); + loadingPane.add(loadingLabel, BorderLayout.CENTER); + loadingPane.setBackground(Color.WHITE); + return loadingPane; + } + + private SwingWorker, Void> createWorker() { + if (this.worker != null && !this.worker.isDone()) { + this.worker.cancel(true); + this.worker = null; + } + return new SwingWorker, Void>() { + + @Override + protected List doInBackground() throws Exception { + if (!AlphaFineHelper.isNetworkOk()) { + throw new AlphaFineNetworkException(); + } + return ProductNewsSearchManager.getInstance().getProductNewsList(); + } + + @Override + protected void done() { + DefaultProductNewsPane.this.removeAll(); + try { + DefaultProductNewsPane.this.add(createContentPane(get())); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + if (e.getCause() instanceof AlphaFineNetworkException) { + DefaultProductNewsPane.this.add(new NetWorkFailedPane(() -> { + DefaultProductNewsPane.this.removeAll(); + add(createLoadingPane()); + refresh(); + worker = createWorker(); + worker.execute(); + })); + } + } + refresh(); + } + }; + + } + + private void refresh() { + this.validate(); + this.repaint(); + if (AlphaFineHelper.getAlphaFineDialog() != null) { + AlphaFineHelper.getAlphaFineDialog().repaint(); + } + } + + private UIScrollPane createContentPane(List productNewsList) { + DefaultListModel productNewsDefaultListModel = new DefaultListModel<>(); + for (ProductNews productNews : productNewsList) { + productNewsDefaultListModel.addElement(productNews); + } + ProductNewsList productNewsJList = new ProductNewsList(productNewsDefaultListModel); + productNewsJList.setBackground(Color.WHITE); + productNewsJList.setCellRenderer(new ProductNewsContentCellRender(productNewsJList)); + UIScrollPane scrollPane = new UIScrollPane(productNewsJList); + scrollPane.setBackground(Color.WHITE); + scrollPane.setBorder(BorderFactory.createEmptyBorder(10, 20, 0, 20)); + return scrollPane; + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/HelpDocumentNoResultPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/HelpDocumentNoResultPane.java new file mode 100644 index 000000000..961d490e5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/HelpDocumentNoResultPane.java @@ -0,0 +1,167 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.constants.UIConstants; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.utils.BrowseUtils; +import com.fr.design.utils.DesignUtils; +import com.fr.json.JSON; +import com.fr.json.JSONArray; +import com.fr.json.JSONFactory; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.GridLayout; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.LinkedHashMap; +import java.util.Map; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.JPanel; +import javax.swing.JSeparator; +import javax.swing.SwingConstants; +import javax.swing.SwingWorker; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/13 + */ +public class HelpDocumentNoResultPane extends JPanel { + + private static final String RECOMMEND = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Recommend_For_You"); + + private static final Color DOT_COLOR = new Color(200, 201, 205); + + private SwingWorker worker; + + private String title; + + private Icon icon; + + private Map linkMap; + + public HelpDocumentNoResultPane(String title, Icon icon) { + this.title = title; + this.icon = icon; + this.linkMap = generateMap(); + setLayout(new BorderLayout()); + worker = createWorker(); + worker.execute(); + } + + private SwingWorker createWorker() { + if (this.worker != null && !this.worker.isDone()) { + this.worker.cancel(true); + this.worker = null; + } + return new SwingWorker() { + + @Override + protected Boolean doInBackground() throws Exception { + return AlphaFineHelper.isNetworkOk(); + } + + @Override + protected void done() { + HelpDocumentNoResultPane.this.removeAll(); + try { + if (get()) { + add(new NoResultPane(title, icon, 150), BorderLayout.CENTER); + add(createRecommendPane(linkMap), BorderLayout.EAST); + } else { + add(new NetWorkFailedPane(() -> { + worker = createWorker(); + worker.execute(); + })); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + refresh(); + } + }; + } + + + private void refresh() { + this.validate(); + this.repaint(); + } + + + private Map generateMap() { + JSONArray jsonArray = JSONFactory.createJSON(JSON.ARRAY, AlphaFineConstants.ALPHA_HELP_RECOMMEND); + Map linkMap = new LinkedHashMap<>(); + for (int i = 0, len = jsonArray.size(); i < len; i++) { + JSONObject json = jsonArray.getJSONObject(i); + linkMap.put(json.getString("name"), json.getString("link")); + } + return linkMap; + } + + private JPanel createRecommendPane(Map linkMap) { + JPanel wrapRecommendPane = new JPanel(new BorderLayout()); + wrapRecommendPane.setPreferredSize(new Dimension(200, 305)); + JPanel recommendPane = new JPanel(); + recommendPane.setLayout(new GridLayout(0, 1)); + recommendPane.setBorder(BorderFactory.createEmptyBorder(0, 5, 130, 0)); + recommendPane.setBackground(Color.WHITE); + recommendPane.add(new UILabel(RECOMMEND)); + for (Map.Entry entry : linkMap.entrySet()) { + recommendPane.add(createListLabel(entry.getKey(), entry.getValue())); + } + // 分割线 + JSeparator sep = new JSeparator(); + sep.setOrientation(JSeparator.VERTICAL); + sep.setLayout(new GridLayout(0, 1)); + sep.setPreferredSize(new Dimension(1, 285)); + sep.setBorder(BorderFactory.createEmptyBorder(10, 0, 10, 0)); + sep.add(new UILabel()); + wrapRecommendPane.add(sep, BorderLayout.WEST); + wrapRecommendPane.add(recommendPane, BorderLayout.CENTER); + return wrapRecommendPane; + } + + private JPanel createListLabel(String text, String link) { + UILabel listLabel = new UILabel(String.format("%s", text)); + listLabel.setForeground(UIConstants.FLESH_BLUE); + listLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + listLabel.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + responseClick(link); + } + }); + listLabel.setCursor(new Cursor(Cursor.HAND_CURSOR)); + + JPanel listPane = new JPanel(new BorderLayout()); + listPane.setBackground(Color.WHITE); + UILabel dotLabel = new UILabel("·"); + dotLabel.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0)); + dotLabel.setFont(DesignUtils.getDefaultGUIFont().applySize(14)); + dotLabel.setHorizontalAlignment(SwingConstants.LEADING); + dotLabel.setForeground(DOT_COLOR); + listPane.add(dotLabel, BorderLayout.WEST); + listPane.add(listLabel, BorderLayout.CENTER); + listPane.setPreferredSize(new Dimension(100, 20)); + return listPane; + } + + /** + * 方便记录埋点 + * + * @param link + */ + private void responseClick(String link) { + BrowseUtils.browser(link); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/LoadingRightSearchResultPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/LoadingRightSearchResultPane.java new file mode 100644 index 000000000..6201c25e5 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/LoadingRightSearchResultPane.java @@ -0,0 +1,167 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.CellType; +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import com.fr.design.mainframe.alphafine.cell.model.FileModel; +import com.fr.design.mainframe.alphafine.cell.model.PluginModel; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.project.ProjectConstants; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.exporter.LocalExportOperator; +import com.fr.workspace.server.exporter.TemplateExportOperator; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.image.BufferedImage; +import java.io.IOException; +import java.net.URL; +import java.util.concurrent.ExecutionException; +import javax.imageio.ImageIO; +import javax.swing.BorderFactory; +import javax.swing.ImageIcon; +import javax.swing.SwingWorker; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/20 + */ +public class LoadingRightSearchResultPane extends ResultShowPane { + + private SwingWorker showWorker; + + public LoadingRightSearchResultPane() { + + this.setBackground(Color.WHITE); + this.setPreferredSize(new Dimension(AlphaFineConstants.RIGHT_WIDTH - 1, AlphaFineConstants.CONTENT_HEIGHT)); + initLoadingLabel(); + + } + + private void initLoadingLabel() { + UILabel label = new UILabel(new ImageIcon(getClass().getResource("/com/fr/design/mainframe/alphafine/images/opening.gif"))); + label.setBorder(BorderFactory.createEmptyBorder(120, 0, 0, 0)); + this.add(label, BorderLayout.CENTER); + } + + private void showDefaultPreviewPane() { + this.removeAll(); + initLoadingLabel(); + validate(); + repaint(); + revalidate(); + } + + @Override + public void showResult(AlphaCellModel selectedValue) { + showDefaultPreviewPane(); + checkWorker(); + if (selectedValue.getType() == CellType.FILE) { + fileShowWorker(selectedValue); + } + + if (selectedValue.getType() == CellType.PLUGIN) { + pluginShowWorker(selectedValue); + } + this.showWorker.execute(); + } + + private void fileShowWorker(AlphaCellModel selectedValue) { + this.showWorker = new SwingWorker() { + @Override + protected BufferedImage doInBackground() throws Exception { + final String fileName = ((FileModel) selectedValue).getFilePath().substring(ProjectConstants.REPORTLETS_NAME.length() + 1); + if (fileName.endsWith(ProjectConstants.FRM_SUFFIX)) { + return frmToImage(fileName); + } else if (fileName.endsWith(ProjectConstants.CPT_SUFFIX)) { + return cptToImage(fileName); + } else { + return null; + } + } + + @Override + protected void done() { + if (!isCancelled()) { + LoadingRightSearchResultPane.this.removeAll(); + try { + LoadingRightSearchResultPane.this.add(new FilePreviewPane(get())); + } catch (InterruptedException | ExecutionException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + validate(); + repaint(); + } + } + }; + } + + private void pluginShowWorker(AlphaCellModel selectedValue) { + this.showWorker = new SwingWorker() { + @Override + protected BufferedImage doInBackground() { + BufferedImage bufferedImage = null; + try { + bufferedImage = ImageIO.read(new URL(((PluginModel) selectedValue).getImageUrl())); + } catch (IOException e) { + try { + bufferedImage = ImageIO.read(getClass().getResource("/com/fr/design/mainframe/alphafine/images/default_product.png")); + } catch (IOException e1) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + return bufferedImage; + } + + @Override + protected void done() { + try { + if (!isCancelled()) { + LoadingRightSearchResultPane.this.removeAll(); + LoadingRightSearchResultPane.this.add(new PluginPreviewPane((selectedValue).getName(), get(), ((PluginModel) selectedValue).getVersion(), ((PluginModel) selectedValue).getJartime(), ((PluginModel) selectedValue).getType(), ((PluginModel) selectedValue).getPrice())); + validate(); + repaint(); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }; + } + + + private BufferedImage frmToImage(String fileName) throws Exception { + byte[] bytes = null; + try { + bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportFormAsImageData(fileName); + } catch (Exception ignored) { + // 兼容下老版本 + bytes = new LocalExportOperator().exportFormAsImageData(fileName); + } + return TemplateExportOperator.byteDataToImage(bytes); + } + + + private BufferedImage cptToImage(String fileName) throws Exception { + byte[] bytes = null; + try { + bytes = WorkContext.getCurrent().get(TemplateExportOperator.class).exportWorkBookAsImageData(fileName); + } catch (Exception ignored) { + // 兼容下老版本 + bytes = new LocalExportOperator().exportWorkBookAsImageData(fileName); + } + return TemplateExportOperator.byteDataToImage(bytes); + } + + + private void checkWorker() { + if (this.showWorker != null && !this.showWorker.isDone()) { + this.showWorker.cancel(true); + this.showWorker = null; + } + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NetWorkFailedPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NetWorkFailedPane.java new file mode 100644 index 000000000..eb4c107c4 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NetWorkFailedPane.java @@ -0,0 +1,69 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.share.ui.base.MouseClickListener; +import com.fr.general.IOUtils; + +import javax.swing.BorderFactory; +import javax.swing.JPanel; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Cursor; +import java.awt.FlowLayout; +import java.awt.event.MouseEvent; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/28 + */ +public class NetWorkFailedPane extends JPanel { + + private Runnable reload; + + public NetWorkFailedPane() { + this(() -> {}); + } + + public NetWorkFailedPane(Runnable reload) { + this.reload = reload; + this.setLayout(new BorderLayout()); + this.add(createInternetErrorPane()); + this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); + this.setBackground(Color.WHITE); + } + + private JPanel createInternetErrorPane() { + JPanel panel = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 5); + panel.setBackground(Color.WHITE); + UILabel imagePanel = new UILabel(IOUtils.readIcon("/com/fr/base/images/share/internet_error.png")); + imagePanel.setBorder(BorderFactory.createEmptyBorder(50, 280, 0, 0)); + panel.add(imagePanel); + UILabel uiLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Internet_Connect_Failed")); + uiLabel.setBorder(BorderFactory.createEmptyBorder(0, 300, 0, 0)); + uiLabel.setForeground(Color.decode("#8F8F92")); + UILabel reloadLabel = tipLabel(Toolkit.i18nText("Fine-Design_Share_Online_Reload")); + reloadLabel.setBorder(BorderFactory.createEmptyBorder(0, 310, 0, 0)); + reloadLabel.setForeground(Color.decode("#419BF9")); + reloadLabel.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); + reloadLabel.addMouseListener(new MouseClickListener() { + @Override + public void mousePressed(MouseEvent e) { + reload.run(); + } + }); + panel.add(uiLabel); + panel.add(reloadLabel); + return panel; + } + + private UILabel tipLabel(String text) { + UILabel tipLabel = new UILabel(text); + tipLabel.setHorizontalAlignment(SwingConstants.CENTER); + return tipLabel; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultPane.java index 29a8c1e08..2187695f9 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultPane.java @@ -1,11 +1,12 @@ package com.fr.design.mainframe.alphafine.preview; -import com.bulenkov.iconloader.IconLoader; import com.fr.design.gui.ilable.UILabel; import com.fr.design.mainframe.alphafine.AlphaFineConstants; import com.fr.design.utils.DesignUtils; +import java.awt.Component; import javax.swing.BorderFactory; +import javax.swing.Icon; import javax.swing.JPanel; import javax.swing.SwingConstants; import java.awt.BorderLayout; @@ -16,21 +17,29 @@ import java.awt.Dimension; * Created by XiaXiang on 2017/8/14. */ public class NoResultPane extends JPanel { - public NoResultPane(String title, String iconUrl) { + public NoResultPane(String title, Icon icon) { + this(title, icon, AlphaFineConstants.LEFT_WIDTH); + } + + public NoResultPane(String title, Icon icon, int width) { setLayout(new BorderLayout()); setBackground(Color.white); - setPreferredSize(new Dimension(AlphaFineConstants.LEFT_WIDTH, AlphaFineConstants.CONTENT_HEIGHT)); + setPreferredSize(new Dimension(width, 305)); UILabel image = new UILabel(); image.setPreferredSize(new Dimension(150, 111)); image.setHorizontalAlignment(SwingConstants.CENTER); - image.setIcon(IconLoader.getIcon(iconUrl)); - image.setBorder(BorderFactory.createEmptyBorder(100, 0, 0, 0)); + image.setIcon(icon); + image.setBorder(BorderFactory.createEmptyBorder(30, 0, 0, 0)); + add(image, BorderLayout.CENTER); + add(generateDescription(title), BorderLayout.SOUTH); + } + + protected Component generateDescription(String title) { UILabel description = new UILabel(title); description.setForeground(AlphaFineConstants.MEDIUM_GRAY); description.setFont(DesignUtils.getDefaultGUIFont().applySize(14)); description.setBorder(BorderFactory.createEmptyBorder(0, 0, 135, 0)); description.setHorizontalAlignment(SwingConstants.CENTER); - add(image, BorderLayout.CENTER); - add(description, BorderLayout.SOUTH); + return description; } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultWithLinkPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultWithLinkPane.java new file mode 100644 index 000000000..3dc4a44b2 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/NoResultWithLinkPane.java @@ -0,0 +1,63 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.utils.BrowseUtils; +import com.fr.design.utils.DesignUtils; +import java.awt.Color; +import java.awt.Component; +import javax.swing.BorderFactory; +import javax.swing.Icon; +import javax.swing.event.HyperlinkEvent; +import javax.swing.event.HyperlinkListener; + +/** + * 带跳转链接的无结果面板 + * + * @author hades + * @version 11.0 + * Created by hades on 2022/4/12 + */ +public class NoResultWithLinkPane extends NoResultPane { + + private static final String TAG_A_START = ""; + private static final String TAG_A_END = ""; + + public NoResultWithLinkPane(String title, Icon icon) { + super(title, icon); + } + + @Override + protected Component generateDescription(String title) { + String[] para1 = title.split(TAG_A_START); + String[] para2 = para1[1].split(TAG_A_END); + + MessageWithLink messageWithLink = new MessageWithLink(para1[0], para2[0], AlphaFineConstants.ALPHA_GO_TO_FORUM, para2[1], Color.WHITE, DesignUtils.getDefaultGUIFont().applySize(14), AlphaFineConstants.MEDIUM_GRAY) { + @Override + protected void initListener(String link) { + + addHyperlinkListener(new HyperlinkListener() { + @Override + public void hyperlinkUpdate(HyperlinkEvent e) { + if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { + jumpToForum(link); + } + } + }); + } + }; + messageWithLink.setBorder(BorderFactory.createEmptyBorder(0, AlphaFineConstants.LEFT_WIDTH - 30, 135, 0)); + return messageWithLink; + } + + + /** + * 方便记录埋点 + * + * @param link + */ + private void jumpToForum(String link) { + BrowseUtils.browser(link); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/ResultShowPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/ResultShowPane.java new file mode 100644 index 000000000..7e82fc047 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/ResultShowPane.java @@ -0,0 +1,14 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public abstract class ResultShowPane extends JPanel { + + public abstract void showResult(AlphaCellModel selectedValue); +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SearchLoadingPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SearchLoadingPane.java new file mode 100644 index 000000000..112a5d2d0 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SearchLoadingPane.java @@ -0,0 +1,27 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; + +import java.awt.BorderLayout; +import java.awt.Color; +import javax.swing.ImageIcon; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/21 + */ +public class SearchLoadingPane extends JPanel { + + private static final ImageIcon LOADING_ICON = new ImageIcon(SearchLoadingPane.class.getResource("/com/fr/design/mainframe/alphafine/images/opening.gif")); + + public SearchLoadingPane() { + setLayout(new BorderLayout()); + this.add(new UILabel(LOADING_ICON)); + this.setPreferredSize(AlphaFineConstants.PREVIEW_SIZE); + this.setBackground(Color.WHITE); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SimpleRightSearchResultPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SimpleRightSearchResultPane.java new file mode 100644 index 000000000..6d94bd9ed --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/preview/SimpleRightSearchResultPane.java @@ -0,0 +1,32 @@ +package com.fr.design.mainframe.alphafine.preview; + +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.CellType; +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import java.awt.Color; +import java.awt.Dimension; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/20 + */ +public class SimpleRightSearchResultPane extends ResultShowPane { + + public SimpleRightSearchResultPane(JPanel contentPane) { + this.add(contentPane); + this.setBackground(Color.WHITE); + this.setPreferredSize(new Dimension(AlphaFineConstants.RIGHT_WIDTH - 1, AlphaFineConstants.CONTENT_HEIGHT)); + } + + @Override + public void showResult(AlphaCellModel selectedValue) { + if (selectedValue.getType() == CellType.DOCUMENT) { + this.removeAll(); + this.add(new DocumentPreviewPane((selectedValue).getName(), (selectedValue).getContent())); + validate(); + repaint(); + } + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java new file mode 100644 index 000000000..929cda762 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java @@ -0,0 +1,59 @@ +package com.fr.design.mainframe.alphafine.question; + +import com.fr.base.svg.SVGIcon; +import com.fr.base.svg.SVGLoader; +import com.fr.base.svg.SystemScaleUtils; +import com.fr.design.mainframe.alphafine.AlphaFineUtil; +import com.fr.design.utils.SvgPaintUtils; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/15 + */ +public class QuestionPane extends JPanel { + + private static final Image NEW_MESSAGE_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/group_new.svg"); + + private static final Image QUESTION_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/group.svg"); + + private static final Image QUESTION_BACKGROUND_IMAGE = SVGLoader.load("/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg"); + + public QuestionPane() { + this.setBackground(new Color(0, 0, 0, 0)); + } + + @Override + protected void paintComponent(Graphics g) { + super.paintComponent(g); + Graphics2D g2 = (Graphics2D) g; + SvgPaintUtils.beforePaint(g2); + // 宽高保持 + int width = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getWidth() * SVGIcon.SYSTEM_SCALE) : getWidth(); + int height = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getHeight() * SVGIcon.SYSTEM_SCALE) : getHeight(); + + if (AlphaFineUtil.unread()) { + g2.drawImage(NEW_MESSAGE_IMAGE, 0, 0, this); + } else { + g2.drawImage(QUESTION_BACKGROUND_IMAGE, 0, 0, this); + } + + int imageWidth = QUESTION_IMAGE.getWidth(this); + int imageHeight = QUESTION_IMAGE.getHeight(this); + g2.drawImage(QUESTION_IMAGE, (width - imageWidth) / 2 - 2, (height - imageHeight) / 2 - 2,this); + SvgPaintUtils.afterPaint(g2); + } + + + @Override + public Dimension getPreferredSize() { + return new Dimension(40, 40); + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionWindow.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionWindow.java new file mode 100644 index 000000000..e5d9edfec --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionWindow.java @@ -0,0 +1,84 @@ +package com.fr.design.mainframe.alphafine.question; + +import com.fr.design.DesignerEnvManager; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseMotionAdapter; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; +import javax.swing.JWindow; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/15 + */ +public class QuestionWindow extends JWindow { + + private static final QuestionWindow INSTANCE = new QuestionWindow(); + private final QuestionPane questionPane = new QuestionPane(); + private int pressX; + private int pressY; + private QuestionWindow() { + this.setBackground(new Color(0, 0, 0, 0)); + questionPane.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + AlphaFineHelper.showAlphaFineDialog(true); + } + + @Override + public void mousePressed(MouseEvent e) { + pressX = e.getX(); + pressY = e.getY(); + } + }); + questionPane.addMouseMotionListener(new MouseMotionAdapter() { + @Override + public void mouseDragged(MouseEvent e) { + int left = getLocation().x; + int top = getLocation().y; + setLocation(left + e.getX() - pressX, top + e.getY() - pressY); + } + }); + + DesignerContext.getDesignerFrame().addWindowListener(new WindowAdapter() { + + @Override + public void windowActivated(WindowEvent e) { + QuestionWindow.getInstance().setVisible(true); + } + + @Override + public void windowDeactivated(WindowEvent e) { + QuestionWindow.getInstance().dispose(); + QuestionWindow.getInstance().setVisible(false); + } + }); + questionPane.setToolTipText(Toolkit.i18nText("Fine-Design_Report_AlphaFine_Learn_More_About")); + this.setContentPane(questionPane); + this.setSize(new Dimension(40, 40)); + // 这个地方可以设置alwaysOnTop 弹窗会跟随主页面失去激活状态而隐藏 不会与其他弹窗冲突 + this.setAlwaysOnTop(true); + this.setLocation(DesignerContext.getDesignerFrame().getWidth() - 100, + DesignerContext.getDesignerFrame().getHeight() - 100); + } + + @Override + public void setVisible(boolean visible) { + if (visible && !DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isEnabled()) { + return; + } + super.setVisible(visible); + } + + public static QuestionWindow getInstance() { + return INSTANCE; + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/ProductNewsSearchWorkerManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/ProductNewsSearchWorkerManager.java new file mode 100644 index 000000000..40161e9ba --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/ProductNewsSearchWorkerManager.java @@ -0,0 +1,127 @@ +package com.fr.design.mainframe.alphafine.search; + +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.CellType; +import com.fr.design.mainframe.alphafine.component.AlphaFineFrame; +import com.fr.design.mainframe.alphafine.component.ProductNewsSearchResultPane; +import com.fr.design.mainframe.alphafine.model.ProductNews; +import com.fr.log.FineLoggerFactory; +import java.util.List; +import java.util.function.Function; +import javax.swing.DefaultListModel; +import javax.swing.SwingWorker; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/22 + */ +public class ProductNewsSearchWorkerManager implements SearchManager { + + private final CellType cellType; + + private SwingWorker, Void> searchWorker; + + private Function> searchFunction; + + private ProductNewsSearchResultPane searchResultPane; + + private AlphaFineFrame alphaFineFrame; + + private volatile boolean hasSearchResult = true; + + private volatile boolean searchOver = false; + + private volatile boolean networkError = false; + + public ProductNewsSearchWorkerManager(CellType cellType, Function> searchFunction, AlphaFineFrame alphaFineFrame) { + this.cellType = cellType; + this.searchFunction = searchFunction; + this.alphaFineFrame = alphaFineFrame; + } + + + + @Override + public void doSearch(SearchTextBean searchTextBean) { + checkSearchWork(); + searchOver = false; + networkError = false; + if (searchResultPane != null) { + alphaFineFrame.removeSearchResultPane(searchResultPane); + } + searchResultPane = new ProductNewsSearchResultPane(searchTextBean.getSegmentation()); + alphaFineFrame.addResult(searchResultPane, cellType.getFlagStr4Result()); + + this.searchWorker = new SwingWorker, Void>() { + @Override + protected DefaultListModel doInBackground() throws Exception { + DefaultListModel productNewsDefaultListModel = new DefaultListModel<>(); + if (!AlphaFineHelper.isNetworkOk() && cellType.isNeedNetWork()) { + networkError = true; + FineLoggerFactory.getLogger().warn("alphaFine network error"); + return productNewsDefaultListModel; + } + List productNewsList = searchFunction.apply(searchTextBean); + for (ProductNews productNews : productNewsList) { + productNewsDefaultListModel.addElement(productNews); + } + return productNewsDefaultListModel; + } + + @Override + protected void done() { + searchOver = true; + if (!isCancelled()) { + try { + if (networkError) { + alphaFineFrame.showResult(AlphaFineConstants.NETWORK_ERROR); + return; + } + DefaultListModel productNewsDefaultListModel = get(); + hasSearchResult = !productNewsDefaultListModel.isEmpty(); + searchResultPane.getProductNewsList().setModel(get()); + if (alphaFineFrame.getSelectedType() == cellType) { + if (!hasSearchResult) { + alphaFineFrame.showResult(CellType.NO_RESULT.getFlagStr4None()); + return; + } + alphaFineFrame.showResult(cellType.getFlagStr4Result()); + searchResultPane.getProductNewsList().setSelectedIndex(0); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + }; + this.searchWorker.execute(); + } + + public ProductNewsSearchResultPane getSearchResultPane() { + return searchResultPane; + } + + @Override + public boolean hasSearchResult() { + return hasSearchResult; + } + + @Override + public boolean isSearchOver() { + return searchOver; + } + + private void checkSearchWork() { + if (this.searchWorker != null && !this.searchWorker.isDone()) { + this.searchWorker.cancel(true); + this.searchWorker = null; + } + } + + @Override + public boolean isNetWorkError() { + return networkError; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchManager.java new file mode 100644 index 000000000..f9f789395 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchManager.java @@ -0,0 +1,17 @@ +package com.fr.design.mainframe.alphafine.search; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/17 + */ +public interface SearchManager { + + void doSearch(SearchTextBean searchTextBean); + + boolean hasSearchResult(); + + boolean isSearchOver(); + + boolean isNetWorkError(); +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchTextBean.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchTextBean.java new file mode 100644 index 000000000..f7148363c --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchTextBean.java @@ -0,0 +1,37 @@ +package com.fr.design.mainframe.alphafine.search; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/17 + */ +public class SearchTextBean { + + private String searchText; + + /** + * 分词搜索 + */ + private String[] segmentation; + + public SearchTextBean(String searchText, String[] segmentation) { + this.searchText = searchText; + this.segmentation = segmentation; + } + + public String getSearchText() { + return searchText; + } + + public void setSearchText(String searchText) { + this.searchText = searchText; + } + + public String[] getSegmentation() { + return segmentation; + } + + public void setSegmentation(String[] segmentation) { + this.segmentation = segmentation; + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchWorkerManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchWorkerManager.java new file mode 100644 index 000000000..0b25c3ca1 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/SearchWorkerManager.java @@ -0,0 +1,146 @@ +package com.fr.design.mainframe.alphafine.search; + +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.CellType; +import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import com.fr.design.mainframe.alphafine.component.AlphaFineFrame; +import com.fr.design.mainframe.alphafine.component.AlphaFineList; +import com.fr.design.mainframe.alphafine.component.SearchListModel; +import com.fr.design.mainframe.alphafine.component.SearchResultPane; +import com.fr.design.mainframe.alphafine.model.SearchResult; +import com.fr.design.mainframe.alphafine.preview.ResultShowPane; +import com.fr.log.FineLoggerFactory; +import java.util.function.Function; +import javax.swing.SwingWorker; +import org.jetbrains.annotations.Nullable; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/4/16 + */ +public class SearchWorkerManager implements SearchManager { + + private final CellType cellType; + + private SwingWorker searchWorker; + + private Function searchResultFunction; + + private SearchResultPane searchResultPane; + + private AlphaFineFrame alphaFineFrame; + + private ResultShowPane resultShowPane; + + private volatile boolean hasSearchResult = true; + + private volatile boolean searchOver = false; + + private volatile boolean networkError = false; + + public SearchWorkerManager(CellType cellType, Function function, AlphaFineFrame alphaFineFrame, ResultShowPane resultShowPane) { + this.cellType = cellType; + this.searchResultFunction = function; + this.alphaFineFrame = alphaFineFrame; + this.resultShowPane = resultShowPane; + } + + private void initSearchResult(SearchTextBean searchTextBean) { + if (searchResultPane != null) { + alphaFineFrame.removeSearchResultPane(searchResultPane); + } + searchResultPane = new SearchResultPane(searchTextBean.getSegmentation(), resultShowPane); + alphaFineFrame.addResult(searchResultPane, cellType.getFlagStr4Result()); + + } + + private void checkSearchWork() { + if (this.searchWorker != null && !this.searchWorker.isDone()) { + this.searchWorker.cancel(true); + this.searchWorker = null; + } + } + + private void initSearchWorker(SearchTextBean searchTextBean) { + this.searchOver = false; + this.networkError = false; + this.searchWorker = new SwingWorker() { + @Override + protected SearchListModel doInBackground() throws Exception { + SearchListModel searchListModel = new SearchListModel(new SearchResult(), searchResultPane.getSearchResultList(), searchResultPane.getLeftSearchResultPane()); + if (!AlphaFineHelper.isNetworkOk() && cellType.isNeedNetWork()) { + networkError = true; + FineLoggerFactory.getLogger().warn("alphaFine network error"); + return searchListModel; + } + SearchResult searchResult = searchResultFunction.apply(searchTextBean); + for (AlphaCellModel object : searchResult) { + AlphaFineHelper.checkCancel(); + searchListModel.addElement(object); + } + return searchListModel; + } + + @Override + protected void done() { + searchOver = true; + if (!isCancelled()) { + try { + if (networkError) { + alphaFineFrame.showResult(AlphaFineConstants.NETWORK_ERROR); + return; + } + SearchListModel searchListModel = get(); + hasSearchResult = !searchListModel.isEmpty(); + searchResultPane.getSearchResultList().setModel(get()); + if (alphaFineFrame.getSelectedType() == cellType) { + if (!hasSearchResult) { + alphaFineFrame.showResult(CellType.NO_RESULT.getFlagStr4None()); + return; + } + alphaFineFrame.showResult(cellType.getFlagStr4Result()); + searchResultPane.getSearchResultList().setSelectedIndex(0); + searchResultPane.getSearchResultList().requestFocus(); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + }; + } + + @Override + public void doSearch(SearchTextBean searchTextBean) { + initSearchResult(searchTextBean); + checkSearchWork(); + initSearchWorker(searchTextBean); + this.searchWorker.execute(); + } + + @Override + public boolean hasSearchResult() { + return hasSearchResult; + } + + @Override + public boolean isSearchOver() { + return searchOver; + } + + @Override + public boolean isNetWorkError() { + return networkError; + } + + @Nullable + public AlphaFineList getSearchResultList() { + if (searchResultPane != null) { + return searchResultPane.getSearchResultList(); + } + return null; + } + +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/fun/AlphaFineSearchProvider.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/fun/AlphaFineSearchProvider.java index b75aa894c..631fce88e 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/fun/AlphaFineSearchProvider.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/fun/AlphaFineSearchProvider.java @@ -1,6 +1,7 @@ package com.fr.design.mainframe.alphafine.search.manager.fun; import com.fr.design.mainframe.alphafine.model.SearchResult; +import com.fr.design.mainframe.alphafine.search.SearchTextBean; /** * Created by XiaXiang on 2017/3/27. @@ -20,4 +21,15 @@ public interface AlphaFineSearchProvider { * @return */ SearchResult getMoreSearchResult(String searchText); + + + /** + * 获取所有搜索结果 取决于具体实现 + * + * @param searchTextBean + * @return + */ + default SearchResult getSearchResult(SearchTextBean searchTextBean) { + return new SearchResult(); + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java index 1c4fec090..a2a1a7037 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java @@ -8,6 +8,7 @@ import com.fr.design.mainframe.alphafine.cell.model.ActionModel; import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; import com.fr.design.mainframe.alphafine.cell.model.MoreModel; import com.fr.design.mainframe.alphafine.model.SearchResult; +import com.fr.design.mainframe.alphafine.search.SearchTextBean; import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider; import com.fr.design.mainframe.toolbar.UpdateActionManager; import com.fr.design.mainframe.toolbar.UpdateActionModel; @@ -101,4 +102,10 @@ public class ActionSearchManager implements AlphaFineSearchProvider { public SearchResult getMoreSearchResult(String searchText) { return moreModelList; } + + @Override + public SearchResult getSearchResult(SearchTextBean searchTextBean) { + getLessSearchResult(searchTextBean.getSegmentation()); + return filterModelList; + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java index 0b4953083..bc3b214d0 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java @@ -7,6 +7,7 @@ import com.fr.design.mainframe.alphafine.CellType; import com.fr.design.mainframe.alphafine.cell.model.DocumentModel; import com.fr.design.mainframe.alphafine.cell.model.MoreModel; import com.fr.design.mainframe.alphafine.model.SearchResult; +import com.fr.design.mainframe.alphafine.search.SearchTextBean; import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider; import com.fr.general.http.HttpToolbox; import com.fr.json.JSONArray; @@ -15,7 +16,6 @@ import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; -import java.io.IOException; /** * Created by XiaXiang on 2017/3/27. @@ -24,6 +24,7 @@ public class DocumentSearchManager implements AlphaFineSearchProvider { private static volatile DocumentSearchManager instance; private SearchResult lessModelList; private SearchResult moreModelList; + private SearchResult searchResult; public static DocumentSearchManager getInstance() { if (instance == null) { @@ -54,6 +55,7 @@ public class DocumentSearchManager implements AlphaFineSearchProvider { public SearchResult getLessSearchResult(String[] searchText) { lessModelList = new SearchResult(); moreModelList = new SearchResult(); + searchResult = new SearchResult(); if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isContainDocument()) { if (ArrayUtils.isEmpty(searchText)) { lessModelList.add(new MoreModel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Community_Help"))); @@ -63,7 +65,7 @@ public class DocumentSearchManager implements AlphaFineSearchProvider { if(noConnectList != null){ return noConnectList; } - SearchResult searchResult = new SearchResult(); + searchResult = new SearchResult(); for (int j = 0; j < searchText.length; j++) { String url = AlphaFineConstants.DOCUMENT_SEARCH_URL + searchText[j]; try { @@ -81,6 +83,8 @@ public class DocumentSearchManager implements AlphaFineSearchProvider { } } } + } catch (JSONException jsonException) { + FineLoggerFactory.getLogger().warn(jsonException, jsonException.getMessage()); } catch (Exception e) { FineLoggerFactory.getLogger().error("document search error: " + e.getMessage()); } @@ -106,4 +110,9 @@ public class DocumentSearchManager implements AlphaFineSearchProvider { return moreModelList; } + @Override + public SearchResult getSearchResult(SearchTextBean searchTextBean) { + getLessSearchResult(searchTextBean.getSegmentation()); + return searchResult; + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java index 327d0555c..744b5a839 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/FileSearchManager.java @@ -9,6 +9,7 @@ import com.fr.design.mainframe.alphafine.CellType; import com.fr.design.mainframe.alphafine.cell.model.FileModel; import com.fr.design.mainframe.alphafine.cell.model.MoreModel; import com.fr.design.mainframe.alphafine.model.SearchResult; +import com.fr.design.mainframe.alphafine.search.SearchTextBean; import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider; import com.fr.file.filetree.FileNode; import com.fr.file.filetree.FileNodes; @@ -114,6 +115,12 @@ public class FileSearchManager implements AlphaFineSearchProvider { return moreModelList; } + @Override + public SearchResult getSearchResult(SearchTextBean searchTextBean) { + getLessSearchResult(searchTextBean.getSearchText(), searchTextBean.getSegmentation()); + return filterModelList; + } + private void doSearch(String searchText) { if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isContainTemplate()) { for (FileNode node : fileNodes) { diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/PluginSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/PluginSearchManager.java index 31a1b18ed..56f7078b4 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/PluginSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/PluginSearchManager.java @@ -7,6 +7,7 @@ import com.fr.design.mainframe.alphafine.CellType; import com.fr.design.mainframe.alphafine.cell.model.MoreModel; import com.fr.design.mainframe.alphafine.cell.model.PluginModel; import com.fr.design.mainframe.alphafine.model.SearchResult; +import com.fr.design.mainframe.alphafine.search.SearchTextBean; import com.fr.design.mainframe.alphafine.search.manager.fun.AlphaFineSearchProvider; import com.fr.general.ComparatorUtils; import com.fr.general.http.HttpToolbox; @@ -28,6 +29,7 @@ import java.net.URLEncoder; public class PluginSearchManager implements AlphaFineSearchProvider { private SearchResult lessModelList; private SearchResult moreModelList; + private SearchResult searchResult; private PluginSearchManager() { @@ -97,7 +99,7 @@ public class PluginSearchManager implements AlphaFineSearchProvider { public SearchResult getLessSearchResult(String[] searchText) { this.lessModelList = new SearchResult(); this.moreModelList = new SearchResult(); - SearchResult searchResult = new SearchResult(); + this.searchResult = new SearchResult(); if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isContainPlugin()) { if (ArrayUtils.isEmpty(searchText)) { lessModelList.add(new MoreModel(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Plugin_Addon"))); @@ -146,4 +148,11 @@ public class PluginSearchManager implements AlphaFineSearchProvider { public SearchResult getMoreSearchResult(String searchText) { return this.moreModelList; } + + + @Override + public SearchResult getSearchResult(SearchTextBean searchTextBean) { + getLessSearchResult(searchTextBean.getSegmentation()); + return searchResult; + } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java new file mode 100644 index 000000000..463eeb4ae --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ProductNewsSearchManager.java @@ -0,0 +1,123 @@ +package com.fr.design.mainframe.alphafine.search.manager.impl; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.mainframe.alphafine.AlphaFineConstants; +import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.model.ProductNews; +import com.fr.general.http.HttpToolbox; +import com.fr.json.JSON; +import com.fr.json.JSONArray; +import com.fr.json.JSONFactory; +import com.fr.json.JSONObject; +import com.fr.log.FineLoggerFactory; +import java.awt.Image; +import java.net.URL; +import java.util.ArrayList; +import java.util.Date; +import java.util.HashSet; +import java.util.List; +import java.util.Set; +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.TimeUnit; +import javax.imageio.ImageIO; +import org.jetbrains.annotations.Nullable; + +public class ProductNewsSearchManager { + + private static final ProductNewsSearchManager INSTANCE = new ProductNewsSearchManager(); + private static final int TIME_GAP = 12; + private List productNewsResultList; + + private List productNewsList = new ArrayList<>(); + + /** + * 单独记录一份cid的唯一id 用来判断是否已读 + */ + private Set idSet = new HashSet<>(); + + + private ScheduledExecutorService service; + + private ProductNewsSearchManager() { + service = Executors.newSingleThreadScheduledExecutor(new NamedThreadFactory("ProductNewsSearchManager", true)); + service.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + try { + getProductNewsList(); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + }, TIME_GAP, TIME_GAP, TimeUnit.HOURS); + } + + public static ProductNewsSearchManager getInstance() { + return INSTANCE; + } + + public List getSearchResult(String[] searchText) { + productNewsResultList = new ArrayList<>(); + try { + List productNewsList = getProductNewsList(); + for (ProductNews productNews : productNewsList) { + for (String str : searchText) { + if (productNews.getTitle().contains(str)) { + productNewsResultList.add(productNews); + break; + } + } + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return productNewsResultList; + } + + + public List getProductNewsList() throws Exception { + productNewsList = new ArrayList<>(); + idSet = new HashSet<>(); + String jsonStr = HttpToolbox.get(AlphaFineConstants.ALPHA_CID); + AlphaFineHelper.checkCancel(); + JSONObject cidJSON = JSONFactory.createJSON(JSON.OBJECT, jsonStr); + JSONArray jsonArray = cidJSON.getJSONArray("data"); + for (int i = 0, size = jsonArray.size(); i < size; i++) { + JSONObject obj = jsonArray.getJSONObject(i); + ProductNews productNews = new ProductNews(). + setId(obj.getLong("id")).setTitle(obj.getString("title")). + setImage(getCoverImage(obj.getString("pic"))). + setUrl(obj.getString("url")).setTag(ProductNews.Tag.parseCode(obj.getInt("tag"))). + setStatus(ProductNews.Status.parseCode(obj.getInt("status"))).setTarget( + ProductNews.Target.parseCode(obj.getInt("target"))). + setCreator(obj.getInt("creator")).setPushDate(new Date(obj.getLong("push_time"))); + Date currentDate = new Date(System.currentTimeMillis()); + // 推送时间check + if (productNews.getPushDate().before(currentDate)) { + productNewsList.add(productNews); + idSet.add(productNews.getId()); + } + } + return productNewsList; + } + + public List getCachedProductNewsList() { + return productNewsList; + } + + public Set getIdSet() { + return idSet; + } + + @Nullable + private Image getCoverImage(String url) { + try { + return ImageIO.read(new URL(url)); + } catch (Exception e) { + FineLoggerFactory.getLogger().warn("get image failed from {}", url); + FineLoggerFactory.getLogger().warn(e.getMessage(), e); + } + return null; + } +} diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java index 8ea078cd4..5fe65cd07 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerActivator.java @@ -51,6 +51,8 @@ import com.fr.design.mainframe.JForm; import com.fr.design.mainframe.WidgetPropertyPane; import com.fr.design.mainframe.WidgetToolBarPane; import com.fr.design.mainframe.alphafine.AlphaFineHelper; +import com.fr.design.mainframe.alphafine.question.QuestionWindow; +import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; import com.fr.design.mainframe.bbs.BBSGuestPane; import com.fr.design.mainframe.bbs.UserInfoPane; import com.fr.design.mainframe.form.FormECCompositeProvider; @@ -72,6 +74,10 @@ import com.fr.design.share.ui.generate.ShareGeneratePane; import com.fr.design.update.actions.RecoverForDesigner; import com.fr.design.update.push.DesignerPushUpdateManager; import com.fr.design.widget.ui.btn.FormSubmitButtonDetailPane; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; +import com.fr.event.Null; import com.fr.general.GeneralContext; import com.fr.general.xml.GeneralXMLTools; import com.fr.js.EmailJavaScript; @@ -128,6 +134,7 @@ import java.util.List; import java.util.Set; import java.awt.Image; import java.awt.image.BufferedImage; +import javax.swing.SwingWorker; /** * Created by juhaoyu on 2018/1/31. @@ -465,5 +472,24 @@ public class DesignerActivator extends Activator implements Prepare { public void prepare() { LoginAuthServer.getInstance().start(); ContentReplacerCenter.getInstance().register(); + EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { + @Override + public void on(Event event, Null param) { + new SwingWorker() { + + @Override + protected Void doInBackground() throws Exception { + // 触发下cid 搜索 + ProductNewsSearchManager.getInstance().getProductNewsList(); + return null; + } + + @Override + protected void done() { + QuestionWindow.getInstance().setVisible(true); + } + }.execute(); + } + }); } } diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/blue_bulb.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/blue_bulb.svg new file mode 100644 index 000000000..6f8d92a46 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/blue_bulb.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bulb.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bulb.svg new file mode 100644 index 000000000..746f1fd61 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/bulb.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/clear.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/clear.svg new file mode 100644 index 000000000..815f7c31b --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/clear.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/close.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/close.svg new file mode 100644 index 000000000..68259ce14 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/close.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group.svg new file mode 100644 index 000000000..2c400e245 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group_new.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group_new.svg new file mode 100644 index 000000000..9b25587c4 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/group_new.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg new file mode 100644 index 000000000..4d1989ea6 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/groupbackgroud.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/history_search.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/history_search.svg new file mode 100644 index 000000000..35b5a2e75 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/history_search.svg @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/hot_search.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/hot_search.svg new file mode 100644 index 000000000..35e2a657b --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/hot_search.svg @@ -0,0 +1,3 @@ + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/minimize.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/minimize.svg new file mode 100644 index 000000000..76c199416 --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/minimize.svg @@ -0,0 +1,3 @@ + + + From aba9f7d5a3b471c18c9e53067d42ec1c22ffbcfc Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 12 May 2022 18:19:57 +0800 Subject: [PATCH 08/55] =?UTF-8?q?REPORT-67417=20=E8=BF=90=E8=90=A5?= =?UTF-8?q?=E4=BA=A7=E5=93=81v1.0=20=20bug=20patch?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alphafine/AlphaFineConfigManager.java | 72 ++++++- .../mainframe/alphafine/AlphaFineUtil.java | 9 +- .../alphafine/component/AlphaFineFrame.java | 186 +++++++++++------- .../alphafine/component/AlphaFineList.java | 10 +- .../alphafine/question/QuestionPane.java | 3 +- 5 files changed, 203 insertions(+), 77 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java index a8970f9d1..1dd08c526 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java @@ -9,7 +9,7 @@ import com.fr.stable.xml.XMLPrintWriter; import com.fr.stable.xml.XMLReadable; import com.fr.stable.xml.XMLable; import com.fr.stable.xml.XMLableReader; -import java.util.ArrayList; +import java.util.Arrays; import java.util.HashSet; import java.util.LinkedHashMap; import java.util.List; @@ -99,7 +99,6 @@ public class AlphaFineConfigManager implements XMLable { private String cacheBuildNO; - // todo 暂不持久化 方便测试 /** * key: 登录的bbs用户 * value: alphaFine历史搜索记录 @@ -154,6 +153,10 @@ public class AlphaFineConfigManager implements XMLable { } else if (reader.isChildNode()) { if (ComparatorUtils.equals(reader.getTagName(), "ActionSearchTextCache")) { readActionSearchTextCacheXML(reader); + } else if ("SearchHistory".equals(reader.getTagName())) { + readHistorySearch(reader); + } else if ("ReadSet".equals(reader.getTagName())) { + readReadSet(reader); } } } @@ -180,6 +183,53 @@ public class AlphaFineConfigManager implements XMLable { }); } + private void readHistorySearch(XMLableReader reader) { + reader.readXMLObject(new XMLReadable() { + @Override + public void readXML(XMLableReader xmLableReader) { + if (ComparatorUtils.equals(reader.getTagName(), "history")) { + String tmpVal = reader.getElementValue(); + if (tmpVal != null) { + tmpVal = tmpVal.replace("[",StringUtils.EMPTY).replace("]",StringUtils.EMPTY); + Stack stack = new SizedStack<>(3); + String[] historyList = tmpVal.split(","); + for (String history : historyList) { + String value = history.trim(); + if (StringUtils.isNotEmpty(value)) { + stack.add(value); + } + } + historySearchMap.put(reader.getAttrAsString("user", StringUtils.EMPTY), stack); + } + } + } + }); + } + + + private void readReadSet(XMLableReader reader) { + reader.readXMLObject(new XMLReadable() { + @Override + public void readXML(XMLableReader xmLableReader) { + if (ComparatorUtils.equals(reader.getTagName(), "readId")) { + String tmpVal = reader.getElementValue(); + if (tmpVal != null) { + tmpVal = tmpVal.replace("[",StringUtils.EMPTY).replace("]",StringUtils.EMPTY); + String[] idArr = tmpVal.split(","); + Set setId = new HashSet<>(); + for (String id : idArr) { + String value = id.trim(); + if (StringUtils.isNotEmpty(value)) { + setId.add(Long.parseLong(value)); + } + } + readSetMap.put(reader.getAttrAsString("user", StringUtils.EMPTY), setId); + } + } + } + }); + } + @Override public void writeXML(XMLPrintWriter writer) { writer.startTAG("AlphaFineConfigManager"); @@ -198,6 +248,8 @@ public class AlphaFineConfigManager implements XMLable { .attr("needIntelligentCustomerService", this.isNeedIntelligentCustomerService()) .attr("productDynamics", this.isProductDynamics()); writeActionSearchTextCacheXML(writer); + writeSearchHistory(writer); + writeReadSet(writer); writer.end(); } @@ -212,6 +264,22 @@ public class AlphaFineConfigManager implements XMLable { writer.end(); } + private void writeSearchHistory(XMLPrintWriter writer) { + writer.startTAG("SearchHistory"); + for (Map.Entry> entry : historySearchMap.entrySet()) { + writer.startTAG("history").attr("user", entry.getKey()).textNode(entry.getValue().toString()).end(); + } + writer.end(); + } + + private void writeReadSet(XMLPrintWriter writer) { + writer.startTAG("ReadSet"); + for (Map.Entry> entry : readSetMap.entrySet()) { + writer.startTAG("readId").attr("user", entry.getKey()).textNode(entry.getValue().toString()).end(); + } + writer.end(); + } + public boolean isSearchOnLine() { return searchOnLine; } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java index 12ff5a9d6..814bc3530 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java @@ -18,9 +18,7 @@ public class AlphaFineUtil { } for (String string : strings) { String primaryStr = getReplacedString(modelName, string); -// modelName = escapeExprSpecialWord(modelName); if (StringUtils.isNotEmpty(primaryStr)) { -// primaryStr = escapeExprSpecialWord(primaryStr); modelName = modelName.replaceAll("(?i)" + primaryStr, "|" + primaryStr + "|"); } } @@ -34,6 +32,10 @@ public class AlphaFineUtil { private static String getReplacedString(String modelName, String string) { + // 如果是直接包含了高亮字符 返回 + if (StringUtils.contains(modelName, string)) { + return string; + } //需要考虑modelName有空格的情况 //比如现在是work boo k 搜索词是workb,应该要替换的部分是work b //先去掉已经匹配替换过的部分,因为考虑到分词的情况,可能会进行多次替换 @@ -48,7 +50,7 @@ public class AlphaFineUtil { StringBuilder result = new StringBuilder(); int count = 0; while (count < string.length()) { - char pos = noBlackName.charAt(index++); + char pos = modelName.charAt(index++); result.append(pos); count += pos == ' ' ? 0 : 1; } @@ -67,7 +69,6 @@ public class AlphaFineUtil { return keyword; } - public static boolean unread() { Set readSet = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getReadSet(); Set idSet = ProductNewsSearchManager.getInstance().getIdSet(); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java index d97710ef1..b6763f8cf 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java @@ -77,6 +77,18 @@ import javax.swing.Timer; public class AlphaFineFrame extends JFrame { private static final String ADVANCED_SEARCH_MARK = "k:"; + private static final String ACTION_MARK_SHORT = "k:1 "; + private static final String ACTION_MARK = "k:setting "; + private static final String DOCUMENT_MARK_SHORT = "k:2 "; + private static final String DOCUMENT_MARK = "k:help "; + private static final String FILE_MARK_SHORT = "k:3 "; + private static final String FILE_MARK = "k:reportlets "; + private static final String CPT_MARK = "k:cpt "; + private static final String FRM_MARK = "k:frm "; + private static final String DS_MARK = "k:ds "; + private static final String DS_NAME = "dsname=\""; + private static final String PLUGIN_MARK_SHORT = "k:4 "; + private static final String PLUGIN_MARK = "k:shop "; private static final int TIMER_DELAY = 300; @@ -282,6 +294,7 @@ public class AlphaFineFrame extends JFrame { @Override public void mousePressed(MouseEvent e) { searchTextField.setText(StringUtils.EMPTY); + beforeSearchStr = StringUtils.EMPTY; clearLabel.setVisible(false); } }); @@ -354,6 +367,87 @@ public class AlphaFineFrame extends JFrame { JPanel tabPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); tabPane.setBackground(Color.WHITE); + List selectedLabelList = createSelectedLabelList(); + selectedType = selectedLabelList.get(0).getCellType(); + // 第一个tab 非产品动态 + if (selectedType != CellType.PRODUCT_NEWS) { + tabLabel.setText(selectedLabelList.get(0).getText()); + readLabel.setVisible(false); + } + for (SelectedLabel selectedLabel : selectedLabelList) { + selectedLabel.addMouseListener(createMouseListener(selectedLabelList, selectedLabel, tabPane, tabLabel, readLabel)); + tabPane.add(selectedLabel); + } + showPane.add(tabPane, BorderLayout.NORTH); + showPane.add(labelPane, BorderLayout.CENTER); + showPane.add(resultPane, BorderLayout.SOUTH); + return showPane; + } + + private MouseAdapter createMouseListener(List selectedLabelList, SelectedLabel selectedLabel, + JPanel tabPane, UILabel tabLabel, UILabel readLabel) { + return new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + for (SelectedLabel label : selectedLabelList) { + label.setSelected(false); + label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); + } + selectedLabel.setSelected(true); + // 处理产品动态 tab与下方文字展示不一致 + if (ComparatorUtils.equals(selectedLabel.getText().trim(), PRODUCT_NEWS)) { + tabLabel.setText(PRODUCT_DYNAMICS); + } else { + tabLabel.setText(selectedLabel.getText()); + } + readLabel.setVisible(false); + tabPane.repaint(); + switch (selectedLabel.getCellType()) { + case PRODUCT_NEWS: + readLabel.setVisible(true); + switchType(CellType.PRODUCT_NEWS); + break; + case ACTION: + currentSearchWorkerManager = settingSearchWorkerManager; + switchType(CellType.ACTION); + break; + case FILE: + currentSearchWorkerManager = fileSearchWorkerManager; + switchType(CellType.FILE); + break; + case DOCUMENT: + currentSearchWorkerManager = documentWorkerManager; + switchType(CellType.DOCUMENT); + break; + case PLUGIN: + currentSearchWorkerManager = pluginSearchWorkerManager; + switchType(CellType.PLUGIN); + break; + } + if (currentSearchWorkerManager != null) { + AlphaFineList alphaFineList = currentSearchWorkerManager.getSearchResultList(); + if (alphaFineList != null) { + alphaFineList.setSelectedIndex(0); + } + } + } + + private Color defaultColor; + + @Override + public void mouseEntered(MouseEvent e) { + defaultColor = selectedLabel.getForeground(); + selectedLabel.setForeground(AlphaFineConstants.SUSPENDED_COLOR); + } + + @Override + public void mouseExited(MouseEvent e) { + selectedLabel.setForeground(defaultColor); + } + }; + } + + private List createSelectedLabelList() { List selectedLabelList = new ArrayList<>(); AlphaFineConfigManager alphaFineConfigManager = DesignerEnvManager.getEnvManager().getAlphaFineConfigManager(); if (alphaFineConfigManager.isProductDynamics()) { @@ -371,74 +465,7 @@ public class AlphaFineFrame extends JFrame { if (alphaFineConfigManager.isContainPlugin()) { selectedLabelList.add(new SelectedLabel(PLUGIN, CellType.PLUGIN)); } - selectedType = selectedLabelList.get(0).getCellType(); - for (SelectedLabel selectedLabel : selectedLabelList) { - - selectedLabel.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - for (SelectedLabel label : selectedLabelList) { - label.setSelected(false); - label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); - } - selectedLabel.setSelected(true); - // 处理产品动态 tab与下方文字展示不一致 - if (ComparatorUtils.equals(selectedLabel.getText().trim(), PRODUCT_NEWS)) { - tabLabel.setText(PRODUCT_DYNAMICS); - } else { - tabLabel.setText(selectedLabel.getText()); - } - readLabel.setVisible(false); - tabPane.repaint(); - switch (selectedLabel.getCellType()) { - case PRODUCT_NEWS: - readLabel.setVisible(true); - switchType(CellType.PRODUCT_NEWS); - break; - case ACTION: - currentSearchWorkerManager = settingSearchWorkerManager; - switchType(CellType.ACTION); - break; - case FILE: - currentSearchWorkerManager = fileSearchWorkerManager; - switchType(CellType.FILE); - break; - case DOCUMENT: - currentSearchWorkerManager = documentWorkerManager; - switchType(CellType.DOCUMENT); - break; - case PLUGIN: - currentSearchWorkerManager = pluginSearchWorkerManager; - switchType(CellType.PLUGIN); - break; - } - if (currentSearchWorkerManager != null) { - AlphaFineList alphaFineList = currentSearchWorkerManager.getSearchResultList(); - if (alphaFineList != null) { - alphaFineList.setSelectedIndex(0); - } - } - } - - private Color defaultColor; - - @Override - public void mouseEntered(MouseEvent e) { - defaultColor = selectedLabel.getForeground(); - selectedLabel.setForeground(AlphaFineConstants.SUSPENDED_COLOR); - } - - @Override - public void mouseExited(MouseEvent e) { - selectedLabel.setForeground(defaultColor); - } - }); - tabPane.add(selectedLabel); - } - showPane.add(tabPane, BorderLayout.NORTH); - showPane.add(labelPane, BorderLayout.CENTER); - showPane.add(resultPane, BorderLayout.SOUTH); - return showPane; + return selectedLabelList; } private void fireOneClickRead() { @@ -543,6 +570,8 @@ public class AlphaFineFrame extends JFrame { if (StringUtils.isNotEmpty(searchTextField.getText())) { clearLabel.setVisible(true); SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); + } else { + beforeSearchStr = StringUtils.EMPTY; } AlphaFineToolTipList alphaFineToolTipList = SearchTooltipPopup.getInstance().getAlphaFineToolTipList(); if (e.getKeyCode() == KeyEvent.VK_ENTER) { @@ -590,6 +619,7 @@ public class AlphaFineFrame extends JFrame { SearchTooltipPopup.getInstance().hide(); clearLabel.setVisible(false); switchType(selectedType); + beforeSearchStr = StringUtils.EMPTY; } else if (searchTextField.hasFocus()) { clearLabel.setVisible(true); SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); @@ -659,7 +689,7 @@ public class AlphaFineFrame extends JFrame { private void doSearch(String text) { initSearchLoadingPane(); - SearchTextBean searchTextBean = new SearchTextBean(text, segmentationResult); + SearchTextBean searchTextBean = generateSearchTextBean(text); this.productNewsSearchWorkerManager.doSearch(searchTextBean); this.settingSearchWorkerManager.doSearch(searchTextBean); this.fileSearchWorkerManager.doSearch(searchTextBean); @@ -667,6 +697,21 @@ public class AlphaFineFrame extends JFrame { this.pluginSearchWorkerManager.doSearch(searchTextBean); } + private SearchTextBean generateSearchTextBean(String searchText) { + if (searchText.startsWith(ACTION_MARK_SHORT) || searchText.startsWith(ACTION_MARK) + || searchText.startsWith(DOCUMENT_MARK_SHORT) || searchText.startsWith(DOCUMENT_MARK)) { + return new SearchTextBean(StringUtils.EMPTY, new String[]{getStoreText(searchText)}); + } else if (searchText.startsWith(FILE_MARK_SHORT) || searchText.startsWith(FILE_MARK) + || searchText.startsWith(CPT_MARK) || searchText.startsWith(FRM_MARK) + || searchText.startsWith(PLUGIN_MARK_SHORT) || searchText.startsWith(PLUGIN_MARK)) { + return new SearchTextBean(getStoreText(searchText), new String[]{getStoreText(searchText)}); + } else if (searchText.startsWith(DS_MARK)) { + return new SearchTextBean(getStoreText(searchText), new String[]{DS_NAME + getStoreText(searchText)}); + } else { + return new SearchTextBean(searchText, segmentationResult == null ? new String[]{} : segmentationResult); + } + } + /** * 仅搜索依赖网络的搜索项 * @@ -772,6 +817,9 @@ public class AlphaFineFrame extends JFrame { public void setVisible(boolean b) { super.setVisible(b); QuestionWindow.getInstance().setVisible(!b); + if (!b) { + AlphaFineHelper.resetAlphaFineDialog(); + } } @Override diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java index b58a3e51b..f4ffe50e3 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineList.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.alphafine.component; import com.fr.design.mainframe.alphafine.AlphaFineConstants; import com.fr.design.mainframe.alphafine.AlphaFineHelper; import com.fr.design.mainframe.alphafine.cell.model.AlphaCellModel; +import com.fr.design.mainframe.alphafine.cell.model.DocumentModel; import com.fr.design.mainframe.alphafine.preview.ResultShowPane; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; @@ -26,7 +27,10 @@ public class AlphaFineList extends JList { AlphaCellModel selectedValue = getSelectedValue(); if (e.getClickCount() == AlphaFineConstants.DEFAULT_CLICK_COUNT && selectedValue.hasAction()) { // 点击搜索结果 主页面移动到后面 - AlphaFineHelper.getAlphaFineDialog().toBack(); + if (!(selectedValue instanceof DocumentModel)) { + // 帮助文档不跳转 + AlphaFineHelper.getAlphaFineDialog().toBack(); + } dealWithSearchResult(); } } @@ -45,6 +49,10 @@ public class AlphaFineList extends JList { @Override public void keyPressed(KeyEvent e) { if (e.getKeyCode() == KeyEvent.VK_ENTER) { + AlphaCellModel selectedValue = getSelectedValue(); + if (selectedValue.hasAction() && !(selectedValue instanceof DocumentModel)) { + AlphaFineHelper.getAlphaFineDialog().toBack(); + } dealWithSearchResult(); } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java index 929cda762..63593c7f7 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/question/QuestionPane.java @@ -3,6 +3,7 @@ package com.fr.design.mainframe.alphafine.question; import com.fr.base.svg.SVGIcon; import com.fr.base.svg.SVGLoader; import com.fr.base.svg.SystemScaleUtils; +import com.fr.design.DesignerEnvManager; import com.fr.design.mainframe.alphafine.AlphaFineUtil; import com.fr.design.utils.SvgPaintUtils; import java.awt.Color; @@ -38,7 +39,7 @@ public class QuestionPane extends JPanel { int width = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getWidth() * SVGIcon.SYSTEM_SCALE) : getWidth(); int height = SystemScaleUtils.isJreHiDPIEnabled() ? (int) (getHeight() * SVGIcon.SYSTEM_SCALE) : getHeight(); - if (AlphaFineUtil.unread()) { + if (AlphaFineUtil.unread() && DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isProductDynamics()) { g2.drawImage(NEW_MESSAGE_IMAGE, 0, 0, this); } else { g2.drawImage(QUESTION_BACKGROUND_IMAGE, 0, 0, this); From 236dece1d88d2e6ea1e1e3da704864438b95574a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=B9=E7=A3=8A?= <294531121@qq.com> Date: Thu, 12 May 2022 21:12:27 +0800 Subject: [PATCH 09/55] =?UTF-8?q?REPORT-69532=2010.0=E5=88=9B=E5=BB=BA?= =?UTF-8?q?=E5=A4=8D=E7=94=A8=E7=BB=84=E4=BB=B6=E8=B6=85=E5=87=BA960*540?= =?UTF-8?q?=E6=97=B6=EF=BC=8C=E7=BB=99=E5=87=BA=E6=8F=90=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../share/action/CreateComponentAction.java | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java index 8d2adceb8..1b0f83c12 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/share/action/CreateComponentAction.java @@ -85,6 +85,8 @@ import static javax.swing.JOptionPane.ERROR_MESSAGE; * 创建组件事件 */ public class CreateComponentAction extends UpdateAction { + private static final double MAX_WIDTH = 960.0; + private static final double MAX_HEIGHT = 540.0; ShareUIAspect aspect; /** * 等待时间 500 ms. @@ -123,6 +125,11 @@ public class CreateComponentAction extends UpdateAction { return; } + if (isBeyondMaxSize(sharedTriple.getRight())) { + showErrMsgDialog(Toolkit.i18nText("Fine-Design_Share_Widget_Size_Error_Tip")); + return; + } + Widget widget = sharedTriple.getLeft(); try { @@ -410,4 +417,20 @@ public class CreateComponentAction extends UpdateAction { } return paras; } + + private boolean isBeyondMaxSize(Rectangle rec) { + double width = rec.getWidth(); + double height = rec.getHeight(); + return width > 0 && height > 0 && (width > MAX_WIDTH || height > MAX_HEIGHT); + } + + private void showErrMsgDialog(String err) { + FineJOptionPane.showMessageDialog( + DesignerContext.getDesignerFrame(), + err, + Toolkit.i18nText("Fine-Design_Basic_Tool_Tips"), + ERROR_MESSAGE, + IOUtils.readIcon("/com/fr/base/images/share/Information_Icon_warning_normal_32x32.png") + ); + } } From 38ded435a475c40cae45b6249a8f86af79c7a4a7 Mon Sep 17 00:00:00 2001 From: hades Date: Mon, 16 May 2022 10:43:06 +0800 Subject: [PATCH 10/55] =?UTF-8?q?REPORT-70681=20=E8=B6=85=E9=95=BF?= =?UTF-8?q?=E6=96=87=E6=9C=AC=E6=90=9C=E7=B4=A2=E9=97=AE=E9=A2=98=20?= =?UTF-8?q?=E5=90=8C=E6=AD=A510.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alphafine/AlphaFineConstants.java | 11 ++++ .../alphafine/component/AlphaFineFrame.java | 65 ++++++++++++++----- .../manager/impl/ActionSearchManager.java | 9 ++- .../manager/impl/DocumentSearchManager.java | 11 ++++ 4 files changed, 79 insertions(+), 17 deletions(-) diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java index f4440fb5c..9ceec2a2f 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java @@ -48,6 +48,17 @@ public class AlphaFineConstants { public static final int HOT_ITEMS = 6; + /** + * 限制搜索字符长度 + */ + public static final int LEN_LIMIT = 50; + + /** + * 帮助文档搜索间隔(ms) api限制了1s之内只能搜索一次 + * + */ + public static final long DOCUMENT_SEARCH_GAP = 1000; + public static final Dimension FULL_SIZE = new Dimension(680, 460); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java index b6763f8cf..db89cf348 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java @@ -146,6 +146,8 @@ public class AlphaFineFrame extends JFrame { private UILabel clearLabel; + private JPanel tabPane; + private CellType selectedType; private String beforeSearchStr = StringUtils.EMPTY; @@ -365,7 +367,7 @@ public class AlphaFineFrame extends JFrame { labelPane.add(labelContentPane); labelPane.setPreferredSize(new Dimension(AlphaFineConstants.FULL_SIZE.width, 30)); - JPanel tabPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); + tabPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 20, 10)); tabPane.setBackground(Color.WHITE); List selectedLabelList = createSelectedLabelList(); selectedType = selectedLabelList.get(0).getCellType(); @@ -624,6 +626,7 @@ public class AlphaFineFrame extends JFrame { clearLabel.setVisible(true); SearchTooltipPopup.getInstance().show(searchTextFieldWrapperPane); } + tabPane.repaint(); }); timer.start(); @@ -644,28 +647,58 @@ public class AlphaFineFrame extends JFrame { beforeSearchStr = StringUtils.EMPTY; return; } + String lowerCaseSearchText = preProcessSearchText(searchTextField.getText().toLowerCase()); if (DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().isNeedSegmentationCheckbox()) { - //是高级搜索 - if (searchTextField.getText().toLowerCase().startsWith(ADVANCED_SEARCH_MARK)) { - segmentationResult = SegmentationManager.getInstance().startSegmentation(getStoreText(searchTextField.getText().toLowerCase())); - } - //是普通搜索 - else { - segmentationResult = SegmentationManager.getInstance().startSegmentation(searchTextField.getText().toLowerCase()); - } + dealSegmentationSearch(lowerCaseSearchText); } else { - if (StringUtils.isEmpty(getRealSearchText(searchTextField.getText()))) { - segmentationResult = null; - } else { - segmentationResult = new String[]{getRealSearchText(searchTextField.getText())}; - } + dealNormalSearch(); } DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getHistorySearch().push(searchTextField.getText()); - doSearch(searchTextField.getText().toLowerCase()); + doSearch(lowerCaseSearchText); beforeSearchStr = searchTextField.getText(); SearchTooltipPopup.getInstance().hide(); } + /** + * 普通搜索 + */ + private void dealNormalSearch() { + String searchText = preProcessSearchText(searchTextField.getText()); + if (StringUtils.isEmpty(getRealSearchText(searchText))) { + segmentationResult = null; + } else { + segmentationResult = new String[]{getRealSearchText(searchText)}; + } + } + + /** + * 分词搜索 + */ + private void dealSegmentationSearch(String lowerCaseSearchText) { + //是高级搜索 + if (searchTextField.getText().toLowerCase().startsWith(ADVANCED_SEARCH_MARK)) { + segmentationResult = SegmentationManager.getInstance().startSegmentation(getStoreText(lowerCaseSearchText)); + } + //是普通搜索 + else { + segmentationResult = SegmentationManager.getInstance().startSegmentation(lowerCaseSearchText); + } + } + + /** + * 文本预处理 限制长度 + * + * @param text + * @return + */ + private String preProcessSearchText(String text) { + if (text.length() > AlphaFineConstants.LEN_LIMIT) { + return text.substring(0, AlphaFineConstants.LEN_LIMIT); + } else { + return text; + } + } + private void dealWithSearchResult() { final AlphaCellModel model = searchResultList.getSelectedValue(); if (model != null) { @@ -717,7 +750,7 @@ public class AlphaFineFrame extends JFrame { * */ private void reSearch() { - String text = this.searchTextField.getText().toLowerCase(); + String text = preProcessSearchText(this.searchTextField.getText().toLowerCase()); if (StringUtils.isEmpty(text)) { return; } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java index a2a1a7037..54d6d1402 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/ActionSearchManager.java @@ -17,7 +17,9 @@ import com.fr.json.JSONObject; import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; +import java.util.HashSet; import java.util.List; +import java.util.Set; /** * Created by XiaXiang on 2017/3/27. @@ -68,12 +70,17 @@ public class ActionSearchManager implements AlphaFineSearchProvider { return lessModelList; } List updateActions = UpdateActionManager.getUpdateActionManager().getUpdateActions(); + Set searchKeySet = new HashSet<>(); for (UpdateActionModel updateActionModel : updateActions) { for (int j = 0; j < searchText.length; j++) { AlphaFineHelper.checkCancel(); if (StringUtils.isNotBlank(updateActionModel.getSearchKey())) { - if (updateActionModel.getSearchKey().contains(searchText[j]) && updateActionModel.getAction().isEnabled()) { + if (updateActionModel.getSearchKey().contains(searchText[j]) + && updateActionModel.getAction().isEnabled() + // 老alphaFine就有问题 加个去重 + && !searchKeySet.contains(updateActionModel.getSearchKey())) { filterModelList.add(new ActionModel(updateActionModel.getActionName(), updateActionModel.getParentName(), updateActionModel.getAction())); + searchKeySet.add(updateActionModel.getSearchKey()); } } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java index bc3b214d0..3ea1f2db2 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/search/manager/impl/DocumentSearchManager.java @@ -15,6 +15,7 @@ import com.fr.json.JSONException; import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; import com.fr.stable.ArrayUtils; +import java.util.concurrent.TimeUnit; /** @@ -67,6 +68,7 @@ public class DocumentSearchManager implements AlphaFineSearchProvider { } searchResult = new SearchResult(); for (int j = 0; j < searchText.length; j++) { + long start = System.currentTimeMillis(); String url = AlphaFineConstants.DOCUMENT_SEARCH_URL + searchText[j]; try { String result = HttpToolbox.get(url); @@ -88,6 +90,15 @@ public class DocumentSearchManager implements AlphaFineSearchProvider { } catch (Exception e) { FineLoggerFactory.getLogger().error("document search error: " + e.getMessage()); } + // 计算等待时间 防止1s内搜索多次 + long spentTime = (System.currentTimeMillis() - start); + long waitTime = AlphaFineConstants.DOCUMENT_SEARCH_GAP - spentTime; + if (waitTime > 0 && j != searchText.length - 1) { + try { + TimeUnit.MILLISECONDS.sleep(waitTime); + } catch (Exception ignored) { + } + } } lessModelList.clear(); moreModelList.clear(); From ada25d5ab82138504a505f9b2de408952078630c Mon Sep 17 00:00:00 2001 From: hades Date: Tue, 17 May 2022 14:09:20 +0800 Subject: [PATCH 11/55] =?UTF-8?q?REPORT-70681=20=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E4=B8=80=E4=BA=9B=E7=89=B9=E6=AE=8A=E5=AD=97=E7=AC=A6=20?= =?UTF-8?q?=E9=AB=98=E4=BA=AE=E5=B1=95=E7=A4=BA=E6=97=B6=20=E5=B1=95?= =?UTF-8?q?=E7=A4=BA=E6=95=88=E6=9E=9C=E4=B8=8D=E5=AF=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/mainframe/alphafine/AlphaFineUtil.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java index 814bc3530..5648ab98d 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineUtil.java @@ -2,6 +2,7 @@ package com.fr.design.mainframe.alphafine; import com.fr.design.DesignerEnvManager; import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; +import com.fr.stable.ArrayUtils; import com.fr.stable.StringUtils; import java.util.Set; @@ -13,10 +14,15 @@ import java.util.Set; public class AlphaFineUtil { public static String highLightModelName(String modelName, String[] strings) { - if (strings == null) { + if (strings == null || ArrayUtils.isEmpty(strings)) { return modelName; } for (String string : strings) { + // 高亮分词 跳过高亮颜色本身的字符 + boolean skipHighLight = modelName.contains(AlphaFineConstants.HIGH_LIGHT_COLOR) && AlphaFineConstants.HIGH_LIGHT_COLOR.contains(string); + if (skipHighLight) { + continue; + } String primaryStr = getReplacedString(modelName, string); if (StringUtils.isNotEmpty(primaryStr)) { modelName = modelName.replaceAll("(?i)" + primaryStr, "|" + primaryStr + "|"); From 67ab1e9f5c756eb63298753b63fbbb46d6ee80c7 Mon Sep 17 00:00:00 2001 From: hades Date: Wed, 18 May 2022 11:12:59 +0800 Subject: [PATCH 12/55] =?UTF-8?q?REPORT-71855=2010.0=E4=B8=8B=E4=BA=A7?= =?UTF-8?q?=E5=93=81=E5=8A=A8=E6=80=81=E4=B8=8D=E6=98=BE=E7=A4=BAnew?= =?UTF-8?q?=E5=9B=BE=E6=A0=87?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../mainframe/alphafine/images/new_tip.svg | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/new_tip.svg diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/new_tip.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/new_tip.svg new file mode 100644 index 000000000..549e6e50a --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/new_tip.svg @@ -0,0 +1,25 @@ + + + + + + + + + + + + + + + + + + + + + + + + + From 78ca28174bbecfbfb363a538b64d405022456049 Mon Sep 17 00:00:00 2001 From: kerry Date: Wed, 18 May 2022 14:46:17 +0800 Subject: [PATCH 13/55] =?UTF-8?q?REPORT-68422=20=E5=86=B3=E7=AD=96?= =?UTF-8?q?=E6=8A=A5=E8=A1=A8-=E5=AE=A2=E6=88=B7=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=EF=BC=8Cbody=E4=B8=8B=E6=94=BE=E7=BB=9D=E5=AF=B9=E7=94=BB?= =?UTF-8?q?=E5=B8=83=E5=9D=97=EF=BC=8C=E7=BB=9D=E5=AF=B9=E7=94=BB=E5=B8=83?= =?UTF-8?q?=E5=9D=97=E4=B8=8Btab=EF=BC=8C=E6=97=A7=E6=A8=A1=E5=BC=8F?= =?UTF-8?q?=E9=A2=84=E8=A7=88=EF=BC=8Ctab=E5=88=87=E6=8D=A2=E4=B8=8D?= =?UTF-8?q?=E7=94=9F=E6=95=88=EF=BC=8C=E5=88=A0=E6=8E=89=E7=BB=9D=E5=AF=B9?= =?UTF-8?q?=E7=94=BB=E5=B8=83=E5=9D=97=E5=B0=B1=E6=AD=A3=E5=B8=B8=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/designer/beans/models/ModelUtil.java | 2 +- .../fr/design/designer/creator/cardlayout/XWCardTagLayout.java | 3 +++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java index 0f75896e1..dda70b96f 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/ModelUtil.java @@ -18,7 +18,7 @@ import java.util.Set; /** * created by Harrison on 2020/06/05 **/ -abstract class ModelUtil { +public abstract class ModelUtil { public static void renameWidgetName(Form form, XCreator xCreator) { diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java index 010a38217..1bf00c234 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardTagLayout.java @@ -9,6 +9,7 @@ import com.fr.design.designer.beans.AdapterBus; import com.fr.design.designer.beans.ComponentAdapter; import com.fr.design.designer.beans.LayoutAdapter; import com.fr.design.designer.beans.adapters.layout.FRWCardTagLayoutAdapter; +import com.fr.design.designer.beans.models.ModelUtil; import com.fr.design.designer.beans.models.SelectionModel; import com.fr.design.designer.creator.XCreator; import com.fr.design.designer.creator.XCreatorUtils; @@ -137,6 +138,8 @@ public class XWCardTagLayout extends XWHorizontalBoxLayout { WTabFitLayout fitLayout = new WTabFitLayout(widgetName, tabFitIndex, currentCard); fitLayout.setTabNameIndex(getTabNameIndex()); XWTabFitLayout tabFitLayout = new XWTabFitLayout(fitLayout, new Dimension()); + FormDesigner formDesigner = WidgetPropertyPane.getInstance().getEditingFormDesigner(); + ModelUtil.renameWidgetName(formDesigner.getTarget(), tabFitLayout); WCardTagLayout layout = (WCardTagLayout) this.toData(); if(!ComparatorUtils.equals(layout.getTemplateStyle().getStyle(), DefaultTemplateStyle.DEFAULT_TEMPLATE_STYLE)){ From 08b8f71b86733d64ebab9457d18d9231859ebc1e Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 19 May 2022 00:10:51 +0800 Subject: [PATCH 14/55] =?UTF-8?q?REPORT-71890=20=E5=A1=AB=E6=8A=A5-?= =?UTF-8?q?=E5=A1=AB=E6=8A=A5=E5=B1=9E=E6=80=A7=E8=AE=BE=E7=BD=AE-?= =?UTF-8?q?=E5=A1=AB=E6=8A=A5=E5=B1=9E=E6=80=A7=E7=9A=84=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E5=BA=93=E4=BF=9D=E5=AD=98=E5=90=8E=E6=89=93=E5=BC=80=EF=BC=8C?= =?UTF-8?q?=E4=B8=8D=E6=98=BE=E7=A4=BA=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/data/datapane/ChoosePane.java | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index 6917f4c08..74a41ea7c 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -649,12 +649,11 @@ public class ChoosePane extends BasicBeanPane implements Refresha */ @Override public void registerDSChangeListener() { - this.addAncestorListener(new ManageDsListenerRegisterListener(new ChangeListener() { - @Override - public void stateChanged(ChangeEvent e) { - initDsNameComboBox(); - } - })); + // do nothing + // 这里dsNameComboBox 实际并不是数据集而是数据连接 不应该响应数据集变化监听 之后 todo 改下名称 引用地方比较多 + // 在单例场景 响应数据连接变化应该使用 DesignerContext.getDesignerBean("databasename").refreshBeanElement() 在数据连接变化时已有调用 + // 在非单例场景 每次都会重新初始化 不需要刷新 + // 综上 这里应该去掉响应数据集的监听 } /** From 8dfb80ad6f02c647e3d16c62e35e60db60515b31 Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 19 May 2022 09:34:20 +0800 Subject: [PATCH 15/55] =?UTF-8?q?REPORT-71890=20=E9=87=8D=E6=96=B0?= =?UTF-8?q?=E5=8A=A0=E4=B8=8A=20=E4=BD=BF=E7=94=A8refresh=E6=A8=A1?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/data/datapane/ChoosePane.java | 48 +++++++++++++++++-- 1 file changed, 43 insertions(+), 5 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index 74a41ea7c..2cb3a9681 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -649,11 +649,49 @@ public class ChoosePane extends BasicBeanPane implements Refresha */ @Override public void registerDSChangeListener() { - // do nothing - // 这里dsNameComboBox 实际并不是数据集而是数据连接 不应该响应数据集变化监听 之后 todo 改下名称 引用地方比较多 - // 在单例场景 响应数据连接变化应该使用 DesignerContext.getDesignerBean("databasename").refreshBeanElement() 在数据连接变化时已有调用 - // 在非单例场景 每次都会重新初始化 不需要刷新 - // 综上 这里应该去掉响应数据集的监听 + // 还是需要保留 恶心 + // 1. 切换工作目录需要依赖这个监听 切换工作目录没有一个数据连接的刷新触发 就很坑 + // 2. DesignerContext.getDesignerBean("databasename").refreshBeanElement()有坑 a.调用不全 b.某些场景下 因为注册覆盖 会失效 + // 监听内容变成刷新模式 不会覆盖 populate填充内容 + this.addAncestorListener(new ManageDsListenerRegisterListener(new ChangeListener() { + @Override + public void stateChanged(ChangeEvent e) { + refreshDsNameComboBox(); + } + })); + } + + + @SuppressWarnings("unchecked") + private void refreshDsNameComboBox() { + if (initWorker != null && !initWorker.isDone()) { + initWorker.cancel(true); + } + dsNameComboBox.setRefreshingModel(true); + initWorker = new SwingWorker, Void>() { + + @Override + protected List doInBackground() throws Exception { + return getHasAuthConnections(); + } + + @Override + protected void done() { + try { + FilterableComboBoxModel dsNameComboBoxModel = new FilterableComboBoxModel(get()); + String selected = dsNameComboBox.getSelectedItem(); + dsNameComboBox.setModel(dsNameComboBoxModel); + dsNameComboBox.setRefreshingModel(true); + dsNameComboBox.setSelectedItem(selected); + dsNameComboBox.setRefreshingModel(false); + } catch (Exception e) { + if (!(e instanceof CancellationException)) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + } + } + }; + initWorker.execute(); } /** From 7b82a2c01b37d0b6d5dc9177e9c69081d4978091 Mon Sep 17 00:00:00 2001 From: hades Date: Fri, 6 May 2022 11:02:53 +0800 Subject: [PATCH 16/55] =?UTF-8?q?REPORT-70387=20=E6=AC=A1=E7=AE=A1?= =?UTF-8?q?=E8=BF=9C=E7=A8=8B=E8=BF=9E=E6=8E=A5=EF=BC=8C=E4=BC=9A=E7=9C=8B?= =?UTF-8?q?=E5=88=B0=E7=89=B9=E5=AE=9A=E7=9A=84=E6=B2=A1=E6=9C=89=E6=9D=83?= =?UTF-8?q?=E9=99=90=E7=9A=84=E6=95=B0=E6=8D=AE=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/data/datapane/connect/ConnectionComboBoxPanel.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java index c0e8ef023..81147d42d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java @@ -204,7 +204,7 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { if (StringUtils.isNotBlank(s)) { // 之前的写法有多线程问题,nameList异步尚未初始化完成的时候,这里可能无法匹配设置数据连接名称,导致DBTableDataPane打开后连接面板空白 // 这里的需求无非是设置上一次使用的数据连接,做个简单检查这个连接是否存在即可,存在就设置 - if (ConnectionConfig.getInstance().getConnection(s) != null) { + if (nameList.contains(s)) { this.setSelectedItem(s); } } From 182d70f604ada283eac66543e37ea6e347247c8b Mon Sep 17 00:00:00 2001 From: Starryi Date: Fri, 20 May 2022 14:27:38 +0800 Subject: [PATCH 17/55] =?UTF-8?q?REPORT-71957=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=A4=8D=E7=94=A8-=E5=88=9B=E5=BB=BA=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E8=AE=A4=E5=90=8E=E6=8F=90=E7=A4=BA=E5=85=B1?= =?UTF-8?q?=E4=BA=AB=E7=BB=84=E4=BB=B6=E5=88=9B=E5=BB=BA=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=EF=BC=8C=E4=B8=94=E6=97=A5=E5=BF=97=E6=9C=89=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【问题原因】 生成组件时需要使用组件名称作为文件名创建临时文件,而组件名称中可能 包含不合法字符,导致临时文件创建失败。虽然这种文件创建失败的情况 只会在特定操作系统上出现,但考虑到共享组件跨平台应用的可能性,因此 需要统一检查组件名称的合法性,以便在使用时能使用此名称创建文件。 若创建组件时名称非法,则给出提示。 【改动思路】 同上 【review建议】 --- .../com/fr/design/share/ui/generate/ShareMainPane.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java index ea5298cf2..6ec3fa61e 100644 --- a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java @@ -32,6 +32,7 @@ import com.fr.design.mainframe.share.ui.base.ui.PlaceHolderUI; import com.fr.design.mainframe.share.util.ShareUIUtils; import com.fr.design.share.effect.EffectItemGroup; import com.fr.design.share.utils.ShareDialogUtils; +import com.fr.file.FileCommonUtils; import com.fr.form.share.DefaultSharableWidget; import com.fr.form.share.bean.StyleThemeBean; import com.fr.form.share.constants.ShareComponentConstants; @@ -581,6 +582,15 @@ public class ShareMainPane extends JPanel { Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); return false; } + if (FileCommonUtils.isFileNameValid(name)) { + FineJOptionPane.showMessageDialog( + shareDialog, + Toolkit.i18nText("Fine-Design_Share_Generate_Failure_Illegal_Component_Name_Tip"), + Toolkit.i18nText("Fine-Design_Basic_Error"), + ERROR_MESSAGE, + UIManager.getIcon("OptionPane.errorIcon")); + return false; + } if (upload && StringUtils.isEmpty(content.getText())) { FineJOptionPane.showMessageDialog(shareDialog, Toolkit.i18nText("Fine-Design_Share_Lack_Content"), Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); From 76d77a6e9ee10449dc4d5836fa8c30d5ef3cb9a3 Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 2 Jun 2022 10:19:52 +0800 Subject: [PATCH 18/55] =?UTF-8?q?REPORT-72073=20alphafine,=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=8A=80=E5=B7=A7=E4=BA=A4=E4=BA=92=E6=95=88=E6=9E=9C?= =?UTF-8?q?=E4=BF=AE=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../alphafine/AlphaFineConstants.java | 4 +- .../alphafine/component/AlphaFineFrame.java | 59 ++++++++++++++++--- .../alphafine/images/light_yellow_bulb.svg | 4 ++ .../alphafine/images/yellow_bulb.svg | 4 ++ 4 files changed, 63 insertions(+), 8 deletions(-) create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg create mode 100644 designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java index 9ceec2a2f..8de2a0d63 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/AlphaFineConstants.java @@ -191,7 +191,9 @@ public class AlphaFineConstants { public static final Icon BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/bulb.svg"); - public static final Icon BLUE_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/blue_bulb.svg"); + public static final Icon YELLOW_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/yellow_bulb.svg"); + + public static final Icon LIGHT_YELLOW_BULB_ICON = IconUtils.readIcon("com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg"); public static final String HOT_SEARCH = Toolkit.i18nText("Fine-Design_Report_AlphaFine_Hot_Search"); diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java index db89cf348..b6819f56c 100644 --- a/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java +++ b/designer-realize/src/main/java/com/fr/design/mainframe/alphafine/component/AlphaFineFrame.java @@ -33,6 +33,7 @@ import com.fr.design.mainframe.alphafine.search.manager.impl.PluginSearchManager import com.fr.design.mainframe.alphafine.search.manager.impl.ProductNewsSearchManager; import com.fr.design.mainframe.alphafine.search.manager.impl.SegmentationManager; import com.fr.design.utils.DesignUtils; +import com.fr.design.utils.gui.GUICoreUtils; import com.fr.general.ComparatorUtils; import com.fr.stable.StringUtils; import java.awt.BorderLayout; @@ -66,8 +67,11 @@ import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; +import javax.swing.JPopupMenu; import javax.swing.SwingConstants; import javax.swing.Timer; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; /** * @author hades @@ -241,13 +245,10 @@ public class AlphaFineFrame extends JFrame { topRightPane.setBackground(Color.WHITE); JPanel tipPane = new JPanel(new BorderLayout()); tipPane.setBackground(Color.WHITE); - String toolTip = AlphaFineShortCutUtil.getDisplayShortCut(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Short_Cut", DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getShortcuts())); tipIconLabel = new UILabel(AlphaFineConstants.BULB_ICON); tipIconLabel.addMouseListener(tipMouseListener); - tipIconLabel.setToolTipText(toolTip); useTipLabel = new UILabel(SKILLS); useTipLabel.addMouseListener(tipMouseListener); - useTipLabel.setToolTipText(toolTip); useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); tipPane.add(tipIconLabel, BorderLayout.WEST); tipPane.add(useTipLabel, BorderLayout.CENTER); @@ -264,19 +265,63 @@ public class AlphaFineFrame extends JFrame { private MouseAdapter tipMouseListener = new MouseAdapter() { + private JPopupMenu popupMenu; + @Override public void mouseEntered(MouseEvent e) { - useTipLabel.setForeground(UIConstants.FLESH_BLUE); - tipIconLabel.setIcon(AlphaFineConstants.BLUE_BULB_ICON); + tipIconLabel.setIcon(AlphaFineConstants.YELLOW_BULB_ICON); } @Override public void mouseExited(MouseEvent e) { - useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); - tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON); + if (popupMenu == null || !popupMenu.isShowing()) { + useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); + tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON); + } + } + + @Override + public void mousePressed(MouseEvent e) { + useTipLabel.setForeground(UIConstants.FLESH_BLUE); + tipIconLabel.setIcon(AlphaFineConstants.LIGHT_YELLOW_BULB_ICON); + popupMenu = createTipPop(); + GUICoreUtils.showPopupMenu(popupMenu, e.getComponent(), e.getComponent().getX() - 60, e.getComponent().getY() + 20); } }; + + private JPopupMenu createTipPop() { + JPanel panel = new JPanel(new BorderLayout()); + String toolTip = AlphaFineShortCutUtil.getDisplayShortCut(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_AlphaFine_Short_Cut", DesignerEnvManager.getEnvManager().getAlphaFineConfigManager().getShortcuts())); + UILabel label = new UILabel(toolTip); + label.setForeground(AlphaFineConstants.FOREGROUND_COLOR_8); + label.setBackground(Color.WHITE); + panel.add(label); + panel.setBackground(Color.WHITE); + JPopupMenu popupMenu = new JPopupMenu(); + popupMenu.setBorder(BorderFactory.createEmptyBorder(20, 5, 10, 5)); + popupMenu.add(panel); + popupMenu.setBackground(Color.WHITE); + popupMenu.addPopupMenuListener(new PopupMenuListener() { + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + // do nothing + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + useTipLabel.setForeground(AlphaFineConstants.FOREGROUND_COLOR_6); + tipIconLabel.setIcon(AlphaFineConstants.BULB_ICON); + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + // do nothing + } + }); + return popupMenu; + } + private JPanel createSearchPane() { JPanel searchPane = new JPanel(new BorderLayout()); searchPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 20)); diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg new file mode 100644 index 000000000..16608753f --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/light_yellow_bulb.svg @@ -0,0 +1,4 @@ + + + + diff --git a/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg new file mode 100644 index 000000000..cabda1d9d --- /dev/null +++ b/designer-realize/src/main/resources/com/fr/design/mainframe/alphafine/images/yellow_bulb.svg @@ -0,0 +1,4 @@ + + + + From f14699bce62ff12c722f43a340c754563a4ba9c8 Mon Sep 17 00:00:00 2001 From: Starryi Date: Tue, 7 Jun 2022 11:27:34 +0800 Subject: [PATCH 19/55] =?UTF-8?q?REPORT-71957=20=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=E5=A4=8D=E7=94=A8-=E5=88=9B=E5=BB=BA=E7=BB=84=E4=BB=B6?= =?UTF-8?q?=EF=BC=8C=E7=A1=AE=E8=AE=A4=E5=90=8E=E6=8F=90=E7=A4=BA=E5=85=B1?= =?UTF-8?q?=E4=BA=AB=E7=BB=84=E4=BB=B6=E5=88=9B=E5=BB=BA=E5=A4=B1=E8=B4=A5?= =?UTF-8?q?=EF=BC=8C=E4=B8=94=E6=97=A5=E5=BF=97=E6=9C=89=E6=8A=A5=E9=94=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 【问题原因】 生成组件时需要使用组件名称作为文件名创建临时文件,而组件名称中可能 包含不合法字符,导致临时文件创建失败。虽然这种文件创建失败的情况 只会在特定操作系统上出现,但考虑到共享组件跨平台应用的可能性,因此 需要统一检查组件名称的合法性,以便在使用时能使用此名称创建文件。 若创建组件时名称非法,则给出提示。 【改动思路】 同上 【review建议】 --- .../java/com/fr/design/share/ui/generate/ShareMainPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java index 6ec3fa61e..550f0a0c0 100644 --- a/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java +++ b/designer-realize/src/main/java/com/fr/design/share/ui/generate/ShareMainPane.java @@ -582,7 +582,7 @@ public class ShareMainPane extends JPanel { Toolkit.i18nText("Fine-Design_Basic_Error"), ERROR_MESSAGE, UIManager.getIcon("OptionPane.errorIcon")); return false; } - if (FileCommonUtils.isFileNameValid(name)) { + if (!FileCommonUtils.isFileNameValid(name)) { FineJOptionPane.showMessageDialog( shareDialog, Toolkit.i18nText("Fine-Design_Share_Generate_Failure_Illegal_Component_Name_Tip"), From c93bd63727dc828920d2fe8b52717f237bb311c0 Mon Sep 17 00:00:00 2001 From: "Bruce.Deng" Date: Wed, 8 Jun 2022 15:51:33 +0800 Subject: [PATCH 20/55] =?UTF-8?q?REPORT-72769=20=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E4=BA=8B=E4=BB=B6-=E5=B7=B2=E5=88=A0=E9=99=A4=E4=BA=8B?= =?UTF-8?q?=E4=BB=B6=E7=9A=84=E5=AF=BC=E5=87=BA=E6=A8=A1=E6=9D=BF=E8=AE=BE?= =?UTF-8?q?=E7=BD=AE=E4=BC=9A=E5=9C=A8=E5=86=8D=E6=AC=A1=E6=96=B0=E5=A2=9E?= =?UTF-8?q?=E7=9A=84=E6=97=B6=E5=80=99=E5=AD=98=E5=9C=A8=E6=AE=8B=E7=95=99?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/javascript/ExportJavaScriptPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java index 460e838c5..b58dd6f65 100644 --- a/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java +++ b/designer-base/src/main/java/com/fr/design/javascript/ExportJavaScriptPane.java @@ -279,8 +279,8 @@ public class ExportJavaScriptPane extends AbstractHyperLinkPane Date: Thu, 9 Jun 2022 11:11:06 +0800 Subject: [PATCH 21/55] =?UTF-8?q?REPORT-73106=20=E5=B0=86=E5=8F=82?= =?UTF-8?q?=E6=95=B0=E9=9D=A2=E6=9D=BF=E6=8E=A7=E4=BB=B6=E5=89=AA=E5=88=87?= =?UTF-8?q?=E5=88=B0=E4=B8=80=E4=B8=AA=E6=96=B0=E7=9A=84cpt,=E5=8E=9Ffrm?= =?UTF-8?q?=E7=95=8C=E9=9D=A2=E5=B0=B1=E5=8F=98=E6=88=90=E5=92=8Ccpt?= =?UTF-8?q?=E4=B8=80=E6=A0=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../designer/beans/models/SelectionModel.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java b/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java index df645e2df..082075707 100644 --- a/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java +++ b/designer-form/src/main/java/com/fr/design/designer/beans/models/SelectionModel.java @@ -25,7 +25,6 @@ import com.fr.design.fun.FormWidgetOptionProvider; import com.fr.design.mainframe.FormDesigner; import com.fr.design.mainframe.FormSelection; import com.fr.design.mainframe.FormSelectionUtils; -import com.fr.design.mainframe.share.encrypt.clipboard.impl.EncryptSelectionClipboardHandler; import com.fr.design.utils.ComponentUtils; import com.fr.design.utils.gui.LayoutUtils; import com.fr.general.ComparatorUtils; @@ -140,11 +139,28 @@ public class SelectionModel { if (cutSelection != null) { cutSelection.cut2ClipBoard(clipboard); designer.getEditListenerTable().fireCreatorModified(DesignerEvent.CREATOR_CUTED); + setSelectedCreator(hasSelectedParaComponent() ? designer.getParaComponent() : designer.getRootComponent()); designer.repaint(); } } } + /** + * 判断是否选中参数面板中的组件 + * @return boolean + */ + private boolean hasSelectedParaComponent() { + XCreator[] roots = selection.getSelectedCreators(); + if (roots.length > 0) { + for (XCreator creator : roots) { + if ((creator.getParent() instanceof XWParameterLayout)) { + return true; + } + } + } + return false; + } + /** * 复制当前选中的组件到剪切板 */ From 9815174813fbb6189ea9703bb0d2b1eb4e81b603 Mon Sep 17 00:00:00 2001 From: hades Date: Tue, 14 Jun 2022 17:00:54 +0800 Subject: [PATCH 22/55] =?UTF-8?q?REPORT-71476=20=E6=96=B0=E5=BB=BA?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E5=90=8E=EF=BC=8C=E7=9B=AE=E5=BD=95=E6=B2=A1?= =?UTF-8?q?=E6=9C=89=E9=80=89=E4=B8=AD=E6=A8=A1=E6=9D=BF=EF=BC=8C=E9=87=8D?= =?UTF-8?q?=E5=91=BD=E5=90=8D=E4=B8=8D=E5=BA=94=E8=AF=A5=E9=AB=98=E4=BA=AE?= =?UTF-8?q?=20=E5=90=8C=E6=AD=A5=E5=88=B010.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/main/java/com/fr/design/mainframe/JTemplate.java | 1 + 1 file changed, 1 insertion(+) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java index 6e8b02000..52dd81b33 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplate.java @@ -1555,6 +1555,7 @@ public abstract class JTemplate> refreshToolArea(); } DesignerFrameFileDealerPane.getInstance().refresh(); + DesignerFrameFileDealerPane.getInstance().stateChange(); } }); From aa611e019d31edc5bc1ea8437c16a78668459cd9 Mon Sep 17 00:00:00 2001 From: hades Date: Wed, 8 Jun 2022 19:34:17 +0800 Subject: [PATCH 23/55] =?UTF-8?q?REPORT-72570=20=E5=AF=8C=E6=96=87?= =?UTF-8?q?=E6=9C=AC=E5=AF=BC=E5=87=BA=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/form/util/FontTransformUtil.java | 8 +++ .../fr/design/form/util/HtmlPaintUtils.java | 42 ++++++++++++++++ .../design/form/util/HtmlPaintUtilsTest.java | 49 +++++++++++++++++++ .../cell/editor/RichTextCellEditor.java | 9 +++- .../design/cell/editor/RichTextToolBar.java | 4 +- 5 files changed, 108 insertions(+), 4 deletions(-) create mode 100644 designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java create mode 100644 designer-form/src/test/java/com/fr/design/form/util/HtmlPaintUtilsTest.java diff --git a/designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java b/designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java index 769707ebe..eab2a64bb 100644 --- a/designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java +++ b/designer-form/src/main/java/com/fr/design/form/util/FontTransformUtil.java @@ -5,6 +5,7 @@ import com.fr.design.ExtraDesignClassManager; import com.fr.design.fun.FormAdaptiveConfigUIProcessor; import com.fr.stable.Constants; import com.fr.stable.unit.PT; +import java.math.BigDecimal; /** @@ -43,4 +44,11 @@ public class FontTransformUtil { return value * (double) Constants.DEFAULT_FONT_PAINT_RESOLUTION / (double) getDesignerFontResolution(); } + + public static int roundUp(double num) { + String numStr = Double.toString(num); + numStr = new BigDecimal(numStr).setScale(0, BigDecimal.ROUND_HALF_UP).toString(); + return Integer.valueOf(numStr); + } + } diff --git a/designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java b/designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java new file mode 100644 index 000000000..f8620f52d --- /dev/null +++ b/designer-form/src/main/java/com/fr/design/form/util/HtmlPaintUtils.java @@ -0,0 +1,42 @@ +package com.fr.design.form.util; + +import com.fr.base.Style; +import com.fr.general.FRFont; +import com.fr.log.FineLoggerFactory; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * 富文本导出工具栏 + * + * @author hades + * @version 11.0 + * Created by hades on 2022/5/19 + */ +public class HtmlPaintUtils { + + + private static final Pattern FONT_SIZE_PATTERN = Pattern.compile(Pattern.quote("font-size:") + "(.*?)" + Pattern.quote("px")); + + /** + * 设置单元格字体为富文本中的最大字体 + * + * @param style + */ + public static Style deriveMaxFontFromRichChar(Style style, String html) { + int maxSize = style.getFRFont().getSize(); + Matcher matcher = FONT_SIZE_PATTERN.matcher(html); + while (matcher.find()) { + String value = matcher.group(1); + try { + double pxSize = Double.parseDouble(value); + int ptSize = FontTransformUtil.roundUp(FontTransformUtil.px2pt(pxSize)); + maxSize = Math.max(maxSize, ptSize); + } catch (Throwable e) { + FineLoggerFactory.getLogger().debug(e.getMessage(), e); + } + } + FRFont cellFont = style.getFRFont(); + return style.deriveFRFont(cellFont.applySize(maxSize)); + } +} diff --git a/designer-form/src/test/java/com/fr/design/form/util/HtmlPaintUtilsTest.java b/designer-form/src/test/java/com/fr/design/form/util/HtmlPaintUtilsTest.java new file mode 100644 index 000000000..445e865ab --- /dev/null +++ b/designer-form/src/test/java/com/fr/design/form/util/HtmlPaintUtilsTest.java @@ -0,0 +1,49 @@ +package com.fr.design.form.util; + +import com.fr.base.Style; +import junit.framework.TestCase; +import org.junit.Assert; + + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/5/25 + */ +public class HtmlPaintUtilsTest extends TestCase { + + public void testDeriveMaxFontFromRichChar() { + // 富文本字体size更大 + String testHtml0 = "这是一条测试数据"; + Style style0 = Style.DEFAULT_STYLE; + Assert.assertEquals(16, HtmlPaintUtils.deriveMaxFontFromRichChar(style0, testHtml0).getFRFont().getSize()); + + // 单元格字体size更大 + String testHtml1 = "这是一条测试数据"; + Style style1 = Style.DEFAULT_STYLE; + int oldFontSize = style1.getFRFont().getSize(); + Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style1, testHtml1).getFRFont().getSize()); + + // 富文本字体size更大 不同文本 有不同size + String testHtml2 = "这是一条测试数"; + Style style2 = Style.DEFAULT_STYLE; + Assert.assertEquals(23, HtmlPaintUtils.deriveMaxFontFromRichChar(style2, testHtml2).getFRFont().getSize()); + + + // 异常场景1 + String testHtml3 = "xxxx奇怪的格式xxxx"; + Style style3 = Style.DEFAULT_STYLE; + oldFontSize = style1.getFRFont().getSize(); + Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style3, testHtml3).getFRFont().getSize()); + + // 异常场景2 + String testHtml4 = "这是一条测试数据"; + Style style4 = Style.DEFAULT_STYLE; + oldFontSize = style1.getFRFont().getSize(); + Assert.assertEquals(oldFontSize, HtmlPaintUtils.deriveMaxFontFromRichChar(style4, testHtml4).getFRFont().getSize()); + + + } + + +} \ No newline at end of file diff --git a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java index 101928135..1d2a5eda2 100644 --- a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java +++ b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextCellEditor.java @@ -1,5 +1,8 @@ package com.fr.design.cell.editor; +import com.fr.design.mainframe.DesignerContext; +import com.fr.general.GeneralUtils; +import com.fr.design.form.util.HtmlPaintUtils; import java.awt.Component; import javax.swing.SwingUtilities; @@ -42,6 +45,11 @@ public class RichTextCellEditor extends AbstractCellEditor implements @Override public void doOk() { RichTextCellEditor.this.fireEditingStopped(); + CellElement newCellElement = parentTplEC.getTemplateCellElement(cellElement.getColumn(), cellElement.getRow()); + if (cellElement.getCellGUIAttr().isShowAsHTML()) { + newCellElement.setStyle(HtmlPaintUtils.deriveMaxFontFromRichChar(newCellElement.getStyle(), GeneralUtils.objectToString(newCellElement.getValue()))); + DesignerContext.getDesignerFrame().refreshToolbar(); + } } @Override @@ -49,7 +57,6 @@ public class RichTextCellEditor extends AbstractCellEditor implements RichTextCellEditor.this.fireEditingCanceled(); } }); - richTextDialog.addDialogActionListener(this); this.richTextPane.populate(parentTplEC, cellElement); setShowAsHtml(cellElement); diff --git a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java index f95681be3..74654cd2e 100644 --- a/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java +++ b/designer-realize/src/main/java/com/fr/design/cell/editor/RichTextToolBar.java @@ -366,9 +366,7 @@ public class RichTextToolBar extends BasicPane { }; private int roundUp(double num) { - String numStr = Double.toString(num); - numStr = new BigDecimal(numStr).setScale(0, BigDecimal.ROUND_HALF_UP).toString(); - return Integer.valueOf(numStr); + return FontTransformUtil.roundUp(num); } private CaretListener textCareListener = new CaretListener() { From af8cf0b5412729c82f0eacd5c02a05b6bf7dbda1 Mon Sep 17 00:00:00 2001 From: hades Date: Fri, 27 May 2022 17:01:17 +0800 Subject: [PATCH 24/55] =?UTF-8?q?REPORT-70562=20=E5=AF=BC=E5=87=BA?= =?UTF-8?q?=E5=AD=97=E4=BD=93=E5=AD=97=E5=8F=B7=E9=97=AE=E9=A2=98-?= =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/gui/ilable/ActionLabel.java | 11 ++- .../fr/design/report/ExportUniversalPane.java | 78 +++++++++++++++++++ .../design/report/ReportExportAttrPane.java | 13 ++++ 3 files changed, 99 insertions(+), 3 deletions(-) create mode 100644 designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java diff --git a/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java b/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java index ebccd24f4..85d73515e 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java +++ b/designer-base/src/main/java/com/fr/design/gui/ilable/ActionLabel.java @@ -13,11 +13,16 @@ import java.awt.event.MouseEvent; */ public class ActionLabel extends UILabel { private ActionListener actionListener; + private Color color; public ActionLabel(String text) { - super(text); + this(text, Color.blue); + } - this.setForeground(Color.blue); + public ActionLabel(String text, Color color) { + super(text); + this.color = color; + this.setForeground(color); this.addMouseListener(mouseInputAdapter); this.addMouseMotionListener(mouseInputAdapter); } @@ -33,7 +38,7 @@ public class ActionLabel extends UILabel { public void paintComponent(Graphics _gfx) { super.paintComponent(_gfx); - _gfx.setColor(Color.blue); + _gfx.setColor(this.color); _gfx.drawLine(0, this.getHeight() - 1, this.getWidth(), this.getHeight() - 1); } diff --git a/designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java b/designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java new file mode 100644 index 000000000..c95d37205 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java @@ -0,0 +1,78 @@ +package com.fr.design.report; + +import com.fr.base.CustomConfig; +import com.fr.config.Configuration; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.BasicPane; +import com.fr.design.gui.icheckbox.UICheckBox; +import com.fr.design.gui.ilable.ActionLabel; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.BrowseUtils; +import com.fr.transaction.Configurations; +import com.fr.transaction.WorkerFacade; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import javax.swing.BorderFactory; +import javax.swing.JPanel; + +/** + * @author hades + * @version 11.0 + * Created by hades on 2022/5/26 + */ +public class ExportUniversalPane extends BasicPane { + + private UICheckBox specialCharacterExport; + + public ExportUniversalPane() { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + JPanel outerNorthPane =FRGUIPaneFactory.createTitledBorderPane(Toolkit.i18nText("Fine-Design_Report_Universal_Export_Config")); + JPanel northPane = FRGUIPaneFactory.createY_AXISBoxInnerContainer_M_Pane(); + JPanel specialCharacterExportPane =FRGUIPaneFactory.createNormalFlowInnerContainer_M_Pane(); + specialCharacterExport = new UICheckBox(Toolkit.i18nText("Fine-Design_Report_Universal_Export_Special_Character")); + specialCharacterExport.setSelected(true); + specialCharacterExportPane.add(specialCharacterExport); + northPane.add(specialCharacterExportPane); + JPanel labelPane = new JPanel(new BorderLayout()); + labelPane.setBorder(BorderFactory.createEmptyBorder(0, 20, 0, 0)); + UILabel centerLabel = new UILabel(Toolkit.i18nText("Fine-Design_Report_Universal_Export_Special_Character_Tip")); + centerLabel.setForeground(Color.GRAY); + ActionLabel rightLabel = new ActionLabel(Toolkit.i18nText("Fine-Design_Report_Universal_Export_More_Alternative_Fonts"), UIConstants.FLESH_BLUE); + rightLabel.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + BrowseUtils.browser("http://www.baidu.com"); + } + }); + labelPane.add(centerLabel, BorderLayout.CENTER); + labelPane.add(rightLabel, BorderLayout.EAST); + northPane.add(labelPane); + outerNorthPane.add(northPane); + this.add(outerNorthPane); + } + + @Override + protected String title4PopupWindow() { + return "ExportUniversalPane"; + } + + public void populate() { + this.specialCharacterExport.setSelected(CustomConfig.getInstance().isOptimizedSpecialCharacterExport()); + } + + public void update() { + Configurations.modify(new WorkerFacade(CustomConfig.class) { + @Override + public void run() { + CustomConfig.getInstance().setOptimizedSpecialCharacterExport(specialCharacterExport.isSelected()); + } + }); + } + + +} diff --git a/designer-realize/src/main/java/com/fr/design/report/ReportExportAttrPane.java b/designer-realize/src/main/java/com/fr/design/report/ReportExportAttrPane.java index 1ac27cc88..d0770a13b 100644 --- a/designer-realize/src/main/java/com/fr/design/report/ReportExportAttrPane.java +++ b/designer-realize/src/main/java/com/fr/design/report/ReportExportAttrPane.java @@ -5,6 +5,7 @@ import com.fr.design.beans.BasicStorePane; import com.fr.design.dialog.BasicPane; import com.fr.design.fun.ExportAttrTabProvider; import com.fr.design.gui.frpane.UITabbedPane; +import com.fr.design.i18n.Toolkit; import com.fr.io.attr.ReportExportAttr; import javax.swing.*; @@ -17,12 +18,15 @@ public class ReportExportAttrPane extends BasicPane { private ExcelExportPane excelExportPane; private PDFExportPane pdfExportPane; private WordExportPane wordExportPane; + private ExportUniversalPane exportUniversalPane; private List> paneList; public ReportExportAttrPane() { UITabbedPane uiTabbedPane = new UITabbedPane(); this.setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); this.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10)); + exportUniversalPane = new ExportUniversalPane(); + uiTabbedPane.addTab(Toolkit.i18nText("Fine-Design_Report_Universal_Export"), exportUniversalPane); excelExportPane = new ExcelExportPane(); uiTabbedPane.addTab("Excel", excelExportPane); pdfExportPane = new PDFExportPane(); @@ -49,6 +53,10 @@ public class ReportExportAttrPane extends BasicPane { reportExportAttr = new ReportExportAttr(); } + if (this.exportUniversalPane != null) { + this.exportUniversalPane.populate(); + } + if (this.excelExportPane != null) { this.excelExportPane.populate(reportExportAttr.getExcelExportAttr()); } @@ -69,6 +77,11 @@ public class ReportExportAttrPane extends BasicPane { public ReportExportAttr update() { ReportExportAttr reportExportAttr = new ReportExportAttr(); + + if (this.exportUniversalPane != null) { + this.exportUniversalPane.update(); + } + if (this.excelExportPane != null) { reportExportAttr.setExcelExportAttr(this.excelExportPane.update()); } From 5e39938cd154803954c0aa573c9a508235009c41 Mon Sep 17 00:00:00 2001 From: hades Date: Fri, 27 May 2022 17:48:56 +0800 Subject: [PATCH 25/55] =?UTF-8?q?REPORT-70562=20=E5=B8=AE=E5=8A=A9?= =?UTF-8?q?=E6=96=87=E6=A1=A3=20url=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/fr/design/report/ExportUniversalPane.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java b/designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java index c95d37205..3714d66a2 100644 --- a/designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java +++ b/designer-realize/src/main/java/com/fr/design/report/ExportUniversalPane.java @@ -10,6 +10,7 @@ import com.fr.design.gui.ilable.UILabel; import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.utils.BrowseUtils; +import com.fr.general.CloudCenter; import com.fr.transaction.Configurations; import com.fr.transaction.WorkerFacade; import java.awt.BorderLayout; @@ -26,6 +27,8 @@ import javax.swing.JPanel; */ public class ExportUniversalPane extends BasicPane { + private static final String HELP_URL = CloudCenter.getInstance().acquireUrlByKind("help.alt_font.zh_CN", "https://help.fanruan.com/finereport/doc-view-4707.html"); + private UICheckBox specialCharacterExport; public ExportUniversalPane() { @@ -46,7 +49,7 @@ public class ExportUniversalPane extends BasicPane { rightLabel.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { - BrowseUtils.browser("http://www.baidu.com"); + BrowseUtils.browser(HELP_URL); } }); labelPane.add(centerLabel, BorderLayout.CENTER); From d61fdf98b90047172ab4ea99b035ccdb4b0a535f Mon Sep 17 00:00:00 2001 From: pengda Date: Fri, 24 Jun 2022 14:25:23 +0800 Subject: [PATCH 26/55] =?UTF-8?q?REPORT-71839=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E5=90=AF=E5=8A=A8=E6=97=B6=E5=90=AF=E5=8A=A8=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BB=8D=E8=BF=9E=E6=9B=BE=E6=96=AD?= =?UTF-8?q?=E5=BC=80=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E6=9C=89=E8=BF=9C=E7=A8=8B=E6=9B=B4=E6=96=B0=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/EnvChangeEntrance.java | 4 +++- .../fr/design/versioncheck/VersionCheckUtils.java | 15 +++++++++++---- .../src/main/java/com/fr/start/BaseDesigner.java | 10 ++++++++++ 3 files changed, 24 insertions(+), 5 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java index cd9c835f3..d575c68d0 100644 --- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java +++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java @@ -427,7 +427,9 @@ public class EnvChangeEntrance { DesignerExiter.getInstance().execute(); } else { updateNotRememberPwdEnv(); - VersionCheckUtils.showVersionCheckDialog(envListPane.getSelectedName()); + if (DesignerContext.getDesignerFrame().isVisible()) { + VersionCheckUtils.showVersionCheckDialog(envListPane.getSelectedName()); + } } } diff --git a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java index d2794cd6e..fcb763461 100644 --- a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java +++ b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java @@ -52,6 +52,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import javax.swing.SwingWorker; /** * @author pengda @@ -95,9 +96,15 @@ public class VersionCheckUtils { } public static void showVersionCheckDialog(String envName) { - if (!VersionCheckUtils.versionCheck(envName)) { - showNotificationDialog(envName); - } + new SwingWorker() { + @Override + protected Void doInBackground() throws Exception { + if (!VersionCheckUtils.versionCheck(envName)) { + showNotificationDialog(envName); + } + return null; + } + }.execute(); } private static void showNotificationDialog(String envName) { @@ -294,7 +301,7 @@ public class VersionCheckUtils { private static boolean isPluginNeedIgnore(JSONObject remotePlugin) { return ComparatorUtils.equals(remotePlugin.getString(RUNNING), "false") || (remotePlugin.containsKey(SYNC) && !remotePlugin.getBoolean(SYNC)) - || (remotePlugin.containsKey(GROUP) && ComparatorUtils.equals(remotePlugin.containsKey(GROUP), BI) || remotePlugin.getString(ID).startsWith(BIPREFIX) + || (remotePlugin.containsKey(GROUP) && ComparatorUtils.equals(remotePlugin.getString(GROUP), BI) || remotePlugin.getString(ID).startsWith(BIPREFIX) || pluginsNeedIgnore.contains(remotePlugin.getString(ID))); } diff --git a/designer-base/src/main/java/com/fr/start/BaseDesigner.java b/designer-base/src/main/java/com/fr/start/BaseDesigner.java index b3945d0d7..d913f7a79 100644 --- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java +++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java @@ -16,6 +16,7 @@ import com.fr.design.mainframe.DesignerFrame; import com.fr.design.mainframe.toolbar.ToolBarMenuDock; import com.fr.design.monitor.DesignerLifecycleMonitorContext; import com.fr.design.ui.util.UIUtil; +import com.fr.design.versioncheck.VersionCheckUtils; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; @@ -84,10 +85,19 @@ public abstract class BaseDesigner extends ToolBarMenuDock { eventPipe.fire(new CarryMessageEvent(ReportState.STOP.getValue())); } collectUserInformation(); + checkVersion(); } }); } + private void checkVersion() { + try { + VersionCheckUtils.showVersionCheckDialog(DesignerEnvManager.getEnvManager().getCurEnvName()); + } catch (Exception e) { + FineLoggerFactory.getLogger().warn("Check Service Failed"); + } + } + public void show() { UIUtil.invokeLaterIfNeeded(this::refreshTemplateTree); } From 903076ed08babf9b141db9f97580ddc2c177d1d8 Mon Sep 17 00:00:00 2001 From: pengda Date: Fri, 24 Jun 2022 14:27:55 +0800 Subject: [PATCH 27/55] =?UTF-8?q?REPORT-71839=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E5=90=AF=E5=8A=A8=E6=97=B6=E5=90=AF=E5=8A=A8=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BB=8D=E8=BF=9E=E6=9B=BE=E6=96=AD?= =?UTF-8?q?=E5=BC=80=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E6=9C=89=E8=BF=9C=E7=A8=8B=E6=9B=B4=E6=96=B0=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/start/module/DesignerWorkspaceProvider.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java index 724f947c9..9c8b2e0f5 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerWorkspaceProvider.java @@ -61,18 +61,6 @@ public class DesignerWorkspaceProvider extends Activator { EnvChangeEntrance.getInstance().dealEvnExceptionWhenStartDesigner(null, workspaceInfo); } else { WorkContext.switchTo(workspace); - //在设计器完全启动完成后,对初始环境进行一次服务检测,对主要功能无影响,异常仅做日志提示即可 - final String selectEnv = current; - EventDispatcher.listen(DesignerLaunchStatus.STARTUP_COMPLETE, new Listener() { - @Override - public void on(Event event, Null aNull) { - try { - VersionCheckUtils.showVersionCheckDialog(selectEnv); - } catch (Exception e) { - FineLoggerFactory.getLogger().warn("Check Service Failed"); - } - } - }); } } catch (Throwable e) { EnvChangeEntrance.getInstance().dealEvnExceptionWhenStartDesigner(e, workspaceInfo); From 0e6693903cf4d51d052221aec2380018d05467b9 Mon Sep 17 00:00:00 2001 From: pengda Date: Fri, 24 Jun 2022 15:01:39 +0800 Subject: [PATCH 28/55] =?UTF-8?q?REPORT-71839=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E5=90=AF=E5=8A=A8=E6=97=B6=E5=90=AF=E5=8A=A8=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BB=8D=E8=BF=9E=E6=9B=BE=E6=96=AD?= =?UTF-8?q?=E5=BC=80=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E6=9C=89=E8=BF=9C=E7=A8=8B=E6=9B=B4=E6=96=B0=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/versioncheck/VersionCheckUtils.java | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java index fcb763461..fb0ea0c76 100644 --- a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java +++ b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java @@ -96,13 +96,21 @@ public class VersionCheckUtils { } public static void showVersionCheckDialog(String envName) { - new SwingWorker() { + new SwingWorker() { @Override - protected Void doInBackground() throws Exception { - if (!VersionCheckUtils.versionCheck(envName)) { - showNotificationDialog(envName); + protected Boolean doInBackground() { + return !VersionCheckUtils.versionCheck(envName); + } + + @Override + protected void done() { + try { + if (get()) { + showNotificationDialog(envName); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); } - return null; } }.execute(); } From 4585ce89a8cac1bd5aaf6e80b3d50b0d87245d0e Mon Sep 17 00:00:00 2001 From: pengda Date: Fri, 24 Jun 2022 15:24:31 +0800 Subject: [PATCH 29/55] =?UTF-8?q?REPORT-71839=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E5=90=AF=E5=8A=A8=E6=97=B6=E5=90=AF=E5=8A=A8=E6=9C=8D?= =?UTF-8?q?=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BB=8D=E8=BF=9E=E6=9B=BE=E6=96=AD?= =?UTF-8?q?=E5=BC=80=E7=9A=84=E6=9C=8D=E5=8A=A1=E5=99=A8=EF=BC=8C=E4=BC=9A?= =?UTF-8?q?=E6=9C=89=E8=BF=9C=E7=A8=8B=E6=9B=B4=E6=96=B0=E6=8F=90=E9=86=92?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/fr/design/versioncheck/VersionCheckUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java index fb0ea0c76..d7823aadf 100644 --- a/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java +++ b/designer-base/src/main/java/com/fr/design/versioncheck/VersionCheckUtils.java @@ -109,7 +109,7 @@ public class VersionCheckUtils { showNotificationDialog(envName); } } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineLoggerFactory.getLogger().warn(e.getMessage(), e); } } }.execute(); From 0f51b6cf27984014cfd732c4dd49cb9f17c772cd Mon Sep 17 00:00:00 2001 From: hades Date: Wed, 22 Jun 2022 14:16:27 +0800 Subject: [PATCH 30/55] =?UTF-8?q?REPORT-73808=20=E6=B5=B7=E5=A4=96?= =?UTF-8?q?=E7=89=88alphafine=E5=8A=9F=E8=83=BD=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/actions/help/alphafine/AlphaFineConfigManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java index 1dd08c526..3d36e563c 100644 --- a/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java +++ b/designer-base/src/main/java/com/fr/design/actions/help/alphafine/AlphaFineConfigManager.java @@ -1,5 +1,6 @@ package com.fr.design.actions.help.alphafine; +import com.fr.base.FRContext; import com.fr.design.DesignerEnvManager; import com.fr.general.ComparatorUtils; import com.fr.license.function.VT4FR; @@ -442,7 +443,7 @@ public class AlphaFineConfigManager implements XMLable { } public boolean isProductDynamics() { - return productDynamics; + return productDynamics && FRContext.isChineseEnv(); } public void setProductDynamics(boolean productDynamics) { From 82b934c1c21c73b846af4ffa34e111eedbd4e48c Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 16 Jun 2022 19:58:32 +0800 Subject: [PATCH 31/55] =?UTF-8?q?REPORT-72851=20TitlePlaceProcessor=2011.0?= =?UTF-8?q?.2=E4=B9=8B=E5=90=8E=E7=89=88=E6=9C=AC=E4=B8=8D=E7=94=9F?= =?UTF-8?q?=E6=95=88=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/mainframe/NorthRegionContainerPane.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java index 91899e5b5..1cde29286 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java @@ -11,6 +11,7 @@ import com.fr.design.mainframe.toolbar.ToolBarMenuDock; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.menu.MenuManager; import com.fr.design.os.impl.SupportOSImpl; +import com.fr.event.EventDispatcher; import com.fr.general.GeneralContext; import com.fr.plugin.context.PluginContext; import com.fr.plugin.injectable.PluginModule; @@ -100,8 +101,7 @@ public class NorthRegionContainerPane extends JPanel { //优先级为-1,保证最后全面刷新一次 GeneralContext.listenPluginRunningChanged(pluginOnRunOrStopListener, pluginFilter); // 在设计器启动时仅在最后一个插件启用时候进行刷新一次 如果插件启用过程中存在实现了设计器接口的插件 - boolean needRefresh = DesignerContext.getDesignerFrame() != null && DesignerContext.getDesignerFrame().isVisible() && existDesignExtraPlugin; - if (needRefresh) { + if (existDesignExtraPlugin) { refreshAll(northEastPane, ad); } } From 3d233422904770b93e77536a358823dcd6970037 Mon Sep 17 00:00:00 2001 From: hades Date: Thu, 16 Jun 2022 20:00:19 +0800 Subject: [PATCH 32/55] =?UTF-8?q?REPORT-72851=20=E5=8E=BB=E9=99=A4?= =?UTF-8?q?=E6=97=A0=E7=94=A8=E5=AF=BC=E5=85=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/design/mainframe/NorthRegionContainerPane.java | 1 - 1 file changed, 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java index 1cde29286..67784159c 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/NorthRegionContainerPane.java @@ -11,7 +11,6 @@ import com.fr.design.mainframe.toolbar.ToolBarMenuDock; import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; import com.fr.design.menu.MenuManager; import com.fr.design.os.impl.SupportOSImpl; -import com.fr.event.EventDispatcher; import com.fr.general.GeneralContext; import com.fr.plugin.context.PluginContext; import com.fr.plugin.injectable.PluginModule; From 2dac9c1512af86cb464169a6d7c15f21f6004cd0 Mon Sep 17 00:00:00 2001 From: "Bruce.Deng" Date: Fri, 24 Jun 2022 17:27:05 +0800 Subject: [PATCH 33/55] =?UTF-8?q?REPORT-73491=20=E8=81=9A=E5=90=88?= =?UTF-8?q?=E6=8A=A5=E8=A1=A8=E6=9D=A1=E4=BB=B6=E5=B1=9E=E6=80=A7=E9=85=8D?= =?UTF-8?q?=E7=BD=AE=E9=9D=A2=E6=9D=BF=EF=BC=8C=E5=9C=A8=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E9=87=8D=E5=90=AF=E5=90=8E=E8=AF=A5=E9=9D=A2=E6=9D=BF?= =?UTF-8?q?=E4=B8=8D=E8=83=BD=E6=AD=A3=E7=A1=AE=E6=98=BE=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/com/fr/poly/creator/ECBlockEditor.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/designer-realize/src/main/java/com/fr/poly/creator/ECBlockEditor.java b/designer-realize/src/main/java/com/fr/poly/creator/ECBlockEditor.java index a387e0f3a..1d69726df 100644 --- a/designer-realize/src/main/java/com/fr/poly/creator/ECBlockEditor.java +++ b/designer-realize/src/main/java/com/fr/poly/creator/ECBlockEditor.java @@ -3,7 +3,6 @@ */ package com.fr.poly.creator; -import com.fr.base.BaseUtils; import com.fr.base.ScreenResolution; import com.fr.base.vcs.DesignerMode; import com.fr.design.constants.UIConstants; @@ -11,7 +10,15 @@ import com.fr.design.event.TargetModifiedEvent; import com.fr.design.event.TargetModifiedListener; import com.fr.design.file.HistoryTemplateListPane; import com.fr.design.gui.frpane.HyperlinkGroupPane; -import com.fr.design.mainframe.*; +import com.fr.design.mainframe.CellElementPropertyPane; +import com.fr.design.mainframe.CellWidgetPropertyPane; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.EastRegionContainerPane; +import com.fr.design.mainframe.ElementCasePane; +import com.fr.design.mainframe.HyperlinkGroupPaneActionImpl; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.JWorkBook; +import com.fr.design.mainframe.ReportFloatPane; import com.fr.design.mainframe.cell.QuickEditorRegion; import com.fr.design.present.ConditionAttributesGroupPane; import com.fr.grid.GridUtils; @@ -26,8 +33,9 @@ import com.fr.report.poly.PolyECBlock; import com.fr.stable.unit.UNITConstants; import com.fr.stable.unit.UnitRectangle; -import javax.swing.*; -import java.awt.*; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; /** * @author richer @@ -166,6 +174,7 @@ public class ECBlockEditor extends BlockEditor { // 条件属性 ConditionAttributesGroupPane conditionAttributesGroupPane = ConditionAttributesGroupPane.getInstance(); conditionAttributesGroupPane.populate(editComponent); + EastRegionContainerPane.getInstance().replaceConditionAttrPane(conditionAttributesGroupPane); EastRegionContainerPane.getInstance().updateCellElementState(isSelectedOneCell()); if (chooseBlock) { From 04515054c110d04d890e277a3e013f2ed228b45b Mon Sep 17 00:00:00 2001 From: kerry Date: Wed, 29 Jun 2022 09:48:28 +0800 Subject: [PATCH 34/55] =?UTF-8?q?REPORT-67316=20=E5=86=B3=E7=AD=96?= =?UTF-8?q?=E6=8A=A5=E8=A1=A8-=E5=AE=A2=E6=88=B7=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E6=98=AF=E7=BB=9D=E5=AF=B9=E5=B8=83=E5=B1=80=E5=9B=BA=E5=AE=9A?= =?UTF-8?q?=E5=A4=A7=E5=B0=8F=E7=9A=84=EF=BC=8C=E5=A4=8D=E5=88=B6=E5=AE=A2?= =?UTF-8?q?=E6=88=B7=E6=A8=A1=E6=9D=BF=E9=87=8C=E7=9A=84tab=E5=88=B0?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=96=B0=E5=BB=BA=E7=9A=84=E7=BB=9D=E5=AF=B9?= =?UTF-8?q?=E5=B8=83=E5=B1=80=E5=9B=BA=E5=AE=9A=E5=A4=A7=E5=B0=8Ffrm?= =?UTF-8?q?=EF=BC=8C=E4=BF=9D=E5=AD=98=E5=85=B3=E9=97=AD=E5=86=8D=E6=89=93?= =?UTF-8?q?=E5=BC=80=E6=96=B0=E5=BB=BA=E6=A8=A1=E6=9D=BF=EF=BC=8Ctab?= =?UTF-8?q?=E4=B8=8B=E7=9A=84=E6=8A=A5=E8=A1=A8=E5=9D=97=E5=B0=BA=E5=AF=B8?= =?UTF-8?q?=E5=8F=98=E4=BA=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/designer/creator/XCreatorUtils.java | 18 ++++++++++++++++++ .../cardlayout/XWCardMainBorderLayout.java | 5 +++++ .../java/com/fr/design/mainframe/FormArea.java | 18 +++--------------- .../design/mainframe/FormSelectionUtils.java | 4 ++++ 4 files changed, 30 insertions(+), 15 deletions(-) diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java index 6445e001b..338f40643 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/XCreatorUtils.java @@ -401,4 +401,22 @@ public class XCreatorUtils { } return container; } + + /** + * 循环遍历组件,调整组件间隙 + * @param creator + */ + //循环遍历布局,按百分比调整子组件大小 + public static void traverAndAdjust(XCreator creator, double percent) { + for (int i = 0; i < creator.getComponentCount(); i++) { + Object object = creator.getComponent(i); + if (object instanceof XCreator) { + XCreator temp = (XCreator) object; + temp.adjustCompSize(percent); + traverAndAdjust(temp, percent); + } + } + + } + } \ No newline at end of file diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java index 0db348a39..31fc59d98 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XWCardMainBorderLayout.java @@ -472,4 +472,9 @@ public class XWCardMainBorderLayout extends XWBorderLayout { public void setShowOuterShadowBorder(boolean showOuterShadowBorder) { this.showOuterShadowBorder = showOuterShadowBorder; } + + @Override + public void recalculateChildrenSize() { + + } } diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java index 23e08e5cf..236843f0a 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormArea.java @@ -5,6 +5,7 @@ import com.fr.common.inputevent.InputEventBaseOnOS; import com.fr.design.designer.beans.events.DesignerEditListener; import com.fr.design.designer.beans.events.DesignerEvent; import com.fr.design.designer.creator.XCreator; +import com.fr.design.designer.creator.XCreatorUtils; import com.fr.design.designer.creator.XLayoutContainer; import com.fr.design.designer.creator.XWBorderLayout; import com.fr.design.designer.creator.XWFitLayout; @@ -428,7 +429,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { if (root.acceptType(XWFitLayout.class)) { XWFitLayout layout = (XWFitLayout) root; layout.setContainerPercent(value / DEFAULT_SLIDER); - traverAndAdjust(layout, percent); + XCreatorUtils.traverAndAdjust(layout, percent); layout.adjustCreatorsWhileSlide(percent); // 拖动滑块,先将内部组件百分比大小计算,再计算容器大小 @@ -464,7 +465,7 @@ public class FormArea extends JComponent implements ScrollRulerComponent { if (root.acceptType(XWFitLayout.class)) { XWFitLayout layout = (XWFitLayout) root; layout.setContainerPercent(1.0); - traverAndAdjust(layout, 0.0); + XCreatorUtils.traverAndAdjust(layout, 0.0); layout.adjustCreatorsWhileSlide(0.0); // 拖动滑块,先将内部组件百分比大小计算,再计算容器大小 @@ -487,19 +488,6 @@ public class FormArea extends JComponent implements ScrollRulerComponent { } } - //循环遍历布局,按百分比调整子组件大小 - private void traverAndAdjust(XCreator creator, double percent) { - for (int i = 0; i < creator.getComponentCount(); i++) { - Object object = creator.getComponent(i); - if (object instanceof XCreator) { - XCreator temp = (XCreator) object; - temp.adjustCompSize(percent); - traverAndAdjust(temp, percent); - } - } - - } - /** * 增加刻度条 */ diff --git a/designer-form/src/main/java/com/fr/design/mainframe/FormSelectionUtils.java b/designer-form/src/main/java/com/fr/design/mainframe/FormSelectionUtils.java index 7d3b17f5b..257ec423a 100644 --- a/designer-form/src/main/java/com/fr/design/mainframe/FormSelectionUtils.java +++ b/designer-form/src/main/java/com/fr/design/mainframe/FormSelectionUtils.java @@ -16,6 +16,7 @@ import com.fr.design.designer.creator.XWTitleLayout; import com.fr.design.designer.creator.cardlayout.XWTabFitLayout; import com.fr.design.fun.FormWidgetOptionProvider; import com.fr.design.utils.ComponentUtils; +import com.fr.design.utils.gui.LayoutUtils; import com.fr.form.main.Form; import com.fr.form.ui.Widget; import com.fr.form.ui.container.WTitleLayout; @@ -291,6 +292,9 @@ public class FormSelectionUtils { public static XCreator copyXcreator(Form form, XCreator xCreator) throws CloneNotSupportedException{ Widget copied = (Widget) xCreator.toData().clone(); XCreator copiedCreator = XCreatorUtils.createXCreator(copied, xCreator.getSize()); + //主要用来处理组件间隔和padding,保证界面上展示的组件尺寸是计算过padding和组件间隔的 + LayoutUtils.layoutContainer(copiedCreator); + XCreatorUtils.traverAndAdjust(copiedCreator, 0.0); ArrayList nameSpace = new ArrayList<>(); copyWidgetName(form, nameSpace, copiedCreator); return copiedCreator; From 66ae55f8ddd08cc32ebbfdf73d022cdb51d66c39 Mon Sep 17 00:00:00 2001 From: rinoux Date: Wed, 29 Jun 2022 19:25:54 +0800 Subject: [PATCH 35/55] =?UTF-8?q?REPORT-74603=20=E5=B5=8C=E5=85=A5?= =?UTF-8?q?=E5=BC=8F=E6=95=B0=E6=8D=AE=E5=BA=93=E7=9A=84=E9=99=90=E5=88=B6?= =?UTF-8?q?=E8=AE=BF=E9=97=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/data/datapane/connect/ConnectionListPane.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 0336c1ce0..3e03e6a5d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -1,5 +1,6 @@ package com.fr.design.data.datapane.connect; +import com.fr.base.TemplateUtils; import com.fr.data.core.db.JDBCSecurityChecker; import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; @@ -195,7 +196,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh Connection connection = entry.getValue(); if (connection instanceof JDBCDatabaseConnection) { try { - JDBCSecurityChecker.checkURL(((JDBCDatabaseConnection) connection).getURL()); + JDBCSecurityChecker.checkURL(TemplateUtils.render(((JDBCDatabaseConnection) connection).getURL())); JDBCSecurityChecker.checkValidationQuery(((JDBCDatabaseConnection) connection).getDbcpAttr().getValidationQuery()); } catch (SQLException e) { throw new SQLException(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Invalid_Config", entry.getKey()) + ", " + e.getMessage(), e.getCause()); From 44e27ef8c6581677b0bfb1a3632a31a237f2ca52 Mon Sep 17 00:00:00 2001 From: "Bruce.Deng" Date: Thu, 30 Jun 2022 10:29:09 +0800 Subject: [PATCH 36/55] =?UTF-8?q?REPORT-74118=20=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=A0=BC=E6=95=B0=E6=8D=AE=E6=BA=90=E8=80=81=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=88=B0=E6=95=B0=E6=8D=AE=E9=9B=86=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=A4=9A=E5=88=86=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=E5=A4=9A=E5=88=86=E7=B1=BB=E4=B8=8D=E5=8F=AF=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/fr/design/mainframe/chart/ChartEditPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java index 902347fb8..8a91eff08 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java @@ -7,7 +7,6 @@ import com.fr.chartx.attr.ChartProvider; import com.fr.common.listener.ManageDsListenerRegisterListener; import com.fr.design.ChartTypeInterfaceManager; import com.fr.design.beans.FurtherBasicBeanPane; -import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.tabledata.Prepare4DataSourceChange; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.chart.ChartEditPaneActionListener; @@ -149,6 +148,7 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare ChartInfoCollector.getInstance().updateChartPropertyTime(collection.getSelectedChartProvider(ChartProvider.class)); selectedPane.update(collection); + selectedPane.populate(collection); if (!ComparatorUtils.equals(collection, lastCollection)) { VanChart vanChart = collection.getSelectedChartProvider(VanChart.class); From fba37ec2417865498ddec122a09cbd587eef1014 Mon Sep 17 00:00:00 2001 From: "Bruce.Deng" Date: Thu, 30 Jun 2022 15:41:47 +0800 Subject: [PATCH 37/55] =?UTF-8?q?REPORT-74118=20=E5=8D=95=E5=85=83?= =?UTF-8?q?=E6=A0=BC=E6=95=B0=E6=8D=AE=E6=BA=90=E8=80=81=E6=A8=A1=E6=9D=BF?= =?UTF-8?q?=E5=88=87=E6=8D=A2=E5=88=B0=E6=95=B0=E6=8D=AE=E9=9B=86=E6=95=B0?= =?UTF-8?q?=E6=8D=AE=E5=B9=B6=E6=B7=BB=E5=8A=A0=E5=A4=9A=E5=88=86=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=E5=A4=9A=E5=88=86=E7=B1=BB=E4=B8=8D=E5=8F=AF=E4=BF=AE?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/fr/design/mainframe/chart/ChartEditPane.java | 1 - .../designer/data/VanChartMoreCateTableDataContentPane.java | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java index 8a91eff08..18d8c0daf 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java @@ -148,7 +148,6 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare ChartInfoCollector.getInstance().updateChartPropertyTime(collection.getSelectedChartProvider(ChartProvider.class)); selectedPane.update(collection); - selectedPane.populate(collection); if (!ComparatorUtils.equals(collection, lastCollection)) { VanChart vanChart = collection.getSelectedChartProvider(VanChart.class); diff --git a/designer-chart/src/main/java/com/fr/van/chart/designer/data/VanChartMoreCateTableDataContentPane.java b/designer-chart/src/main/java/com/fr/van/chart/designer/data/VanChartMoreCateTableDataContentPane.java index dcf160aec..4d9f0aa61 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/designer/data/VanChartMoreCateTableDataContentPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/designer/data/VanChartMoreCateTableDataContentPane.java @@ -22,13 +22,14 @@ public class VanChartMoreCateTableDataContentPane extends CategoryPlotMoreCateTa @Override public void populateBean(ChartCollection collection) { super.populateBean(collection); - VanChartRectanglePlot plot = (VanChartRectanglePlot) collection.getSelectedChart().getPlot(); + VanChartRectanglePlot plot = collection.getSelectedChart().getPlot(); isSupportMultiCategory = plot.isSupportMultiCategory(); checkBoxList(isSupportMultiCategory); } protected void updateMoreCate(NormalTableDataDefinition normal, Plot plot) { super.updateMoreCate(normal, plot); + isSupportMultiCategory = ((VanChartRectanglePlot) plot).isSupportMultiCategory(); ((VanChartPlot) plot).setCategoryNum(getBoxList().size() + 1); if (!getBoxList().isEmpty()) { plot.getDataSheet().setVisible(false); From 0ee72b90d9a2a9ad67ce44c0aad0998fb7b536c4 Mon Sep 17 00:00:00 2001 From: rinoux Date: Thu, 30 Jun 2022 16:19:08 +0800 Subject: [PATCH 38/55] =?UTF-8?q?=E6=97=A0JIRA=E4=BB=BB=E5=8A=A1=20?= =?UTF-8?q?=E5=90=88final?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/data/datapane/connect/ConnectionListPane.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 0336c1ce0..3e03e6a5d 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -1,5 +1,6 @@ package com.fr.design.data.datapane.connect; +import com.fr.base.TemplateUtils; import com.fr.data.core.db.JDBCSecurityChecker; import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; @@ -195,7 +196,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh Connection connection = entry.getValue(); if (connection instanceof JDBCDatabaseConnection) { try { - JDBCSecurityChecker.checkURL(((JDBCDatabaseConnection) connection).getURL()); + JDBCSecurityChecker.checkURL(TemplateUtils.render(((JDBCDatabaseConnection) connection).getURL())); JDBCSecurityChecker.checkValidationQuery(((JDBCDatabaseConnection) connection).getDbcpAttr().getValidationQuery()); } catch (SQLException e) { throw new SQLException(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Invalid_Config", entry.getKey()) + ", " + e.getMessage(), e.getCause()); From 325dc63113b947cd70fa6f8908e887f2c3ad78a9 Mon Sep 17 00:00:00 2001 From: pengda Date: Thu, 30 Jun 2022 19:02:18 +0800 Subject: [PATCH 39/55] =?UTF-8?q?REPORT-74887=20=E6=96=B0=E5=BB=BA?= =?UTF-8?q?=E5=86=B3=E7=AD=96=E6=8A=A5=E8=A1=A8=EF=BC=8C=E6=8B=96=E5=85=A5?= =?UTF-8?q?=E7=AC=AC=E4=B8=89=E6=96=B9=E6=8F=92=E4=BB=B6=E5=9B=BE=E8=A1=A8?= =?UTF-8?q?=E6=97=A0=E6=B3=95=E7=BC=96=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../main/java/com/fr/design/mainframe/chart/ChartEditPane.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java index 902347fb8..000ef9cd2 100644 --- a/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java +++ b/designer-chart/src/main/java/com/fr/design/mainframe/chart/ChartEditPane.java @@ -411,7 +411,7 @@ public class ChartEditPane extends BasicPane implements AttributeChange, Prepare this.addAncestorListener(new ManageDsListenerRegisterListener(new ChangeListener() { public void stateChanged(ChangeEvent e) { AbstractChartAttrPane attrPane = paneList.get(tabsHeaderIconPane.getSelectedIndex()); - if (attrPane.isShowing()) { + if (attrPane.isShowing() && collection != null) { attrPane.refreshChartDataPane(collection); } } From d6c2f9fa849a43b8915f484533583888223820c4 Mon Sep 17 00:00:00 2001 From: "Destiny.Lin" Date: Fri, 8 Jul 2022 14:11:43 +0800 Subject: [PATCH 40/55] =?UTF-8?q?REPORT-38523=20fix:=20=E5=8F=B3=E4=BE=A7?= =?UTF-8?q?=E5=8D=95=E5=85=83=E6=A0=BC=E5=B1=9E=E6=80=A7=E8=A1=A8=E9=BC=A0?= =?UTF-8?q?=E6=A0=87=E4=BA=8B=E4=BB=B6=E6=9C=89=E8=AF=AF=EF=BC=8C=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=E4=BA=86mouseReleased=E4=BA=8B=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/gui/icontainer/UIEastResizableContainer.java | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/gui/icontainer/UIEastResizableContainer.java b/designer-base/src/main/java/com/fr/design/gui/icontainer/UIEastResizableContainer.java index 125cd3aa1..dcd33498a 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icontainer/UIEastResizableContainer.java +++ b/designer-base/src/main/java/com/fr/design/gui/icontainer/UIEastResizableContainer.java @@ -296,10 +296,9 @@ public class UIEastResizableContainer extends JPanel { model = UIConstants.MODEL_NORMAL; refreshContainer(); } - @Override - public void mouseClicked(MouseEvent e) { - if (e.getX() <= ARROW_RANGE) { + public void mouseReleased(MouseEvent e) { + if (isInPane(e)) { if (containerWidth == leftPaneWidth) { showContainer(); } else { @@ -309,7 +308,9 @@ public class UIEastResizableContainer extends JPanel { } }); } - + public boolean isInPane(MouseEvent e){ + return e.getX() <= ARROW_RANGE && e.getX() >= 0 && e.getY() <= topToolPaneHeight && e.getY() >= 0; + } @Override public void paint(Graphics g) { Image button; From 878470d77d151c3b80117edd333ae6fb45e9f2ff Mon Sep 17 00:00:00 2001 From: "Destiny.Lin" Date: Mon, 11 Jul 2022 18:19:51 +0800 Subject: [PATCH 41/55] =?UTF-8?q?REPORT-38555=20fix:=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E4=B8=AD=E5=86=85=E5=AE=B9=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E7=A9=BA=E6=A0=BC=E5=92=8C=E5=87=8F=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/gui/ispinner/UISpinner.java | 17 +------ .../design/gui/itextfield/UINumberField.java | 12 ++++- .../component/NumberEditorValidatePane.java | 25 +++++++++-- .../gui/itextfield/UINumberFieldTest.java | 44 +++++++++++++++++++ 4 files changed, 77 insertions(+), 21 deletions(-) create mode 100644 designer-base/src/test/java/com/fr/design/gui/itextfield/UINumberFieldTest.java diff --git a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java index 22f6cb246..10e6e5837 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java @@ -22,19 +22,8 @@ import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.plaf.ButtonUI; -import java.awt.BorderLayout; -import java.awt.Color; -import java.awt.Dimension; -import java.awt.Graphics; -import java.awt.Graphics2D; -import java.awt.GridLayout; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.FocusAdapter; -import java.awt.event.FocusEvent; -import java.awt.event.FocusListener; -import java.awt.event.MouseWheelEvent; -import java.awt.event.MouseWheelListener; +import java.awt.*; +import java.awt.event.*; public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver { @@ -72,7 +61,6 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver init(minValue, maxValue, dierta); textField.setValue(defaultValue); } - protected void init(double minValue, double maxValue, double dierta) { this.minValue = minValue; this.maxValue = maxValue; @@ -411,7 +399,6 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver public boolean shouldResponseNameListener() { return true; } - /** * 程序入口 测试 * diff --git a/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java b/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java index 0d1287d8c..5a2bda66e 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java +++ b/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java @@ -4,6 +4,8 @@ import com.fr.base.Utils; import com.fr.general.ComparatorUtils; import com.fr.stable.CoreConstants; import com.fr.stable.StringUtils; +import org.gradle.internal.impldep.org.junit.Test; + import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; import javax.swing.text.PlainDocument; @@ -164,10 +166,16 @@ public class UINumberField extends UITextField { || ComparatorUtils.equals(s, "D") || ComparatorUtils.equals(s, "d") || (ComparatorUtils.equals(str.trim(), "0") && !ComparatorUtils.equals(s.substring(0, 1), ".") && offset != 0)// 第一位是0时,第二位只能为小数点 - || (ComparatorUtils.equals(s, ".") && maxDecimalLength == 0)); + || (ComparatorUtils.equals(s, ".") && maxDecimalLength == 0)) + || s.contains(" ")//不允许空格 + || (ComparatorUtils.equals(s.substring(0, 1),"-") && offset != 0)//负号只允许出现在第一位 + || (ComparatorUtils.equals(s.substring(0, 1),".") && offset == 0)//小数点不能在第一位 + || s.contains("-.") + || s.contains(".-")//不能包含-.或.-非法格式 + || (str.startsWith("-") && ComparatorUtils.equals(s.substring(0, 1), ".") && offset == 1 )//负号不能接小数点 + || (s.contains("-") && !ComparatorUtils.equals(s.substring(0,1), "-"));//输入的字符串如果包含负号,负号必须在第一位 } - public void insertString(int offset, String s, AttributeSet a) throws BadLocationException { String str = getText(0, getLength()); diff --git a/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java b/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java index 7fd88dd95..23e9d3077 100644 --- a/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java +++ b/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java @@ -21,11 +21,16 @@ import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dimension; +import javax.swing.text.AttributeSet; +import javax.swing.text.BadLocationException; +import javax.swing.text.PlainDocument; +import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.regex.Matcher; +import java.util.regex.Pattern; /** * Created by kerry on 2017/9/10. @@ -102,8 +107,20 @@ public class NumberEditorValidatePane extends JPanel { int[][] rowCount = {{1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}, {1, 1}}; JPanel panel = TableLayoutHelper.createGapTableLayoutPane(components, rowSize, columnSize, rowCount, IntervalConstants.INTERVAL_L2, IntervalConstants.INTERVAL_L1); this.add(panel); + decimalLength.getTextField().addKeyListener(new KeyAdapter() { + @Override + public void keyTyped(KeyEvent e) { + // Digit only + if (isDigit(e)) { + } else { + e.consume(); + } + } + }); + } + private boolean isDigit(KeyEvent e){ + return e.getKeyChar() >= KeyEvent.VK_0 && e.getKeyChar() <= KeyEvent.VK_9; } - private void initErrorMsgPane() { TextFieldAdapterProvider provider = ExtraDesignClassManager.getInstance().getSingle(TextFieldAdapterProvider.XML_TAG); if (provider != null) { diff --git a/designer-base/src/test/java/com/fr/design/gui/itextfield/UINumberFieldTest.java b/designer-base/src/test/java/com/fr/design/gui/itextfield/UINumberFieldTest.java new file mode 100644 index 000000000..17b0f547c --- /dev/null +++ b/designer-base/src/test/java/com/fr/design/gui/itextfield/UINumberFieldTest.java @@ -0,0 +1,44 @@ +package com.fr.design.gui.itextfield; + +import org.junit.Assert; +import org.junit.Test; + +/** + * @author Destiny.Lin + * @version 10.0 + * created by Destiny.Lin on 2022-07-11 + */ +public class UINumberFieldTest { + + @Test + public void testUINumberFieldTest(){ + UINumberField uiNumberField = new UINumberField(); + uiNumberField.setFieldDocument(); + //异常输入测试 + uiNumberField.setText("-.1"); + Assert.assertEquals("",uiNumberField.getText()); + uiNumberField.setText(".-1"); + Assert.assertEquals("",uiNumberField.getText()); + uiNumberField.setText("1-"); + Assert.assertEquals("",uiNumberField.getText()); + uiNumberField.setText("1-1"); + Assert.assertEquals("",uiNumberField.getText()); + uiNumberField.setText("1 "); + Assert.assertEquals("",uiNumberField.getText()); + uiNumberField.setText(".1"); + Assert.assertEquals("",uiNumberField.getText()); + uiNumberField.setText("1 -"); + Assert.assertEquals("",uiNumberField.getText()); + + //正常输入测试 + uiNumberField.setText("0.1"); + Assert.assertEquals("0.1",uiNumberField.getText()); + uiNumberField.setText("1"); + Assert.assertEquals("1",uiNumberField.getText()); + uiNumberField.setText("-1.5"); + Assert.assertEquals("-1.5",uiNumberField.getText()); + uiNumberField.setText("-123.123"); + Assert.assertEquals("-123.123",uiNumberField.getText()); + + } +} From 8d26f1b05807986f00e2d320fa94b37003c1a192 Mon Sep 17 00:00:00 2001 From: "Destiny.Lin" Date: Mon, 11 Jul 2022 18:30:57 +0800 Subject: [PATCH 42/55] =?UTF-8?q?REPORT-38555=20fix:=E6=95=B0=E5=AD=97?= =?UTF-8?q?=E6=8E=A7=E4=BB=B6=E4=B8=AD=E5=86=85=E5=AE=B9=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E8=BE=93=E5=85=A5=E7=A9=BA=E6=A0=BC=E5=92=8C=E5=87=8F=E5=8F=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/gui/ispinner/UISpinner.java | 17 +++++++++++++++-- .../fr/design/gui/itextfield/UINumberField.java | 1 - .../component/NumberEditorValidatePane.java | 10 ++++------ 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java index 10e6e5837..22f6cb246 100644 --- a/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java +++ b/designer-base/src/main/java/com/fr/design/gui/ispinner/UISpinner.java @@ -22,8 +22,19 @@ import javax.swing.event.ChangeListener; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import javax.swing.plaf.ButtonUI; -import java.awt.*; -import java.awt.event.*; +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Dimension; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusAdapter; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.MouseWheelEvent; +import java.awt.event.MouseWheelListener; public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver { @@ -61,6 +72,7 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver init(minValue, maxValue, dierta); textField.setValue(defaultValue); } + protected void init(double minValue, double maxValue, double dierta) { this.minValue = minValue; this.maxValue = maxValue; @@ -399,6 +411,7 @@ public class UISpinner extends JPanel implements UIObserver, GlobalNameObserver public boolean shouldResponseNameListener() { return true; } + /** * 程序入口 测试 * diff --git a/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java b/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java index 5a2bda66e..f40237659 100644 --- a/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java +++ b/designer-base/src/main/java/com/fr/design/gui/itextfield/UINumberField.java @@ -4,7 +4,6 @@ import com.fr.base.Utils; import com.fr.general.ComparatorUtils; import com.fr.stable.CoreConstants; import com.fr.stable.StringUtils; -import org.gradle.internal.impldep.org.junit.Test; import javax.swing.text.AttributeSet; import javax.swing.text.BadLocationException; diff --git a/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java b/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java index 23e9d3077..d10f58e18 100644 --- a/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java +++ b/designer-base/src/main/java/com/fr/design/widget/component/NumberEditorValidatePane.java @@ -21,16 +21,14 @@ import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; -import javax.swing.text.AttributeSet; -import javax.swing.text.BadLocationException; -import javax.swing.text.PlainDocument; -import java.awt.*; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; -import java.util.regex.Matcher; -import java.util.regex.Pattern; + /** * Created by kerry on 2017/9/10. From cfbaa750c705c4006d1d08bc69cba39043d66c8e Mon Sep 17 00:00:00 2001 From: rinoux Date: Thu, 28 Jul 2022 14:15:31 +0800 Subject: [PATCH 43/55] =?UTF-8?q?REPORT-76370=20=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=95=B0=E6=8D=AE=E8=BF=9E=E6=8E=A5=E5=89=8D?= =?UTF-8?q?=E7=BD=AE=E6=A3=80=E6=9F=A5=E6=8E=A5=E5=8F=A3&=E6=8F=90?= =?UTF-8?q?=E4=BA=A410.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datapane/connect/ConnectionListPane.java | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 3e03e6a5d..347906bb1 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -5,6 +5,7 @@ import com.fr.data.core.db.JDBCSecurityChecker; import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; +import com.fr.data.operator.DataOperator; import com.fr.design.ExtraDesignClassManager; import com.fr.design.data.MapCompareUtils; import com.fr.design.dialog.FineJOptionPane; @@ -181,7 +182,7 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh } }); - this.checkSecurity(addedOrUpdatedConnections); + this.validateConnections(addedOrUpdatedConnections); alterConnections(removedConnNames, addedOrUpdatedConnections); } @@ -190,17 +191,14 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh addedOrUpdatedConnections.forEach((name, conn) -> ConnectionConfig.getInstance().addConnection(name, conn)); } - private void checkSecurity(Map addedOrUpdatedConnections) throws Exception { + private void validateConnections(Map addedOrUpdatedConnections) throws Exception { for (Map.Entry entry : addedOrUpdatedConnections.entrySet()) { Connection connection = entry.getValue(); - if (connection instanceof JDBCDatabaseConnection) { - try { - JDBCSecurityChecker.checkURL(TemplateUtils.render(((JDBCDatabaseConnection) connection).getURL())); - JDBCSecurityChecker.checkValidationQuery(((JDBCDatabaseConnection) connection).getDbcpAttr().getValidationQuery()); - } catch (SQLException e) { - throw new SQLException(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Invalid_Config", entry.getKey()) + ", " + e.getMessage(), e.getCause()); - } + try { + DataOperator.getInstance().validateConnectionSettings(connection); + } catch (SQLException e) { + throw new SQLException(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Invalid_Config", entry.getKey()) + ", " + e.getMessage(), e.getCause()); } } } From a62468ba8ce25a2bf760657c11f30e392020d681 Mon Sep 17 00:00:00 2001 From: rinoux Date: Thu, 28 Jul 2022 14:16:18 +0800 Subject: [PATCH 44/55] =?UTF-8?q?REPORT-76370=20=E6=8F=90=E4=BE=9B?= =?UTF-8?q?=E4=B8=80=E4=B8=AA=E6=95=B0=E6=8D=AE=E8=BF=9E=E6=8E=A5=E5=89=8D?= =?UTF-8?q?=E7=BD=AE=E6=A3=80=E6=9F=A5=E6=8E=A5=E5=8F=A3&=E6=8F=90?= =?UTF-8?q?=E4=BA=A410.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/data/datapane/connect/ConnectionListPane.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 347906bb1..9d18031b0 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -1,7 +1,5 @@ package com.fr.design.data.datapane.connect; -import com.fr.base.TemplateUtils; -import com.fr.data.core.db.JDBCSecurityChecker; import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; From 5248163c6bca1820bfc73fa95598cb0003bf692d Mon Sep 17 00:00:00 2001 From: Yvan Date: Thu, 28 Jul 2022 14:58:26 +0800 Subject: [PATCH 45/55] =?UTF-8?q?REPORT-72635=20-=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E9=9D=A2=E6=9D=BF=E4=B8=BA=E7=A9=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=88=E5=90=AB=E6=8E=A7=E5=88=B6=E6=9D=83?= =?UTF-8?q?=E9=99=90=EF=BC=89=20=E3=80=90=E9=97=AE=E9=A2=98=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0=E3=80=91=E5=90=8C=E6=AD=A5=E5=88=B010.0=20=E3=80=90?= =?UTF-8?q?=E6=94=B9=E5=8A=A8=E6=80=9D=E8=B7=AF=E3=80=91=E5=90=8C=E6=AD=A5?= =?UTF-8?q?=E5=88=B010.0=20=E3=80=90review=E5=BB=BA=E8=AE=AE=E3=80=91?= =?UTF-8?q?=E6=97=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../data/datapane/TableDataTreePane.java | 63 +++++++++- .../connect/ConnectionComboBoxPanel.java | 38 ++++-- .../connect/ConnectionTableProcedurePane.java | 115 ++++++++++++++++-- .../connect/ItemEditableComboBoxPanel.java | 16 +++ .../tabledatapane/DBTableDataPane.java | 62 ++++++++-- 5 files changed, 259 insertions(+), 35 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java index 31630b85c..09c82ade6 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/TableDataTreePane.java @@ -2,6 +2,7 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; import com.fr.data.TableDataSource; +import com.fr.data.impl.DBTableData; import com.fr.data.impl.TableDataSourceDependent; import com.fr.design.DesignModelAdapter; import com.fr.design.ExtraDesignClassManager; @@ -10,8 +11,10 @@ import com.fr.design.constants.UIConstants; import com.fr.design.data.BasicTableDataTreePane; import com.fr.design.data.BasicTableDataUtils; import com.fr.design.data.DesignTableDataManager; +import com.fr.design.data.datapane.auth.TableDataAuthHelper; import com.fr.design.data.tabledata.StoreProcedureWorkerListener; import com.fr.design.data.tabledata.tabledatapane.AbstractTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.loading.TableDataLoadingPane; import com.fr.design.data.tabledata.wrapper.AbstractTableDataWrapper; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; @@ -31,6 +34,7 @@ import com.fr.design.menu.ToolBarDef; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralContext; import com.fr.general.NameObject; +import com.fr.log.FineLoggerFactory; import com.fr.plugin.context.PluginContext; import com.fr.plugin.injectable.PluginModule; import com.fr.plugin.manage.PluginFilter; @@ -42,6 +46,7 @@ import javax.swing.BorderFactory; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; import javax.swing.ToolTipManager; import java.awt.BorderLayout; import java.awt.GridLayout; @@ -49,6 +54,7 @@ import java.awt.dnd.DnDConstants; import java.awt.event.ActionEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.Iterator; @@ -239,7 +245,11 @@ public class TableDataTreePane extends BasicTableDataTreePane { doPropertyChange(dg, nPanel, oldName); } }); - dg.setVisible(true); + // 有些数据集(DBTableData)面板的初始化过程中是包含了SwingWorker处理(查询数据连接、查表等)的 + // 如果这里直接setVisible,可能阻塞SwingWorker的done方法,导致面板渲染出现问题 + SwingUtilities.invokeLater(() -> { + dg.setVisible(true); + }); } private class EditAction extends UpdateAction { @@ -249,13 +259,60 @@ public class TableDataTreePane extends BasicTableDataTreePane { this.setSmallIcon("/com/fr/design/images/control/edit"); } + @Override public void actionPerformed(ActionEvent e) { final NameObject selectedNO = dataTree.getSelectedNameObject(); if (selectedNO == null) { return; } - DesignTableDataManager.removeSelectedColumnNames(selectedNO.getName()); - dgEdit(((AbstractTableDataWrapper) selectedNO.getObject()).creatTableDataPane(), selectedNO.getName(), false); + + String dsName = selectedNO.getName(); + DesignTableDataManager.removeSelectedColumnNames(dsName); + + AbstractTableDataWrapper wrapper = (AbstractTableDataWrapper) selectedNO.getObject(); + + AbstractTableDataPane tableDataPane = wrapper.creatTableDataPane(); + + if (TableDataAuthHelper.needCheckAuthWhenEdit(wrapper.getTableData())) { + // 先打开一个Loading面板 + TableDataLoadingPane loadingPane = new TableDataLoadingPane(); + BasicDialog loadingDialog = loadingPane.showLargeWindow(SwingUtilities.getWindowAncestor(TableDataTreePane.this), null); + // 查询权限 + new SwingWorker() { + @Override + protected Boolean doInBackground() throws Exception { + // 获取无权限连接名称集合 + Collection noAuthConnections = TableDataAuthHelper.getNoAuthConnections(); + // 获取当前数据集对应的数据连接名称 + String connectionName = TableDataAuthHelper.getConnectionNameByDBTableData((DBTableData) wrapper.getTableData()); + return !noAuthConnections.contains(connectionName); + } + + @Override + protected void done() { + try { + Boolean hasAuth = get(); + if (hasAuth) { + // 有权限时,关闭Loading面板,打开编辑面板 + loadingDialog.setVisible(false); + dgEdit(tableDataPane, dsName, false); + } else { + // 无权限时,给出无权限提示 + loadingPane.switchTo(TableDataLoadingPane.NO_AUTH_PANE_NAME); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error("loading connection error in remote design", e.getMessage()); + // 查询权限失败时,给出报错提示 + loadingPane.switchTo(TableDataLoadingPane.ERROR_NAME); + } + } + }.execute(); + loadingDialog.setVisible(true); + } else { + // 无需检查权限时,直接打开数据库查询编辑面板 + //下面创建creatTableDataPane后会直接populate,所以populate时不能用后设置的一些参数,比如name + dgEdit(tableDataPane, dsName, false); + } } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java index 81147d42d..9fa03aca1 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionComboBoxPanel.java @@ -200,18 +200,34 @@ public class ConnectionComboBoxPanel extends ItemEditableComboBoxPanel { if (connection instanceof NameDatabaseConnection) { this.setSelectedItem(((NameDatabaseConnection) connection).getName()); } else { - String s = DesignerEnvManager.getEnvManager().getRecentSelectedConnection(); - if (StringUtils.isNotBlank(s)) { - // 之前的写法有多线程问题,nameList异步尚未初始化完成的时候,这里可能无法匹配设置数据连接名称,导致DBTableDataPane打开后连接面板空白 - // 这里的需求无非是设置上一次使用的数据连接,做个简单检查这个连接是否存在即可,存在就设置 - if (nameList.contains(s)) { - this.setSelectedItem(s); - } - } - // alex:如果这个ComboBox还是没有选中,那么选中第一个 - if (StringUtils.isBlank(this.getSelectedItem()) && this.getConnectionSize() > 0) { - this.setSelectedItem(this.getConnection(0)); + setRecentConnection(); + } + } + + /** + * 下拉框选项设置成最近选择的connection,如果最近选择不存在,则选择列表中的第一个 + */ + protected void setRecentConnection() { + String s = DesignerEnvManager.getEnvManager().getRecentSelectedConnection(); + if (StringUtils.isNotBlank(s)) { + // 之前的写法有多线程问题,nameList异步尚未初始化完成的时候,这里可能无法匹配设置数据连接名称,导致DBTableDataPane打开后连接面板空白 + // 这里的需求无非是设置上一次使用的数据连接,做个简单检查这个连接是否存在即可,存在就设置 + if (nameList.contains(s)) { + this.setSelectedItem(s); } } + // alex:如果这个ComboBox还是没有选中,那么选中第一个 + if (StringUtils.isBlank(this.getSelectedItem()) && this.getConnectionSize() > 0) { + this.setSelectedItem(this.getConnection(0)); + } + } + + /** + * 是否无选中状态(空白item也视为无选中) + * @return + */ + protected boolean isSelectedItemEmpty() { + String selectedItem = this.getSelectedItem(); + return selectedItem == null || StringUtils.equals(selectedItem, EMPTY.toString()); } } diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java index a979a20cd..613eed9a4 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionTableProcedurePane.java @@ -1,26 +1,32 @@ package com.fr.design.data.datapane.connect; import com.fr.base.BaseUtils; +import com.fr.base.svg.IconUtils; import com.fr.data.core.db.TableProcedure; import com.fr.data.impl.AbstractDatabaseConnection; import com.fr.data.impl.Connection; import com.fr.design.border.UIRoundedBorder; import com.fr.design.constants.UIConstants; +import com.fr.design.data.tabledata.tabledatapane.DBTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.loading.SwitchableTableDataPane; import com.fr.design.dialog.BasicPane; import com.fr.design.gui.icheckbox.UICheckBox; import com.fr.design.gui.icontainer.UIScrollPane; import com.fr.design.gui.ilable.UILabel; import com.fr.design.gui.ilist.TableViewList; import com.fr.design.gui.itextfield.UITextField; +import com.fr.design.i18n.Toolkit; import com.fr.design.layout.FRGUIPaneFactory; import com.fr.general.GeneralContext; import com.fr.stable.ArrayUtils; +import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.ToolTipManager; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import java.awt.BorderLayout; +import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -45,7 +51,39 @@ public class ConnectionTableProcedurePane extends BasicPane { private java.util.List listeners = new java.util.ArrayList(); public ConnectionTableProcedurePane() { + init(null); + } + + /** + * 传入父容器 + * @param parent + */ + public ConnectionTableProcedurePane(SwitchableTableDataPane parent) { + init(parent); + } + + private void init(SwitchableTableDataPane parent) { this.setLayout(new BorderLayout(4, 4)); + // 初始化数据连接下拉框 + initConnectionComboBox(parent); + // 初始化中间的面板 + JPanel centerPane = initCenterPane(); + this.add(connectionComboBox, BorderLayout.NORTH); + this.add(centerPane, BorderLayout.CENTER); + this.setPreferredSize(new Dimension(WIDTH, getPreferredSize().height)); + addKeyMonitor(); + } + + private JPanel initCenterPane() { + JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + // 搜索面板 + centerPane.add(createSearchPane(), BorderLayout.NORTH); + // 数据库表视图面板 + centerPane.add(createTableViewBorderPane(), BorderLayout.CENTER); + return centerPane; + } + + private void initConnectionComboBox(SwitchableTableDataPane parent) { connectionComboBox = new ConnectionComboBoxPanel(com.fr.data.impl.Connection.class) { @Override @@ -60,10 +98,34 @@ public class ConnectionTableProcedurePane extends BasicPane { search(true); } } + + @Override + protected void afterRefreshItems() { + // 刷新完成后,如果未选中(在nameList初始化完成之前可能会出现),则尝试再次设置 + if (isSelectedItemEmpty()) { + setRecentConnection(); + } + // 获取数据连接之后,让父容器切换面板 + if (parent != null) { + parent.switchTo(SwitchableTableDataPane.CONTENT_PANE_NAME); + } + } + + @Override + protected void refreshItemsError() { + // 获取数据连接出现错误时,也让父容器从Loading面板切换至内容面板 + if (parent != null) { + parent.switchTo(SwitchableTableDataPane.CONTENT_PANE_NAME); + } + } }; + connectionComboBox.addComboBoxActionListener(filter); + } + + private JPanel createTableViewBorderPane() { tableViewList = new TableViewList(); ToolTipManager.sharedInstance().registerComponent(tableViewList); - connectionComboBox.addComboBoxActionListener(filter); + tableViewList.addMouseListener(new MouseAdapter() { public void mouseClicked(MouseEvent evt) { if (evt.getClickCount() >= 2) { @@ -80,23 +142,50 @@ public class ConnectionTableProcedurePane extends BasicPane { } } }); - JPanel filterPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + UIScrollPane tableViewListPane = new UIScrollPane(tableViewList); + tableViewListPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); + JPanel tableViewBorderPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + tableViewBorderPane.add(tableViewListPane, BorderLayout.CENTER); JPanel checkBoxgroupPane = createCheckBoxgroupPane(); if (checkBoxgroupPane != null) { - filterPane.add(createCheckBoxgroupPane(), BorderLayout.NORTH); + tableViewBorderPane.add(createCheckBoxgroupPane(), BorderLayout.SOUTH); } + return tableViewBorderPane; + } + + /** + * 创建搜索Panel,用于搜索表或视图 + * @return + */ + private JPanel createSearchPane() { + JPanel panel = FRGUIPaneFactory.createBorderLayout_S_Pane(); JPanel searchPane = new JPanel(new BorderLayout(10, 0)); + searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR)); + searchPane.setBackground(Color.WHITE); searchField = new UITextField(); - searchPane.add(searchField, BorderLayout.CENTER); + searchField.setBorderPainted(false); + searchField.setPlaceholder(Toolkit.i18nText("Fine-Design_Basic_Table_Search")); searchField.getDocument().addDocumentListener(searchListener); - filterPane.add(searchPane, BorderLayout.CENTER); - UIScrollPane tableViewListPane = new UIScrollPane(tableViewList); - tableViewListPane.setBorder(new UIRoundedBorder(UIConstants.LINE_COLOR, 1, UIConstants.ARC)); - this.add(connectionComboBox, BorderLayout.NORTH); - this.add(tableViewListPane, BorderLayout.CENTER); - this.add(filterPane, BorderLayout.SOUTH); - this.setPreferredSize(new Dimension(WIDTH, getPreferredSize().height)); - addKeyMonitor(); + searchField.addMouseListener(new MouseAdapter() { + @Override + public void mouseEntered(MouseEvent e) { + super.mouseEntered(e); + searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.CHECKBOX_HOVER_SELECTED)); + } + + @Override + public void mouseExited(MouseEvent e) { + super.mouseExited(e); + searchPane.setBorder(BorderFactory.createLineBorder(UIConstants.TOOLBAR_BORDER_COLOR)); + } + }); + // 搜索图标 + UILabel searchLabel = new UILabel(IconUtils.readIcon("/com/fr/design/images/data/search")); + searchLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5)); + searchPane.add(searchField, BorderLayout.CENTER); + searchPane.add(searchLabel, BorderLayout.EAST); + panel.add(searchPane, BorderLayout.CENTER); + return panel; } protected void filter(Connection connection, String conName, List nameList) { @@ -224,4 +313,4 @@ public class ConnectionTableProcedurePane extends BasicPane { */ public void actionPerformed(TableProcedure target); } -} \ No newline at end of file +} diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java index d0738e57b..a430a13bd 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ItemEditableComboBoxPanel.java @@ -127,10 +127,12 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() + 1); itemComboBox.setMaximumRowCount(itemComboBox.getMaximumRowCount() - 1); } + afterRefreshItems(); } catch (Exception e) { if (!(e instanceof CancellationException)) { FineLoggerFactory.getLogger().error(e.getMessage(), e); } + refreshItemsError(); } } @@ -160,6 +162,20 @@ public abstract class ItemEditableComboBoxPanel extends JPanel { */ protected abstract java.util.Iterator items(); + /** + * 刷新ComboBox.items之后 + */ + protected void afterRefreshItems() { + // 空实现,供子类重写 + } + + /** + * 刷新ComboBox.items时出现异常 + */ + protected void refreshItemsError() { + // 空实现,供子类重写 + } + /* * 弹出对话框编辑Items */ diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java index fecf9c079..f1b804377 100644 --- a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/DBTableDataPane.java @@ -18,6 +18,8 @@ import com.fr.design.data.datapane.connect.ConnectionTableProcedurePane.DoubleCl import com.fr.design.data.datapane.preview.PreviewTablePane; import com.fr.design.data.datapane.preview.sql.PreviewPerformedSqlPane; import com.fr.design.data.datapane.sqlpane.SQLEditPane; +import com.fr.design.data.tabledata.tabledatapane.loading.SwitchableTableDataPane; +import com.fr.design.data.tabledata.tabledatapane.loading.TipsPane; import com.fr.design.dialog.BasicDialog; import com.fr.design.dialog.BasicPane; import com.fr.design.dialog.DialogActionAdapter; @@ -30,6 +32,7 @@ import com.fr.design.gui.itableeditorpane.UITableEditorPane; import com.fr.design.gui.itoolbar.UIToolbar; import com.fr.design.gui.syntax.ui.rsyntaxtextarea.SyntaxConstants; import com.fr.design.gui.syntax.ui.rtextarea.RTextScrollPane; +import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.mainframe.DesignerContext; import com.fr.design.menu.SeparatorDef; import com.fr.design.menu.ToolBarDef; @@ -54,6 +57,7 @@ import javax.swing.JToolBar; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import java.awt.BorderLayout; +import java.awt.CardLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.event.ActionEvent; @@ -64,7 +68,7 @@ import java.awt.event.KeyListener; import java.util.ArrayList; import java.util.List; -public class DBTableDataPane extends AbstractTableDataPane { +public class DBTableDataPane extends AbstractTableDataPane implements SwitchableTableDataPane { private static final int BOTTOM = 6; private static final String PREVIEW_BUTTON = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview"); private static final String REFRESH_BUTTON = com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Refresh"); @@ -78,8 +82,42 @@ public class DBTableDataPane extends AbstractTableDataPane { private String pageQuery = null; private DBTableData dbTableData; + private CardLayout card; + /** 数据库查询面板真正的内容面板 */ + private JPanel contentPane; + /** 加载中面板 */ + private JPanel loadingPane; + + public DBTableDataPane() { + initCards(); + initContentPane(); + } + + /** + * 初始化cardLayout以及LoadingPane等,并且布局切到LoadingPane + */ + protected void initCards() { + card = new CardLayout(); + setLayout(card); + + loadingPane = new TipsPane(true); + contentPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane(); + + add(LOADING_PANE_NAME, loadingPane); + add(CONTENT_PANE_NAME, contentPane); + switchTo(LOADING_PANE_NAME); + } + + /** + * 初始化内容面板 + */ + protected void initContentPane() { + init(); + initMainSplitPane(); + } + private void init() { - this.setLayout(new BorderLayout(4, 4)); + contentPane.setLayout(new BorderLayout(4, 4)); sqlTextPane = new SQLEditPane(); sqlTextPane.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_SQL); @@ -93,7 +131,7 @@ public class DBTableDataPane extends AbstractTableDataPane { editorPane = new UITableEditorPane(model); // 左边的Panel,上面是选择DatabaseConnection的ComboBox,下面DatabaseConnection对应的Table - connectionTableProcedurePane = new ConnectionTableProcedurePane() { + connectionTableProcedurePane = new ConnectionTableProcedurePane(this) { @Override protected void filter(Connection connection, String conName, List nameList) { @@ -194,15 +232,23 @@ public class DBTableDataPane extends AbstractTableDataPane { JSplitPane mainSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true, connectionTableProcedurePane, sqlSplitPane); mainSplitPane.setBorder(BorderFactory.createLineBorder(GUICoreUtils.getTitleLineBorderColor())); mainSplitPane.setOneTouchExpandable(true); - this.add(mainSplitPane, BorderLayout.CENTER); + contentPane.add(mainSplitPane, BorderLayout.CENTER); } - public DBTableDataPane() { - init(); - initMainSplitPane(); + @Override + public void switchTo(String panelName) { + try { + if (panelName != null) { + card.show(this, panelName); + } + } catch (IllegalArgumentException ingore) { + // 有些直接继承此面板或者替换掉此面板的插件,在未适配此功能时会出现报错,因为不是CardLayout,无法切换,这里处理下 + FineLoggerFactory.getLogger().info("cannot switch pane by {}", this.getClass().getName()); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } } - private boolean isPreviewOrRefreshButton(FocusEvent e) { if (e.getOppositeComponent() != null) { String name = e.getOppositeComponent().getName(); From 3a12f12eef2f5dcc0e8cab52664c71a7960d1ac4 Mon Sep 17 00:00:00 2001 From: Yvan Date: Thu, 28 Jul 2022 15:13:28 +0800 Subject: [PATCH 46/55] =?UTF-8?q?REPORT-72635=20-=20=E6=95=B0=E6=8D=AE?= =?UTF-8?q?=E8=BF=9E=E6=8E=A5=E9=9D=A2=E6=9D=BF=E4=B8=BA=E7=A9=BA=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98=EF=BC=88=E5=90=AB=E6=8E=A7=E5=88=B6=E6=9D=83?= =?UTF-8?q?=E9=99=90=EF=BC=89=20=E6=9C=89=E4=BA=9B=E6=96=B0=E7=B1=BB?= =?UTF-8?q?=EF=BC=8C=E6=B2=A1=E6=8F=90=E4=BA=A4=E8=BF=9B=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../datapane/auth/TableDataAuthHelper.java | 57 +++++++++++++++++++ .../loading/SwitchableTableDataPane.java | 23 ++++++++ .../loading/TableDataLoadingPane.java | 54 ++++++++++++++++++ .../tabledatapane/loading/TipsPane.java | 45 +++++++++++++++ 4 files changed, 179 insertions(+) create mode 100644 designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java create mode 100644 designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/SwitchableTableDataPane.java create mode 100644 designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TableDataLoadingPane.java create mode 100644 designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TipsPane.java diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java b/designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java new file mode 100644 index 000000000..382e04dd9 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/datapane/auth/TableDataAuthHelper.java @@ -0,0 +1,57 @@ +package com.fr.design.data.datapane.auth; + +import com.fr.base.TableData; +import com.fr.data.impl.Connection; +import com.fr.data.impl.DBTableData; +import com.fr.data.impl.NameDatabaseConnection; +import com.fr.stable.StringUtils; +import com.fr.workspace.WorkContext; +import com.fr.workspace.server.connection.DBConnectAuth; + +import java.util.Collection; +import java.util.Collections; + +/** + * 数据连接权限相关的工具类 + * @author Yvan + */ +public class TableDataAuthHelper { + + /** + * 编辑数据集时是否需要检查权限 + * @param tableData + * @return + */ + public static boolean needCheckAuthWhenEdit(TableData tableData) { + // 远程设计下,编辑DBTableData时需要判断权限 + return !WorkContext.getCurrent().isLocal() && tableData instanceof DBTableData; + } + + /** + * 获取无权限数据连接集合 + * 远程下需要调用RPC,为耗时操作,谨慎使用 + * @return + */ + public static Collection getNoAuthConnections() { + // 获取无权限连接集合 + Collection noAuthConnections = WorkContext.getCurrent().get(DBConnectAuth.class).getNoAuthConnections(); + return noAuthConnections == null ? Collections.emptyList() : noAuthConnections; + } + + /** + * 通过数据集获取其数据连接的名称 + * + * 注意: + * 1. Connection接口本身是不提供名称的,只有我们内部为了使用方便,将其包装成了NameDataBaseConnection + * 如果不是NameDataBaseConnection类型,则无名称,因此这里只能用判断类型的方式获取名称 + * 2. 仅支持DBTableData获取连接名 + * @return + */ + public static String getConnectionNameByDBTableData(DBTableData tableData) { + Connection database = tableData.getDatabase(); + if (database instanceof NameDatabaseConnection) { + return ((NameDatabaseConnection) database).getName(); + } + return StringUtils.EMPTY; + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/SwitchableTableDataPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/SwitchableTableDataPane.java new file mode 100644 index 000000000..221ee1cbb --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/SwitchableTableDataPane.java @@ -0,0 +1,23 @@ +package com.fr.design.data.tabledata.tabledatapane.loading; + + + +/** + * 可切换的DBTableData对应的数据集面板,需要使用CardLayout布局 + * 主要是给插件适配用的 + * @author Yvan + */ +public interface SwitchableTableDataPane { + + /** Loading面板 */ + String LOADING_PANE_NAME = "Loading"; + /** 内容面板 */ + String CONTENT_PANE_NAME = "Content"; + + /** + * 根据面板名称切换面板 + * @param paneName 面板名称 + */ + void switchTo(String paneName); + +} diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TableDataLoadingPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TableDataLoadingPane.java new file mode 100644 index 000000000..c3f12c3e7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TableDataLoadingPane.java @@ -0,0 +1,54 @@ +package com.fr.design.data.tabledata.tabledatapane.loading; + +import com.fr.design.dialog.BasicPane; +import com.fr.design.i18n.Toolkit; + +import javax.swing.JPanel; +import java.awt.CardLayout; + +/** + * @author Yvan + */ +public class TableDataLoadingPane extends BasicPane { + + /** Loading面板 */ + public static final String LOADING_PANE_NAME = "Loading"; + /** 无权限提示面板 */ + public static final String NO_AUTH_PANE_NAME = "NoAuthority"; + /** 错误提示面板 */ + public static final String ERROR_NAME = "Error"; + + private CardLayout card; + + /** 加载中面板 */ + private JPanel loadingPane; + /** 错误提示面板 */ + private JPanel errorPane; + /** 数据连接无权限面板 */ + private JPanel noAuthorityPane; + + public TableDataLoadingPane() { + initPanes(); + } + + private void initPanes() { + card = new CardLayout(); + this.setLayout(card); + loadingPane = new TipsPane(true); + errorPane = new TipsPane(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Error")); + noAuthorityPane = new TipsPane(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_No_Auth")); + add(LOADING_PANE_NAME, loadingPane); + add(NO_AUTH_PANE_NAME, noAuthorityPane); + add(ERROR_NAME, errorPane); + switchTo(LOADING_PANE_NAME); + } + + public void switchTo(String panelName) { + card.show(this, panelName); + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Basic_DS-Database_Query"); + } +} diff --git a/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TipsPane.java b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TipsPane.java new file mode 100644 index 000000000..40fcb6ef2 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/data/tabledata/tabledatapane/loading/TipsPane.java @@ -0,0 +1,45 @@ +package com.fr.design.data.tabledata.tabledatapane.loading; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; + +import javax.swing.JPanel; +import javax.swing.JProgressBar; +import javax.swing.SwingConstants; +import java.awt.BorderLayout; + +/** + * 提示面板,支持自定义提示,支持进度条配置可选 + * @author Yvan + */ +public class TipsPane extends JPanel { + + /** + * 默认提示 + */ + private static final String LOADING = Toolkit.i18nText("Fine-Design_Basic_Loading_And_Waiting"); + + public TipsPane () { + this(LOADING, false); + } + + public TipsPane (String tip) { + this(tip, false); + } + + public TipsPane (boolean needProgressBar) { + this(LOADING, needProgressBar); + } + + public TipsPane (String tips, boolean needProgressBar) { + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + UILabel tipsLabel = new UILabel(tips, SwingConstants.CENTER); + this.add(tipsLabel, BorderLayout.CENTER); + if (needProgressBar) { + JProgressBar progressBar = new JProgressBar(); + progressBar.setIndeterminate(true); + this.add(progressBar, BorderLayout.SOUTH); + } + } +} From 1c88c2d07373df922371faf21d580078f62e4b71 Mon Sep 17 00:00:00 2001 From: Yvan Date: Fri, 29 Jul 2022 12:11:10 +0800 Subject: [PATCH 47/55] =?UTF-8?q?REPORT-75991=20=E6=8F=92=E4=BB=B6?= =?UTF-8?q?=E5=AE=8C=E6=95=B4=E6=80=A7=E6=A0=A1=E9=AA=8C=EF=BC=8C=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E9=93=BE=E6=8E=A5=E5=B8=AE=E5=8A=A9=E6=96=87=E6=A1=A3?= =?UTF-8?q?=E8=AF=B4=E6=98=8E=20=E3=80=90=E9=97=AE=E9=A2=98=E5=8E=9F?= =?UTF-8?q?=E5=9B=A0=E3=80=91=E5=AE=89=E5=85=A8=E7=B1=BB=E9=9C=80=E6=B1=82?= =?UTF-8?q?=EF=BC=8C=E5=B0=86=E5=8E=9F=E6=9D=A5=E4=BB=85=E5=AF=B9=E5=AE=98?= =?UTF-8?q?=E6=96=B9=E6=8F=92=E4=BB=B6=E5=BC=80=E5=90=AF=E7=9A=84=20?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E5=AE=8C=E6=95=B4=E6=80=A7=E6=A0=A1=E9=AA=8C?= =?UTF-8?q?=EF=BC=8C=E6=89=A9=E5=A4=A7=E5=88=B0=E4=BA=86=20=E7=AC=AC?= =?UTF-8?q?=E4=B8=89=E6=96=B9=E6=8F=92=E4=BB=B6=E3=80=82=E4=BD=86=E5=BC=B9?= =?UTF-8?q?=E7=AA=97=E4=B8=8D=E6=98=8E=E7=A1=AE=EF=BC=8C=E5=AF=B9=E4=BA=8E?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E4=BE=A7=E6=B2=A1=E6=9C=89=E9=97=AD=E7=8E=AF?= =?UTF-8?q?=EF=BC=8C=E9=9C=80=E8=A6=81=E6=B7=BB=E5=8A=A0=E5=B8=AE=E5=8A=A9?= =?UTF-8?q?=E6=96=87=E6=A1=A3=E9=93=BE=E6=8E=A5=EF=BC=8C=E5=B8=AE=E5=8A=A9?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E6=B8=85=E6=A5=9A=E5=89=8D=E5=9B=A0=E5=90=8E?= =?UTF-8?q?=E6=9E=9C=E4=B8=8E=E8=A7=A3=E5=86=B3=E6=96=B9=E6=A1=88=E3=80=82?= =?UTF-8?q?=20=E3=80=90=E6=94=B9=E5=8A=A8=E6=96=B9=E6=A1=88=E3=80=911.?= =?UTF-8?q?=E6=8F=90=E7=A4=BA=E6=96=87=E6=A1=88=E5=86=85=E5=AE=B9=E4=BF=AE?= =?UTF-8?q?=E6=94=B9=EF=BC=9B2.=E6=8F=90=E7=A4=BA=E4=B8=AD=E5=AD=98?= =?UTF-8?q?=E5=9C=A8=E8=B6=85=E9=93=BE=E6=8E=A5=EF=BC=8C=E5=B0=86=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E8=BF=99=E8=BE=B9=E5=9B=A0=E4=B8=BA"=E6=8F=92?= =?UTF-8?q?=E4=BB=B6=E5=AE=8C=E6=95=B4=E6=80=A7=E6=A0=A1=E9=AA=8C"?= =?UTF-8?q?=E8=80=8C=E5=A4=B1=E8=B4=A5=E7=9A=84=E5=BC=B9=E7=AA=97=E5=8D=95?= =?UTF-8?q?=E7=8B=AC=E5=A4=84=E7=90=86=E4=BA=86=E4=B8=8B=EF=BC=8C=E7=94=B1?= =?UTF-8?q?=E5=8E=9F=E6=9C=AC=E7=9A=84JOptionPane=E4=BF=AE=E6=94=B9?= =?UTF-8?q?=E4=B8=BAJEditorPane=20=E3=80=90review=E5=BB=BA=E8=AE=AE?= =?UTF-8?q?=E3=80=91=E5=85=B6=E5=AE=83=E7=9A=84=E5=BC=B9=E7=AA=97=E6=9A=82?= =?UTF-8?q?=E6=97=B6=E6=B2=A1=E6=9C=89=E5=8F=98=E5=8A=A8=E7=9A=84=E9=9C=80?= =?UTF-8?q?=E6=B1=82=EF=BC=8C=E8=B7=9F=E4=BA=A7=E5=93=81=E6=B2=9F=E9=80=9A?= =?UTF-8?q?=E8=BF=87=E4=BA=86=EF=BC=8C=E5=A6=82=E6=9E=9C=E4=BB=A5=E5=90=8E?= =?UTF-8?q?=E6=9C=89=E5=BF=85=E8=A6=81=E7=BB=9F=E4=B8=80=E7=9A=84=E6=97=B6?= =?UTF-8?q?=E5=80=99=E5=86=8D=E6=9D=A5=E7=BB=9F=E4=B8=80=E5=A4=84=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../exe/callback/InstallFromDiskCallback.java | 3 +- .../exe/callback/InstallOnlineCallback.java | 3 +- .../exe/callback/UpdateFromDiskCallback.java | 3 +- .../exe/callback/UpdateOnlineCallback.java | 3 +- .../callback/handle/PluginCallBackHelper.java | 70 +++++++++++++++ .../handle/PluginTaskResultErrorDialog.java | 86 +++++++++++++++++++ .../fr/design/standard/system/error_tips.svg | 14 +++ 7 files changed, 178 insertions(+), 4 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginCallBackHelper.java create mode 100644 designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginTaskResultErrorDialog.java create mode 100644 designer-base/src/main/resources/com/fr/design/standard/system/error_tips.svg diff --git a/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallFromDiskCallback.java b/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallFromDiskCallback.java index 92fdd4878..ea591f3bf 100644 --- a/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallFromDiskCallback.java +++ b/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallFromDiskCallback.java @@ -3,6 +3,7 @@ package com.fr.design.extra.exe.callback; import com.fr.design.bridge.exec.JSCallback; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.extra.PluginOperateUtils; +import com.fr.design.extra.exe.callback.handle.PluginCallBackHelper; import com.fr.design.i18n.Toolkit; import com.fr.log.FineLoggerFactory; @@ -73,7 +74,7 @@ public class InstallFromDiskCallback extends AbstractPluginTaskCallback { }else { jsCallback.execute("failed"); FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Plugin_Install_Failed")); - FineJOptionPane.showMessageDialog(null, pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), FineJOptionPane.ERROR_MESSAGE); + PluginCallBackHelper.showErrorMessage(result, pluginInfo); } } } diff --git a/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallOnlineCallback.java b/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallOnlineCallback.java index 0b1eb33fb..09c360b4f 100644 --- a/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallOnlineCallback.java +++ b/designer-base/src/main/java/com/fr/design/extra/exe/callback/InstallOnlineCallback.java @@ -4,6 +4,7 @@ import com.fr.design.bridge.exec.JSCallback; import com.fr.design.bridge.exec.JSExecutor; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.extra.PluginOperateUtils; +import com.fr.design.extra.exe.callback.handle.PluginCallBackHelper; import com.fr.design.i18n.Toolkit; import com.fr.log.FineLoggerFactory; @@ -63,7 +64,7 @@ public class InstallOnlineCallback extends AbstractDealPreTaskCallback { } else { jsCallback.execute("failed"); FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Plugin_Install_Failed")); - FineJOptionPane.showMessageDialog(null, pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), FineJOptionPane.ERROR_MESSAGE); + PluginCallBackHelper.showErrorMessage(result, pluginInfo); } } diff --git a/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateFromDiskCallback.java b/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateFromDiskCallback.java index 21c7871f5..31bf482eb 100644 --- a/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateFromDiskCallback.java +++ b/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateFromDiskCallback.java @@ -3,6 +3,7 @@ package com.fr.design.extra.exe.callback; import com.fr.design.bridge.exec.JSCallback; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.extra.PluginOperateUtils; +import com.fr.design.extra.exe.callback.handle.PluginCallBackHelper; import com.fr.design.i18n.Toolkit; import com.fr.log.FineLoggerFactory; @@ -72,7 +73,7 @@ public class UpdateFromDiskCallback extends AbstractPluginTaskCallback { }else { jsCallback.execute("failed"); FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Plugin_Update_Failed")); - FineJOptionPane.showMessageDialog(null, pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), FineJOptionPane.ERROR_MESSAGE); + PluginCallBackHelper.showErrorMessage(result, pluginInfo); } } } diff --git a/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateOnlineCallback.java b/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateOnlineCallback.java index 8dbad6a54..3469ed1a5 100644 --- a/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateOnlineCallback.java +++ b/designer-base/src/main/java/com/fr/design/extra/exe/callback/UpdateOnlineCallback.java @@ -3,6 +3,7 @@ package com.fr.design.extra.exe.callback; import com.fr.design.bridge.exec.JSCallback; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.extra.PluginOperateUtils; +import com.fr.design.extra.exe.callback.handle.PluginCallBackHelper; import com.fr.design.i18n.Toolkit; import com.fr.log.FineLoggerFactory; @@ -38,7 +39,7 @@ public class UpdateOnlineCallback extends AbstractDealPreTaskCallback { } else { jsCallback.execute("failed"); FineLoggerFactory.getLogger().info(Toolkit.i18nText("Fine-Design_Basic_Plugin_Update_Failed")); - FineJOptionPane.showMessageDialog(null, pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), FineJOptionPane.ERROR_MESSAGE); + PluginCallBackHelper.showErrorMessage(result, pluginInfo); } } } diff --git a/designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginCallBackHelper.java b/designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginCallBackHelper.java new file mode 100644 index 000000000..fc5f957f6 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginCallBackHelper.java @@ -0,0 +1,70 @@ +package com.fr.design.extra.exe.callback.handle; + +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.i18n.Toolkit; +import com.fr.plugin.error.PluginErrorCode; +import com.fr.plugin.manage.control.PluginTaskResult; + +/** + * 帮助处理插件操作(安装、更新等)的弹窗 + * @author Yvan + */ +public class PluginCallBackHelper { + + private static final String NEW_LINE_TAG = "
"; + private static final String REFERENCE = Toolkit.i18nText("Fine-Design_Basic_Plugin_File_Validate_Reference"); + private static final String HELP_DOCUMENT_NAME = Toolkit.i18nText("Fine-Design_Basic_Plugin_File_Validate_HELP_DOCUMENT_NAME"); + private static final String CONNECTOR = "-"; + private static final String HELP_DOCUMENT_LINK = Toolkit.i18nText("Fine-Design_Basic_Plugin_File_Validate_HELP_DOCUMENT_LINK"); + + + /** + * 展示插件操作失败后的提示弹窗 + * @param result + * @param pluginInfo + */ + public static void showErrorMessage(PluginTaskResult result, String pluginInfo) { + // 单独处理下插件完整性校验失败的提示 + if (PluginCallBackHelper.needHandleInvalidatePackage(result)) { + MessageWithLink messageWithLink = PluginCallBackHelper.generate4InvalidatePackage(pluginInfo); + PluginTaskResultErrorDialog resultDialog = new PluginTaskResultErrorDialog(null, messageWithLink); + resultDialog.showResult(); + } else { + FineJOptionPane.showMessageDialog(null, pluginInfo, Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning"), FineJOptionPane.ERROR_MESSAGE); + } + } + + /** + * 判断是否需要处理 插件安装包校验失败 导致的安装失败任务 + * @param result + * @return + */ + private static boolean needHandleInvalidatePackage(PluginTaskResult result) { + return !result.isSuccess() && result.getCode() == PluginErrorCode.InstallPackageValidateFailed; + } + + /** + * 根据插件原始报错信息,构建MessageWithLink + * @param originInfo + * @return + */ + private static MessageWithLink generate4InvalidatePackage(String originInfo) { + + return new MessageWithLink(getSupplementaryMessage(originInfo), HELP_DOCUMENT_NAME, HELP_DOCUMENT_LINK); + } + + /** + * 根据插件原始报错信息,获取增加了补充说明后的信息 + * @param originInfo + * @return + */ + private static String getSupplementaryMessage(String originInfo) { + return new StringBuilder() + .append(originInfo) + .append(NEW_LINE_TAG) + .append(REFERENCE) + .append(CONNECTOR) + .toString(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginTaskResultErrorDialog.java b/designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginTaskResultErrorDialog.java new file mode 100644 index 000000000..da4f43208 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/extra/exe/callback/handle/PluginTaskResultErrorDialog.java @@ -0,0 +1,86 @@ +package com.fr.design.extra.exe.callback.handle; + +import com.fr.base.svg.IconUtils; +import com.fr.design.dialog.link.MessageWithLink; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.layout.VerticalFlowLayout; +import com.fr.design.utils.gui.GUICoreUtils; + +import javax.swing.BorderFactory; +import javax.swing.JDialog; +import javax.swing.JPanel; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.Frame; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * 当前仅处理Error提示,之后有需要再扩展 + * @author Yvan + */ +public class PluginTaskResultErrorDialog extends JDialog { + + private static final Dimension LABEL = new Dimension(60, 90); + + private JPanel contentPane; + + private UILabel errorLabel; + + private UIButton confirmButton; + + private MessageWithLink messageWithLink; + + public PluginTaskResultErrorDialog(Frame parent, MessageWithLink messageWithLink) { + super(parent, true); + this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Plugin_Warning")); + this.messageWithLink = messageWithLink; + + initContentPane(); + this.setLayout(FRGUIPaneFactory.createBorderLayout()); + this.setResizable(false); + this.add(contentPane, BorderLayout.CENTER); + this.setSize(new Dimension( 380, 160)); + GUICoreUtils.centerWindow(this); + } + + /** + * 初始化内容面板 + */ + private void initContentPane() { + this.contentPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + // error图标 + errorLabel = new UILabel(IconUtils.readIcon("/com/fr/design/standard/system/error_tips.svg")); + errorLabel.setPreferredSize(LABEL); + errorLabel.setBorder(BorderFactory.createEmptyBorder(10, 20, 40, 20)); + // 提示内容 + JPanel messagePane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + messagePane.add(errorLabel, BorderLayout.WEST); + messagePane.add(messageWithLink, BorderLayout.CENTER); + messagePane.setBorder(BorderFactory.createEmptyBorder(20, 10, 0, 10)); + this.contentPane.add(messagePane, BorderLayout.CENTER); + // 确定按钮 + confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Button_OK")); + confirmButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + hideResult(); + } + }); + JPanel confirmPane = new JPanel(new VerticalFlowLayout()); + confirmPane.add(confirmButton); + confirmPane.setBorder(BorderFactory.createEmptyBorder(0, 160, 10, 0)); + this.contentPane.add(confirmPane, BorderLayout.SOUTH); + } + + public void showResult() { + this.setVisible(true); + } + + public void hideResult() { + this.setVisible(false); + } +} diff --git a/designer-base/src/main/resources/com/fr/design/standard/system/error_tips.svg b/designer-base/src/main/resources/com/fr/design/standard/system/error_tips.svg new file mode 100644 index 000000000..900205215 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/standard/system/error_tips.svg @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + From 6a0820c9e8d9ae271e6b2e6ea419d06d49d5dd15 Mon Sep 17 00:00:00 2001 From: Lanlan Date: Mon, 20 Jun 2022 14:52:14 +0800 Subject: [PATCH 48/55] =?UTF-8?q?REPORT-72595=20FR=E6=BA=90=E7=A0=81?= =?UTF-8?q?=E4=B8=AD=E5=AD=98=E5=9C=A8=E5=8A=A0=E5=AF=86=E5=AF=86=E9=92=A5?= =?UTF-8?q?=E7=A1=AC=E7=BC=96=E7=A0=81=EF=BC=8C=E5=BB=BA=E8=AE=AE=E6=94=BE?= =?UTF-8?q?=E5=88=B0=E9=85=8D=E7=BD=AE=E6=96=87=E4=BB=B6=E4=B8=AD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../login/utils/DesignerLoginUtils.java | 22 ++++++++++++++++--- .../resources/com/fr/design/config/default | 1 + 2 files changed, 20 insertions(+), 3 deletions(-) create mode 100644 designer-base/src/main/resources/com/fr/design/config/default diff --git a/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java b/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java index a39a0be4b..ca238d154 100644 --- a/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java +++ b/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java @@ -9,12 +9,16 @@ import com.fr.general.http.HttpToolbox; import com.fr.general.log.MessageFormatter; import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; +import com.fr.security.encryption.storage.keys.DefaultKeys; import com.fr.stable.StringUtils; import com.fr.third.org.bouncycastle.util.encoders.Hex; import java.awt.Window; +import java.io.IOException; +import java.io.InputStream; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; +import java.util.Properties; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -28,8 +32,6 @@ public class DesignerLoginUtils { private static final String PRODUCT_FINEREPORT = "product-finereport"; - private static final String KEY = "i7hP48WAcuTrmxfN"; - public static Map renderMap() { Map map4Tpl = new HashMap<>(); map4Tpl.put("language", GeneralContext.getLocale().toString()); @@ -85,8 +87,11 @@ public class DesignerLoginUtils { jo.put("uid", manager.getDesignerLoginUid()); jo.put("username", manager.getDesignerLoginUsername()); jo.put("source", PRODUCT_FINEREPORT); + + Properties properties = read("/default"); + byte[] iv = randomIv(); - return new String(Hex.encode(iv)) + encrypt(jo.toString(), KEY.getBytes(), iv); + return new String(Hex.encode(iv)) + encrypt(jo.toString(), properties.getProperty("Fine-Designer_Login").getBytes(), iv); } private static byte[] randomIv() { @@ -105,4 +110,15 @@ public class DesignerLoginUtils { byte[] resultBytes = cipher.doFinal(content.getBytes()); return new String(Hex.encode(resultBytes)); } + + private static Properties read(String fileName) { + fileName = "com/fr/design/config" + fileName; + Properties properties = new Properties(); + try (InputStream inputStream = DefaultKeys.class.getClassLoader().getResourceAsStream(fileName)){ + properties.load(inputStream); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return properties; + } } diff --git a/designer-base/src/main/resources/com/fr/design/config/default b/designer-base/src/main/resources/com/fr/design/config/default new file mode 100644 index 000000000..f808a8237 --- /dev/null +++ b/designer-base/src/main/resources/com/fr/design/config/default @@ -0,0 +1 @@ +Fine-Designer_Login=i7hP48WAcuTrmxfN From 78218164b4ac454458eabefc7efe5c3be07538df Mon Sep 17 00:00:00 2001 From: Lanlan Date: Mon, 20 Jun 2022 15:10:08 +0800 Subject: [PATCH 49/55] =?UTF-8?q?=E5=8D=95=E7=8B=AC=E5=86=99=E4=B8=80?= =?UTF-8?q?=E4=B8=AA=20DefaultLoginKeys?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/login/config/DefaultLoginKeys.java | 48 +++++++++++++++++++ .../login/utils/DesignerLoginUtils.java | 25 +++------- 2 files changed, 54 insertions(+), 19 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/login/config/DefaultLoginKeys.java diff --git a/designer-base/src/main/java/com/fr/design/login/config/DefaultLoginKeys.java b/designer-base/src/main/java/com/fr/design/login/config/DefaultLoginKeys.java new file mode 100644 index 000000000..36988aa5c --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/login/config/DefaultLoginKeys.java @@ -0,0 +1,48 @@ +package com.fr.design.login.config; + +import com.fr.log.FineLoggerFactory; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * @author Lanlan + * @version 10.0 + * Created by Lanlan on 2022/6/20 + */ +public class DefaultLoginKeys { + + private static final String FILENAME = "com/fr/design/config/default"; + + private static final DefaultLoginKeys INSTANCE = new DefaultLoginKeys(); + + public static DefaultLoginKeys getInstance() { + return INSTANCE; + } + + private final Map keys = new HashMap<>(); + + private DefaultLoginKeys() { + Properties properties = load(); + for (Map.Entry entry : properties.entrySet()) { + String name = entry.getKey().toString(); + keys.put(name, entry.getValue().toString()); + } + } + + public String getKey(String name) { + return keys.get(name); + } + + private Properties load() { + Properties properties = new Properties(); + try (InputStream inputStream = DefaultLoginKeys.class.getClassLoader().getResourceAsStream(FILENAME)) { + properties.load(inputStream); + } catch (IOException e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return properties; + } +} diff --git a/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java b/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java index ca238d154..8845f00e1 100644 --- a/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java +++ b/designer-base/src/main/java/com/fr/design/login/utils/DesignerLoginUtils.java @@ -1,6 +1,7 @@ package com.fr.design.login.utils; import com.fr.design.DesignerEnvManager; +import com.fr.design.login.config.DefaultLoginKeys; import com.fr.design.mainframe.toast.DesignerToastMsgUtil; import com.fr.general.CloudCenter; import com.fr.general.CloudCenterConfig; @@ -9,16 +10,12 @@ import com.fr.general.http.HttpToolbox; import com.fr.general.log.MessageFormatter; import com.fr.json.JSONObject; import com.fr.log.FineLoggerFactory; -import com.fr.security.encryption.storage.keys.DefaultKeys; import com.fr.stable.StringUtils; import com.fr.third.org.bouncycastle.util.encoders.Hex; import java.awt.Window; -import java.io.IOException; -import java.io.InputStream; import java.security.SecureRandom; import java.util.HashMap; import java.util.Map; -import java.util.Properties; import javax.crypto.Cipher; import javax.crypto.spec.IvParameterSpec; import javax.crypto.spec.SecretKeySpec; @@ -87,11 +84,12 @@ public class DesignerLoginUtils { jo.put("uid", manager.getDesignerLoginUid()); jo.put("username", manager.getDesignerLoginUsername()); jo.put("source", PRODUCT_FINEREPORT); - - Properties properties = read("/default"); - byte[] iv = randomIv(); - return new String(Hex.encode(iv)) + encrypt(jo.toString(), properties.getProperty("Fine-Designer_Login").getBytes(), iv); + return new String(Hex.encode(iv)) + encrypt( + jo.toString(), + DefaultLoginKeys.getInstance().getKey("Fine-Designer_Login").getBytes(), + iv + ); } private static byte[] randomIv() { @@ -110,15 +108,4 @@ public class DesignerLoginUtils { byte[] resultBytes = cipher.doFinal(content.getBytes()); return new String(Hex.encode(resultBytes)); } - - private static Properties read(String fileName) { - fileName = "com/fr/design/config" + fileName; - Properties properties = new Properties(); - try (InputStream inputStream = DefaultKeys.class.getClassLoader().getResourceAsStream(fileName)){ - properties.load(inputStream); - } catch (IOException e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - return properties; - } } From a919ce7c27804b3ca96bcc6d37424d5df5cc89cd Mon Sep 17 00:00:00 2001 From: Yvan Date: Mon, 1 Aug 2022 18:42:42 +0800 Subject: [PATCH 50/55] =?UTF-8?q?REPORT-77217=20ConnectionProvider-?= =?UTF-8?q?=E4=BF=AE=E6=94=B9=E4=B9=8B=E5=90=8E=E6=95=B0=E6=8D=AE=E8=BF=9E?= =?UTF-8?q?=E6=8E=A5=E4=BF=A1=E6=81=AF=E6=97=A0=E6=B3=95=E4=BF=9D=E5=AD=98?= =?UTF-8?q?=20=E5=90=8C=E6=AD=A510.0=20=E3=80=90=E9=97=AE=E9=A2=98?= =?UTF-8?q?=E5=8E=9F=E5=9B=A0=E3=80=91=E4=BA=A7=E7=94=9F=E5=81=87=E4=BF=9D?= =?UTF-8?q?=E5=AD=98=E7=9A=84=E5=8E=9F=E5=9B=A0=E6=98=AF=EF=BC=8C=E5=9C=A8?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E7=9A=84=E6=97=B6=E5=80=99=E4=BC=9A=E5=88=A4?= =?UTF-8?q?=E6=96=AD=E7=8E=B0=E6=9C=89=E7=9A=84Connection=E4=B8=8E?= =?UTF-8?q?=E4=BB=A5=E5=89=8D=E5=AD=98=E5=82=A8=E7=9A=84Connection?= =?UTF-8?q?=E6=98=AF=E5=90=A6=E6=9C=89=E4=B8=8D=E5=90=8C=EF=BC=8C=E5=A6=82?= =?UTF-8?q?=E6=9E=9C=E4=B8=8D=E5=90=8C=E5=B0=B1=E4=BB=A3=E8=A1=A8=E9=9C=80?= =?UTF-8?q?=E8=A6=81=E6=9B=B4=E6=96=B0=E3=80=82=E5=AE=9E=E9=99=85=E4=B8=8A?= =?UTF-8?q?=E6=8F=92=E4=BB=B6=E4=B8=AD=E7=9A=84Connection=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E7=B1=BB=E6=B2=A1=E6=9C=89=E5=86=99equals=E6=96=B9?= =?UTF-8?q?=E6=B3=95=EF=BC=8C=E7=84=B6=E5=90=8E=E6=96=B0=E6=97=A7Connectio?= =?UTF-8?q?n=E8=A2=AB=E8=AE=A4=E4=B8=BA=E6=98=AF=E7=9B=B8=E5=90=8C?= =?UTF-8?q?=E4=BA=86=EF=BC=8C=E5=B0=B1=E6=B2=A1=E6=9C=89=E8=B5=B0=E5=90=8E?= =?UTF-8?q?=E9=9D=A2=E7=9A=84=E6=9B=B4=E6=96=B0=E9=85=8D=E7=BD=AE=E7=9A=84?= =?UTF-8?q?=E9=80=BB=E8=BE=91=20=E3=80=90=E6=94=B9=E5=8A=A8=E6=96=B9?= =?UTF-8?q?=E6=A1=88=E3=80=91=E6=8B=89rinoux=E3=80=81vito=E3=80=81hugh?= =?UTF-8?q?=E4=B8=80=E8=B5=B7=E6=B2=9F=E9=80=9A=E4=BA=86=E4=B8=8B=E6=96=B9?= =?UTF-8?q?=E6=A1=88=EF=BC=8C=E6=9A=82=E6=97=B6=E4=B8=BB=E4=BB=A3=E7=A0=81?= =?UTF-8?q?=E9=87=8C=E5=81=9A=E4=B8=AA=E5=85=BC=E5=AE=B9=EF=BC=8C=E8=AE=A9?= =?UTF-8?q?=E4=B8=BB=E4=BB=A3=E7=A0=81=E5=86=85=E7=BD=AE=E7=9A=84=E4=B8=A4?= =?UTF-8?q?=E7=A7=8DConnection=E5=8E=BB=E5=88=A4=E6=96=AD=E6=98=AF?= =?UTF-8?q?=E5=90=A6=E8=A6=81=E6=9B=B4=E6=96=B0=EF=BC=8C=E5=85=B6=E4=BD=99?= =?UTF-8?q?=E7=9A=84Connection=EF=BC=88=E6=8F=92=E4=BB=B6Connection?= =?UTF-8?q?=EF=BC=89=E9=83=BD=E5=BF=85=E9=A1=BB=E6=9B=B4=E6=96=B0=20?= =?UTF-8?q?=E3=80=90review=E5=BB=BA=E8=AE=AE=E3=80=91=E5=90=8C=E6=AD=A510.?= =?UTF-8?q?0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/fr/design/data/MapCompareUtils.java | 42 ++++++++++++++++++- .../datapane/connect/ConnectionListPane.java | 26 ++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) diff --git a/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java b/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java index f7492aefc..57fba6178 100644 --- a/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java +++ b/designer-base/src/main/java/com/fr/design/data/MapCompareUtils.java @@ -16,6 +16,8 @@ public final class MapCompareUtils { /** * 对比两个map 查找出相比orig,other中有哪些是新增的、删除的或者被修改的,并分别进行处理 * + * 对比时默认用equals方法来判断是否为 EntryEventKind#UPDATED + * * @param orig 原始map * @param other 参考的新map * @param eventHandler 有区别时的事件处理器 @@ -24,12 +26,29 @@ public final class MapCompareUtils { */ public static void contrastMapEntries(@NotNull Map orig, @NotNull Map other, @NotNull EventHandler eventHandler) { + contrastMapEntries(orig, other, eventHandler, UpdateRule.DEFAULT); + } + + /** + * 对比两个map 查找出相比orig,other中有哪些是新增的、删除的或者被修改的,并分别进行处理 + * + * 对比时用自定义的规则来判断是否为 EntryEventKind#UPDATED + * + * @param orig 原始map + * @param other 参考的新map + * @param eventHandler 有区别时的事件处理器 + * @param updateRule 自定义的Update事件判定规则 + * @param + * @param + */ + public static void contrastMapEntries(@NotNull Map orig, @NotNull Map other, @NotNull EventHandler eventHandler, @NotNull UpdateRule updateRule) { + Map copiedOrig = new LinkedHashMap<>(orig); other.forEach((k, v) -> { V existedV = copiedOrig.remove(k); if (existedV != null) { - if (!v.equals(existedV)) { + if (updateRule.needUpdate(existedV, v)) { eventHandler.on(EntryEventKind.UPDATED, k, v); } } else { @@ -41,10 +60,31 @@ public final class MapCompareUtils { } + /** + * 事件处理器,对应比较后的三种结果的事件处理 + * @param + * @param + */ public interface EventHandler { void on(EntryEventKind entryEventKind, K k, V v); } + /** + * 判定 数据被修改 的判定规则 + * @param + * @param + */ + public interface UpdateRule { + + EntryEventKind eventKind = EntryEventKind.UPDATED; + + UpdateRule DEFAULT = new UpdateRule() {}; + + default boolean needUpdate(V origin, V v) { + return !v.equals(origin); + } + } + public enum EntryEventKind { ADDED, REMOVED, diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 9d18031b0..63a4a47cb 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -178,6 +178,32 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh default: break; } + }, new MapCompareUtils.UpdateRule() { + @Override + public boolean needUpdate(Connection origin, Connection connection) { + return needUpdate0(origin, connection); + } + + /** + * 是否需要更新处理 + * 1. Connection本身equals为false,代表字段修改 + * 2. 非内置的Connection,即插件提供的Connection + * todo 原本一个equals方法就可以搞定,但是插件里面没有实现equals,结果导致不能正确判断,只能主代码里做兼容,很恶心,先记个todo,以后看有没有办法改掉 + * @param origin + * @param connection + * @return + */ + private boolean needUpdate0(Connection origin, Connection connection) { + return !connection.equals(origin) || !isEmbedConnection(connection); + } + + /** + * 是否是主工程里内置的Connection + * @return + */ + private boolean isEmbedConnection(Connection connection) { + return connection instanceof JDBCDatabaseConnection || connection instanceof JNDIDatabaseConnection; + } }); this.validateConnections(addedOrUpdatedConnections); From 51a2660cfedeb10c0d6075e12832147cb667fd78 Mon Sep 17 00:00:00 2001 From: Tommy Date: Mon, 22 Aug 2022 10:21:20 +0800 Subject: [PATCH 51/55] =?UTF-8?q?REPORT-64340=20=E5=88=A0=E9=99=A4?= =?UTF-8?q?=E6=97=A0=E6=95=88=E6=97=A5=E5=BF=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/mainframe/share/collect/ComponentSender.java | 6 ------ 1 file changed, 6 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java index 5043e5fb7..8941cfba8 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/share/collect/ComponentSender.java @@ -17,13 +17,7 @@ public class ComponentSender { private static final String CLOUD_REUSE_URL = "https://cloud.fanruan.com/api/monitor/record_of_reusePlugin/single"; public static boolean send() { - - long start = System.currentTimeMillis(); - String content = ComponentCollector.getInstance().generateTotalInfo(); - - long end = System.currentTimeMillis(); - FineLoggerFactory.getLogger().error("cal time cost {} ms", end - start); return sendInfo(CLOUD_REUSE_URL, content); } From 867a19ab0a0ad631644e9189902d3b3b84cf8655 Mon Sep 17 00:00:00 2001 From: Maximus <49313791+num73@users.noreply.github.com> Date: Wed, 31 Aug 2022 17:13:25 +0800 Subject: [PATCH 52/55] =?UTF-8?q?REPORT-79440=20=E6=89=BE=E4=B8=8D?= =?UTF-8?q?=E5=88=B0=E9=A9=B1=E5=8A=A8=E7=9A=84=E8=AF=9D=E5=8F=AF=E4=BB=A5?= =?UTF-8?q?=E4=BF=9D=E5=AD=98=E6=95=B0=E6=8D=AE=E8=BF=9E=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/data/datapane/connect/ConnectionListPane.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java index 63a4a47cb..1ba3de933 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/connect/ConnectionListPane.java @@ -1,5 +1,6 @@ package com.fr.design.data.datapane.connect; +import com.fr.data.driver.DriverClassNotFoundException; import com.fr.data.impl.Connection; import com.fr.data.impl.JDBCDatabaseConnection; import com.fr.data.impl.JNDIDatabaseConnection; @@ -221,6 +222,8 @@ public class ConnectionListPane extends JListControlPane implements ConnectionSh Connection connection = entry.getValue(); try { DataOperator.getInstance().validateConnectionSettings(connection); + } catch (DriverClassNotFoundException e) { + FineLoggerFactory.getLogger().info(e.getMessage()); } catch (SQLException e) { throw new SQLException(Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Invalid_Config", entry.getKey()) + ", " + e.getMessage(), e.getCause()); } From bca1d09ded35d78d016a8cf369ab32abee7c529d Mon Sep 17 00:00:00 2001 From: "Destiny.Lin" Date: Thu, 8 Sep 2022 10:36:14 +0800 Subject: [PATCH 53/55] =?UTF-8?q?REPORT-79909=20=E8=AE=BE=E8=AE=A1?= =?UTF-8?q?=E5=99=A8=E5=90=AF=E5=8A=A8=E5=A4=B1=E8=B4=A5=EF=BC=8C=E6=9C=89?= =?UTF-8?q?=E6=A8=A1=E6=9D=BF=E5=90=8D=E7=A7=B0=E5=8F=ABWorkBook8888888888?= =?UTF-8?q?8888.cpt=E5=AF=BC=E8=87=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../design/mainframe/JTemplateNameHelper.java | 76 ++++++++++++------- .../mainframe/JTemplateNameHelperTest.java | 23 ++++++ 2 files changed, 73 insertions(+), 26 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java index 22d5985ba..ee5273d8d 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/JTemplateNameHelper.java @@ -3,8 +3,10 @@ package com.fr.design.mainframe; import com.fr.design.file.TemplateTreePane; import com.fr.design.gui.itree.filetree.TemplateFileTree; import com.fr.stable.StringUtils; +import org.jetbrains.annotations.Nullable; import javax.swing.tree.DefaultMutableTreeNode; +import java.math.BigInteger; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -27,19 +29,18 @@ public class JTemplateNameHelper { DefaultMutableTreeNode gen = (DefaultMutableTreeNode) tt.getModel().getRoot(); String[] str = new String[gen.getChildCount()]; - List reportNum = new ArrayList<>(); + List reportNum = new ArrayList<>(); for (int j = 0; j < gen.getChildCount(); j++) { str[j] = gen.getChildAt(j).toString(); //返回文件名中的index(算法中没有再匹配文件后缀了,因为DefaultMutableTreeNode中已经匹配过了) - Integer index = getFileNameIndex(prefix, str[j]); + BigInteger index = getFileNameIndex(prefix, str[j]); if (index != null) { reportNum.add(index); } } Collections.sort(reportNum); - int idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1) + 1 : 1; - - idx = idx + currentIndex; + BigInteger idx = reportNum.size() > 0 ? reportNum.get(reportNum.size() - 1).add(BigInteger.valueOf(1)) : BigInteger.valueOf(1); + idx = idx.add(BigInteger.valueOf(currentIndex)); currentIndex++; return prefix + idx; } @@ -52,35 +53,58 @@ public class JTemplateNameHelper { * @Author Henry.Wang * @Date 2021/4/9 11:13 **/ - private static Integer getFileNameIndex(String prefix, String fileName) { - if (fileName.length() <= prefix.length()) { + @Nullable + private static BigInteger getFileNameIndex(String prefix, String fileName) { + //如果文件名长度小于等于前缀长度或者匹配前缀失败,直接返回就可以了 + if ((prefix.length() >= fileName.length()) || (!StringUtils.equals(prefix, fileName.substring(0, prefix.length())))) { return null; } - char[] chars = new char[fileName.length()]; - int i = 0; - for (; i < fileName.length(); i++) { + BigInteger integer = null; + integer = matchFileNameIndex(prefix, fileName); + return integer; + } + + /** + * 匹配文件名称的数字后缀Index + * @param prefix 前缀 + * @param fileName 文件名称全名 + * @return 返回对应的数字后缀Index + */ + @Nullable + private static BigInteger matchFileNameIndex(String prefix, String fileName) { + StringBuilder result = new StringBuilder(); + for (int i = prefix.length(); i < fileName.length(); i++) { char c = fileName.charAt(i); - //匹配前缀 - if (i < prefix.length()) { - if (c != prefix.charAt(i)) { - return null; - } + if (isDot(c)) { + break; } else { - if (c == '.') { - break; - } else { - //匹配0~9 - if (c < 48 || c > 57) { - return null; - } - chars[i - prefix.length()] = c; + if (isNotNumber(c)) { + return null; } + result.append(c); } } - String s = new String(chars).substring(0, i - prefix.length()); - if (StringUtils.isBlank(s)) { + if (StringUtils.isBlank(result.toString())) { return null; } - return Integer.valueOf(s); + return new BigInteger(result.toString(), 10); + } + + /** + * 是否不属于数字0-9 + * @param c 用于判断的char + * @return 返回对应判断结果 + */ + private static boolean isNotNumber(char c) { + return c < 48 || c > 57; + } + + /** + * 是否属于'.' + * @param c 用于判断的char + * @return 返回对应判断结果 + */ + private static boolean isDot(char c) { + return c == '.'; } } diff --git a/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java b/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java index 032e715f6..6781f3de9 100644 --- a/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java +++ b/designer-base/src/test/java/com/fr/design/mainframe/JTemplateNameHelperTest.java @@ -1,5 +1,6 @@ package com.fr.design.mainframe; +import com.fr.invoke.Reflect; import junit.framework.TestCase; /** @@ -20,4 +21,26 @@ public class JTemplateNameHelperTest extends TestCase { assertEquals("TEST2", name1); } + + public void testGetFileNameIndex() { + //正常情况 + assertEquals("1", Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "WorkBook1").toString()); + + //正常情况 + assertEquals("8888888888", Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "WorkBook8888888888").toString()); + + //正常情况 + assertEquals("88812214128888881231238123123", Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "WorkBook88812214128888881231238123123").toString()); + + //前缀不匹配 + assertNull(Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "Work123", "WorkBook8888888888").get()); + + //前缀为空 + assertNull(Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "", "WorkBook8888888888").get()); + + //文件长度小于前缀 + assertNull(Reflect.on(JTemplateNameHelper.class).call("getFileNameIndex", "WorkBook", "").get()); + + + } } From 46ff873f85a9274492b3d5d18a0e91765c99285f Mon Sep 17 00:00:00 2001 From: lucian Date: Tue, 13 Sep 2022 10:52:28 +0800 Subject: [PATCH 54/55] =?UTF-8?q?REPORT-79999=20=E5=A1=AB=E6=8A=A5-?= =?UTF-8?q?=E5=A1=AB=E6=8A=A5=E5=B1=9E=E6=80=A7=E8=AE=BE=E7=BD=AE-?= =?UTF-8?q?=E5=AF=B9=E8=A1=A8=E7=9A=84=E6=A8=A1=E7=B3=8A=E6=90=9C=E7=B4=A2?= =?UTF-8?q?=E5=8C=B9=E9=85=8D=E4=B8=8D=E7=B2=BE=E7=A1=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../fr/design/data/datapane/ChoosePane.java | 120 ++------- .../datapane/ChoosePaneSupportFormula.java | 2 +- .../design/gui/icombobox/FRTreeComboBox.java | 4 +- .../icombobox/SearchPreTaskTreeComboBox.java | 77 ------ .../icombobox/TableSearchTreeComboBox.java | 228 ++++++++++++++++++ 5 files changed, 248 insertions(+), 183 deletions(-) delete mode 100644 designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java create mode 100644 designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java index 2cb3a9681..4c83667b4 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePane.java @@ -2,17 +2,16 @@ package com.fr.design.data.datapane; import com.fr.base.TableData; import com.fr.common.listener.ManageDsListenerRegisterListener; -import com.fr.concurrent.NamedThreadFactory; import com.fr.data.core.DataCoreUtils; import com.fr.data.core.db.DBUtils; import com.fr.data.core.db.TableProcedure; import com.fr.data.core.db.dialect.Dialect; import com.fr.data.core.db.dialect.DialectFactory; +import com.fr.data.impl.Connection; import com.fr.data.impl.DBTableData; import com.fr.data.operator.DataOperator; import com.fr.design.DesignerEnvManager; import com.fr.design.beans.BasicBeanPane; -import com.fr.design.data.DesignTableDataManager; import com.fr.design.data.datapane.RefreshLabel.Refreshable; import com.fr.design.data.datapane.preview.PreviewLabel; import com.fr.design.data.datapane.preview.PreviewLabel.Previewable; @@ -20,7 +19,7 @@ import com.fr.design.data.datapane.preview.PreviewTablePane; import com.fr.design.data.tabledata.Prepare4DataSourceChange; import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.icombobox.FilterableComboBoxModel; -import com.fr.design.gui.icombobox.SearchPreTaskTreeComboBox; +import com.fr.design.gui.icombobox.TableSearchTreeComboBox; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.gui.icombobox.UIComboBoxEditor; import com.fr.design.gui.icombobox.UIComboBoxRenderer; @@ -41,11 +40,6 @@ import com.fr.stable.StringUtils; import com.fr.workspace.WorkContext; import com.fr.workspace.server.connection.DBConnectAuth; -import java.awt.BorderLayout; -import java.awt.Component; -import java.awt.Dimension; -import java.util.Collections; -import java.util.concurrent.CancellationException; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.JPanel; @@ -59,21 +53,20 @@ import javax.swing.tree.DefaultMutableTreeNode; import javax.swing.tree.DefaultTreeCellRenderer; import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.TreeCellRenderer; -import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; +import java.awt.BorderLayout; +import java.awt.Component; +import java.awt.Dimension; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.util.ArrayList; import java.util.Collection; -import java.util.Enumeration; +import java.util.Collections; import java.util.List; import java.util.Set; -import java.util.concurrent.Callable; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.FutureTask; +import java.util.concurrent.CancellationException; /** * @author zhou @@ -98,41 +91,12 @@ public class ChoosePane extends BasicBeanPane implements Refresha /** * 表名 */ - protected SearchPreTaskTreeComboBox tableNameComboBox; - - private static final ExecutorService SERVICE = Executors.newSingleThreadExecutor(new NamedThreadFactory("ChoosePane")); + protected TableSearchTreeComboBox tableNameComboBox; private SwingWorker populateWorker; private SwingWorker, Void> initWorker; - private PopupMenuListener popupMenuListener = new PopupMenuListener() { - - @Override - public void popupMenuWillBecomeVisible(PopupMenuEvent e) { - FutureTask task = new FutureTask(new Callable() { - @Override - public Void call() throws Exception { - calculateTableDataNames(); - return null; - } - }); - tableNameComboBox.setPreSearchTask(task); - SERVICE.submit(task); - } - - @Override - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { - // Do nothing - } - - @Override - public void popupMenuCanceled(PopupMenuEvent e) { - // Do nothing - } - }; - - private PopupMenuListener listener = new PopupMenuListener() { @Override public void popupMenuCanceled(PopupMenuEvent e) { @@ -182,7 +146,7 @@ public class ChoosePane extends BasicBeanPane implements Refresha schemaBox = new StringUIComboBox(); schemaBox.setEditor(new ComboBoxEditor()); - tableNameComboBox = new SearchPreTaskTreeComboBox(new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer, false); + tableNameComboBox = new TableSearchTreeComboBox(this, new JTree(new DefaultMutableTreeNode()), tableNameTreeRenderer); tableNameComboBox.setEditable(true); tableNameComboBox.setRenderer(listCellRenderer); registerDSChangeListener(); @@ -199,7 +163,6 @@ public class ChoosePane extends BasicBeanPane implements Refresha }); schemaBox.addPopupMenuListener(listener); addFocusListener(); - this.tableNameComboBox.addPopupMenuListener(popupMenuListener); } protected void addDSBoxListener() { @@ -356,7 +319,7 @@ public class ChoosePane extends BasicBeanPane implements Refresha GUICoreUtils.setSelectedItemQuietly(tableNameComboBox, -1); } - protected com.fr.data.impl.Connection getConnection() { + public Connection getConnection() { String selectedDSName = this.getDSName(); if (StringUtils.isEmpty(selectedDSName)) { return null; // peter:选中了当前的零长度的节点,直接返回. @@ -456,56 +419,6 @@ public class ChoosePane extends BasicBeanPane implements Refresha return "choosepane"; } - protected void calculateTableDataNames() { - JTree tree = tableNameComboBox.getTree(); - if (tree == null) { - return; - } - DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot(); - rootTreeNode.removeAllChildren(); - - String selectedDSName = this.getDSName(); - com.fr.data.impl.Connection selectedDatabase = this.getConnection(); - if (selectedDatabase == null) { - return; - } - try { - String schema = StringUtils.isEmpty(this.schemaBox.getSelectedItem()) ? null : this.schemaBox.getSelectedItem(); - TableProcedure[] sqlTableArray = DataCoreUtils.getTables(selectedDatabase, TableProcedure.TABLE, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); - if (sqlTableArray.length > 0) { - ExpandMutableTreeNode tableTreeNode = new ExpandMutableTreeNode(selectedDSName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_Table")); - rootTreeNode.add(tableTreeNode); - for (int i = 0; i < sqlTableArray.length; i++) { - ExpandMutableTreeNode tableChildTreeNode = new ExpandMutableTreeNode(sqlTableArray[i]); - tableTreeNode.add(tableChildTreeNode); - } - } - TableProcedure[] sqlViewArray = DataCoreUtils.getTables(selectedDatabase, TableProcedure.VIEW, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); - if (sqlViewArray.length > 0) { - ExpandMutableTreeNode viewTreeNode = new ExpandMutableTreeNode(selectedDSName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_View")); - rootTreeNode.add(viewTreeNode); - for (int i = 0; i < sqlViewArray.length; i++) { - ExpandMutableTreeNode viewChildTreeNode = new ExpandMutableTreeNode(sqlViewArray[i]); - viewTreeNode.add(viewChildTreeNode); - } - } - ((DefaultTreeModel) tree.getModel()).reload(); - // daniel 展开所有tree - TreeNode root = (TreeNode) tree.getModel().getRoot(); - TreePath parent = new TreePath(root); - TreeNode node = (TreeNode) parent.getLastPathComponent(); - for (Enumeration e = node.children(); e.hasMoreElements(); ) { - TreeNode n = (TreeNode) e.nextElement(); - TreePath path = parent.pathByAddingChild(n); - tree.expandPath(path); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"), - com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Failed"), JOptionPane.ERROR_MESSAGE); - } - } - /** * 创建选中的数据集数据 * @@ -559,22 +472,23 @@ public class ChoosePane extends BasicBeanPane implements Refresha return tableData; } - protected String getDSName() { + public String getDSName() { return this.dsNameComboBox.getSelectedItem(); } + public String getSchema() { + return this.schemaBox.getSelectedItem(); + } + protected void failedToFindTable() { // Do nothing } protected String getTableName() { String tableName = ""; - Object obj = this.tableNameComboBox.getSelectedItemObject(); + Object obj = this.tableNameComboBox.getSelectedItem(); if (obj == null) { - obj = this.tableNameComboBox.getSelectedItem(); - if (obj == null) { - obj = this.tableNameComboBox.getEditor().getItem(); - } + obj = this.tableNameComboBox.getEditor().getItem(); } if (obj instanceof TreePath) { Object tp = ((ExpandMutableTreeNode) ((TreePath) obj).getLastPathComponent()).getUserObject(); diff --git a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java index 14d0431e2..8fc62cd77 100644 --- a/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java +++ b/designer-base/src/main/java/com/fr/design/data/datapane/ChoosePaneSupportFormula.java @@ -83,7 +83,7 @@ public class ChoosePaneSupportFormula extends ChoosePane { * * @return */ - protected String getDSName() { + public String getDSName() { String selectedDSName = null; String item = Utils.objectToString(this.dsNameComboBox.getEditor().getItem()); // 没有选中的列表项 那么看看是不是手输值 diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java index 8fe79d41e..c12239447 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/FRTreeComboBox.java @@ -248,7 +248,7 @@ public class FRTreeComboBox extends UIComboBox { private static TreePopup treePopup; - private static class FRTreeComboBoxUI extends BasicComboBoxUI implements MouseListener{ + protected static class FRTreeComboBoxUI extends BasicComboBoxUI implements MouseListener{ private boolean isRollover = false; public FRTreeComboBoxUI() { @@ -535,7 +535,7 @@ public class FRTreeComboBox extends UIComboBox { public class FrTreeSearchComboBoxEditor extends UIComboBoxEditor implements DocumentListener { private volatile boolean setting = false; private FRTreeComboBox comboBox; - private Object item; + protected Object item; public FrTreeSearchComboBoxEditor(FRTreeComboBox comboBox) { super(); diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java deleted file mode 100644 index 2d936d896..000000000 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/SearchPreTaskTreeComboBox.java +++ /dev/null @@ -1,77 +0,0 @@ -package com.fr.design.gui.icombobox; - -import com.fr.log.FineLoggerFactory; - -import javax.swing.JTree; -import javax.swing.SwingWorker; -import javax.swing.tree.TreeCellRenderer; -import java.util.concurrent.FutureTask; - -/** - * 模糊搜索前需执行完前置任务的TreeComboBox - * @author Lucian.Chen - * @version 10.0 - * Created by Lucian.Chen on 2021/4/14 - */ -public class SearchPreTaskTreeComboBox extends FRTreeComboBox { - - /** - * 模糊搜索前任务 - */ - private FutureTask preSearchTask; - - public SearchPreTaskTreeComboBox(JTree tree, TreeCellRenderer renderer, boolean editable) { - super(tree, renderer, editable); - } - - public FutureTask getPreSearchTask() { - return preSearchTask; - } - - public void setPreSearchTask(FutureTask preSearchTask) { - this.preSearchTask = preSearchTask; - } - - protected UIComboBoxEditor createEditor() { - return new SearchPreTaskComboBoxEditor(this); - } - - private class SearchPreTaskComboBoxEditor extends FrTreeSearchComboBoxEditor { - - public SearchPreTaskComboBoxEditor(FRTreeComboBox comboBox) { - super(comboBox); - } - - protected void changeHandler() { - if (isSetting()) { - return; - } - setPopupVisible(true); - new SwingWorker() { - @Override - protected Void doInBackground() { - FutureTask task = getPreSearchTask(); - try { - // 确保模糊搜索前任务执行完成后,再进行模糊搜索 - if (task != null) { - task.get(); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - if (task != null) { - // 任务执行后置空,否则会被别的操作重复触发 - setPreSearchTask(null); - } - return null; - } - - @Override - protected void done() { - // 模糊搜索 - search(); - } - }.execute(); - } - } -} diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java new file mode 100644 index 000000000..7198eeef0 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java @@ -0,0 +1,228 @@ +package com.fr.design.gui.icombobox; + +import com.fr.data.core.DataCoreUtils; +import com.fr.data.core.db.TableProcedure; +import com.fr.data.impl.Connection; +import com.fr.design.DesignerEnvManager; +import com.fr.design.data.datapane.ChoosePane; +import com.fr.design.dialog.FineJOptionPane; +import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; +import com.fr.design.mainframe.DesignerContext; +import com.fr.log.FineLoggerFactory; +import com.fr.stable.ArrayUtils; +import com.fr.stable.Filter; +import com.fr.stable.StringUtils; + +import javax.swing.JOptionPane; +import javax.swing.JTree; +import javax.swing.SwingWorker; +import javax.swing.event.PopupMenuEvent; +import javax.swing.event.PopupMenuListener; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.util.Enumeration; + +/** + * 实现模糊搜索表名的FRTreeComboBox + * FRTreeComboBox:搜索后滚动到首个匹配节点 + * SearchFRTreeComboBox:显示所有匹配的节点 + * + * @author Lucian.Chen + * @version 10.0 + * Created by Lucian.Chen on 2021/4/14 + */ +public class TableSearchTreeComboBox extends FRTreeComboBox { + // 持有父容器,需要实时获取其他组件值 + private final ChoosePane parent; + + public TableSearchTreeComboBox(ChoosePane parent, JTree tree, TreeCellRenderer renderer) { + super(tree, renderer); + this.parent = parent; + initPopupListener(); + } + + protected UIComboBoxEditor createEditor() { + return new TableSearchComboBoxEditor(this); + } + + @Override + protected String pathToString(TreePath path) { + Object obj = ((DefaultMutableTreeNode) path.getLastPathComponent()).getUserObject(); + if (obj instanceof TableProcedure) { + return ((TableProcedure) obj).getName(); + } + return super.pathToString(path); + } + + @Override + public void setSelectedItemString(String _name) { + super.setSelectedItemString(_name); + // 会因为连续两次选中的值一致,导致未触发编辑框联动 + this.getEditor().setItem(_name); + } + + /** + * 执行模糊搜索 + */ + private void searchExecute() { + UIComboBoxEditor searchEditor = (UIComboBoxEditor) this.getEditor(); + new SwingWorker() { + @Override + protected Void doInBackground() { + processTableDataNames( + parent.getDSName(), + parent.getConnection(), + parent.getSchema(), + createFilter((String) searchEditor.getItem())); + return null; + } + + @Override + protected void done() { + expandTree(); + // 输入框获取焦点 + searchEditor.getEditorComponent().requestFocus(); + } + }.execute(); + } + + private TableNameFilter createFilter(String text) { + return StringUtils.isEmpty(text) ? EMPTY_FILTER : new TableNameFilter(text); + } + + /** + * 查询数据库表,并构建节点目录 + * + * @param databaseName 数据库名 + * @param connection 数据连接 + * @param schema 模式 + * @param filter 模糊搜索过滤器 + */ + private void processTableDataNames(String databaseName, Connection connection, String schema, TableNameFilter filter) { + if (tree == null) { + return; + } + DefaultMutableTreeNode rootTreeNode = (DefaultMutableTreeNode) tree.getModel().getRoot(); + rootTreeNode.removeAllChildren(); + + if (connection == null) { + return; + } + try { + schema = StringUtils.isEmpty(schema) ? null : schema; + TableProcedure[] sqlTableArray = DataCoreUtils.getTables(connection, TableProcedure.TABLE, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); + if (ArrayUtils.isNotEmpty(sqlTableArray)) { + ExpandMutableTreeNode tableTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_Table")); + rootTreeNode.add(tableTreeNode); + addArrayNode(tableTreeNode, sqlTableArray, filter); + } + TableProcedure[] sqlViewArray = DataCoreUtils.getTables(connection, TableProcedure.VIEW, schema, DesignerEnvManager.getEnvManager().isOracleSystemSpace()); + if (ArrayUtils.isNotEmpty(sqlViewArray)) { + ExpandMutableTreeNode viewTreeNode = new ExpandMutableTreeNode(databaseName + "-" + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_SQL_View")); + rootTreeNode.add(viewTreeNode); + addArrayNode(viewTreeNode, sqlViewArray, filter); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + FineJOptionPane.showMessageDialog(DesignerContext.getDesignerFrame(), com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Database_Connection_Failed"), + com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Failed"), JOptionPane.ERROR_MESSAGE); + } + } + + private void addArrayNode(ExpandMutableTreeNode rootNode, TableProcedure[] sqlArray, TableNameFilter filter) { + if (sqlArray != null) { + for (TableProcedure procedure : sqlArray) { + if (filter.accept(procedure)) { + ExpandMutableTreeNode viewChildTreeNode = new ExpandMutableTreeNode(procedure); + rootNode.add(viewChildTreeNode); + } + } + } + } + + /** + * 展开节点 + */ + private void expandTree() { + ((DefaultTreeModel) tree.getModel()).reload(); + // daniel 展开所有tree + TreeNode root = (TreeNode) tree.getModel().getRoot(); + TreePath parent = new TreePath(root); + TreeNode node = (TreeNode) parent.getLastPathComponent(); + for (Enumeration e = node.children(); e.hasMoreElements(); ) { + TreeNode n = (TreeNode) e.nextElement(); + TreePath path = parent.pathByAddingChild(n); + tree.expandPath(path); + } + } + + /** + * 表名模糊搜索实现 + */ + private static class TableNameFilter implements Filter { + private String searchFilter; + + public TableNameFilter() { + } + + public TableNameFilter(String searchFilter) { + this.searchFilter = searchFilter.toLowerCase().trim(); + } + + // 表名匹配 + @Override + public boolean accept(TableProcedure procedure) { + return procedure.getName().toLowerCase().contains(searchFilter); + } + } + + private static final TableNameFilter EMPTY_FILTER = new TableNameFilter() { + public boolean accept(TableProcedure procedure) { + return true; + } + }; + + private void initPopupListener() { + // 点击下拉时触发模糊搜索 + this.addPopupMenuListener(new PopupMenuListener() { + + @Override + public void popupMenuWillBecomeVisible(PopupMenuEvent e) { + searchExecute(); + } + + @Override + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { + + } + + @Override + public void popupMenuCanceled(PopupMenuEvent e) { + + } + }); + } + + /** + * 重写输入框编辑器,实现输入框模糊搜索逻辑 + */ + private class TableSearchComboBoxEditor extends FrTreeSearchComboBoxEditor { + + public TableSearchComboBoxEditor(FRTreeComboBox comboBox) { + super(comboBox); + } + + @Override + protected void changeHandler() { + if (isSetting()) { + return; + } + setPopupVisible(true); + this.item = textField.getText(); + searchExecute(); + } + } +} From e20b3a89cbd6dd4c9a1c222695822c78ece6aa1c Mon Sep 17 00:00:00 2001 From: lucian Date: Wed, 14 Sep 2022 16:04:36 +0800 Subject: [PATCH 55/55] =?UTF-8?q?REPORT-80276=20=E5=A1=AB=E6=8A=A5-?= =?UTF-8?q?=E5=A1=AB=E6=8A=A5=E5=B1=9E=E6=80=A7=E8=AE=BE=E7=BD=AE-?= =?UTF-8?q?=E6=95=B0=E6=8D=AE=E8=A1=A8=E6=90=9C=E7=B4=A2=E6=97=B6=E6=A6=82?= =?UTF-8?q?=E7=8E=87=E5=87=BA=E7=8E=B0=E5=A4=9A=E4=B8=AA=E9=87=8D=E5=A4=8D?= =?UTF-8?q?=E7=9A=84=E6=90=9C=E7=B4=A2=E7=BB=93=E6=9E=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gui/icombobox/TableSearchTreeComboBox.java | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java b/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java index 7198eeef0..916cd3cf6 100644 --- a/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java +++ b/designer-base/src/main/java/com/fr/design/gui/icombobox/TableSearchTreeComboBox.java @@ -1,5 +1,6 @@ package com.fr.design.gui.icombobox; +import com.fr.concurrent.NamedThreadFactory; import com.fr.data.core.DataCoreUtils; import com.fr.data.core.db.TableProcedure; import com.fr.data.impl.Connection; @@ -9,6 +10,7 @@ import com.fr.design.dialog.FineJOptionPane; import com.fr.design.gui.itree.refreshabletree.ExpandMutableTreeNode; import com.fr.design.mainframe.DesignerContext; import com.fr.log.FineLoggerFactory; +import com.fr.module.ModuleContext; import com.fr.stable.ArrayUtils; import com.fr.stable.Filter; import com.fr.stable.StringUtils; @@ -24,6 +26,7 @@ import javax.swing.tree.TreeCellRenderer; import javax.swing.tree.TreeNode; import javax.swing.tree.TreePath; import java.util.Enumeration; +import java.util.concurrent.ExecutorService; /** * 实现模糊搜索表名的FRTreeComboBox @@ -37,6 +40,10 @@ import java.util.Enumeration; public class TableSearchTreeComboBox extends FRTreeComboBox { // 持有父容器,需要实时获取其他组件值 private final ChoosePane parent; + /** + * 保证模糊搜索的原子性操作 + */ + private final ExecutorService singleExecutor = ModuleContext.getExecutor().newSingleThreadScheduledExecutor(new NamedThreadFactory("TableSearchTreeComboBox")); public TableSearchTreeComboBox(ChoosePane parent, JTree tree, TreeCellRenderer renderer) { super(tree, renderer); @@ -69,14 +76,15 @@ public class TableSearchTreeComboBox extends FRTreeComboBox { */ private void searchExecute() { UIComboBoxEditor searchEditor = (UIComboBoxEditor) this.getEditor(); - new SwingWorker() { + String searchText = (String) searchEditor.getItem(); + singleExecutor.execute(new SwingWorker() { @Override protected Void doInBackground() { processTableDataNames( parent.getDSName(), parent.getConnection(), parent.getSchema(), - createFilter((String) searchEditor.getItem())); + createFilter(searchText)); return null; } @@ -86,7 +94,7 @@ public class TableSearchTreeComboBox extends FRTreeComboBox { // 输入框获取焦点 searchEditor.getEditorComponent().requestFocus(); } - }.execute(); + }); } private TableNameFilter createFilter(String text) {