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 columnData = new LinkedHashSet<>(); + for (int i = 0; i < size; i++) { + columnData.add(dataModel.getValueAt(i, colIndex)); + } + return columnData.toArray(); + } catch (TableDataException ignore) { + return null; + } + } + + private void populateMatchData(Object[] columnData) { + Set geoAreas = matchAreaTable.getItems(); + + Map resultMap = ChartGEOJSONHelper.matchArea(columnData, geoAreas, matchResultTable.getCustomResult()); + + Object[][] data = new Object[resultMap.size()][2]; + + //构造table的数据结构 + Map areaNameIndex = new HashMap<>(); + int i = 0; + for (Map.Entry entry : resultMap.entrySet()) { + areaNameIndex.put(entry.getKey(), i); + data[i++] = new Object[]{entry.getKey(), entry.getValue()}; + } + + matchAreaTable.setAreaNameIndex(areaNameIndex); + matchAreaTable.setModel(new DefaultTableModel(data, HEADER)); + } + + private void refreshBox() { + TableDataWrapper dataWrap = tableNameCombox.getSelectedItem(); + + if (dataWrap == null) { + return; + } + + List columnNameList = dataWrap.calculateColumnNameList(); + + DataPaneHelper.refreshBoxItems(areaNameBox, columnNameList); + areaNameBox.setSelectedItem(null); + } + + public MapMatchResult updateBean() { + return null; + } + + @Override + protected String title4PopupWindow() { + return Toolkit.i18nText("Fine-Design_Chart_Location_With_Area_Name"); + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/MatchAreaTable.java b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchAreaTable.java new file mode 100644 index 000000000..e8f98f2a3 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchAreaTable.java @@ -0,0 +1,148 @@ +package com.fr.design.chartx.component; + +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.i18n.Toolkit; +import com.fr.general.GeneralUtils; +import com.fr.plugin.chart.map.server.ChartGEOJSONHelper; + +import javax.swing.AbstractCellEditor; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; +import java.awt.Color; +import java.awt.Component; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-11-19 + */ +public class MatchAreaTable extends JTable { + + private Set items; + + private MatchResultTable matchResultTable; + + private Map areaNameIndex = new HashMap<>(); + + private DefaultMutableTreeNode root; + + public MatchAreaTable(Object[][] data, Object[] header) { + super(data, header); + this.getTableHeader().setReorderingAllowed(false); + } + + public void setItems(Set items) { + this.items = items; + } + + public Set getItems() { + return items; + } + + public void setRoot(DefaultMutableTreeNode root) { + this.root = root; + } + + public void setMatchResultTable(MatchResultTable matchResultTable) { + this.matchResultTable = matchResultTable; + } + + public void setAreaNameIndex(Map areaNameIndex) { + this.areaNameIndex = areaNameIndex; + } + + public void setModel(TableModel dataModel) { + super.setModel(dataModel); + + if (items == null) { + items = new HashSet<>(); + } + TableColumnModel columnModel = getColumnModel(); + columnModel.getColumn(0).setCellEditor(new UILabelEditor()); + columnModel.getColumn(1).setCellEditor(new UIComboBoxRenderAndEditor()); + columnModel.getColumn(1).setCellRenderer(new UIComboBoxRenderAndEditor()); + } + + public void reMatch(Object areaName) { + if (!areaNameIndex.containsKey(areaName)) { + return; + } + int index = areaNameIndex.get(areaName); + Map resultMap = ChartGEOJSONHelper.matchArea(new Object[]{areaName}, items); + String result = resultMap.get(areaName); + getColumnModel().getColumn(1).getCellEditor().stopCellEditing(); + this.setValueAt(result, index, 1); + } + + public class UIComboBoxRenderAndEditor extends AbstractCellEditor implements TableCellRenderer, TableCellEditor { + + TableTreeComboBox comboBox; + + public UIComboBoxRenderAndEditor() { + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + initComboBox(value, false); + return comboBox; + } + + public Component getTableCellEditorComponent(final JTable table, Object value, boolean isSelected, final int row, int column) { + initComboBox(value, true); + comboBox.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + UIComboBoxRenderAndEditor.this.stopCellEditing(); + Object areaName = MatchAreaTable.this.getValueAt(row, 0); + Object result = MatchAreaTable.this.getValueAt(row, 1); + if (items.contains(result)) { + matchResultTable.dealMatch(areaName, result); + } + } + }); + return comboBox; + } + + private void initComboBox(Object value, boolean editor) { + comboBox = new TableTreeComboBox(new JTree(root)); + comboBox.setEditable(true); + + comboBox.setSelectedItem(value); + if (!editor && value == null) { + JTextField textField = (JTextField) (comboBox.getEditor().getEditorComponent()); + textField.setForeground(Color.RED); + textField.setText(Toolkit.i18nText("Fine-Design_Chart_Prompt_Not_Selected")); + } + } + + public Object getCellEditorValue() { + return comboBox.getSelectedItem(); + } + } + + public static class UILabelEditor extends AbstractCellEditor implements TableCellEditor { + + UILabel uiLabel; + + public Component getTableCellEditorComponent(JTable table, Object value, + boolean isSelected, + int row, int column) { + uiLabel = new UILabel(GeneralUtils.objectToString(value)); + return uiLabel; + } + + public Object getCellEditorValue() { + return uiLabel.getText(); + } + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/MatchResultTable.java b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchResultTable.java new file mode 100644 index 000000000..55287f00a --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/MatchResultTable.java @@ -0,0 +1,146 @@ +package com.fr.design.chartx.component; + +import com.fr.base.BaseUtils; +import com.fr.base.Utils; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.i18n.Toolkit; +import com.fr.general.ComparatorUtils; +import com.fr.plugin.chart.map.MapMatchResult; +import com.fr.stable.StringUtils; + +import javax.swing.AbstractCellEditor; +import javax.swing.JOptionPane; +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellEditor; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumnModel; +import javax.swing.table.TableModel; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Vector; +import java.awt.Component; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-11-20 + */ +public class MatchResultTable extends JTable { + + private MatchAreaTable matchAreaTable; + + public MatchResultTable(Object[][] data, Object[] header) { + super(data, header); + this.getTableHeader().setReorderingAllowed(false); + } + + public void setMatchAreaTable(MatchAreaTable matchAreaTable) { + this.matchAreaTable = matchAreaTable; + } + + public void setModel(TableModel dataModel) { + super.setModel(dataModel); + + TableColumnModel columnModel = getColumnModel(); + columnModel.getColumn(0).setCellEditor(new MatchAreaTable.UILabelEditor()); + columnModel.getColumn(1).setCellEditor(new MatchAreaTable.UILabelEditor()); + columnModel.getColumn(2).setCellEditor(new UIButtonEditorAndRender()); + columnModel.getColumn(2).setCellRenderer(new UIButtonEditorAndRender()); + columnModel.getColumn(2).setMaxWidth(20); + } + + public void dealMatch(Object areaName, Object result) { + int rowCount = this.getRowCount(); + for (int i = 0; i < rowCount; i++) { + if (ComparatorUtils.equals(this.getValueAt(i, 0), areaName)) { + getColumnModel().getColumn(1).getCellEditor().stopCellEditing(); + this.setValueAt(result, i, 1); + return; + } + } + DefaultTableModel model = (DefaultTableModel) this.getModel(); + Vector vector = new Vector(); + vector.add(areaName); + vector.add(result); + vector.add(""); + model.addRow(vector); + } + + public void populateBean(MapMatchResult matchResult) { + if (matchResult == null) { + return; + } + Map customResult = matchResult.getCustomResult(); + if (customResult == null) { + return; + } + DefaultTableModel model = (DefaultTableModel) this.getModel(); + for (Map.Entry entry : customResult.entrySet()) { + Vector vector = new Vector(); + vector.add(entry.getKey()); + vector.add(entry.getValue()); + vector.add(""); + model.addRow(vector); + } + } + + public void updateBean(MapMatchResult matchResult) { + matchResult.setCustomResult(getCustomResult()); + } + + public Map getCustomResult() { + Map customResult = new LinkedHashMap<>(); + DefaultTableModel model = (DefaultTableModel) this.getModel(); + for (int i = 0, rowCount = model.getRowCount(); i < rowCount; i++) { + customResult.put(Utils.objectToString(model.getValueAt(i, 0)), Utils.objectToString(model.getValueAt(i, 1))); + } + return customResult; + } + + public class UIButtonEditorAndRender extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { + + public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, final int row, int column) { + UIButton uiButton = new UIButton(BaseUtils.readIcon("com/fr/design/images/toolbarbtn/close.png")); + uiButton.addMouseListener(new MouseAdapter() { + boolean mouseEntered = false; + + public void mouseEntered(MouseEvent e) { // 当鼠标进入时候调用. + mouseEntered = true; + + } + + public void mouseExited(MouseEvent e) { + mouseEntered = false; + } + + public void mouseReleased(MouseEvent e) { + if (mouseEntered) { + MatchResultTable.this.getCellEditor().stopCellEditing(); + int val = JOptionPane.showConfirmDialog(MatchResultTable.this, Toolkit.i18nText("Fine-Design_Basic_Utils_Are_You_Sure_To_Remove_The_Selected_Item") + "?", + Toolkit.i18nText("Fine-Design_Basic_Remove"), JOptionPane.OK_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE); + if (val == JOptionPane.OK_OPTION) { + DefaultTableModel model = (DefaultTableModel) MatchResultTable.this.getModel(); + Object areaName = MatchResultTable.this.getValueAt(row, 0); + model.removeRow(row); + matchAreaTable.reMatch(areaName); + } + } + } + }); + return uiButton; + } + + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + UIButton button = new UIButton(BaseUtils.readIcon("com/fr/design/images/toolbarbtn/close.png")); + return button; + } + + public Object getCellEditorValue() { + return StringUtils.EMPTY; + } + } + +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/component/TableTreeComboBox.java b/designer-chart/src/main/java/com/fr/design/chartx/component/TableTreeComboBox.java new file mode 100644 index 000000000..793b49b31 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/component/TableTreeComboBox.java @@ -0,0 +1,100 @@ +package com.fr.design.chartx.component; + +import com.fr.design.gui.icombobox.FRTreeComboBox; +import com.fr.design.gui.itextfield.UITextField; +import com.fr.general.IOUtils; +import com.fr.plugin.chart.map.server.ChartGEOJSONHelper; + +import javax.swing.JTextField; +import javax.swing.JTree; +import javax.swing.MenuSelectionManager; +import javax.swing.tree.DefaultMutableTreeNode; +import javax.swing.tree.DefaultTreeCellRenderer; +import javax.swing.tree.TreeCellRenderer; +import javax.swing.tree.TreeNode; +import javax.swing.tree.TreePath; +import java.util.Enumeration; +import java.awt.Component; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.KeyListener; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-12-24 + */ +public class TableTreeComboBox extends FRTreeComboBox { + + private JTextField textField; + + public TableTreeComboBox(JTree tree) { + super(tree, null); + textField = (JTextField) (this.getEditor().getEditorComponent()); + textField.addKeyListener(treeKeyListener); + tree.setCellRenderer(tableNameTreeRenderer); + } + + @Override + protected void dealSamePath(TreePath parent, TreeNode node, UITextField textField) { + matchLeafNode(parent, node, textField); + } + + private boolean matchLeafNode(TreePath parent, TreeNode node, UITextField textField) { + for (Enumeration e = node.children(); e.hasMoreElements(); ) { + TreeNode n = (TreeNode) e.nextElement(); + TreePath path = parent.pathByAddingChild(n); + TreeNode pathNode = (TreeNode) path.getLastPathComponent(); + if (pathNode.getChildCount() == 0) { + if (pathToString(path).toUpperCase().contains(textField.getText().toUpperCase())) { + tree.scrollPathToVisible(path); + tree.setSelectionPath(path); + return true; + } + } else { + if (matchLeafNode(path, pathNode, textField)) { + return true; + } + } + } + return false; + } + + private KeyListener treeKeyListener = new KeyAdapter() { + public void keyPressed(KeyEvent e) { + int key = e.getKeyCode(); + if (key == KeyEvent.VK_ENTER) { + TreePath treePath = tree.getSelectionPath(); + if (treePath == null) { + return; + } + DefaultMutableTreeNode node = (DefaultMutableTreeNode) treePath + .getLastPathComponent(); + if (node.isLeaf()) { + TableTreeComboBox.this.setSelectedItem(treePath); + textField.setText(pathToString(treePath)); + MenuSelectionManager.defaultManager().clearSelectedPath(); + } + } + } + }; + + private TreeCellRenderer tableNameTreeRenderer = new DefaultTreeCellRenderer() { + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus) { + super.getTreeCellRendererComponent(tree, value, sel, expanded, leaf, row, hasFocus); + if (value instanceof DefaultMutableTreeNode) { + DefaultMutableTreeNode node = (DefaultMutableTreeNode) value; + Object userObj = node.getUserObject(); + if (node.getChildCount() > 0) { + this.setIcon(IOUtils.readIcon("com/fr/design/images/m_insert/expandCell.gif")); + } + if (userObj != null) { + this.setText(ChartGEOJSONHelper.getPresentNameWithPath(userObj.toString())); + } + } + return this; + } + }; + +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java index ae52b401d..7d1d1c52a 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapChartDataPane.java @@ -37,7 +37,7 @@ public class DrillMapChartDataPane extends AbstractChartDataPane private EachLayerDataDefinitionPane eachLayerDataDefinitionPane;//各层级分别指定 - public DrillMapDataPane(VanChartDrillMapPlot drillMapPlot) { - bottomDataPane = new SingleDataPane(new AreaMapDataSetFieldsPane(), new AreaMapCellDataFieldsPane()); - eachLayerDataDefinitionPane = new EachLayerDataDefinitionPane(drillMapPlot); + public DrillMapDataPane(VanChart vanChart) { + AreaMapDataSetFieldsPane areaMapDataSetFieldsPane = new AreaMapDataSetFieldsPane(); + areaMapDataSetFieldsPane.setChart(vanChart); + areaMapDataSetFieldsPane.setLevel(ChartGEOJSONHelper.BOTTOM_LEVEL); + bottomDataPane = new SingleDataPane(areaMapDataSetFieldsPane, new AreaMapCellDataFieldsPane()); + eachLayerDataDefinitionPane = new EachLayerDataDefinitionPane(vanChart); dataDefinitionType = new UIComboBoxPane() { @Override diff --git a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java index b12bf385a..975faffca 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/DrillMapLayerPane.java @@ -8,6 +8,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.design.layout.TableLayout; import com.fr.design.layout.TableLayoutHelper; import com.fr.plugin.chart.drillmap.VanChartDrillMapPlot; +import com.fr.plugin.chart.map.MapMatchResult; import com.fr.plugin.chart.map.server.CompatibleGeoJSONTreeHelper; import com.fr.plugin.chart.type.MapType; import com.fr.plugin.chart.type.ZoomLevel; @@ -18,10 +19,11 @@ import com.fr.van.chart.map.designer.type.VanChartMapSourceChoosePane; import javax.swing.BorderFactory; import javax.swing.JPanel; import javax.swing.tree.DefaultMutableTreeNode; -import java.awt.BorderLayout; -import java.awt.Component; import java.util.ArrayList; import java.util.HashMap; +import java.util.List; +import java.awt.BorderLayout; +import java.awt.Component; /** * Created by Mitisky on 16/6/20. @@ -62,6 +64,7 @@ public class DrillMapLayerPane extends BasicBeanPane { java.util.List levelList = drillMapPlot.getLayerLevelList(); java.util.List mapTypeList = drillMapPlot.getLayerMapTypeList(); + List matchResultList = drillMapPlot.getMatchResultList(); //根据层级初始属性,一切以json那边读到的层级为准 int levelSize = levelList.size(); @@ -73,6 +76,11 @@ public class DrillMapLayerPane extends BasicBeanPane { for (int j = typeSize; j < depth; j++) { mapTypeList.add(mapType); } + + int matchSize = matchResultList.size(); + for (int k = matchSize; k < depth; k++) { + matchResultList.add(new MapMatchResult()); + } } } @@ -120,10 +128,10 @@ public class DrillMapLayerPane extends BasicBeanPane { return panel; } - private JPanel createTitlePane (String title, JPanel panel) { + private JPanel createTitlePane(String title, JPanel panel) { JPanel jPanel = TableLayout4VanChartHelper.createExpandablePaneWithTitle(title, panel); - panel.setBorder(BorderFactory.createEmptyBorder(10,5,0,0)); - jPanel.setBorder(BorderFactory.createEmptyBorder(0,5,0,0)); + panel.setBorder(BorderFactory.createEmptyBorder(10, 5, 0, 0)); + jPanel.setBorder(BorderFactory.createEmptyBorder(0, 5, 0, 0)); return jPanel; } diff --git a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java index 02c6c4d08..a7180e4c5 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/data/drillMap/EachLayerDataDefinitionPane.java @@ -13,6 +13,7 @@ import com.fr.design.i18n.Toolkit; import com.fr.general.ComparatorUtils; import com.fr.plugin.chart.drillmap.VanChartDrillMapPlot; import com.fr.plugin.chart.type.MapType; +import com.fr.plugin.chart.vanchart.VanChart; import java.util.ArrayList; import java.util.List; @@ -26,8 +27,11 @@ public class EachLayerDataDefinitionPane extends MultiTabPane oldTypeList; private VanChartDrillMapPlot plot; - public EachLayerDataDefinitionPane(VanChartDrillMapPlot drillMapPlot) { - this.plot = drillMapPlot; + private VanChart vanChart; + + public EachLayerDataDefinitionPane(VanChart vanChart) { + this.vanChart = vanChart; + this.plot = vanChart.getPlot(); initComps(); } @@ -52,17 +56,29 @@ public class EachLayerDataDefinitionPane extends MultiTabPane extends BasicBeanPane { + public String tableName; + public AbstractDataSetFieldsPane() { initComponents(); } + public String getTableName() { + return tableName; + } + + public void setTableName(String tableName) { + this.tableName = tableName; + } + protected void initComponents() { this.setLayout(new BorderLayout(0, 6)); diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/AreaMapDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/AreaMapDataSetFieldsPane.java index 2d8bba01a..2f4dc37ea 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/AreaMapDataSetFieldsPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/AreaMapDataSetFieldsPane.java @@ -4,12 +4,14 @@ import com.fr.chartx.data.field.diff.AreaMapColumnFieldCollection; import com.fr.design.gui.icombobox.UIComboBox; import com.fr.design.i18n.Toolkit; +import java.awt.Component; + /** * @author shine * @version 10.0 * Created by shine on 2019/11/7 */ -public class AreaMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesValuePane { +public class AreaMapDataSetFieldsPane extends MapDataSetFieldsPane { private UIComboBox areaName; @@ -27,6 +29,13 @@ public class AreaMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVal }; } + @Override + protected Component[] fieldComponents() { + return new Component[]{ + createAreaPanel(createAreaName()) + }; + } + private UIComboBox createAreaName() { if (areaName == null) { areaName = new UIComboBox(); diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java index 24220b993..b1a058783 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/LineMapDataSetFieldsPane.java @@ -12,7 +12,7 @@ import javax.swing.JPanel; * @version 10.0 * Created by shine on 2019/11/11 */ -public class LineMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesValuePane { +public class LineMapDataSetFieldsPane extends MapDataSetFieldsPane { private LineMapAreaLngLatPaneWithComboBox areaLngLatPane; private UIComboBox lineName; @@ -20,7 +20,7 @@ public class LineMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVal @Override protected JPanel createNorthPane() { if (areaLngLatPane == null) { - areaLngLatPane = new LineMapAreaLngLatPaneWithComboBox(); + areaLngLatPane = new LineMapAreaLngLatPaneWithComboBox(this); } return areaLngLatPane; } diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/MapDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/MapDataSetFieldsPane.java new file mode 100644 index 000000000..bec4e78b7 --- /dev/null +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/MapDataSetFieldsPane.java @@ -0,0 +1,92 @@ +package com.fr.design.chartx.fields.diff; + +import com.fr.base.BaseUtils; +import com.fr.base.Utils; +import com.fr.chartx.TwoTuple; +import com.fr.chartx.data.field.diff.ColumnFieldCollectionWithSeriesValue; +import com.fr.design.chartx.component.MapAreaMatchPane; +import com.fr.design.dialog.BasicDialog; +import com.fr.design.dialog.DialogActionListener; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.icombobox.UIComboBox; +import com.fr.plugin.chart.map.MapMatchResult; +import com.fr.plugin.chart.map.VanChartMapPlot; +import com.fr.plugin.chart.map.server.ChartGEOJSONHelper; +import com.fr.plugin.chart.vanchart.VanChart; + +import javax.swing.JFrame; +import javax.swing.JPanel; +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.Set; +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2019-12-25 + */ +public abstract class MapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesValuePane { + + private VanChart chart; + + //钻取地图有层级,默认-1代表无层级关系 + private int level = ChartGEOJSONHelper.DEFAULT_LEVEL; + + public int getLevel() { + return level; + } + + public void setLevel(int level) { + this.level = level; + } + + public void setChart(VanChart chart) { + this.chart = chart; + } + + public VanChart getChart() { + return chart; + } + + public JPanel createAreaPanel(final UIComboBox areaBox) { + JPanel areaPanel = new JPanel(new BorderLayout(10, 0)); + areaBox.setPreferredSize(new Dimension(91, 20)); + areaPanel.add(areaBox, BorderLayout.WEST); + UIButton uiButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/config.png")); + uiButton.addActionListener(new ActionListener() { + private TwoTuple> treeNodeAndItems; + + @Override + public void actionPerformed(ActionEvent e) { + VanChartMapPlot plot = chart.getPlot(); + if (treeNodeAndItems == null) { + treeNodeAndItems = ChartGEOJSONHelper.getTreeNodeAndItems(plot.getGeoUrl(), level); + } + final MapAreaMatchPane pane = new MapAreaMatchPane(treeNodeAndItems); + + String nameTable = getTableName(); + final MapMatchResult matchResult = plot.getMatchResult(level); + + pane.populateBean(matchResult, nameTable, Utils.objectToString(areaBox.getSelectedItem())); + BasicDialog dialog = pane.showWindow(new JFrame()); + dialog.addDialogActionListener(new DialogActionListener() { + @Override + public void doOk() { + pane.updateBean(matchResult); + } + + @Override + public void doCancel() { + + } + }); + dialog.setVisible(true); + } + }); + areaPanel.add(uiButton, BorderLayout.EAST); + return areaPanel; + } +} diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java index 1771637ab..220f840d3 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/PointMapDataSetFieldsPane.java @@ -11,13 +11,13 @@ import javax.swing.JPanel; * @version 10.0 * Created by shine on 2019/11/8 */ -public class PointMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesValuePane { +public class PointMapDataSetFieldsPane extends MapDataSetFieldsPane { private PointMapAreaLngLatPaneWithComboBox areaLngLatPane; @Override protected JPanel createNorthPane() { if (areaLngLatPane == null) { - areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(); + areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(this); } return areaLngLatPane; } @@ -30,7 +30,7 @@ public class PointMapDataSetFieldsPane extends AbstractDataSetFieldsWithSeriesVa @Override protected UIComboBox[] filedComboBoxes() { if (areaLngLatPane == null) { - areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(); + areaLngLatPane = new PointMapAreaLngLatPaneWithComboBox(this); } return areaLngLatPane.allFieldComboBox(); } diff --git a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/SingleCategoryDataSetFieldsPane.java b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/SingleCategoryDataSetFieldsPane.java index 663daecdf..9eb6d94e2 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/SingleCategoryDataSetFieldsPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/fields/diff/SingleCategoryDataSetFieldsPane.java @@ -55,7 +55,10 @@ public class SingleCategoryDataSetFieldsPane label.setPreferredSize(new Dimension(ChartDataPane.LABEL_WIDTH, ChartDataPane.LABEL_HEIGHT)); JPanel northPane = new JPanel(new BorderLayout(HGAP, VGAP)); - northPane.add(GUICoreUtils.createBorderLayoutPane(new Component[]{categoryPane, null, null, label, null}), BorderLayout.NORTH); + northPane.add(GUICoreUtils.createBorderLayoutPane( + new Component[]{categoryPane, null, null, label, null}), + BorderLayout.NORTH + ); northPane.add(new JSeparator(), BorderLayout.CENTER); northPane.add(createCenterPane(), BorderLayout.SOUTH); northPane.setBorder(BorderFactory.createEmptyBorder(TOP, LEFT, BOTTOM, RIGHT)); diff --git a/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java b/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java index 87a3b5083..cfb9a2c18 100644 --- a/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java +++ b/designer-chart/src/main/java/com/fr/design/chartx/single/DataSetPane.java @@ -39,7 +39,7 @@ public class DataSetPane extends FurtherBasicBeanPane { tableDataPane = new DatabaseTableDataPane(label) { @Override protected void userEvent() { - refreshBoxList(); + refreshBoxListAndTableName(); checkBoxUse(); } }; @@ -67,7 +67,7 @@ public class DataSetPane extends FurtherBasicBeanPane { /** * 刷新字段下拉列表 */ - private void refreshBoxList() { + private void refreshBoxListAndTableName() { TableDataWrapper dataWrap = tableDataPane.getTableDataWrapper(); if (dataWrap == null) { @@ -78,6 +78,7 @@ public class DataSetPane extends FurtherBasicBeanPane { if (dataSetFieldsPane != null) { dataSetFieldsPane.refreshBoxListWithSelectTableData(columnNameList); + dataSetFieldsPane.setTableName(dataWrap.getTableDataName()); } } @@ -102,7 +103,7 @@ public class DataSetPane extends FurtherBasicBeanPane { return; } - refreshBoxList(); + refreshBoxListAndTableName(); tableDataPane.populateBean(ob.getNameTableData()); diff --git a/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java b/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java index af11a8b96..b5efad3b6 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java +++ b/designer-chart/src/main/java/com/fr/van/chart/custom/component/VanChartHyperLinkPane.java @@ -279,4 +279,4 @@ public class VanChartHyperLinkPane extends VanChartUIListControlPane { } -} +} \ No newline at end of file diff --git a/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java b/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java index 90926a106..f3ad4e22d 100644 --- a/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java +++ b/designer-chart/src/main/java/com/fr/van/chart/heatmap/designer/VanHeatMapChartTypeUI.java @@ -66,7 +66,9 @@ public class VanHeatMapChartTypeUI extends VanMapChartTypeUI { return new AbstractVanSingleDataPane(listener) { @Override protected SingleDataPane createSingleDataPane() { - return new SingleDataPane(new PointMapDataSetFieldsPane(), new PointMapCellDataFieldsPane()); + PointMapDataSetFieldsPane pointMapDataSetFieldsPane = new PointMapDataSetFieldsPane(); + pointMapDataSetFieldsPane.setChart(getVanChart()); + return new SingleDataPane(pointMapDataSetFieldsPane, new PointMapCellDataFieldsPane()); } }; } diff --git a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java index 5a7ae9817..1cf1b944c 100644 --- a/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java +++ b/designer-form/src/main/java/com/fr/design/designer/creator/cardlayout/XCardSwitchButton.java @@ -1,5 +1,5 @@ /** - * + * */ package com.fr.design.designer.creator.cardlayout; @@ -61,6 +61,8 @@ public class XCardSwitchButton extends XButton { private static final int MIN_SIZE = 1; + private static final int HALF_NUMBER = 2; + // 删除按钮识别区域偏移量 private static final int CLOSE_ICON_RIGHT_OFFSET = 15; private static final int CLOSE_ICON_TOP_OFFSET = 15; @@ -80,7 +82,7 @@ public class XCardSwitchButton extends XButton { private UILabel label; private Icon closeIcon = MOUSE_CLOSE; - + public XWCardTagLayout getTagLayout() { return tagLayout; } @@ -126,12 +128,12 @@ public class XCardSwitchButton extends XButton { /** * 响应点击事件 - * + * * @param editingMouseListener * 事件处理器 * @param e * 点击事件 - * + * */ @Override public void respondClick(EditingMouseListener editingMouseListener, @@ -143,12 +145,12 @@ public class XCardSwitchButton extends XButton { if(cardLayout == null){ initRelateLayout(); } - + //获取当前tab的index CardSwitchButton currentButton = (CardSwitchButton) this.toData(); int index = currentButton.getIndex(); int maxIndex = cardLayout.getComponentCount() - 1; - + //点击删除图标时 if (isSelectedClose(e, designer)) { //当删除到最后一个tab时,删除整个tab布局 @@ -235,8 +237,8 @@ public class XCardSwitchButton extends XButton { } } } - - + + //SwitchButton对应的XWCardLayout和XWCardTagLayout暂未存到xml中,重新打开时根据父子层关系获取 private void initRelateLayout(){ this.tagLayout = (XWCardTagLayout)this.getBackupParent(); @@ -244,28 +246,28 @@ public class XCardSwitchButton extends XButton { XWCardMainBorderLayout borderLayout = (XWCardMainBorderLayout)titleLayout.getBackupParent(); this.cardLayout = borderLayout.getCardPart(); } - + //是否进入点击关闭按钮区域 private boolean isSelectedClose(MouseEvent e, FormDesigner designer){ - + int diff = designer.getArea().getHorScrollBar().getValue(); - + // mouse position int ex = e.getX() + diff; int ey = e.getY(); - + //获取tab布局的位置,鼠标相对于tab按钮的位置 XLayoutContainer mainLayout = cardLayout.getBackupParent(); Point point = mainLayout.getLocation(); double mainX = point.getX(); double mainY = point.getY(); - + // 参数界面对坐标的影响 JForm jform = (JForm) HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); if(jform.getFormDesign().getParaComponent() != null){ ey -= jform.getFormDesign().getParaHeight(); } - + //减掉tab布局的相对位置 ex -= mainX; ey -= mainY; @@ -280,10 +282,10 @@ public class XCardSwitchButton extends XButton { // 鼠标进入按钮右侧删除图标区域 double recX = position.getX() + titlePoint.getX() + (width - CLOSE_ICON_RIGHT_OFFSET); double recY = position.getY() + titlePoint.getY() + CLOSE_ICON_TOP_OFFSET; - + return (recX < ex && ex < recX + CLOSE_ICON_RIGHT_OFFSET && ey < recY && ey > position.getY()); } - + //将当前switchButton改为选中状态 private void changeButtonState(int index) { for (int i = 0; i < this.tagLayout.getComponentCount(); i++) { @@ -292,7 +294,7 @@ public class XCardSwitchButton extends XButton { tempButton.setShowButton(tempButton.getIndex() == index); } } - + @Override public void paintComponent(Graphics g) { super.paintComponent(g); @@ -305,12 +307,12 @@ public class XCardSwitchButton extends XButton { this.getContentBackground().paint(g, new Rectangle2D.Double(0, 0, panelSize.getWidth(), panelSize.getHeight())); drawCloseIcon(g2d); } - + //画删除图标 private void drawCloseIcon(Graphics2D g2d){ closeIcon.paintIcon(this, g2d, this.getWidth() - LEFT_GAP, 0); } - + //画背景 private void drawBackground(CardSwitchButton button, TitlePacker widgetTitle){ Background background = widgetTitle.getBackground() == null ? ColorBackground.getInstance(NORMAL_GRAL) : widgetTitle.getBackground(); @@ -328,7 +330,7 @@ public class XCardSwitchButton extends XButton { this.setContentBackground(initialBackground == null ? background : initialBackground); } } - + //画标题 private void drawTitle(CardSwitchButton button, TitlePacker widgetTitle) { String titleText = button.getText(); @@ -348,7 +350,7 @@ public class XCardSwitchButton extends XButton { BorderPacker style = this.cardLayout.toData().getBorderStyle(); return style.getTitle(); } - + //删除tab布局 private void deleteTabLayout(SelectionModel selectionModel, FormDesigner designer){ String titleName = this.getContentLabel().getText(); @@ -455,7 +457,8 @@ public class XCardSwitchButton extends XButton { StringBuilder titleStringBuf = new StringBuilder(); TitlePacker title = getWidgetTitle(); FRFont font = title.getFrFont(); - FRFont newFont = FRFont.getInstance(font.getName(), font.getStyle(), font.getSize() + FONT_SIZE_ADJUST); + int fontSize = font.getSize() + FONT_SIZE_ADJUST; + FRFont newFont = FRFont.getInstance(font.getName(), font.getStyle(), fontSize); FontMetrics fm = GraphHelper.getFontMetrics(newFont); for (int i = 0; i < titleText.length(); i++) { titleStringBuf.append(titleText.charAt(i)); @@ -469,12 +472,13 @@ public class XCardSwitchButton extends XButton { for (int i = 0; i < verticalTextList.size(); i++) { String paint_str = (String) verticalTextList.get(i); - GraphHelper.drawString(g2d, paint_str, (width - fm.stringWidth(paint_str)) / 2, textY); + GraphHelper.drawString(g2d, paint_str, + (width - fm.stringWidth(paint_str)) / (HALF_NUMBER * 1.0D), textY); textY += textHeight; textY += PT.pt2pix(0, RESLUTION); if (textY > height - textHeight && i < verticalTextList.size() - 1) { textY -= DOTS_HEIGHT; - paintDots(g2d, textY, (width - fm.stringWidth(paint_str)) / 2); + paintDots(g2d, textY, (width - fm.stringWidth(paint_str)) / HALF_NUMBER); break; } } diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartErrorMessageCollector.java b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartErrorMessageCollector.java new file mode 100644 index 000000000..0b6a6b0e4 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/StartErrorMessageCollector.java @@ -0,0 +1,43 @@ +package com.fr.design.mainframe.messagecollect; + +import com.fr.config.MarketConfig; +import com.fr.design.DesignerEnvManager; +import com.fr.design.mainframe.errorinfo.ErrorInfo; +import com.fr.stable.StringUtils; + +/** + * + * @author hades + * @version 10.0 + * Created by hades on 2020/1/8 + */ +public class StartErrorMessageCollector { + + private static final StartErrorMessageCollector INSTANCE = new StartErrorMessageCollector(); + + private String uuid; + private String activeKey; + + + public static StartErrorMessageCollector getInstance() { + return INSTANCE; + } + + private StartErrorMessageCollector() { + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + this.uuid = envManager.getUUID(); + this.activeKey = envManager.getActivationKey(); + } + + public void record(String id, String msg, String detail) { + ErrorInfo errorInfo = new ErrorInfo(StringUtils.EMPTY, uuid, activeKey); + errorInfo.setLogid(id); + errorInfo.setLog(msg); + errorInfo.setStackTrace(detail); + errorInfo.saveAsJSON(); + } + + public void record(String id, String msg) { + record(id, msg, StringUtils.EMPTY); + } +} diff --git a/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/entity/DesignerErrorMessage.java b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/entity/DesignerErrorMessage.java new file mode 100644 index 000000000..d2047336e --- /dev/null +++ b/designer-realize/src/main/java/com/fr/design/mainframe/messagecollect/entity/DesignerErrorMessage.java @@ -0,0 +1,37 @@ +package com.fr.design.mainframe.messagecollect.entity; + +import com.fr.design.i18n.Toolkit; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2020/1/8 + */ +public enum DesignerErrorMessage { + + DESIGNER_PROCESS_OCCUPIED("11300201", Toolkit.i18nText("Fine-Design_Error_Process_Occupied_Message")), + PORT_OCCUPIED("11300202", Toolkit.i18nText("Fine-Design_Error_Port_Occupied_Message")), + FINEDB_PROBLEM("11300203", Toolkit.i18nText("Fine-Design_Error_Finedb_Problem_Message")), + DESIGNER_OUT_OF_MEMORY("11300204", Toolkit.i18nText("Fine-Design_Error_Out_Of_Memory_Message")), + REMOTE_DESIGN_NO_RESPONSE("11300205", Toolkit.i18nText("Fine-Design_Error_Remote_No_Response_Message")), + UNEXCEPTED_START_FAILED("11300200", Toolkit.i18nText("Fine-Design_Error_UnExcepted_Start_Failed")), + UNEXCEPTED_FALL_BACK("11300400 ", Toolkit.i18nText("Fine-Design_Error_UnExcepted_Fall_Back")); + + + + private String id; + private String message; + + public String getId() { + return id; + } + + public String getMessage() { + return message; + } + + DesignerErrorMessage(String id, String message) { + this.id = id; + this.message = message; + } +} diff --git a/designer-realize/src/main/java/com/fr/start/CollectUserInformationDialog.java b/designer-realize/src/main/java/com/fr/start/CollectUserInformationDialog.java index 139030642..f6a2f8500 100644 --- a/designer-realize/src/main/java/com/fr/start/CollectUserInformationDialog.java +++ b/designer-realize/src/main/java/com/fr/start/CollectUserInformationDialog.java @@ -11,9 +11,7 @@ import com.fr.design.layout.FRGUIPaneFactory; import com.fr.design.locale.impl.UserInfoMark; import com.fr.design.mainframe.ActiveKeyGenerator; import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.general.CloudCenter; -import com.fr.general.ComparatorUtils; -import com.fr.general.GeneralContext; +import com.fr.exit.DesignerExiter; import com.fr.general.locale.LocaleCenter; import com.fr.general.locale.LocaleMark; @@ -155,7 +153,7 @@ public class CollectUserInformationDialog extends UIDialog { exitButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent evt) { - System.exit(0); + DesignerExiter.getInstance().execute(); } }); // set default pane. diff --git a/designer-realize/src/main/java/com/fr/start/Designer.java b/designer-realize/src/main/java/com/fr/start/Designer.java index 19c9a5dba..d2a8bb01e 100644 --- a/designer-realize/src/main/java/com/fr/start/Designer.java +++ b/designer-realize/src/main/java/com/fr/start/Designer.java @@ -1,507 +1,39 @@ package com.fr.start; -import com.fr.base.BaseUtils; -import com.fr.base.vcs.DesignerMode; -import com.fr.design.DesignerEnvManager; -import com.fr.design.actions.core.ActionFactory; -import com.fr.design.actions.file.WebPreviewUtils; -import com.fr.design.actions.file.newReport.NewPolyReportAction; -import com.fr.design.actions.file.newReport.NewWorkBookAction; -import com.fr.design.actions.server.ServerConfigManagerAction; -import com.fr.design.actions.server.StyleListAction; -import com.fr.design.actions.server.WidgetManagerAction; -import com.fr.design.base.mode.DesignModeContext; -import com.fr.design.constants.UIConstants; -import com.fr.design.file.HistoryTemplateListCache; -import com.fr.design.file.HistoryTemplateListPane; -import com.fr.design.file.MutilTempalteTabPane; -import com.fr.design.fun.MenuHandler; -import com.fr.design.gui.ibutton.UIButton; -import com.fr.design.gui.ibutton.UIPreviewButton; -import com.fr.design.gui.imenu.UIMenuItem; -import com.fr.design.gui.imenu.UIPopupMenu; -import com.fr.design.gui.itoolbar.UILargeToolbar; -import com.fr.design.i18n.Toolkit; -import com.fr.design.mainframe.ActiveKeyGenerator; -import com.fr.design.mainframe.DesignerContext; -import com.fr.design.mainframe.InformationCollector; -import com.fr.design.mainframe.JTemplate; -import com.fr.design.mainframe.JWorkBook; -import com.fr.design.mainframe.alphafine.component.AlphaFinePane; -import com.fr.design.mainframe.bbs.UserInfoLabel; -import com.fr.design.mainframe.bbs.UserInfoPane; -import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; -import com.fr.design.menu.KeySetUtils; -import com.fr.design.menu.MenuDef; -import com.fr.design.menu.SeparatorDef; -import com.fr.design.menu.ShortCut; -import com.fr.design.module.DesignModuleFactory; -import com.fr.design.utils.concurrent.ThreadFactoryBuilder; -import com.fr.design.utils.gui.GUICoreUtils; -import com.fr.general.ComparatorUtils; -import com.fr.log.FineLoggerFactory; -import com.fr.module.Module; -import com.fr.module.ModuleContext; -import com.fr.runtime.FineRuntime; -import com.fr.stable.ProductConstants; -import com.fr.stable.StableUtils; -import com.fr.stable.StringUtils; -import com.fr.stable.lifecycle.LifecycleFatalError; -import com.fr.stable.xml.XMLTools; -import com.fr.start.module.StartupArgs; -import com.fr.start.server.ServerTray; -import com.fr.third.org.apache.commons.lang3.time.StopWatch; -import com.fr.workspace.WorkContext; +import com.fr.event.Event; +import com.fr.event.Listener; +import com.fr.event.Null; +import com.fr.process.FineProcess; +import com.fr.process.engine.FineJavaProcessFactory; +import com.fr.process.engine.core.FineProcessEngineEvent; + +/** + * 设计器主进程入口(无缝更换升级jar包,若使用其他类作为入口,需要重新打包designer.exe等,升级后仍然走的原来逻辑) + * + * 设计器逻辑/UI调试 see MainDesigner/Designer4Debug + * + * @author hades + * @date 2019/8/27 + */ +public class Designer { -import javax.swing.JComponent; -import javax.swing.JOptionPane; -import javax.swing.JPanel; -import javax.swing.border.MatteBorder; -import java.awt.Component; -import java.awt.Dimension; -import java.awt.FlowLayout; -import java.awt.Insets; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.io.File; -import java.util.ArrayList; -import java.util.concurrent.LinkedBlockingQueue; -import java.util.concurrent.ThreadFactory; -import java.util.concurrent.ThreadPoolExecutor; -import java.util.concurrent.TimeUnit; - -public class Designer extends BaseDesigner { - - private static final int TOOLBARPANEVGAP = -4; - private static final int PREVIEW_DOWN_X_GAP = 92; - private static final int GAP = 7; - private static final String OLD_ENV_FOLDER_71 = ".FineReport71"; - private static final String OLD_ENV_FOLDER_70 = ".FineReport70"; - - private UserInfoPane userInfoPane; - private UIButton saveButton; - private UIButton undo; - private UIButton redo; - private UIButton[] upToolBar; - private UIPreviewButton run; - - public Designer(String[] args) { - super(args); - } - - /** - * 设计器启动的Main方法 - * - * @param args 参数 - */ public static void main(String[] args) { + // 创建进程 + final FineProcess process = FineJavaProcessFactory.create(). + entry("com.fr.start.MainDesigner"). + javaRuntime(DesignerJavaRuntime.getInstance().getJavaExec()). + classPath(DesignerJavaRuntime.getInstance().getClassPath()). + inheritJvmSettings(). + jvmSettings(DesignerJavaRuntime.getInstance().getJvmOptions()). + arguments(args). + startProcess(DesignerProcessType.INSTANCE); - StopWatch watch = new StopWatch(); - watch.start(); - //启动运行时 - FineRuntime.start(); - Module designerRoot = ModuleContext.parseRoot("designer-startup.xml"); - //传递启动参数 - designerRoot.setSingleton(StartupArgs.class, new StartupArgs(args)); - try { - designerRoot.start(); - } catch (LifecycleFatalError fatal) { - SplashContext.getInstance().hide(); - JOptionPane.showMessageDialog(null, fatal.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE); - FineLoggerFactory.getLogger().error(fatal.getMessage(), fatal); - System.exit(0); - } - - if (WorkContext.getCurrent().isLocal()) { - //初始化一下serverTray - ServerTray.init(); - } - FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", watch.getTime()); - watch.stop(); - } - - /** - * 创建新建文件的快捷方式数组。 - * - * @return 返回快捷方式的数组 - */ - @Override - public ShortCut[] createNewFileShortCuts() { - ArrayList shortCuts = new ArrayList(); -// shortCuts.add(new NewWorkBookXAction()); - shortCuts.add(new NewWorkBookAction()); - shortCuts.add(new NewPolyReportAction()); - try { - if (DesignModuleFactory.getNewFormAction() != null) { - shortCuts.add((ShortCut) DesignModuleFactory.getNewFormAction().newInstance()); - } - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - return shortCuts.toArray(new ShortCut[shortCuts.size()]); - } - - @Override - protected MenuDef createServerMenuDef(ToolBarMenuDockPlus plus) { - MenuDef menuDef = super.createServerMenuDef(plus); - - if (WorkContext.getCurrent() == null) { - return menuDef; - } - - if (!DesignerMode.isAuthorityEditing()) { - menuDef.addShortCut(SeparatorDef.DEFAULT); - - if (WorkContext.getCurrent().isRoot()) { - menuDef.addShortCut(new ServerConfigManagerAction(), new StyleListAction(), new WidgetManagerAction()); - if (ActionFactory.getChartPreStyleAction() != null) { - menuDef.addShortCut(ActionFactory.getChartPreStyleAction()); - } - if (ActionFactory.getChartEmptyDataStyleAction() != null) { - menuDef.addShortCut(ActionFactory.getChartEmptyDataStyleAction()); - } - if (ActionFactory.getChartMapEditorAction() != null) { - menuDef.addShortCut(ActionFactory.getChartMapEditorAction()); - } - } - - insertMenu(menuDef, MenuHandler.SERVER); - } - - return menuDef; - } - - - /** - * 创建设计器上几个比较大的图标:新建cpt,保存,前进,后退,运行。 - * - * @return 返回大图标对应的工具栏 - */ - @Override - public UILargeToolbar createLargeToolbar() { - UILargeToolbar largeToolbar = super.createLargeToolbar(); - largeToolbar.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 4)); - largeToolbar.add(generateEmptyGap(1)); - createRunButton(largeToolbar); - largeToolbar.add(run); - largeToolbar.add(generateEmptyGap(GAP)); - largeToolbar.addSeparator(new Dimension(2, 42)); - largeToolbar.setBorder(new MatteBorder(new Insets(0, 0, 1, 0), UIConstants.LINE_COLOR)); - return largeToolbar; - } - - private JPanel generateEmptyGap(final int width) { - JPanel panel = new JPanel() { + process.getPipe().listen(FineProcessEngineEvent.DESTROY, new Listener() { @Override - public Dimension getPreferredSize() { - Dimension dim = super.getPreferredSize(); - dim.width = width; - return dim; - } - }; - panel.setBackground(null); - panel.setOpaque(false); - return panel; - } - - /** - * 创建上面一排的工具栏按钮 - * - * @return 按钮 - */ - @Override - public UIButton[] createUp() { - if (upToolBar == null) { - createSaveButton(); - createUndoButton(); - createRedoButton(); - return upToolBar = new UIButton[]{saveButton, undo, redo}; - } - return upToolBar; - } - - - private void createSaveButton() { - saveButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/save.png")); - saveButton.setToolTipText(KeySetUtils.SAVE_TEMPLATE.getMenuKeySetName()); - saveButton.set4ToolbarButton(); - saveButton.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - jt.stopEditing(); - jt.saveTemplate(); - jt.requestFocus(); - } - }); - } - - - private void createUndoButton() { - undo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/undo.png")); - undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName()); - undo.set4ToolbarButton(); - undo.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); - if (jt != null) { - jt.undo(); - } + public void on(Event event, Null param) { + process.destroy(); } }); - } - - private void createRedoButton() { - redo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/redo.png")); - redo.setToolTipText(KeySetUtils.REDO.getMenuKeySetName()); - redo.set4ToolbarButton(); - redo.addActionListener(new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); - if (jt != null) { - jt.redo(); - } - } - }); - } - - private void createRunButton(UILargeToolbar largeToolbar) { - run = new UIPreviewButton(new UIButton(UIConstants.PAGE_BIG_ICON) { - @Override - public Dimension getPreferredSize() { - return new Dimension(34, 34); - } - }, new UIButton(UIConstants.PREVIEW_DOWN) { - @Override - public Dimension getPreferredSize() { - return new Dimension(34, 10); - } - } - ) { - @Override - protected void upButtonClickEvent() { - JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jt == null) { - return; - } - WebPreviewUtils.preview(jt); - } - - @Override - protected void downButtonClickEvent() { - final JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jt == null) { - return; - } - - UIPopupMenu menu = new UIPopupMenu(); - - UIMenuItem[] items = jt.createMenuItem4Preview(); - for (int i = 0; i < items.length; i++) { - menu.add(items[i]); - } - GUICoreUtils.showPopupMenu(menu, MutilTempalteTabPane.getInstance(), MutilTempalteTabPane.getInstance().getX() - PREVIEW_DOWN_X_GAP, MutilTempalteTabPane.getInstance().getY() - 1 + MutilTempalteTabPane.getInstance().getHeight()); - } - - @Override - public Dimension getPreferredSize() { - // TODO Auto-generated method stub - return new Dimension(34, 46); - } - }; - run.setExtraPainted(false); - run.set4Toolbar(); - run.getUpButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview")); - run.getDownButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Dropdown_More_Preview")); - } - - @Override - protected void refreshLargeToolbarState() { - JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); - if (jt == null) { - return; - } - saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode()); - MutilTempalteTabPane.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList()); - MutilTempalteTabPane.getInstance().repaint(); - if (DesignerEnvManager.getEnvManager().isSupportUndo()) { - undo.setEnabled(jt.canUndo()); - redo.setEnabled(jt.canRedo()); - } else { - undo.setEnabled(false); - redo.setEnabled(false); - } - - run.getUpButton().setIcon(jt.getPreviewLargeIcon()); - - } - - /** - * 生成工具栏 - * - * @param toolbarComponent 工具栏 - * @param plus 对象 - * @return 更新后的toolbar - */ - @Override - public JComponent resetToolBar(JComponent toolbarComponent, ToolBarMenuDockPlus plus) { - //如果是处于权限编辑状态 - if (DesignerMode.isAuthorityEditing()) { - if (plus instanceof JWorkBook && plus.toolbars4Target() == null) { - //聚合块编辑 - return super.polyToolBar(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Privilege_Poly_Block_Edit")); - } else { - return plus.toolBar4Authority(); - } - } - - if (plus.toolbarPanes4Form().length == 0) { - return super.resetToolBar(toolbarComponent, plus); - } else { - JPanel toolbarPane; - toolbarPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, TOOLBARPANEVGAP)); - Dimension dim = new Dimension(); - dim.height = plus.getToolBarHeight(); - toolbarPane.setPreferredSize(dim); - toolbarPane.setFocusable(true); - JPanel[] paneArray = plus.toolbarPanes4Form(); - for (int i = 0; i < paneArray.length; i++) { - toolbarPane.add(paneArray[i]); - } - return toolbarPane; - } - } - - /** - * 生成报表设计和表单设计的编辑区域 - * - * @return 返回编辑区域 - */ - @Override - public JTemplate createNewTemplate() { - return new JWorkBook(); } - - /** - * 创建论坛登录面板, chart那边不需要 - * - * @return 面板组件 - */ - @Override - public Component createBBSLoginPane() { - if (userInfoPane == null) { - userInfoPane = UserInfoPane.getInstance(); - } - return userInfoPane; - } - - /** - * 创建alphafine打开面板 - * - * @return 面板组件 - */ - @Override - public Component createAlphaFinePane() { - return AlphaFinePane.getAlphaFinePane(); - } - - /** - * 收集用户信息吗 - */ - @Override - protected void collectUserInformation() { - //定制的就不弹出来了 - if (!ComparatorUtils.equals(ProductConstants.APP_NAME, ProductConstants.DEFAULT_APP_NAME)) { - return; - } - - DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); - final String key = envManager.getActivationKey(); - //本地验证通过 - if (ActiveKeyGenerator.localVerify(key)) { - onLineVerify(envManager, key); - UserInfoLabel.showBBSDialog(); - return; - } - - if (StableUtils.checkDesignerActive(readOldKey())) { - //只要有老的key, 就不弹窗, 下次启动的时候, 在线验证下就行. - String newKey = ActiveKeyGenerator.generateActiveKey(); - envManager.setActivationKey(newKey); - UserInfoLabel.showBBSDialog(); - return; - } - - CollectUserInformationDialog activeDialog = new CollectUserInformationDialog( - DesignerContext.getDesignerFrame()); - activeDialog.setVisible(true); - } - - private void onLineVerify(DesignerEnvManager envManager, final String key) { - int status = envManager.getActiveKeyStatus(); - //没有联网验证过 - if (status != 0) { - ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() - .setNameFormat("net-verify-thread-%s").build(); - ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( - 1, 1, - 0L, TimeUnit.MILLISECONDS, - new LinkedBlockingQueue(1), - namedThreadFactory); - threadPoolExecutor.execute(new Runnable() { - @Override - public void run() { - ActiveKeyGenerator.onLineVerify(key); - } - }); - } - } - - private File getOldEnvFile(String folderName) { - String userHome = System.getProperty("user.home"); - if (userHome == null) { - userHome = System.getProperty("userHome"); - } - String filePath = StableUtils.pathJoin(userHome, folderName, ProductConstants.APP_NAME + "Env.xml"); - return new File(filePath); - } - - private String getOldActiveKeyFromFile(File envFile) { - if (!envFile.exists()) { - return StringUtils.EMPTY; - } - - DesignerEnvManager temp = new DesignerEnvManager(); - try { - XMLTools.readFileXML(temp, envFile); - } catch (Exception e) { - FineLoggerFactory.getLogger().error(e.getMessage(), e); - } - return temp.getActivationKey(); - } - - //默认只从7.0和711的设计器里读取key - private String readOldKey() { - File file71 = getOldEnvFile(OLD_ENV_FOLDER_71); - if (!file71.exists()) { - File file70 = getOldEnvFile(OLD_ENV_FOLDER_70); - return getOldActiveKeyFromFile(file70); - } - - return getOldActiveKeyFromFile(file71); - } - - /** - * 设计器退出时, 做的一些操作. - */ - @Override - public void shutDown() { - InformationCollector collector = InformationCollector.getInstance(); - collector.collectStopTime(); - collector.saveXMLFile(); - } - } diff --git a/designer-realize/src/main/java/com/fr/start/Designer4Debug.java b/designer-realize/src/main/java/com/fr/start/Designer4Debug.java index 0786fee6f..6704b9c8c 100644 --- a/designer-realize/src/main/java/com/fr/start/Designer4Debug.java +++ b/designer-realize/src/main/java/com/fr/start/Designer4Debug.java @@ -6,6 +6,6 @@ package com.fr.start; public class Designer4Debug { public static void main(String... args) { - org.swingexplorer.Launcher.main(new String[]{"com.fr.start.Designer"}); + org.swingexplorer.Launcher.main(new String[]{"com.fr.start.MainDesigner"}); } } diff --git a/designer-realize/src/main/java/com/fr/start/DesignerInitial.java b/designer-realize/src/main/java/com/fr/start/DesignerInitial.java index e6b9e4f46..856208f40 100644 --- a/designer-realize/src/main/java/com/fr/start/DesignerInitial.java +++ b/designer-realize/src/main/java/com/fr/start/DesignerInitial.java @@ -14,13 +14,13 @@ import com.fr.event.Null; */ public class DesignerInitial { - private static volatile Designer designer; + private static volatile MainDesigner designer; public static void init(final String... args) { UIUtil.invokeLaterIfNeeded(new Runnable() { @Override public void run() { - designer = new Designer(args); + designer = new MainDesigner(args); } }); } diff --git a/designer-realize/src/main/java/com/fr/start/DesignerJavaRuntime.java b/designer-realize/src/main/java/com/fr/start/DesignerJavaRuntime.java new file mode 100644 index 000000000..351bf1e44 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/DesignerJavaRuntime.java @@ -0,0 +1,71 @@ +package com.fr.start; + +import com.fr.general.ComparatorUtils; +import com.fr.process.engine.core.AbstractJavaRuntime; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.os.OperatingSystem; + +/** + * 设计器Java运行环境 + * + * @author hades + * @version 10.0 + * Created by hades on 2019/9/22 + */ +public class DesignerJavaRuntime extends AbstractJavaRuntime { + + private static final String DOT = "."; + private static final String INSTALL4J = ".install4j"; + private static final String JAVA_EXEC = "java"; + private static final String WIN_JRE_BIN = StableUtils.pathJoin("jre", "bin"); + private static final String MAC_JRE_BIN = StableUtils.pathJoin("jre.bundle", "Contents", "Home", "jre", "bin"); + private static final String[] DEBUG_OPTIONS = new String[]{"-Dfile.encoding=UTF-8", "-Xmx2048m"}; + + private static final DesignerJavaRuntime INSTANCE = new DesignerJavaRuntime(); + + public static DesignerJavaRuntime getInstance() { + return INSTANCE; + } + + @Override + public String getJavaExec() { + String installHome = StableUtils.getInstallHome(); + if (!isInstallVersion()) { + return JAVA_EXEC; + } + if (OperatingSystem.isWindows()) { + return StableUtils.pathJoin(installHome, WIN_JRE_BIN, JAVA_EXEC); + } + if (OperatingSystem.isMacos()) { + + return StableUtils.pathJoin(installHome, INSTALL4J, MAC_JRE_BIN, JAVA_EXEC); + } + if (OperatingSystem.isUnix()) { + return StableUtils.pathJoin(installHome, WIN_JRE_BIN, JAVA_EXEC); + + } + return StringUtils.EMPTY; + } + + private boolean isInstallVersion() { + return !ComparatorUtils.equals(StableUtils.getInstallHome(), DOT); + } + + + /** + * 非安装版本需要添加下内存参数 + * 工程中可根据需要修改 + * + * @return 参数 + */ + @Override + public String[] getJvmOptions() { + if (isInstallVersion()) { + return super.getJvmOptions(); + } else { + return DEBUG_OPTIONS; + } + + } +} diff --git a/designer-realize/src/main/java/com/fr/start/DesignerProcessType.java b/designer-realize/src/main/java/com/fr/start/DesignerProcessType.java new file mode 100644 index 000000000..6a530125c --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/DesignerProcessType.java @@ -0,0 +1,18 @@ +package com.fr.start; + +import com.fr.process.FineProcessType; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2020/1/14 + */ +public enum DesignerProcessType implements FineProcessType { + + INSTANCE; + + @Override + public String obtain() { + return "designer"; + } +} diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java new file mode 100644 index 000000000..ec32a6469 --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -0,0 +1,538 @@ +package com.fr.start; + +import com.fr.base.BaseUtils; +import com.fr.base.vcs.DesignerMode; +import com.fr.design.DesignerEnvManager; +import com.fr.design.RestartHelper; +import com.fr.design.actions.core.ActionFactory; +import com.fr.design.actions.file.WebPreviewUtils; +import com.fr.design.actions.file.newReport.NewPolyReportAction; +import com.fr.design.actions.file.newReport.NewWorkBookAction; +import com.fr.design.actions.server.ServerConfigManagerAction; +import com.fr.design.actions.server.StyleListAction; +import com.fr.design.actions.server.WidgetManagerAction; +import com.fr.design.base.mode.DesignModeContext; +import com.fr.design.constants.UIConstants; +import com.fr.design.dialog.ErrorDialog; +import com.fr.design.file.HistoryTemplateListCache; +import com.fr.design.file.HistoryTemplateListPane; +import com.fr.design.file.MutilTempalteTabPane; +import com.fr.design.fun.MenuHandler; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIPreviewButton; +import com.fr.design.gui.imenu.UIMenuItem; +import com.fr.design.gui.imenu.UIPopupMenu; +import com.fr.design.gui.itoolbar.UILargeToolbar; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.ActiveKeyGenerator; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.InformationCollector; +import com.fr.design.mainframe.JTemplate; +import com.fr.design.mainframe.JWorkBook; +import com.fr.design.mainframe.alphafine.component.AlphaFinePane; +import com.fr.design.mainframe.bbs.UserInfoLabel; +import com.fr.design.mainframe.bbs.UserInfoPane; +import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; +import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; +import com.fr.design.mainframe.toolbar.ToolBarMenuDockPlus; +import com.fr.design.menu.KeySetUtils; +import com.fr.design.menu.MenuDef; +import com.fr.design.menu.SeparatorDef; +import com.fr.design.menu.ShortCut; +import com.fr.design.module.DesignModuleFactory; +import com.fr.design.utils.concurrent.ThreadFactoryBuilder; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.exit.DesignerExiter; +import com.fr.general.ComparatorUtils; +import com.fr.log.FineLoggerFactory; +import com.fr.module.Module; +import com.fr.module.ModuleContext; +import com.fr.process.engine.core.FineProcessContext; +import com.fr.process.engine.core.FineProcessEngineEvent; +import com.fr.runtime.FineRuntime; +import com.fr.stable.ProductConstants; +import com.fr.stable.StableUtils; +import com.fr.stable.StringUtils; +import com.fr.stable.lifecycle.ErrorType; +import com.fr.stable.lifecycle.LifecycleFatalError; +import com.fr.stable.xml.XMLTools; +import com.fr.start.module.StartupArgs; +import com.fr.start.server.ServerTray; +import com.fr.third.org.apache.commons.lang3.time.StopWatch; +import com.fr.workspace.WorkContext; + +import javax.swing.JComponent; +import javax.swing.JOptionPane; +import javax.swing.JPanel; +import javax.swing.border.MatteBorder; +import java.awt.Component; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.io.File; +import java.util.ArrayList; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.concurrent.ThreadFactory; +import java.util.concurrent.ThreadPoolExecutor; +import java.util.concurrent.TimeUnit; + +public class MainDesigner extends BaseDesigner { + + private static final int TOOLBARPANEVGAP = -4; + private static final int PREVIEW_DOWN_X_GAP = 92; + private static final int GAP = 7; + private static final String OLD_ENV_FOLDER_71 = ".FineReport71"; + private static final String OLD_ENV_FOLDER_70 = ".FineReport70"; + + private UserInfoPane userInfoPane; + private UIButton saveButton; + private UIButton undo; + private UIButton redo; + private UIButton[] upToolBar; + private UIPreviewButton run; + + public MainDesigner(String[] args) { + super(args); + } + + /** + * 设计器启动的Main方法 + * + * @param args 参数 + */ + public static void main(String[] args) { + + StopWatch watch = new StopWatch(); + watch.start(); + //启动运行时 + FineRuntime.start(); + Module designerRoot = ModuleContext.parseRoot("designer-startup.xml"); + //传递启动参数 + designerRoot.setSingleton(StartupArgs.class, new StartupArgs(args)); + try { + designerRoot.start(); + } catch (LifecycleFatalError fatal) { + SplashContext.getInstance().hide(); + if (ErrorType.FINEDB.equals(fatal.getErrorType())) { + StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.FINEDB_PROBLEM.getId(), + DesignerErrorMessage.FINEDB_PROBLEM.getMessage(), + fatal.getMessage()); + JOptionPane.showMessageDialog(null, fatal.getMessage(), Toolkit.i18nText("Fine-Design_Basic_Error"), JOptionPane.ERROR_MESSAGE); + } + FineLoggerFactory.getLogger().error(fatal.getMessage(), fatal); + StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.UNEXCEPTED_START_FAILED.getId(), + DesignerErrorMessage.UNEXCEPTED_START_FAILED.getMessage(), + fatal.getMessage()); + ErrorDialog dialog = new ErrorDialog(null, Toolkit.i18nText("Fine-Design_Error_Start_Apology_Message"), + Toolkit.i18nText("Fine-Design_Error_Start_Report"), + fatal.getMessage()) { + @Override + protected void okEvent() { + dispose(); + DesignerExiter.getInstance().execute(); + } + + @Override + protected void restartEvent() { + dispose(); + RestartHelper.restart(); + } + }; + dialog.setVisible(true); + } + + if (WorkContext.getCurrent().isLocal()) { + //初始化一下serverTray + ServerTray.init(); + } + FineLoggerFactory.getLogger().info("Designer started.Time used {} ms", watch.getTime()); + watch.stop(); + } + + /** + * 创建新建文件的快捷方式数组。 + * + * @return 返回快捷方式的数组 + */ + @Override + public ShortCut[] createNewFileShortCuts() { + ArrayList shortCuts = new ArrayList(); +// shortCuts.add(new NewWorkBookXAction()); + shortCuts.add(new NewWorkBookAction()); + shortCuts.add(new NewPolyReportAction()); + try { + if (DesignModuleFactory.getNewFormAction() != null) { + shortCuts.add((ShortCut) DesignModuleFactory.getNewFormAction().newInstance()); + } + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return shortCuts.toArray(new ShortCut[shortCuts.size()]); + } + + @Override + protected MenuDef createServerMenuDef(ToolBarMenuDockPlus plus) { + MenuDef menuDef = super.createServerMenuDef(plus); + + if (WorkContext.getCurrent() == null) { + return menuDef; + } + + if (!DesignerMode.isAuthorityEditing()) { + menuDef.addShortCut(SeparatorDef.DEFAULT); + + if (WorkContext.getCurrent().isRoot()) { + menuDef.addShortCut(new ServerConfigManagerAction(), new StyleListAction(), new WidgetManagerAction()); + if (ActionFactory.getChartPreStyleAction() != null) { + menuDef.addShortCut(ActionFactory.getChartPreStyleAction()); + } + if (ActionFactory.getChartEmptyDataStyleAction() != null) { + menuDef.addShortCut(ActionFactory.getChartEmptyDataStyleAction()); + } + if (ActionFactory.getChartMapEditorAction() != null) { + menuDef.addShortCut(ActionFactory.getChartMapEditorAction()); + } + } + + insertMenu(menuDef, MenuHandler.SERVER); + } + + return menuDef; + } + + + /** + * 创建设计器上几个比较大的图标:新建cpt,保存,前进,后退,运行。 + * + * @return 返回大图标对应的工具栏 + */ + @Override + public UILargeToolbar createLargeToolbar() { + UILargeToolbar largeToolbar = super.createLargeToolbar(); + largeToolbar.setLayout(new FlowLayout(FlowLayout.CENTER, 0, 4)); + largeToolbar.add(generateEmptyGap(1)); + createRunButton(largeToolbar); + largeToolbar.add(run); + largeToolbar.add(generateEmptyGap(GAP)); + largeToolbar.addSeparator(new Dimension(2, 42)); + largeToolbar.setBorder(new MatteBorder(new Insets(0, 0, 1, 0), UIConstants.LINE_COLOR)); + return largeToolbar; + } + + private JPanel generateEmptyGap(final int width) { + JPanel panel = new JPanel() { + @Override + public Dimension getPreferredSize() { + Dimension dim = super.getPreferredSize(); + dim.width = width; + return dim; + } + }; + panel.setBackground(null); + panel.setOpaque(false); + return panel; + } + + /** + * 创建上面一排的工具栏按钮 + * + * @return 按钮 + */ + @Override + public UIButton[] createUp() { + if (upToolBar == null) { + createSaveButton(); + createUndoButton(); + createRedoButton(); + return upToolBar = new UIButton[]{saveButton, undo, redo}; + } + return upToolBar; + } + + + private void createSaveButton() { + saveButton = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/save.png")); + saveButton.setToolTipText(KeySetUtils.SAVE_TEMPLATE.getMenuKeySetName()); + saveButton.set4ToolbarButton(); + saveButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + jt.stopEditing(); + jt.saveTemplate(); + jt.requestFocus(); + } + }); + } + + + private void createUndoButton() { + undo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/undo.png")); + undo.setToolTipText(KeySetUtils.UNDO.getMenuKeySetName()); + undo.set4ToolbarButton(); + undo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + if (jt != null) { + jt.undo(); + } + } + }); + } + + private void createRedoButton() { + redo = new UIButton(BaseUtils.readIcon("/com/fr/design/images/buttonicon/redo.png")); + redo.setToolTipText(KeySetUtils.REDO.getMenuKeySetName()); + redo.set4ToolbarButton(); + redo.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + JTemplate jt = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate(); + if (jt != null) { + jt.redo(); + } + } + }); + } + + private void createRunButton(UILargeToolbar largeToolbar) { + run = new UIPreviewButton(new UIButton(UIConstants.PAGE_BIG_ICON) { + @Override + public Dimension getPreferredSize() { + return new Dimension(34, 34); + } + }, new UIButton(UIConstants.PREVIEW_DOWN) { + @Override + public Dimension getPreferredSize() { + return new Dimension(34, 10); + } + } + ) { + @Override + protected void upButtonClickEvent() { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jt == null) { + return; + } + WebPreviewUtils.preview(jt); + } + + @Override + protected void downButtonClickEvent() { + final JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jt == null) { + return; + } + + UIPopupMenu menu = new UIPopupMenu(); + + UIMenuItem[] items = jt.createMenuItem4Preview(); + for (int i = 0; i < items.length; i++) { + menu.add(items[i]); + } + GUICoreUtils.showPopupMenu(menu, MutilTempalteTabPane.getInstance(), MutilTempalteTabPane.getInstance().getX() - PREVIEW_DOWN_X_GAP, MutilTempalteTabPane.getInstance().getY() - 1 + MutilTempalteTabPane.getInstance().getHeight()); + } + + @Override + public Dimension getPreferredSize() { + // TODO Auto-generated method stub + return new Dimension(34, 46); + } + }; + run.setExtraPainted(false); + run.set4Toolbar(); + run.getUpButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Basic_Preview")); + run.getDownButton().setToolTipText(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Dropdown_More_Preview")); + } + + @Override + protected void refreshLargeToolbarState() { + JTemplate jt = HistoryTemplateListCache.getInstance().getCurrentEditingTemplate(); + if (jt == null) { + return; + } + saveButton.setEnabled(!jt.isSaved() && !DesignModeContext.isVcsMode()); + MutilTempalteTabPane.getInstance().refreshOpenedTemplate(HistoryTemplateListCache.getInstance().getHistoryList()); + MutilTempalteTabPane.getInstance().repaint(); + if (DesignerEnvManager.getEnvManager().isSupportUndo()) { + undo.setEnabled(jt.canUndo()); + redo.setEnabled(jt.canRedo()); + } else { + undo.setEnabled(false); + redo.setEnabled(false); + } + + run.getUpButton().setIcon(jt.getPreviewLargeIcon()); + + } + + /** + * 生成工具栏 + * + * @param toolbarComponent 工具栏 + * @param plus 对象 + * @return 更新后的toolbar + */ + @Override + public JComponent resetToolBar(JComponent toolbarComponent, ToolBarMenuDockPlus plus) { + //如果是处于权限编辑状态 + if (DesignerMode.isAuthorityEditing()) { + if (plus instanceof JWorkBook && plus.toolbars4Target() == null) { + //聚合块编辑 + return super.polyToolBar(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Report_Privilege_Poly_Block_Edit")); + } else { + return plus.toolBar4Authority(); + } + } + + if (plus.toolbarPanes4Form().length == 0) { + return super.resetToolBar(toolbarComponent, plus); + } else { + JPanel toolbarPane; + toolbarPane = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, TOOLBARPANEVGAP)); + Dimension dim = new Dimension(); + dim.height = plus.getToolBarHeight(); + toolbarPane.setPreferredSize(dim); + toolbarPane.setFocusable(true); + JPanel[] paneArray = plus.toolbarPanes4Form(); + for (int i = 0; i < paneArray.length; i++) { + toolbarPane.add(paneArray[i]); + } + return toolbarPane; + } + } + + + /** + * 生成报表设计和表单设计的编辑区域 + * + * @return 返回编辑区域 + */ + @Override + public JTemplate createNewTemplate() { + return new JWorkBook(); + } + + /** + * 创建论坛登录面板, chart那边不需要 + * + * @return 面板组件 + */ + @Override + public Component createBBSLoginPane() { + if (userInfoPane == null) { + userInfoPane = UserInfoPane.getInstance(); + } + return userInfoPane; + } + + /** + * 创建alphafine打开面板 + * + * @return 面板组件 + */ + @Override + public Component createAlphaFinePane() { + return AlphaFinePane.getAlphaFinePane(); + } + + /** + * 收集用户信息吗 + */ + @Override + protected void collectUserInformation() { + //定制的就不弹出来了 + if (!ComparatorUtils.equals(ProductConstants.APP_NAME, ProductConstants.DEFAULT_APP_NAME)) { + return; + } + + DesignerEnvManager envManager = DesignerEnvManager.getEnvManager(); + final String key = envManager.getActivationKey(); + //本地验证通过 + if (ActiveKeyGenerator.localVerify(key)) { + onLineVerify(envManager, key); + UserInfoLabel.showBBSDialog(); + return; + } + + if (StableUtils.checkDesignerActive(readOldKey())) { + //只要有老的key, 就不弹窗, 下次启动的时候, 在线验证下就行. + String newKey = ActiveKeyGenerator.generateActiveKey(); + envManager.setActivationKey(newKey); + UserInfoLabel.showBBSDialog(); + return; + } + + CollectUserInformationDialog activeDialog = new CollectUserInformationDialog( + DesignerContext.getDesignerFrame()); + activeDialog.setVisible(true); + } + + private void onLineVerify(DesignerEnvManager envManager, final String key) { + int status = envManager.getActiveKeyStatus(); + //没有联网验证过 + if (status != 0) { + ThreadFactory namedThreadFactory = new ThreadFactoryBuilder() + .setNameFormat("net-verify-thread-%s").build(); + ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor( + 1, 1, + 0L, TimeUnit.MILLISECONDS, + new LinkedBlockingQueue(1), + namedThreadFactory); + threadPoolExecutor.execute(new Runnable() { + @Override + public void run() { + ActiveKeyGenerator.onLineVerify(key); + } + }); + } + } + + private File getOldEnvFile(String folderName) { + String userHome = System.getProperty("user.home"); + if (userHome == null) { + userHome = System.getProperty("userHome"); + } + String filePath = StableUtils.pathJoin(userHome, folderName, ProductConstants.APP_NAME + "Env.xml"); + return new File(filePath); + } + + private String getOldActiveKeyFromFile(File envFile) { + if (!envFile.exists()) { + return StringUtils.EMPTY; + } + + DesignerEnvManager temp = new DesignerEnvManager(); + try { + XMLTools.readFileXML(temp, envFile); + } catch (Exception e) { + FineLoggerFactory.getLogger().error(e.getMessage(), e); + } + return temp.getActivationKey(); + } + + //默认只从7.0和711的设计器里读取key + private String readOldKey() { + File file71 = getOldEnvFile(OLD_ENV_FOLDER_71); + if (!file71.exists()) { + File file70 = getOldEnvFile(OLD_ENV_FOLDER_70); + return getOldActiveKeyFromFile(file70); + } + + return getOldActiveKeyFromFile(file71); + } + + /** + * 设计器退出时, 做的一些操作. + */ + @Override + public void shutDown() { + InformationCollector collector = InformationCollector.getInstance(); + collector.collectStopTime(); + collector.saveXMLFile(); + } + +} diff --git a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java index 1d781d31e..0adb4a6e2 100644 --- a/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java +++ b/designer-realize/src/main/java/com/fr/start/module/DesignerStartup.java @@ -3,12 +3,17 @@ package com.fr.start.module; import com.fr.concurrent.NamedThreadFactory; import com.fr.design.DesignerEnvManager; +import com.fr.design.RestartHelper; +import com.fr.design.dialog.TipDialog; import com.fr.design.fun.OemProcessor; import com.fr.design.fun.impl.GlobalListenerProviderManager; +import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; import com.fr.design.mainframe.messagecollect.StartupMessageCollector; +import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; import com.fr.design.ui.util.UIUtil; import com.fr.design.utils.DesignUtils; import com.fr.design.utils.DesignerPort; +import com.fr.exit.DesignerExiter; import com.fr.general.ComparatorUtils; import com.fr.log.FineLoggerFactory; import com.fr.module.Activator; @@ -17,6 +22,7 @@ import com.fr.record.analyzer.Metrics; import com.fr.stable.BuildContext; import com.fr.stable.ProductConstants; import com.fr.stable.StableUtils; +import com.fr.start.DesignerProcessType; import com.fr.start.OemHandler; import com.fr.start.ServerStarter; import com.fr.start.SplashContext; @@ -26,6 +32,8 @@ import com.fr.start.server.FineEmbedServer; import com.fr.value.NotNullLazyValue; import org.jetbrains.annotations.NotNull; +import javax.swing.JFrame; +import javax.swing.JOptionPane; import java.io.File; import java.util.concurrent.ExecutorService; @@ -48,12 +56,35 @@ public class DesignerStartup extends Activator { BuildContext.setBuildFilePath("/com/fr/stable/build.properties"); // 检查是否是-Ddebug = true 启动 并切换对应的端口以及环境配置文件 checkDebugStart(); + // 初始化look and feel + DesignUtils.initLookAndFeel(); + if (DesignUtils.isPortOccupied()) { + StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.PORT_OCCUPIED.getId(), + DesignerErrorMessage.PORT_OCCUPIED.getMessage()); + DesignerPort.getInstance().resetPort(); + } if (DesignUtils.isStarted()) { // 如果端口被占用了 说明程序已经运行了一次,也就是说,已经建立一个监听服务器,现在只要给服务器发送命令就好了 final String[] args = startupArgsValue.getValue().get(); DesignUtils.clientSend(args); FineLoggerFactory.getLogger().info("The Designer Has Been Started"); - System.exit(0); + if (args.length == 0) { + TipDialog dialog = new TipDialog(null, DesignerProcessType.INSTANCE.obtain()) { + @Override + protected void endEvent() { + dispose(); + DesignUtils.clientSend(new String[]{"end"}); + RestartHelper.restart(); + } + + @Override + protected void cancelEvent() { + dispose(); + } + }; + dialog.setVisible(true); + } + DesignerExiter.getInstance().execute(); return; } // 快快显示启动画面 @@ -137,7 +168,7 @@ public class DesignerStartup extends Activator { */ private void setDebugEnv() { - DesignUtils.setPort(DesignerPort.DEBUG_MESSAGE_PORT); + DesignUtils.setPort(DesignerPort.getInstance().getDebugMessagePort()); DesignerEnvManager.setEnvFile(new File(StableUtils.pathJoin( ProductConstants.getEnvHome(), ProductConstants.APP_NAME + "Env_debug.xml" diff --git a/designer-realize/src/test/java/com.fr/design/mainframe/JFileTest.java b/designer-realize/src/test/java/com.fr/design/mainframe/JFileTest.java index 3b5bd1a14..1fe29fa5d 100644 --- a/designer-realize/src/test/java/com.fr/design/mainframe/JFileTest.java +++ b/designer-realize/src/test/java/com.fr/design/mainframe/JFileTest.java @@ -19,6 +19,7 @@ import com.fr.report.worksheet.WorkSheet; import com.fr.restriction.Restrictions; import com.fr.stable.module.Module; import com.fr.start.Designer; +import com.fr.start.MainDesigner; import junit.framework.TestCase; import org.junit.Assert; @@ -33,7 +34,7 @@ public class JFileTest extends TestCase { Restrictions.register(ReportRestrictionScene.CELL_COUNT, new CellCountRestriction()); ModuleContext.startModule(Module.PAGE_MODULE); ModuleContext.startModule(Module.VIEW_MODULE); - Designer designer = new Designer(new String[0]); + MainDesigner designer = new MainDesigner(new String[0]); } public void testJWorkBookSetPicture() {