diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/DebugModeMenuDef.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/DebugModeMenuDef.java new file mode 100644 index 0000000000..989e88b5c5 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/DebugModeMenuDef.java @@ -0,0 +1,51 @@ +package com.fr.design.mainframe.toolbar; + +import com.fanruan.gui.UiInspector; +import com.fine.theme.light.ui.laf.FineDarkLaf; +import com.fine.theme.light.ui.laf.FineLightLaf; +import com.fr.design.actions.UpdateAction; +import com.fr.design.gui.UILookAndFeel; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.menu.MenuDef; +import com.fr.design.remote.ui.debug.RemoteDesignNetWorkAction; + +import java.awt.event.ActionEvent; + +/** + * 调试模式菜单 + * + * @author vito + * @since 11.0 + * Created on 2024/9/24 + */ +public class DebugModeMenuDef extends MenuDef { + + public DebugModeMenuDef() { + super("Debug"); + addLookAndFeelMenu(); + addRemotePane(); + } + + private void addUIInspect() { + this.addShortCut(new UpdateAction() { + @Override + public void actionPerformed(ActionEvent e) { + new UiInspector().showInspector(DesignerContext.getDesignerFrame()); + } + }); + } + + private void addLookAndFeelMenu() { + MenuDef lookAndFeel = new MenuDef("Look And Feel", 'L'); + lookAndFeel.addShortCut( + new LookAndFeelAction(new FineLightLaf()), + new LookAndFeelAction(new FineDarkLaf()), + new LookAndFeelAction(new UILookAndFeel()) + ); + this.addShortCut(lookAndFeel); + } + + private void addRemotePane() { + this.addShortCut(new RemoteDesignNetWorkAction()); + } +} diff --git a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java index e74ffc708b..fec6fdc9e5 100644 --- a/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java +++ b/designer-base/src/main/java/com/fr/design/mainframe/toolbar/ToolBarMenuDock.java @@ -3,8 +3,6 @@ */ package com.fr.design.mainframe.toolbar; -import com.fine.theme.light.ui.laf.FineDarkLaf; -import com.fine.theme.light.ui.laf.FineLightLaf; import com.fr.base.FRContext; import com.fr.base.vcs.DesignerMode; import com.fr.design.DesignState; @@ -34,7 +32,6 @@ import com.fr.design.actions.file.SwitchExistEnv; import com.fr.design.actions.help.AboutAction; import com.fr.design.actions.help.FineUIAction; import com.fr.design.actions.help.TutorialAction; -import com.fr.design.actions.help.WebDemoAction; import com.fr.design.actions.help.alphafine.AlphaFineAction; import com.fr.design.actions.help.alphafine.AlphaFineConfigManager; import com.fr.design.actions.server.ConnectionListAction; @@ -49,7 +46,6 @@ import com.fr.design.fun.MenuHandler; import com.fr.design.fun.OemProcessor; import com.fr.design.fun.PluginManagerProvider; import com.fr.design.fun.TableDataPaneProcessor; -import com.fr.design.gui.UILookAndFeel; import com.fr.design.gui.ibutton.UIButton; import com.fr.design.gui.ibutton.UICombinationButton; import com.fr.design.gui.ilable.UILabel; @@ -66,9 +62,7 @@ import com.fr.design.menu.ShortCut; import com.fr.design.menu.ToolBarDef; import com.fr.design.os.impl.SupportOSImpl; import com.fr.design.remote.action.RemoteDesignAuthManagerAction; -import com.fr.design.update.actions.SoftwareUpdateAction; import com.fr.design.utils.ThemeUtils; -import com.fr.env.detect.ui.EnvDetectorAction; import com.fr.general.ComparatorUtils; import com.fr.general.GeneralContext; import com.fr.general.locale.LocaleAction; @@ -298,7 +292,7 @@ public abstract class ToolBarMenuDock { // 当前仅UI开发者模式显示外观配置选项 if (DesignerUIModeConfig.getInstance().isUIDevMode()) { - menuList.add(createLookAndFeel()); + menuList.add(new DebugModeMenuDef()); } // 添加全部UpdateAction到actionmanager中 @@ -668,17 +662,6 @@ public abstract class ToolBarMenuDock { return menuDef; } - public MenuDef createLookAndFeel() { - MenuDef menuDef = new MenuDef("外观", 'H'); - menuDef.addShortCut( - new LookAndFeelAction(new FineLightLaf()), - new LookAndFeelAction(new FineDarkLaf()), - new LookAndFeelAction(new UILookAndFeel()) - ); - insertMenu(menuDef, "laf"); - return menuDef; - } - public MenuDef createCommunityMenuDef() { diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkAction.java b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkAction.java new file mode 100644 index 0000000000..29f149eed8 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkAction.java @@ -0,0 +1,46 @@ +package com.fr.design.remote.ui.debug; + +import com.fine.theme.utils.FineUIScale; +import com.fr.design.actions.UpdateAction; +import com.fr.design.mainframe.DesignerContext; +import com.fr.design.mainframe.DesignerFrame; +import com.fr.design.utils.gui.GUICoreUtils; +import com.fr.workspace.WorkContext; + +import javax.swing.JDialog; +import java.awt.Dimension; +import java.awt.event.ActionEvent; + +/** + * 远程设计网络调试 + * + * @author vito + * @since 11.0 + * Created on 2024/9/24 + */ +public class RemoteDesignNetWorkAction extends UpdateAction { + public static final String TITLE = "Remote Design NetWork"; + + public RemoteDesignNetWorkAction() { + setName(TITLE); + } + + @Override + public void actionPerformed(ActionEvent e) { + if (WorkContext.getCurrent().isLocal()) { + return; + } + JDialog jDialog = new JDialog(DesignerContext.getDesignerFrame(), TITLE); + jDialog.setSize(calculatePaneDimension()); + jDialog.add(new RemoteDesignNetWorkTablePane()); + GUICoreUtils.centerWindow(jDialog); + jDialog.setVisible(true); + } + + private static Dimension calculatePaneDimension() { + DesignerFrame parent = DesignerContext.getDesignerFrame(); + return new Dimension((int) (FineUIScale.unscale(parent.getWidth()) * 0.8), + (int) (FineUIScale.unscale(parent.getHeight()) * 0.6)); + } +} + diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTablePane.java b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTablePane.java new file mode 100644 index 0000000000..456d6266d4 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTablePane.java @@ -0,0 +1,109 @@ +package com.fr.design.remote.ui.debug; + +import com.fanruan.workplace.http.debug.RequestInfo; +import com.formdev.flatlaf.util.ScaledEmptyBorder; +import com.fr.event.Event; +import com.fr.event.EventDispatcher; +import com.fr.event.Listener; +import com.fr.workspace.WorkContext; + +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableCellRenderer; +import javax.swing.table.TableColumn; +import java.awt.BorderLayout; +import java.awt.Component; +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +import static com.fanruan.workplace.http.debug.RemoteDesignDebugEvent.REMOTE_HTTP_REQUEST; + +/** + * 远程设计网络调试面板 + * + * @author vito + * @since 11.0 + * Created on 2024/9/24 + */ +public class RemoteDesignNetWorkTablePane extends JPanel { + private static final int K = 1024; + private static final int TWO = 2; + private JTable uiTable; + private DefaultTableModel model; + + public RemoteDesignNetWorkTablePane() { + setLayout(new BorderLayout()); + setBorder(new ScaledEmptyBorder(10, 10, 10, 10)); + initComponent(); + initListener(); + } + + private void initComponent() { + model = new DefaultTableModel(); + model.addColumn("status"); + model.addColumn("time"); + model.addColumn("path"); + model.addColumn("cost"); + model.addColumn("request size"); + model.addColumn("response size"); + model.addColumn("request"); + model.addColumn("response"); + uiTable = new JTable(model); + add(new JScrollPane(uiTable), BorderLayout.CENTER); + } + + private void initListener() { + EventDispatcher.listen(REMOTE_HTTP_REQUEST, new Listener() { + @Override + public void on(Event event, RequestInfo requestInfo) { + model.addRow(new Object[]{ + requestInfo.getStatus(), + dateFormat(requestInfo.getDate()), + requestInfo.getPath().substring(WorkContext.getCurrent().getPath().length() - 1), + requestInfo.getConsume() + "ms", + simpleSize(requestInfo.getRequestSize()), + simpleSize(requestInfo.getResponseSize()), + requestInfo.getSendBody(), + requestInfo.getReturnBody(), + }); + adjustColumnWidths(uiTable); + } + }); + } + + private static void adjustColumnWidths(JTable table) { + for (int column = 0; column < table.getColumnCount() - TWO; column++) { + TableColumn tableColumn = table.getColumnModel().getColumn(column); + int preferredWidth = 20; + int maxWidth = tableColumn.getMaxWidth(); + tableColumn.setMinWidth(0); + // 从最后一行来调整大小 + int row = table.getRowCount() - 1; + TableCellRenderer cellRenderer = table.getCellRenderer(row, column); + Component component = table.prepareRenderer(cellRenderer, row, column); + int width = component.getPreferredSize().width + table.getIntercellSpacing().width; + preferredWidth = Math.max(preferredWidth, Math.min(width, maxWidth)); + tableColumn.setPreferredWidth(preferredWidth); + } + } + + private static String dateFormat(Date date) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + return dateFormat.format(date); + } + + private static String simpleSize(long bytes) { + if (bytes < 0) { + return bytes + ""; + } else if (bytes < K) { + return bytes + " B"; + } else { + DecimalFormat df = new DecimalFormat("#.00"); + return df.format((float) bytes / K) + " K"; + } + } + +}