diff --git a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
index 6ebd349cb..cb8634c00 100644
--- a/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
+++ b/designer-base/src/main/java/com/fr/design/DesignerEnvManager.java
@@ -19,6 +19,7 @@ import com.fr.design.mainframe.vcs.VcsConfigManager;
import com.fr.design.update.push.DesignerPushUpdateConfigManager;
import com.fr.design.style.color.ColorSelectConfigManager;
import com.fr.design.utils.DesignUtils;
+import com.fr.design.utils.DesignerPort;
import com.fr.file.FILEFactory;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRLogFormatter;
@@ -1545,7 +1546,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
readDesignerPushUpdateAttr(reader);
} else if (name.equals(vcsConfigManager.XML_TAG)) {
readVcsAttr(reader);
- } else {
+ } else if (DesignerPort.XML_TAG.equals(name)) {
+ readDesignerPort(reader);
+ }
+ else {
readLayout(reader, name);
}
}
@@ -1736,6 +1740,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
reader.readXMLObject(vcsConfigManager);
}
+ public void readDesignerPort(XMLableReader reader) {
+ reader.readXMLObject(DesignerPort.getInstance());
+ }
+
/**
* Write XML.
* The method will be invoked when save data to XML file.
@@ -1761,6 +1769,7 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
writeOpenDebug(writer);
writeDesignerPushUpdateAttr(writer);
writeVcsAttr(writer);
+ writeDesignerPort(writer);
writer.end();
}
@@ -2010,6 +2019,10 @@ public class DesignerEnvManager implements XMLReadable, XMLWriter {
this.vcsConfigManager.writeXML(writer);
}
+ private void writeDesignerPort(XMLPrintWriter writer) {
+ DesignerPort.getInstance().writeXML(writer);
+ }
+
public VcsConfigManager getVcsConfigManager() {
return vcsConfigManager;
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 c1c11553f..cfb488694 100644
--- a/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
+++ b/designer-base/src/main/java/com/fr/design/EnvChangeEntrance.java
@@ -13,6 +13,7 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.DesignUtils;
import com.fr.env.EnvListPane;
+import com.fr.exit.DesignerExiter;
import com.fr.general.GeneralContext;
import com.fr.license.exception.RegistEditionException;
import com.fr.log.FineLoggerFactory;
@@ -243,14 +244,13 @@ public class EnvChangeEntrance {
@Override
public void doOk() {
if (!envListOkAction(envListPane, PopTipStrategy.NOW)) {
- System.exit(0);
+ DesignerExiter.getInstance().execute();
}
}
@Override
public void doCancel() {
- System.exit(0);
- }
+ DesignerExiter.getInstance().execute(); }
});
envListDialog.setVisible(true);
}
diff --git a/designer-base/src/main/java/com/fr/design/RestartHelper.java b/designer-base/src/main/java/com/fr/design/RestartHelper.java
index cdb4fc532..596257d70 100644
--- a/designer-base/src/main/java/com/fr/design/RestartHelper.java
+++ b/designer-base/src/main/java/com/fr/design/RestartHelper.java
@@ -2,6 +2,7 @@ package com.fr.design;
import com.fr.design.mainframe.DesignerContext;
import com.fr.design.os.impl.RestartAction;
+import com.fr.exit.DesignerExiter;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralUtils;
import com.fr.log.FineLoggerFactory;
@@ -152,7 +153,7 @@ public class RestartHelper {
} finally {
WorkContext.getCurrent().close();
frame.dispose();
- System.exit(0);
+ DesignerExiter.getInstance().execute();
}
}
diff --git a/designer-base/src/main/java/com/fr/design/dialog/ErrorDialog.java b/designer-base/src/main/java/com/fr/design/dialog/ErrorDialog.java
new file mode 100644
index 000000000..21042a57a
--- /dev/null
+++ b/designer-base/src/main/java/com/fr/design/dialog/ErrorDialog.java
@@ -0,0 +1,94 @@
+package com.fr.design.dialog;
+
+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.utils.gui.GUICoreUtils;
+import com.fr.general.FRFont;
+
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * @author hades
+ * @version 10.0
+ * Created by hades on 2020/1/8
+ */
+public abstract class ErrorDialog extends JDialog implements ActionListener {
+
+ private UIButton okButton;
+ private UIButton restartButton;
+
+
+ public ErrorDialog(Frame parent, String message, String title, String detail) {
+ super(parent, true);
+ JPanel northPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
+ JPanel messagePane = FRGUIPaneFactory.createVerticalFlowLayout_S_Pane(true);
+ UILabel boldFontLabel = new UILabel(message);
+ UILabel label = new UILabel(Toolkit.i18nText("Fine-Design_Send_Report_To_Us"));
+ Font font = FRFont.getInstance("Dialog", Font.BOLD, 20);
+ boldFontLabel.setFont(font);
+ messagePane.add(boldFontLabel);
+ messagePane.add(label);
+ northPane.add(messagePane);
+
+ JTextArea area = new JTextArea(detail);
+ area.setPreferredSize(new Dimension(400, 100));
+ area.setEnabled(true);
+ area.setEditable(false);
+ JPanel centerPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
+ UILabel detailLabel = new UILabel(Toolkit.i18nText("Fine-Design_Problem_Detail_Message"));
+ centerPane.add(detailLabel, BorderLayout.NORTH);
+ centerPane.add(area, BorderLayout.CENTER);
+
+ JPanel southPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
+ JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
+ JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0));
+ okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Ok"));
+ okButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ okEvent();
+ }
+ });
+ buttonPane.add(okButton);
+ restartButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Restart"));
+ restartButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ restartEvent();
+ }
+ });
+ buttonPane.add(restartButton);
+ controlPane.add(buttonPane, BorderLayout.EAST);
+ southPane.add(controlPane);
+
+ this.setTitle(title);
+ this.setResizable(false);
+ this.add(northPane, BorderLayout.NORTH);
+ this.add(centerPane, BorderLayout.CENTER);
+ this.add(southPane, BorderLayout.SOUTH);
+ this.setSize(new Dimension(600, 500));
+ GUICoreUtils.centerWindow(this);
+
+ }
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ dispose();
+ }
+
+ protected abstract void okEvent();
+
+ protected abstract void restartEvent();
+
+}
diff --git a/designer-base/src/main/java/com/fr/design/dialog/TipDialog.java b/designer-base/src/main/java/com/fr/design/dialog/TipDialog.java
new file mode 100644
index 000000000..14997f868
--- /dev/null
+++ b/designer-base/src/main/java/com/fr/design/dialog/TipDialog.java
@@ -0,0 +1,92 @@
+package com.fr.design.dialog;
+
+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.utils.gui.GUICoreUtils;
+import com.fr.general.IOUtils;
+
+import javax.swing.JDialog;
+import javax.swing.JPanel;
+import javax.swing.JTextArea;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+/**
+ * @author hades
+ * @version 10.0
+ * Created by hades on 2020/1/8
+ */
+public abstract class TipDialog extends JDialog implements ActionListener {
+
+ private UIButton endButton;
+ private UIButton cancelButton;
+
+ public TipDialog(Frame parent, String type) {
+ super(parent, true);
+ JPanel northPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
+ JPanel iconPane = new JPanel();
+ UILabel iconLabel = new UILabel();
+ iconLabel.setIcon(IOUtils.readIcon("com/fr/design/images/error/error.png"));
+ iconPane.add(iconLabel);
+ iconPane.setPreferredSize(new Dimension(100, 100));
+ JPanel tipPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
+ UILabel tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Last_Designer_Process_Not_Exist"));
+ tipPane.add(tipLabel);
+ northPane.add(iconPane, BorderLayout.WEST);
+ northPane.add(tipPane, BorderLayout.CENTER);
+
+ JTextArea area = new JTextArea(type);
+ area.setPreferredSize(new Dimension(400, 100));
+ area.setEnabled(true);
+ area.setEditable(false);
+ JPanel centerPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
+ centerPane.add(area);
+
+ JPanel southPane = FRGUIPaneFactory.createBorderLayout_L_Pane();
+ JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
+ JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT, 10, 0));
+ endButton = new UIButton(Toolkit.i18nText("Fine-Design_End_Occupied_Process"));
+ endButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ endEvent();
+ }
+ });
+ buttonPane.add(endButton);
+ cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel"));
+ cancelButton.addActionListener(new ActionListener() {
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ cancelEvent();
+ }
+ });
+ buttonPane.add(cancelButton);
+ controlPane.add(buttonPane, BorderLayout.EAST);
+ southPane.add(controlPane);
+
+ this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Error_Tittle"));
+ this.setResizable(false);
+ this.add(northPane, BorderLayout.NORTH);
+ this.add(centerPane, BorderLayout.CENTER);
+ this.add(southPane, BorderLayout.SOUTH);
+ this.setSize(new Dimension(600, 500));
+ GUICoreUtils.centerWindow(this);
+
+ }
+
+ protected abstract void endEvent();
+
+ protected abstract void cancelEvent();
+
+ @Override
+ public void actionPerformed(ActionEvent e) {
+ dispose();
+ }
+
+}
diff --git a/designer-base/src/main/java/com/fr/design/icon/BorderIcon.java b/designer-base/src/main/java/com/fr/design/icon/BorderIcon.java
index 3afc423be..8250cd702 100644
--- a/designer-base/src/main/java/com/fr/design/icon/BorderIcon.java
+++ b/designer-base/src/main/java/com/fr/design/icon/BorderIcon.java
@@ -85,9 +85,9 @@ public class BorderIcon implements Icon {
cellBorderStyle.getBottomColor());
drawLine(gr, x1, y1, x1, y2, cellBorderStyle.getLeftStyle(),
cellBorderStyle.getLeftColor());
- drawLine(gr, defaultWidth / 2, y1, defaultWidth / 2, y2,
+ drawLine(gr, defaultWidth / 2.0, y1, defaultWidth / 2.0, y2,
cellBorderStyle.getVerticalStyle(), cellBorderStyle.getVerticalColor());
- drawLine(gr, x1, defaultHeight / 2, x2, defaultHeight / 2,
+ drawLine(gr, x1, defaultHeight / 2.0, x2, defaultHeight / 2.0,
cellBorderStyle.getHorizontalStyle(), cellBorderStyle.getHorizontalColor());
}
diff --git a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
index 082775a62..718a9f50c 100644
--- a/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
+++ b/designer-base/src/main/java/com/fr/design/mainframe/DesignerFrame.java
@@ -43,6 +43,7 @@ import com.fr.design.os.impl.SupportOSImpl;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.event.EventDispatcher;
import com.fr.exception.DecryptTemplateException;
+import com.fr.exit.DesignerExiter;
import com.fr.file.FILE;
import com.fr.file.FILEFactory;
import com.fr.file.FileFILE;
@@ -1159,8 +1160,7 @@ public class DesignerFrame extends JFrame implements JTemplateActionListener, Ta
this.dispose();
this.ad.shutDown();
-
- System.exit(0);
+ DesignerExiter.getInstance().execute();
}
// harry:添加程序外拖拽文件进来打开的功能
diff --git a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java
index 8d32e6e0e..d8f5d0116 100644
--- a/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java
+++ b/designer-base/src/main/java/com/fr/design/utils/DesignUtils.java
@@ -8,6 +8,7 @@ import com.fr.design.ExtraDesignClassManager;
import com.fr.design.fun.DesignerEnvProcessor;
import com.fr.design.gui.UILookAndFeel;
import com.fr.design.mainframe.DesignerContext;
+import com.fr.exit.DesignerExiter;
import com.fr.file.FileFILE;
import com.fr.general.ComparatorUtils;
import com.fr.general.FRFont;
@@ -29,7 +30,9 @@ import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
+import java.io.InputStream;
import java.io.InputStreamReader;
+import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.ServerSocket;
@@ -38,15 +41,21 @@ import java.net.URI;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.Locale;
+import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
/**
* Some util method of Designer
*/
public class DesignUtils {
- private static int port = DesignerPort.MESSAGE_PORT;
+ private static int port = DesignerPort.getInstance().getMessagePort();
+
+ private static boolean started = false;
private DesignUtils() {
}
@@ -61,15 +70,54 @@ public class DesignUtils {
}
/**
- * 通过端口是否被占用判断设计器有没有启动
- * s
+ * 判断设计器有没有启动
*
* @return 启动了返回true
*/
public static boolean isStarted() {
- try (Socket socket = new Socket("localhost", port)) {
+ return started;
+ }
+
+
+ /**
+ * 判断设计器端口是否被其他程序占用
+ * 尝试去通信,无回应就是其他程序占用端口,否则需要继续判断是否为设计器进程未关闭
+ * @return
+ */
+ public static boolean isPortOccupied() {
+ ExecutorService executor = null;
+ Future future = null;
+ try (Socket socket = new Socket("localhost", port);
+ BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream(), StandardCharsets.UTF_8));
+ PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8)))) {
+ writer.println("check");
+ writer.flush();
+ executor = Executors.newSingleThreadExecutor();
+ future = executor.submit(new Callable() {
+ @Override
+ public String call() throws Exception {
+ String line;
+ while ((line = reader.readLine()) != null) {
+ if ("response".equals(line)) {
+ // 正常通信 上一次设计器进程未关闭
+ started = true;
+ return line;
+ }
+ }
+ return StringUtils.EMPTY;
+ }
+ });
+ future.get(2, TimeUnit.SECONDS);
+ return false;
+ } catch (TimeoutException e) {
+ future.cancel(true);
return true;
- } catch (Exception ignored) {
+ } catch (Exception ignore) {
+
+ } finally {
+ if (executor != null) {
+ executor.shutdownNow();
+ }
}
return false;
}
@@ -79,15 +127,12 @@ public class DesignUtils {
*
* @param lines 命令行
*/
- public static void clientSend(String[] lines) {
+ public static void clientSend(String[] lines, Socket socket) {
if (lines == null || lines.length == 0) {
return;
}
- Socket socket = null;
PrintWriter writer = null;
try {
- socket = new Socket("localhost", port);
-
writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(socket.getOutputStream(), StandardCharsets.UTF_8)));
for (int i = 0; i < lines.length; i++) {
writer.println(lines[i]);
@@ -96,19 +141,23 @@ public class DesignUtils {
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
} finally {
- try {
- if (writer != null) {
- writer.close();
- }
- if (socket != null) {
- socket.close();
- }
- } catch (IOException e) {
- FineLoggerFactory.getLogger().error(e.getMessage(), e);
+ if (writer != null) {
+ writer.close();
}
}
}
+ public static void clientSend(String[] lines) {
+ if (lines == null || lines.length == 0) {
+ return;
+ }
+ try (Socket socket = new Socket("localhost", port)) {
+ clientSend(lines, socket);
+ } catch (Exception ignore) {
+
+ }
+ }
+
/**
* 建立监听端口
*
@@ -138,7 +187,11 @@ public class DesignUtils {
if (line.startsWith("demo")) {
DesignerEnvManager.getEnvManager().setCurrentEnv2Default();
ServerStarter.browserDemoURL();
- } else if (StringUtils.isNotEmpty(line)) {
+ } else if ("check".equals(line)) {
+ clientSend(new String[] {"response"}, socket);
+ } else if ("end".equals(line)) {
+ DesignerExiter.getInstance().execute(); }
+ else if (StringUtils.isNotEmpty(line)) {
File f = new File(line);
String path = f.getAbsolutePath();
@@ -165,6 +218,14 @@ public class DesignUtils {
}
+ public static void responseToClient(Socket socket) {
+ try (OutputStream outputStream = socket.getOutputStream()) {
+ outputStream.write("reponse".getBytes(StandardCharsets.UTF_8));
+ outputStream.flush();
+ } catch (IOException ignore) {
+ }
+ }
+
/**
* 弹出对话框,显示报错
*
diff --git a/designer-base/src/main/java/com/fr/design/utils/DesignerPort.java b/designer-base/src/main/java/com/fr/design/utils/DesignerPort.java
index 7c082800e..46bdd52a8 100644
--- a/designer-base/src/main/java/com/fr/design/utils/DesignerPort.java
+++ b/designer-base/src/main/java/com/fr/design/utils/DesignerPort.java
@@ -1,26 +1,95 @@
package com.fr.design.utils;
+import com.fr.design.i18n.Toolkit;
+import com.fr.general.ComparatorUtils;
+import com.fr.stable.xml.XMLPrintWriter;
+import com.fr.stable.xml.XMLReadable;
+import com.fr.stable.xml.XMLWriter;
+import com.fr.stable.xml.XMLableReader;
+
+import javax.swing.JOptionPane;
+
/**
* 为的就是能替换 DesignPort.class 实现多开,因此避免编译器常量编译展开优化
*/
-public class DesignerPort {
+public class DesignerPort implements XMLReadable, XMLWriter {
+
+ public static final String XML_TAG = "DesignerPort";
+ private static final int MIN_PORT = 1024;
+ private static final int MAX_PORT = 65536;
+
+ public static final DesignerPort INSTANCE = new DesignerPort();
+
+ public static DesignerPort getInstance() {
+ return INSTANCE;
+ }
+
private DesignerPort() {
}
/**
- * 设计器端口,避免编译期常量优化展开
+ * 设计器端口
*/
- public static final int MESSAGE_PORT = getMessagePort();
+ private int messagePort = 51462;
+
/**
- * 设计器端口,避免编译期常量优化展开
+ * 设计器端口,debug模式下
*/
- public static final int DEBUG_MESSAGE_PORT = getDebugMessagePort();
+ private int debugMessagePort = 51463;
+
+ public int getMessagePort() {
+ return messagePort;
+ }
- private static int getMessagePort() {
- return 51462;
+ public int getDebugMessagePort() {
+ return debugMessagePort;
}
- private static int getDebugMessagePort() {
- return 51463;
+ public void setMessagePort(int messagePort) {
+ this.messagePort = messagePort;
}
+
+ public void setDebugMessagePort(int debugMessagePort) {
+ this.debugMessagePort = debugMessagePort;
+ }
+
+ @Override
+ public void readXML(XMLableReader reader) {
+ if (reader.isAttr()) {
+ this.setMessagePort(reader.getAttrAsInt("messagePort", 51462));
+ this.setDebugMessagePort(reader.getAttrAsInt("debugMessagePort", 51463));
+ }
+ }
+
+ @Override
+ public void writeXML(XMLPrintWriter writer) {
+ writer.startTAG(XML_TAG);
+ writer.attr("messagePort", this.messagePort);
+ writer.attr("debugMessagePort", this.debugMessagePort);
+ writer.end();
+ }
+
+ public int resetPort() {
+ String port = JOptionPane.showInputDialog(null,
+ Toolkit.i18nText("Fine-Design_Modify_Designer_Port_Tip"),
+ Toolkit.i18nText("Fine-Design_Modify_Designer_Port"), JOptionPane.INFORMATION_MESSAGE);
+ int value;
+ try {
+ value = Integer.parseInt(port);
+ } catch (NumberFormatException e) {
+ JOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Modify_Designer_Port_Not_Number_Tip"));
+ value = resetPort();
+ }
+ if (value < MIN_PORT || value > MAX_PORT) {
+ JOptionPane.showMessageDialog(null, Toolkit.i18nText("Fine-Design_Modify_Designer_Port_Out_Of_Range_Tip"));
+ value = resetPort();
+ }
+ if (ComparatorUtils.equals("true", System.getProperty("debug"))) {
+ setDebugMessagePort(value);
+ } else {
+ setMessagePort(value);
+ }
+ return value;
+ }
+
}
diff --git a/designer-base/src/main/java/com/fr/exit/DesignerExiter.java b/designer-base/src/main/java/com/fr/exit/DesignerExiter.java
new file mode 100644
index 000000000..8264d8db9
--- /dev/null
+++ b/designer-base/src/main/java/com/fr/exit/DesignerExiter.java
@@ -0,0 +1,30 @@
+package com.fr.exit;
+
+import com.fr.process.engine.core.FineProcessContext;
+import com.fr.process.engine.core.FineProcessEngineEvent;
+import com.fr.stable.StableUtils;
+
+
+/**
+ * @author hades
+ * @version 10.0
+ * Created by hades on 2020/2/12
+ */
+public class DesignerExiter {
+
+ public static final DesignerExiter INSTANCE = new DesignerExiter();
+
+ private static final String DOT = ".";
+
+ public static DesignerExiter getInstance() {
+ return INSTANCE;
+ }
+
+ public void execute() {
+ if (FineProcessContext.getParentPipe() == null && DOT.equals(StableUtils.getInstallHome())) {
+ System.exit(0);
+ } else {
+ FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY);
+ }
+ }
+}
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 833faaef7..a36c29822 100644
--- a/designer-base/src/main/java/com/fr/start/BaseDesigner.java
+++ b/designer-base/src/main/java/com/fr/start/BaseDesigner.java
@@ -14,11 +14,11 @@ import com.fr.design.mainframe.DesignerContext;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.toolbar.ToolBarMenuDock;
import com.fr.design.ui.util.UIUtil;
-import com.fr.design.utils.DesignUtils;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.event.Null;
+import com.fr.exit.DesignerExiter;
import com.fr.file.FILE;
import com.fr.file.FILEFactory;
import com.fr.file.FileFILE;
@@ -47,8 +47,6 @@ public abstract class BaseDesigner extends ToolBarMenuDock {
private void init() {
prepare();
- // 初始化look and feel.这个在预加载之前执行是因为lookAndFeel里的东西,预加载时也要用到
- DesignUtils.initLookAndFeel();
// 初始化Log Handler
DesignerEnvManager.loadLogSetting();
createDesignerFrame();
@@ -137,7 +135,7 @@ public abstract class BaseDesigner extends ToolBarMenuDock {
if (!isException) {
showDesignerFrame(true);
} else {
- System.exit(0);
+ DesignerExiter.getInstance().execute();
}
}
}
diff --git a/designer-base/src/main/resources/com/fr/design/images/error/error.png b/designer-base/src/main/resources/com/fr/design/images/error/error.png
new file mode 100644
index 000000000..fd4a46509
Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/error/error.png differ
diff --git a/designer-base/src/test/java/com/fr/design/utils/DesignUtilsTest.java b/designer-base/src/test/java/com/fr/design/utils/DesignUtilsTest.java
new file mode 100644
index 000000000..9db729a97
--- /dev/null
+++ b/designer-base/src/test/java/com/fr/design/utils/DesignUtilsTest.java
@@ -0,0 +1,32 @@
+package com.fr.design.utils;
+
+
+import com.fr.general.ComparatorUtils;
+import junit.framework.TestCase;
+import org.junit.Test;
+
+import java.net.ServerSocket;
+
+/**
+ * @author hades
+ * @version 10.0
+ * Created by hades on 2020/1/10
+ */
+public class DesignUtilsTest extends TestCase {
+
+ @Test
+ public void testIsPortOccupied() {
+ assertFalse(DesignUtils.isPortOccupied());
+ try {
+ if (ComparatorUtils.equals("true", System.getProperty("debug"))) {
+ new ServerSocket(DesignerPort.getInstance().getDebugMessagePort());
+ } else {
+ new ServerSocket(DesignerPort.getInstance().getMessagePort());
+ }
+ } catch (Exception ignore) {
+ System.exit(0);
+ }
+ assertTrue(DesignUtils.isPortOccupied());
+ }
+
+}
\ No newline at end of file
diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java b/designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java
new file mode 100644
index 000000000..708b99365
--- /dev/null
+++ b/designer-chart/src/main/java/com/fr/design/chartx/component/MapAreaMatchPane.java
@@ -0,0 +1,301 @@
+package com.fr.design.chartx.component;
+
+import com.fr.base.BaseUtils;
+import com.fr.base.ParameterMapNameSpace;
+import com.fr.chartx.TwoTuple;
+import com.fr.chartx.data.execute.ExecuteDataSetHelper;
+import com.fr.data.TableDataSource;
+import com.fr.data.TableDataSourceTailor;
+import com.fr.data.core.DataCoreUtils;
+import com.fr.data.impl.NameTableData;
+import com.fr.design.beans.BasicBeanPane;
+import com.fr.design.data.DesignTableDataManager;
+import com.fr.design.data.datapane.TableDataComboBox;
+import com.fr.design.data.tabledata.wrapper.TableDataWrapper;
+import com.fr.design.dialog.DialogActionAdapter;
+import com.fr.design.file.HistoryTemplateListPane;
+import com.fr.design.gui.icombobox.UIComboBox;
+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.chart.gui.data.table.DataPaneHelper;
+import com.fr.design.parameter.ParameterInputPane;
+import com.fr.general.GeneralUtils;
+import com.fr.general.data.DataModel;
+import com.fr.general.data.TableDataException;
+import com.fr.plugin.chart.map.MapMatchResult;
+import com.fr.plugin.chart.map.server.ChartGEOJSONHelper;
+import com.fr.script.Calculator;
+import com.fr.stable.ArrayUtils;
+import com.fr.stable.ParameterProvider;
+import com.fr.stable.StringUtils;
+
+import javax.swing.BorderFactory;
+import javax.swing.Icon;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.table.DefaultTableModel;
+import javax.swing.tree.DefaultMutableTreeNode;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+
+/**
+ * @author Bjorn
+ * @version 10.0
+ * Created by Bjorn on 2019-11-04
+ */
+public class MapAreaMatchPane extends BasicBeanPane {
+
+ private TableDataComboBox tableNameCombox;
+ private UIComboBox areaNameBox;
+ private UILabel refreshLabel;
+
+ private MatchAreaTable matchAreaTable;
+
+ private MatchResultTable matchResultTable;
+
+ private static final Object[] HEADER = new Object[]{Toolkit.i18nText("Fine-Design_Chart_Area_Name"), Toolkit.i18nText("Fine-Design_Chart_Match_To")};
+
+ private static final Object[] HEADER_WITH_EMPTY = new Object[]{Toolkit.i18nText("Fine-Design_Chart_Area_Name"), Toolkit.i18nText("Fine-Design_Chart_Match_To"), ""};
+
+
+ public MapAreaMatchPane(TwoTuple> treeNodeAndItems) {
+ initButtonGroup();
+ initRefreshLabel();
+ areaNameBox = new UIComboBox();
+ this.setLayout(new BorderLayout(5, 10));
+ this.add(createContentPane(), BorderLayout.NORTH);
+ initTable(treeNodeAndItems);
+ JScrollPane matchAreaScroll = new JScrollPane(matchAreaTable) {
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(400, 300);
+ }
+ };
+ this.add(matchAreaScroll, BorderLayout.CENTER);
+ JScrollPane matchResultScroll = new JScrollPane(matchResultTable) {
+ @Override
+ public Dimension getPreferredSize() {
+ return new Dimension(400, 200);
+ }
+ };
+ matchResultScroll.setBorder(BorderFactory.createTitledBorder(Toolkit.i18nText("Fine-Design_Chart_Custom_Match_List")));
+ this.add(matchResultScroll, BorderLayout.SOUTH);
+ this.setBorder(BorderFactory.createEmptyBorder(5, 20, 5, 20));
+ }
+
+ private JPanel createContentPane() {
+ JPanel panel = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
+
+ JPanel tableDataPane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
+ panel.add(tableDataPane);
+ tableDataPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Chart_Table_Data") + ":"));
+ tableNameCombox.setPreferredSize(new Dimension(96, 20));
+ tableDataPane.add(tableNameCombox);
+
+ JPanel areaNamePane = FRGUIPaneFactory.createNormalFlowInnerContainer_S_Pane();
+ panel.add(areaNamePane);
+ areaNamePane.add(new UILabel(Toolkit.i18nText("Fine-Design_Chart_Area_Name") + ":"));
+ areaNamePane.add(areaNameBox);
+ areaNameBox.setPreferredSize(new Dimension(96, 20));
+ panel.add(refreshLabel);
+ return panel;
+ }
+
+ private void initTable(TwoTuple> treeNodeAndItems) {
+ matchAreaTable = new MatchAreaTable(new Object[0][2], HEADER);
+ matchAreaTable.setRoot(treeNodeAndItems.getFirst());
+ matchAreaTable.setItems(treeNodeAndItems.getSecond());
+
+ matchResultTable = new MatchResultTable(new Object[0][3], HEADER_WITH_EMPTY);
+
+ DefaultTableModel model = new DefaultTableModel(new Object[0][3], HEADER_WITH_EMPTY);
+ matchResultTable.setModel(model);
+
+ matchAreaTable.setMatchResultTable(matchResultTable);
+ matchResultTable.setMatchAreaTable(matchAreaTable);
+ }
+
+ private void initButtonGroup() {
+ tableNameCombox = new TableDataComboBox(DesignTableDataManager.getEditingTableDataSource());
+ tableNameCombox.addItemListener(new ItemListener() {
+ @Override
+ public void itemStateChanged(ItemEvent e) {
+ if (e.getStateChange() == ItemEvent.SELECTED) {
+ refreshBox();
+ }
+ }
+ });
+ }
+
+ private void initRefreshLabel() {
+ Icon refreshImage = BaseUtils.readIcon("/com/fr/design/images/control/refresh.png");
+ refreshLabel = new UILabel(refreshImage);
+ refreshLabel.addMouseListener(new MouseAdapter() {
+ boolean mouseEntered = false;
+ boolean buttonPressed = false;
+
+ public void mouseEntered(MouseEvent e) { // 当鼠标进入时候调用.
+ mouseEntered = true;
+ if (!buttonPressed) {
+ refreshLabel.setBackground(java.awt.Color.WHITE);
+ refreshLabel.setOpaque(true);
+ refreshLabel.setBorder(BorderFactory.createLineBorder(java.awt.Color.GRAY));
+ }
+ }
+
+ public void mouseExited(MouseEvent e) {
+ mouseEntered = false;
+ refreshLabel.setOpaque(false);
+ refreshLabel.setBorder(BorderFactory.createEmptyBorder());
+ }
+
+ public void mousePressed(MouseEvent e) {
+ buttonPressed = true;
+ refreshLabel.setBackground(java.awt.Color.lightGray);
+ }
+
+ public void mouseReleased(MouseEvent e) {
+ buttonPressed = false;
+ if (mouseEntered) {
+ refreshLabel.setBackground(java.awt.Color.WHITE);
+ populateData(tableNameCombox.getSelectedItem().getTableDataName(), GeneralUtils.objectToString(areaNameBox.getSelectedItem()));
+ }
+ }
+ });
+ }
+
+ public void updateBean(MapMatchResult matchResult) {
+ if (matchResult == null) {
+ return;
+ }
+ if (tableNameCombox.getSelectedItem() != null) {
+ matchResult.setTableName(tableNameCombox.getSelectedItem().getTableDataName());
+ }
+ matchResult.setColumnName(GeneralUtils.objectToString(areaNameBox.getSelectedItem()));
+
+ matchResultTable.updateBean(matchResult);
+ }
+
+ public void populateBean(MapMatchResult matchResult) {
+
+ }
+
+ public void populateBean(MapMatchResult matchResult, String tableName, String areaName) {
+ //先取保存的数据集名称和区域名,若不存在,就取数据集面板配置的数据集名称和区域名
+ matchResultTable.populateBean(matchResult);
+
+ if (matchResult != null && matchResult.getTableName() != null) {
+ tableName = matchResult.getTableName();
+ areaName = matchResult.getColumnName();
+ }
+ tableNameCombox.setSelectedTableDataByName(tableName);
+ if (StringUtils.isEmpty(areaName)) {
+ return;
+ }
+ areaNameBox.setSelectedItem(areaName);
+ populateData(tableName, areaName);
+ }
+
+ private void populateData(String tableName, String columnName) {
+ Object[] columnData = getColumnData(tableName, columnName);
+ if (columnData == null) {
+ return;
+ }
+ populateMatchData(columnData);
+ }
+
+ private Object[] getColumnData(String tableName, String columnName) {
+ NameTableData nameTableData = new NameTableData(tableName);
+ TableDataSource dataSource = TableDataSourceTailor.extractTableData(HistoryTemplateListPane.getInstance().getCurrentEditingTemplate().getTarget());
+ Calculator calculator = Calculator.createCalculator();
+ calculator.setAttribute(TableDataSource.KEY, dataSource);
+ ParameterProvider[] parameters = nameTableData.getParameters(calculator);
+ final Map parameterMap = new HashMap<>();
+
+ if (ArrayUtils.isNotEmpty(parameters)) {
+ final ParameterInputPane pPane = new ParameterInputPane(parameters);
+ pPane.showSmallWindow(DesignerContext.getDesignerFrame(), new DialogActionAdapter() {
+ @Override
+ public void doOk() {
+ parameterMap.putAll(pPane.update());
+ }
+ }).setVisible(true);
+ }
+ for (ParameterProvider parameter : parameters) {
+ if (parameterMap.containsKey(parameter.getName())) {
+ parameter.setValue(parameterMap.get(parameter.getName()));
+ }
+ }
+ ParameterMapNameSpace parameterMapNameSpace = ParameterMapNameSpace.create(parameterMap);
+ calculator.pushNameSpace(parameterMapNameSpace);
+
+ try {
+ DataModel dataModel = ExecuteDataSetHelper.createDataModel(calculator, nameTableData);
+ int colIndex = DataCoreUtils.getColumnIndexByName(dataModel, columnName);
+ if (colIndex == DataModel.COLUMN_NAME_NOT_FOUND) {
+ return null;
+ }
+ int size = dataModel.getRowCount();
+ HashSet