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 index 14997f8687..e4cf0c8e71 100644 --- a/designer-base/src/main/java/com/fr/design/dialog/TipDialog.java +++ b/designer-base/src/main/java/com/fr/design/dialog/TipDialog.java @@ -7,9 +7,7 @@ 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 javax.swing.*; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; @@ -27,16 +25,16 @@ public abstract class TipDialog extends JDialog implements ActionListener { private UIButton endButton; private UIButton cancelButton; - public TipDialog(Frame parent, String type) { + public TipDialog(Frame parent, String type, String tip, String endText, String cancelText) { 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")); + iconLabel.setIcon(IOUtils.readIcon("com/fr/design/images/error/error2.png")); iconPane.add(iconLabel); - iconPane.setPreferredSize(new Dimension(100, 100)); + iconPane.setPreferredSize(new Dimension(50, 50)); JPanel tipPane = FRGUIPaneFactory.createBorderLayout_L_Pane(); - UILabel tipLabel = new UILabel(Toolkit.i18nText("Fine-Design_Last_Designer_Process_Not_Exist")); + UILabel tipLabel = new UILabel(tip); tipPane.add(tipLabel); northPane.add(iconPane, BorderLayout.WEST); northPane.add(tipPane, BorderLayout.CENTER); @@ -51,7 +49,7 @@ public abstract class TipDialog extends JDialog implements ActionListener { 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 = new UIButton(endText); endButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { @@ -59,7 +57,7 @@ public abstract class TipDialog extends JDialog implements ActionListener { } }); buttonPane.add(endButton); - cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel")); + cancelButton = new UIButton(cancelText); cancelButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { 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 46bdd52a83..cd02bc5c5e 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,13 +1,29 @@ package com.fr.design.utils; +import com.fr.design.DesignerEnvManager; +import com.fr.design.RestartHelper; +import com.fr.design.dialog.TipDialog; +import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ilable.UILabel; +import com.fr.design.gui.itextfield.UITextField; import com.fr.design.i18n.Toolkit; +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.exit.DesignerExiter; import com.fr.general.ComparatorUtils; +import com.fr.general.IOUtils; +import com.fr.stable.StringUtils; 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; +import javax.swing.*; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; /** * 为的就是能替换 DesignPort.class 实现多开,因此避免编译器常量编译展开优化 @@ -69,27 +85,138 @@ public class DesignerPort implements XMLReadable, XMLWriter { 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(); + public void resetPort() { + + TipDialog dialog = new TipDialog(null, + StringUtils.EMPTY, + Toolkit.i18nText("Fine-Design_Port_Found_Port_Conflict"), + Toolkit.i18nText("Fine-Design_End_Occupied_Process"), + Toolkit.i18nText("Fine-Design_Modify_Designer_Port")) { + @Override + protected void endEvent() { + dispose(); + } + + @Override + protected void cancelEvent() { + new ResetPortDialog(); + } + }; + dialog.setVisible(true); + DesignerExiter.getInstance().execute(); + } + + private class ResetPortDialog extends JDialog { + private UITextField portFiled; + private UILabel warnLabel; + private UIButton okButton; + + private ResetPortDialog() { + this.setLayout(new BorderLayout()); + this.setModal(true); + this.portFiled = new UITextField(); + this.portFiled.setPreferredSize(new Dimension(180, 20)); + this.portFiled.getDocument().addDocumentListener(new DocumentListener() { + @Override + public void insertUpdate(DocumentEvent e) { + checkValid(); + } + + @Override + public void removeUpdate(DocumentEvent e) { + checkValid(); + } + + @Override + public void changedUpdate(DocumentEvent e) { + checkValid(); + } + }); + JPanel iconPanel = new JPanel(); + UILabel iconLabel = new UILabel(); + iconLabel.setIcon(IOUtils.readIcon("com/fr/design/images/edit/edit_typing.png")); + iconPanel.add(iconLabel); + iconPanel.add(iconLabel); + JPanel textPane = FRGUIPaneFactory.createVerticalFlowLayout_Pane(true, FlowLayout.LEADING, 0, 10); + textPane.add(new UILabel(Toolkit.i18nText("Fine-Design_Modify_Designer_Port_Tip"))); + textPane.add(portFiled); + warnLabel = new UILabel(); + warnLabel.setVisible(false); + warnLabel.setForeground(Color.RED); + okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Button_OK")); + okButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + int value = Integer.parseInt(portFiled.getText().trim()); + if (ComparatorUtils.equals("true", System.getProperty("debug"))) { + setDebugMessagePort(value); + } else { + setMessagePort(value); + } + dispose(); + DesignerEnvManager.getEnvManager().saveXMLFile(); + RestartHelper.restart(); + } + }); + UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Button_Cancel")); + cancelButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + dispose(); + } + }); + JPanel buttonPane = new JPanel(new FlowLayout(FlowLayout.RIGHT)); + buttonPane.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15)); + buttonPane.add(okButton); + buttonPane.add(cancelButton); + JPanel controlPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + controlPane.add(buttonPane, BorderLayout.EAST); + JPanel northPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + northPane.add(iconPanel, BorderLayout.WEST); + northPane.add(textPane, BorderLayout.CENTER); + JPanel centerPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + centerPane.add(warnLabel); + JPanel southPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + southPane.add(controlPane); + this.add(northPane, BorderLayout.NORTH); + this.add(centerPane, BorderLayout.CENTER); + this.add(southPane, BorderLayout.SOUTH); + this.setSize(300, 150); + this.setTitle(Toolkit.i18nText("Fine-Design_Modify_Designer_Port")); + this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + this.setResizable(false); + this.setAlwaysOnTop(true); + GUICoreUtils.centerWindow(this); + this.setVisible(true); } - if (ComparatorUtils.equals("true", System.getProperty("debug"))) { - setDebugMessagePort(value); - } else { - setMessagePort(value); + + private void checkValid() { + String port = this.portFiled.getText().trim(); + if (StringUtils.isEmpty(port)) { + okButton.setEnabled(false); + return; + } + + int value; + try { + value = Integer.parseInt(port); + } catch (NumberFormatException ignore) { + warnLabel.setText(Toolkit.i18nText("Fine-Design_Modify_Designer_Port_Not_Number_Tip")); + warnLabel.setVisible(true); + okButton.setEnabled(false); + return; + } + + if (value < MIN_PORT || value > MAX_PORT) { + warnLabel.setText(Toolkit.i18nText("Fine-Design_Modify_Designer_Port_Out_Of_Range_Tip")); + warnLabel.setVisible(true); + okButton.setEnabled(false); + return; + } + + warnLabel.setVisible(false); + okButton.setEnabled(true); } - 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 index 8264d8db91..c7319f4c63 100644 --- a/designer-base/src/main/java/com/fr/exit/DesignerExiter.java +++ b/designer-base/src/main/java/com/fr/exit/DesignerExiter.java @@ -21,10 +21,9 @@ public class DesignerExiter { } public void execute() { - if (FineProcessContext.getParentPipe() == null && DOT.equals(StableUtils.getInstallHome())) { - System.exit(0); - } else { + if (FineProcessContext.getParentPipe() != null || !DOT.equals(StableUtils.getInstallHome())) { FineProcessContext.getParentPipe().fire(FineProcessEngineEvent.DESTROY); } + System.exit(0); } } diff --git a/designer-base/src/main/resources/com/fr/design/images/edit/edit_typing.png b/designer-base/src/main/resources/com/fr/design/images/edit/edit_typing.png new file mode 100644 index 0000000000..929f14137a Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/edit/edit_typing.png differ diff --git a/designer-base/src/main/resources/com/fr/design/images/error/error2.png b/designer-base/src/main/resources/com/fr/design/images/error/error2.png new file mode 100644 index 0000000000..ff0450a5a4 Binary files /dev/null and b/designer-base/src/main/resources/com/fr/design/images/error/error2.png differ 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 d2a8bb01ed..57a6532250 100644 --- a/designer-realize/src/main/java/com/fr/start/Designer.java +++ b/designer-realize/src/main/java/com/fr/start/Designer.java @@ -1,12 +1,5 @@ package com.fr.start; -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等,升级后仍然走的原来逻辑) * @@ -19,21 +12,6 @@ public class Designer { 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); - - process.getPipe().listen(FineProcessEngineEvent.DESTROY, new Listener() { - @Override - public void on(Event event, Null param) { - process.destroy(); - } - }); - + DesignerLauncher.getInstance().start(args); } } diff --git a/designer-realize/src/main/java/com/fr/start/DesignerLauncher.java b/designer-realize/src/main/java/com/fr/start/DesignerLauncher.java new file mode 100644 index 0000000000..38f28346aa --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/DesignerLauncher.java @@ -0,0 +1,55 @@ +package com.fr.start; + +import com.fr.process.FineProcess; +import com.fr.process.engine.FineJavaProcessFactory; +import com.fr.process.engine.core.FineProcessContext; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2020/2/21 + */ +public class DesignerLauncher { + + private static final DesignerLauncher INSTANCE = new DesignerLauncher(); + + private String[] args; + + private DesignerLauncher() { + + } + + public static DesignerLauncher getInstance() { + return INSTANCE; + } + + public void start(String[] args) { + this.args = args; + 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); + DesignerSuperListener.getInstance().start(); + } + + private void beforeExit() { + DesignerSuperListener.getInstance().stopTask(); + FineProcess process = FineProcessContext.getProcess(DesignerProcessType.INSTANCE); + process.destroy(); + } + + public void exit() { + beforeExit(); + DesignerSuperListener.getInstance().stop(); + System.exit(0); + } + + public void restart() { + beforeExit(); + start(args); + } +} diff --git a/designer-realize/src/main/java/com/fr/start/DesignerSubListener.java b/designer-realize/src/main/java/com/fr/start/DesignerSubListener.java new file mode 100644 index 0000000000..3e8663f89e --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/DesignerSubListener.java @@ -0,0 +1,38 @@ +package com.fr.start; + +import com.fr.design.mainframe.DesignerContext; +import com.fr.event.Event; +import com.fr.event.Listener; +import com.fr.event.Null; +import com.fr.process.engine.core.CarryMessageEvent; +import com.fr.process.engine.core.FineProcessContext; +import com.fr.process.engine.core.FineProcessEngineEvent; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2020/2/21 + */ +public class DesignerSubListener { + + public static DesignerSubListener INSTANCE = new DesignerSubListener(); + + public static DesignerSubListener getInstance() { + return INSTANCE; + } + + private DesignerSubListener() { + + } + + public void start() { + FineProcessContext.getParentPipe().listen(FineProcessEngineEvent.READY, new Listener() { + @Override + public void on(Event event, Null param) { + if (DesignerContext.getDesignerFrame() == null || !DesignerContext.getDesignerFrame().isShowing()) { + FineProcessContext.getParentPipe().fire(new CarryMessageEvent(DesignerProcessType.INSTANCE.obtain())); + } + } + }); + } +} diff --git a/designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java b/designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java new file mode 100644 index 0000000000..acbd92271a --- /dev/null +++ b/designer-realize/src/main/java/com/fr/start/DesignerSuperListener.java @@ -0,0 +1,147 @@ +package com.fr.start; + +import com.fr.concurrent.NamedThreadFactory; +import com.fr.design.dialog.ErrorDialog; +import com.fr.design.i18n.Toolkit; +import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; +import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; +import com.fr.design.utils.DesignUtils; +import com.fr.event.Event; +import com.fr.event.Listener; +import com.fr.event.Null; +import com.fr.process.FineProcess; +import com.fr.process.ProcessEventPipe; +import com.fr.process.engine.core.FineProcessContext; +import com.fr.process.engine.core.FineProcessEngineEvent; +import com.fr.stable.StringUtils; + +import java.util.concurrent.Executors; +import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; +import java.util.concurrent.TimeUnit; + +/** + * @author hades + * @version 10.0 + * Created by hades on 2020/2/21 + */ +public class DesignerSuperListener { + + private static final DesignerSuperListener INSTANCE = new DesignerSuperListener(); + private static final int ONCE_DELAY = 90; + private static final int FIXED_DELAY = 0; + private static final int FIXED_FREQ = 2; + + private final ScheduledExecutorService service = Executors.newScheduledThreadPool(2, new NamedThreadFactory("DesignerListener")); + + private FineProcess process; + private ScheduledFuture fixedFuture; + private ScheduledFuture onceFuture; + + private DesignerSuperListener() { + + } + + public static DesignerSuperListener getInstance() { + return INSTANCE; + } + + public void start() { + process = FineProcessContext.getProcess(DesignerProcessType.INSTANCE); + startExitListener(); + startFrameListener(); + startFallBackListener(); + } + + private void startExitListener() { + process.getPipe().listen(FineProcessEngineEvent.DESTROY, new Listener() { + @Override + public void on(Event event, Null param) { + DesignerLauncher.getInstance().exit(); + } + }); + } + + private void startFrameListener() { + onceFuture = service.schedule(new Runnable() { + @Override + public void run() { + ProcessEventPipe pipe = process.getPipe(); + pipe.fire(FineProcessEngineEvent.READY); + if (StringUtils.isNotEmpty(pipe.info())) { + frameReport(); + } + } + }, ONCE_DELAY, TimeUnit.SECONDS); + + } + + private void frameReport() { + DesignUtils.initLookAndFeel(); + StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.UNEXCEPTED_START_FAILED.getId(), + DesignerErrorMessage.UNEXCEPTED_START_FAILED.getMessage(), + StringUtils.EMPTY); + ErrorDialog dialog = new ErrorDialog(null, + Toolkit.i18nText("Fine-Design_Error_Start_Apology_Message"), + Toolkit.i18nText("Fine-Design_Error_Start_Report"), + Toolkit.i18nText(DesignerErrorMessage.UNEXCEPTED_START_FAILED.getMessage())) { + @Override + protected void okEvent() { + dispose(); + } + + @Override + protected void restartEvent() { + dispose(); + DesignerLauncher.getInstance().restart(); + } + }; + dialog.setVisible(true); + DesignerLauncher.getInstance().exit(); + } + + private void startFallBackListener() { + fixedFuture = service.scheduleAtFixedRate(new Runnable() { + @Override + public void run() { + if (!process.isAlive()) { + fallBackReport(); + } + } + }, FIXED_DELAY, FIXED_FREQ, TimeUnit.SECONDS); + } + + private void fallBackReport() { + DesignUtils.initLookAndFeel(); + StartErrorMessageCollector.getInstance().record(DesignerErrorMessage.UNEXCEPTED_FALL_BACK.getId(), + DesignerErrorMessage.UNEXCEPTED_FALL_BACK.getMessage(), + StringUtils.EMPTY); + ErrorDialog dialog = new ErrorDialog(null, + Toolkit.i18nText("Fine-Design_Error_Fall_Back_Apology_Message"), + Toolkit.i18nText("Fine-Design_Error_Fall_Back_Report"), + Toolkit.i18nText(DesignerErrorMessage.UNEXCEPTED_FALL_BACK.getMessage())) { + @Override + protected void okEvent() { + dispose(); + } + + @Override + protected void restartEvent() { + dispose(); + DesignerLauncher.getInstance().restart(); + } + }; + dialog.setVisible(true); + DesignerLauncher.getInstance().exit(); + } + + public void stopTask() { + onceFuture.cancel(false); + fixedFuture.cancel(false); + } + + public void stop() { + stopTask(); + service.shutdown(); + } +} diff --git a/designer-realize/src/main/java/com/fr/start/MainDesigner.java b/designer-realize/src/main/java/com/fr/start/MainDesigner.java index ec32a64699..238b035125 100644 --- a/designer-realize/src/main/java/com/fr/start/MainDesigner.java +++ b/designer-realize/src/main/java/com/fr/start/MainDesigner.java @@ -47,8 +47,6 @@ 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; 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 0adb4a6e28..3dd7322f61 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 @@ -7,6 +7,7 @@ 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.i18n.Toolkit; import com.fr.design.mainframe.messagecollect.StartErrorMessageCollector; import com.fr.design.mainframe.messagecollect.StartupMessageCollector; import com.fr.design.mainframe.messagecollect.entity.DesignerErrorMessage; @@ -15,6 +16,7 @@ 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.general.IOUtils; import com.fr.log.FineLoggerFactory; import com.fr.module.Activator; import com.fr.record.analyzer.EnableMetrics; @@ -69,7 +71,11 @@ public class DesignerStartup extends Activator { DesignUtils.clientSend(args); FineLoggerFactory.getLogger().info("The Designer Has Been Started"); if (args.length == 0) { - TipDialog dialog = new TipDialog(null, DesignerProcessType.INSTANCE.obtain()) { + TipDialog dialog = new TipDialog(null, + DesignerProcessType.INSTANCE.obtain(), + Toolkit.i18nText("Fine-Design_Last_Designer_Process_Not_Exist"), + Toolkit.i18nText("Fine-Design_End_Occupied_Process"), + Toolkit.i18nText("Fine-Design_Basic_Cancel")) { @Override protected void endEvent() { dispose();