diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkHelper.java b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkHelper.java new file mode 100644 index 0000000000..ba08291379 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkHelper.java @@ -0,0 +1,83 @@ +package com.fr.design.remote.ui.debug; + +import com.fr.stable.StringUtils; + +import java.text.DecimalFormat; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * 帮助类 + * + * @author vito + * @since 11.0 + * Created on 2024/10/11 + */ +public class RemoteDesignNetWorkHelper { + private static final int UNIT = 1000; + private static final int UNIT_BYTES = 1024; + private static final String SECOND = "s"; + private static final int K = 1024; + private static final int MS = 1000; + + static String dateFormat(Date date) { + SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); + return dateFormat.format(date); + } + + static String simpleTime(long time) { + if (time < 0) { + return time + ""; + } else if (time < MS) { + return time + " ms"; + } else { + DecimalFormat df = new DecimalFormat("#.0"); + return df.format((float) time / MS) + " s"; + } + } + + 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"; + } + } + + static long parseCostToMS(String timeStr) { + String[] split = timeStr.split(" "); + if (split.length > 1) { + double number = Double.parseDouble(split[0]); + String unit = split[1].toLowerCase(); + + if (StringUtils.equals(unit, SECOND)) { + return (long) (number * UNIT); + } + return (long) number; + } + return 0; + } + + static long parseSizeToBytes(String sizeStr) { + String[] split = sizeStr.split(" "); + if (split.length > 1) { + double number = Double.parseDouble(split[0]); + String unit = split[1].toUpperCase(); + + switch (unit) { + case "K": + return (long) (number * UNIT_BYTES); + case "M": + return (long) (number * UNIT_BYTES * UNIT_BYTES); + case "G": + return (long) (number * UNIT_BYTES * UNIT_BYTES * UNIT_BYTES); + default: + return (long) number; + } + } + return 0; + } +} 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 index 21cb2ab049..c29633aa5c 100644 --- 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 @@ -4,6 +4,7 @@ import com.fanruan.workplace.http.debug.RequestInfo; import com.fine.theme.icon.LazyIcon; import com.formdev.flatlaf.util.ScaledEmptyBorder; import com.fr.design.gui.ibutton.UIButton; +import com.fr.design.gui.ibutton.UIToggleButton; import com.fr.event.Event; import com.fr.event.EventDispatcher; import com.fr.event.Listener; @@ -13,17 +14,19 @@ import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.JToolBar; +import javax.swing.SwingUtilities; import javax.swing.border.EmptyBorder; 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 java.util.concurrent.atomic.AtomicLong; import static com.fanruan.workplace.http.debug.RemoteDesignDebugEvent.REMOTE_HTTP_REQUEST; +import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.dateFormat; +import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.simpleSize; +import static com.fr.design.remote.ui.debug.RemoteDesignNetWorkHelper.simpleTime; /** * 远程设计网络调试面板 @@ -33,25 +36,29 @@ import static com.fanruan.workplace.http.debug.RemoteDesignDebugEvent.REMOTE_HTT * 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; + private final AtomicLong count = new AtomicLong(0); + private boolean scrollRectToVisible = false; private final Listener remoteDesignDebugListener = 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(), + SwingUtilities.invokeLater(() -> { + model.addRow(new Object[]{ + count.incrementAndGet(), + dateFormat(requestInfo.getDate()), + requestInfo.getPath().substring(WorkContext.getCurrent().getPath().length() - 1), + requestInfo.getStatus(), + simpleTime(requestInfo.getConsume()), + simpleSize(requestInfo.getRequestSize()), + simpleSize(requestInfo.getResponseSize()), + requestInfo.getSendBody(), + requestInfo.getReturnBody(), + }); + adjustColumnWidths(uiTable); }); - adjustColumnWidths(uiTable); } }; @@ -69,15 +76,17 @@ public class RemoteDesignNetWorkTablePane extends JPanel { private void initTable() { model = new DefaultTableModel(); - model.addColumn("status"); + model.addColumn("No."); model.addColumn("time"); model.addColumn("path"); + model.addColumn("status"); model.addColumn("cost"); model.addColumn("request size"); model.addColumn("response size"); model.addColumn("request"); model.addColumn("response"); uiTable = new JTable(model); + uiTable.setRowSorter(new RemoteDesignNetWorkTableRowSorter(model)); add(new JScrollPane(uiTable), BorderLayout.CENTER); } @@ -86,7 +95,8 @@ public class RemoteDesignNetWorkTablePane extends JPanel { jToolBar.setBorder(new EmptyBorder(5, 0, 10, 0)); UIButton run = new UIButton(new LazyIcon("run")); UIButton forbid = new UIButton(new LazyIcon("forbid")); - UIButton refresh = new UIButton(new LazyIcon("remove")); + UIButton remove = new UIButton(new LazyIcon("remove")); + UIToggleButton refresh = new UIToggleButton(new LazyIcon("refresh")); run.setEnabled(false); run.setToolTipText("Start Record"); run.addActionListener(e -> { @@ -100,10 +110,16 @@ public class RemoteDesignNetWorkTablePane extends JPanel { run.setEnabled(true); forbid.setEnabled(false); }); - refresh.setToolTipText("Clear Records"); - refresh.addActionListener(e -> model.setRowCount(0)); + remove.setToolTipText("Clear Records"); + remove.addActionListener(e -> { + model.setRowCount(0); + count.set(0); + }); + refresh.setToolTipText("Always Scroll To Visible"); + refresh.addChangeListener(e -> scrollRectToVisible = !scrollRectToVisible); jToolBar.add(run); jToolBar.add(forbid); + jToolBar.add(remove); jToolBar.add(refresh); add(jToolBar, BorderLayout.NORTH); } @@ -120,36 +136,24 @@ public class RemoteDesignNetWorkTablePane extends JPanel { EventDispatcher.listen(REMOTE_HTTP_REQUEST, remoteDesignDebugListener); } - private static void adjustColumnWidths(JTable table) { + private void adjustColumnWidths(JTable table) { + int row = table.getRowCount() - 1; + // 从最后一行来调整大小 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"; + if (scrollRectToVisible) { + table.scrollRectToVisible(table.getCellRect(row, 0, true)); } } + } diff --git a/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTableRowSorter.java b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTableRowSorter.java new file mode 100644 index 0000000000..231acc72c7 --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/remote/ui/debug/RemoteDesignNetWorkTableRowSorter.java @@ -0,0 +1,32 @@ +package com.fr.design.remote.ui.debug; + +import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableRowSorter; +import java.util.Comparator; + +/** + * 行排序器 + * + * @author vito + * @since 11.0 + * Created on 2024/10/11 + */ +public class RemoteDesignNetWorkTableRowSorter extends TableRowSorter { + + public RemoteDesignNetWorkTableRowSorter(DefaultTableModel model) { + super(model); + setComparator(0, (Comparator) Long::compareTo); + setComparator(4, Comparator.comparingLong(RemoteDesignNetWorkHelper::parseCostToMS)); + setComparator(5, Comparator.comparingLong(RemoteDesignNetWorkHelper::parseSizeToBytes)); + setComparator(6, Comparator.comparingLong(RemoteDesignNetWorkHelper::parseSizeToBytes)); + } + + @Override + public boolean isSortable(int column) { + return column == 0 + || column == 4 + || column == 5 + || column == 6; + } + +}