diff --git a/README.md b/README.md index 88dcfc5..677f509 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ -- ![JDK](https://img.shields.io/badge/JDK-17-blue.svg) ![Apache 2.0](https://img.shields.io/badge/Apache-2.0-blue.svg) -![Release](https://img.shields.io/badge/Release-1.1.2-blue.svg) [![Release](https://img.shields.io/github/v/release/ptma/mqtt-insight.svg)](https://github.com/ptma/mqtt-insight/releases) ![](https://img.shields.io/github/downloads/ptma/mqtt-insight/total.svg) @@ -13,12 +12,14 @@ MqttInsight is an open source cross platform MQTT desktop client. * Supports MQTT3 and MQTT5; * Supports Websocket; * Switchable table and dialogue message views; +* Topic hierarchy visualization; * Supports Node.js JavaScript (Supported by [Javet](https://github.com/caoccao/Javet)); * Built in message codecs such as PlainText, JSON, XML, HEX, Base64, Protobuf, Message Pack, Avro, Hessian, Hessian2, and Kryo; * Supports codecs through Java SPI; * Supports codecs written in JavaScript; * Provides charts such as message quantity statistics, message load statistics, and message content statistics; +* Message search and filtering. ## Screenshots diff --git a/README_zh_CN.md b/README_zh_CN.md index dfb635b..3cc7933 100644 --- a/README_zh_CN.md +++ b/README_zh_CN.md @@ -12,11 +12,13 @@ MqttInsight 是开源跨平台的 MQTT 图形客户端. * 支持 MQTT3、MQTT5; * 支持 Websocket; * 支持表格和对话两种消息视图; +* 主题层次结构可视化; * 支持 Node.js 脚本 (由 Javet 提供支持); * 内置 PlainText、JSON、XML、HEX、Base64、Protobuf、MessagePack、Avro、Hessian、Hessian2 和 Kryo 等消息编解码; * 支持通过 SPI 扩展编解码器; * 支持 Javascript 编解码器; * 支持消息数量、消息负载、消息内容等统计图表; +* 消息搜索和过滤。 ## 界面截图 diff --git a/doc/Changelog.md b/doc/Changelog.md index e6809ab..3d31ad2 100644 --- a/doc/Changelog.md +++ b/doc/Changelog.md @@ -1,5 +1,9 @@ Changelog -- +## 1.1.4 (2025-02-18) +* **优化 🙌** + * 重构主题树,提升界面响应性能 + ## 1.1.3 (2025-01-06) * **新增 ✨** * 主题树形层级显示及过滤功能 diff --git a/screenshots/dialogue_view.png b/screenshots/dialogue_view.png index f1a9ede..fe8f603 100644 Binary files a/screenshots/dialogue_view.png and b/screenshots/dialogue_view.png differ diff --git a/screenshots/table_view.png b/screenshots/table_view.png index 3a83deb..dee826a 100644 Binary files a/screenshots/table_view.png and b/screenshots/table_view.png differ diff --git a/src/main/java/com/mqttinsight/ui/component/TopicSegment.java b/src/main/java/com/mqttinsight/ui/component/TopicSegment.java deleted file mode 100644 index ad4fdc3..0000000 --- a/src/main/java/com/mqttinsight/ui/component/TopicSegment.java +++ /dev/null @@ -1,518 +0,0 @@ -package com.mqttinsight.ui.component; - -import com.formdev.flatlaf.extras.FlatSVGIcon; -import com.mqttinsight.ui.form.panel.MqttInstance; -import com.mqttinsight.ui.form.panel.TopicTreePanel; -import com.mqttinsight.util.Icons; -import com.mqttinsight.util.LangUtil; -import lombok.Getter; -import net.miginfocom.swing.MigLayout; -import org.jdesktop.swingx.JXLabel; -import org.jdesktop.swingx.VerticalLayout; - -import javax.swing.*; -import javax.swing.border.EmptyBorder; -import java.awt.*; -import java.awt.event.MouseAdapter; -import java.awt.event.MouseEvent; -import java.awt.event.MouseListener; -import java.util.List; -import java.util.*; -import java.util.concurrent.CopyOnWriteArrayList; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.concurrent.atomic.AtomicInteger; -import java.util.stream.Collectors; - -/** - * @author ptma - */ -public class TopicSegment extends JPanel { - - private static final Color HOVER_BG_COLOR = UIManager.getColor("Button.default.hoverBackground"); - private static final Color NORMAL_BG_COLOR = UIManager.getColor("Tree.background"); - private static final Color SELECTED_BG_COLOR = UIManager.getColor("Table.selectionInactiveBackground"); - - private static final Color TEXT_VISIBLE_COLOR = UIManager.getColor("Label.foreground"); - private static final Color TEXT_INVISIBLE_COLOR = UIManager.getColor("Label.disabledForeground"); - private static final Icon ICON_COLLAPSED = UIManager.getIcon("Tree.collapsedIcon"); - private static final Icon ICON_EXPANDED = UIManager.getIcon("Tree.expandedIcon"); - private static final Icon ICON_EMPTY = new FlatSVGIcon("svg/icons/dot.svg", ICON_EXPANDED.getIconWidth(), ICON_EXPANDED.getIconHeight()); - - private final MqttInstance mqttInstance; - private final TopicTreePanel topicTreePanel; - private final JComponent parent; - - private final SegmentNodePanel nodePanel; - private final JPanel childrenPanel; - - @Getter - private final String name; - @Getter - private final String fullTopic; - @Getter - private boolean expanded; - @Getter - private boolean segmentVisible = true; - - private boolean selected = false; - private int level; - - private final AtomicInteger messageCount = new AtomicInteger(0); - - public TopicSegment(MqttInstance mqttInstance, TopicTreePanel topicTreePanel, JComponent parent, String name, int level, boolean expanded) { - super(); - setOpaque(false); - setLayout(new VerticalLayout(0)); - - this.mqttInstance = mqttInstance; - this.topicTreePanel = topicTreePanel; - this.parent = parent; - this.name = name; - this.expanded = expanded; - this.level = level; - this.fullTopic = (parent instanceof TopicSegment parentSegment) ? - ( - // Root segment, topic start with / - parentSegment.getName().equals("/") ? - parentSegment.getFullTopic() + name - : - parentSegment.getFullTopic() + "/" + name - ) - : - name; - - nodePanel = new SegmentNodePanel(this); - add(nodePanel); - - childrenPanel = new JPanel(); - childrenPanel.setLayout(new VerticalLayout(0)); - childrenPanel.setOpaque(false); - childrenPanel.setBorder(new EmptyBorder(0, 0, 0, 0)); - if (!expanded) { - childrenPanel.setPreferredSize(new Dimension(0, 0)); - } - add(childrenPanel); - - if (parent instanceof TopicSegment parentSegment) { - if (!parentSegment.isSegmentVisible()) { - toggleSegmentVisible(false, false, false); - } - } - } - - public Set getInvisibleTopics() { - if (!isSegmentCompositeVisible()) { - return new HashSet<>(Collections.singletonList(getFullTopic())); - } else { - return getChildren().stream() - .map(TopicSegment::getInvisibleTopics) - .reduce((setA, setB) -> { - setA.addAll(setB); - return setA; - }) - .orElseGet(HashSet::new); - } - } - - public int getChildrenCount() { - return childrenPanel.getComponentCount(); - } - - public List getChildren() { - return Arrays.stream(childrenPanel.getComponents()) - .map(c -> (TopicSegment) c) - .collect(Collectors.toCollection(CopyOnWriteArrayList::new)); - } - - public Optional getChild(String segment) { - return Arrays.stream(childrenPanel.getComponents()).map(c -> (TopicSegment) c) - .filter(c -> c.getName().equals(segment)) - .findFirst(); - } - - public void removeSelf() { - if (parent instanceof TopicSegment parentSegment) { - parentSegment.removeChildSegment(this); - } else if (parent instanceof TopicTreePanel topicTree) { - topicTree.removeRootSegment(this); - } - } - - private void removeChildSegment(TopicSegment child) { - childrenPanel.remove(child); - updateNode(true); - if (isExpanded()) { - updateSize(); - } - if (getTopicCount() == 0) { - removeSelf(); - } - } - - public void incrementMessages() { - messageCount.incrementAndGet(); - updateNode(false); - } - - public void incrementMessages(List topicSegments) { - if (topicSegments.isEmpty()) { - return; - } - String segment = topicSegments.get(0); - - AtomicBoolean childAppended = new AtomicBoolean(false); - TopicSegment child = getChild(segment).orElseGet(() -> { - TopicSegment newChild = new TopicSegment(mqttInstance, topicTreePanel, this, segment, level + 1, false); - addChildSegment(newChild); - updateSegmentCompositeVisibleStatus(true, false); - childAppended.set(true); - return newChild; - }); - if (topicSegments.size() > 1) { - child.incrementMessages(topicSegments.subList(1, topicSegments.size())); - } else { - child.incrementMessages(); - } - if (childAppended.get() && isExpanded()) { - updateSize(); - } - if (childAppended.get() && !isSegmentVisible()) { - topicTreePanel.notifyTopicSegmentsVisibleChange(); - } - } - - private void addChildSegment(TopicSegment segment) { - List segments = getChildren(); - for (int i = 0; i < segments.size(); i++) { - TopicSegment existingSegment = segments.get(i); - if (segment.getName().compareTo(existingSegment.getName()) <= 0) { - childrenPanel.add(segment, i); - return; - } - } - childrenPanel.add(segment); - } - - public void decrementMessages(String topic) { - if (fullTopic.equals(topic)) { - if (messageCount.get() > 0) { - messageCount.decrementAndGet(); - } - if (getTopicCount() == 0) { - removeSelf(); - } else { - updateNode(false); - } - } else if (topic.startsWith(fullTopic)) { - getChildren().forEach(segment -> segment.decrementMessages(topic)); - } - } - - public void toggleExpanded() { - this.expanded = !this.expanded; - updateNode(false); - updateSize(); - } - - public void setSelected(boolean selected) { - this.selected = selected; - nodePanel.selected(selected); - if (selected) { - topicTreePanel.changeSelectedSegment(this); - } - } - - public int getSelfMessageCount() { - return messageCount.get(); - } - - public int getTotalMessageCount() { - return getSelfMessageCount() + getChildren().stream().map(TopicSegment::getTotalMessageCount) - .reduce(0, Integer::sum); - } - - public int getTopicCount() { - int count = 0; - if (getSelfMessageCount() > 0) { - count++; - } - count += getChildren().stream() - .map(TopicSegment::getTopicCount) - .reduce(0, Integer::sum); - return count; - } - - public Dimension getComponentSize() { - int width = nodePanel.getPreferredSize().width; - int height = nodePanel.getPreferredSize().height; - if (this.expanded) { - resizeChildrenPanel(); - height += childrenPanel.getPreferredSize().height; - } - return new Dimension(width, height); - } - - public int calcSegmentScrollHeight(List topicSegments) { - int height = 0; - for (TopicSegment segment : getChildren()) { - if (segment.getName().equals(topicSegments.get(0))) { - height += segment.nodePanel.getHeight(); - if (topicSegments.size() > 1) { - if (!segment.isExpanded()) { - segment.toggleExpanded(); - } - height += segment.calcSegmentScrollHeight(topicSegments.subList(1, topicSegments.size())); - } else { - segment.setSelected(true); - } - return height; - } else { - height += segment.getHeight(); - } - } - return height; - } - - private void resizeChildrenPanel() { - int width = nodePanel.getPreferredSize().width; - int height = 0; - if (this.expanded) { - for (TopicSegment child : getChildren()) { - Dimension itemSize = child.getComponentSize(); - height += itemSize.height; - } - } - childrenPanel.setPreferredSize(new Dimension(width, height)); - childrenPanel.revalidate(); - //childrenPanel.repaint(); - } - - /** - * During the clearing process, the number of messages in this segment will be updated synchronously. - * When the number is 0, this segment will be removed - *

- * {@link com.mqttinsight.ui.form.panel.MessageViewPanel#doClearMessages(String)} (String)} - */ - public void removeSegmentMessages() { - SwingUtilities.invokeLater(() -> { - mqttInstance.applyEvent(l -> l.clearMessages(getFullTopic())); - }); - } - - public boolean isSegmentCompositeVisible() { - return segmentVisible || getChildren().stream().anyMatch(TopicSegment::isSegmentCompositeVisible); - } - - public void updateSegmentCompositeVisibleStatus(boolean updateParent, boolean notify) { - nodePanel.changeSegmentVisibleStatus(isSegmentCompositeVisible()); - if (updateParent && parent instanceof TopicSegment parentSegment) { - parentSegment.updateSegmentCompositeVisibleStatus(true, notify); - } - if (notify && parent instanceof TopicTreePanel topicTree) { - topicTree.notifyTopicSegmentsVisibleChange(); - } - } - - /** - * @param segmentVisible Whether the segment is visible - * @param effectOnChildren Does visibility change need to affect its children - */ - public void toggleSegmentVisible(boolean segmentVisible, boolean effectOnChildren, boolean updateParentCompositeVisibleStatus) { - if (effectOnChildren) { - getChildren().forEach(child -> child.toggleSegmentVisible(segmentVisible, true, false)); - } - - this.segmentVisible = segmentVisible; - nodePanel.changeSegmentVisibleStatus(this.segmentVisible); - - if (updateParentCompositeVisibleStatus) { - updateSegmentCompositeVisibleStatus(true, true); - } - } - - public void updateNode(boolean repaint) { - nodePanel.setIcon(getChildrenCount() > 0 ? (this.expanded ? ICON_EXPANDED : ICON_COLLAPSED) : ICON_EMPTY); - - String topicsDescription, messagesDescription; - int topicsCount = getTopicCount(); - if (topicsCount > 1) { - topicsDescription = LangUtil.getString("SegmentTopicsDescription"); - } else { - topicsDescription = LangUtil.getString("SegmentTopicDescription"); - } - int messagesCount = getTotalMessageCount(); - if (messagesCount > 1) { - messagesDescription = LangUtil.getString("SegmentMessagesDescription"); - } else { - messagesDescription = LangUtil.getString("SegmentMessageDescription"); - } - String descriptionTemplate = String.format("(%s, %s)", topicsDescription, messagesDescription); - nodePanel.description(String.format(descriptionTemplate, topicsCount, messagesCount)); - this.revalidate(); - if (repaint) { - this.repaint(); - } - - if (parent instanceof TopicSegment) { - ((TopicSegment) parent).updateNode(repaint); - } - } - - public void updateSize() { - this.setPreferredSize(getComponentSize()); - this.revalidate(); - //this.repaint(); - if (parent instanceof TopicSegment) { - ((TopicSegment) parent).updateSize(); - } - } - - public static class SegmentNodePanel extends JPanel implements MouseListener { - - private final TopicSegment segment; - private final JXLabel iconLabel; - private final JXLabel nameLabel; - private final JXLabel descriptionLabel; - private final JToolBar toolBar; - private final JButton visibleButton; - private final JButton clearButton; - - private boolean segmentVisible = true; - - public SegmentNodePanel(TopicSegment segment) { - super(); - this.segment = segment; - setLayout(new MigLayout( - String.format("insets 0 %d 0 0", segment.level * 10 + 5), - "[]5[]5[grow]5[]", - "[]" - )); - setBackground(UIManager.getColor("Tree.background")); - iconLabel = new JXLabel(ICON_COLLAPSED); - iconLabel.setOpaque(false); - add(iconLabel, "cell 0 0,hmin 26px"); - nameLabel = new JXLabel(segment.getName()); - nameLabel.setOpaque(false); - nameLabel.putClientProperty("FlatLaf.styleClass", "h4"); - nameLabel.setToolTipText(segment.getFullTopic()); - add(nameLabel, "cell 1 0"); - descriptionLabel = new JXLabel(); - descriptionLabel.setOpaque(false); - descriptionLabel.setForeground(TEXT_INVISIBLE_COLOR); - add(descriptionLabel, "cell 2 0,wmin 10px,growx"); - - toolBar = new JToolBar(); - toolBar.setFloatable(false); - toolBar.setOpaque(false); - toolBar.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0)); - toolBar.setVisible(false); - - clearButton = new JButton(Icons.CLEAR); - clearButton.setToolTipText(LangUtil.getString("ClearMessages")); - clearButton.addActionListener((e) -> segment.removeSegmentMessages()); - toolBar.add(clearButton); - - visibleButton = new JButton(Icons.EYE); - visibleButton.setToolTipText(LangUtil.getString("ShowOrHideMessages")); - visibleButton.addActionListener((e) -> segment.toggleSegmentVisible(!segmentVisible, true, true)); - toolBar.add(visibleButton); - - add(toolBar, "cell 3 0, hidemode 2"); - - addMouseListener(this); - initActions(); - } - - public void initActions() { - iconLabel.addMouseListener(new MouseAdapter() { - @Override - public void mousePressed(MouseEvent e) { - segment.toggleExpanded(); - } - - @Override - public void mouseEntered(MouseEvent e) { - SegmentNodePanel.this.mouseEntered(e); - } - - @Override - public void mouseExited(MouseEvent e) { - SegmentNodePanel.this.mouseExited(e); - } - }); - clearButton.addMouseListener(this); - visibleButton.addMouseListener(this); - nameLabel.addMouseListener(this); - descriptionLabel.addMouseListener(this); - } - - public void setIcon(Icon icon) { - iconLabel.setIcon(icon); - } - - public void description(String description) { - descriptionLabel.setText(description); - } - - public void changeSegmentVisibleStatus(boolean segmentVisible) { - if (this.segmentVisible == segmentVisible) { - return; - } - this.segmentVisible = segmentVisible; - visibleButton.setIcon(segmentVisible ? Icons.EYE : Icons.EYE_CLOSE); - nameLabel.setForeground(segmentVisible ? TEXT_VISIBLE_COLOR : TEXT_INVISIBLE_COLOR); - } - - @Override - public void mouseClicked(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) { - SwingUtilities.invokeLater(segment::toggleExpanded); - } - } - - @Override - public void mousePressed(MouseEvent e) { - if (e.getButton() == MouseEvent.BUTTON1) { - SwingUtilities.invokeLater(() -> { - segment.setSelected(true); - }); - } - } - - @Override - public void mouseReleased(MouseEvent e) { - - } - - @Override - public void mouseEntered(MouseEvent e) { - SwingUtilities.invokeLater(() -> { - if (!segment.selected) { - this.setBackground(HOVER_BG_COLOR); - } - toolBar.setVisible(true); - }); - } - - @Override - public void mouseExited(MouseEvent e) { - SwingUtilities.invokeLater(() -> { - if (!segment.selected) { - this.setBackground(NORMAL_BG_COLOR); - } - toolBar.setVisible(false); - }); - } - - public void selected(boolean selected) { - if (selected) { - this.setBackground(SELECTED_BG_COLOR); - } else { - this.setBackground(NORMAL_BG_COLOR); - } - this.revalidate(); - //this.repaint(); - } - } - -} diff --git a/src/main/java/com/mqttinsight/ui/component/tree/SegmentNode.java b/src/main/java/com/mqttinsight/ui/component/tree/SegmentNode.java new file mode 100644 index 0000000..9ca01b0 --- /dev/null +++ b/src/main/java/com/mqttinsight/ui/component/tree/SegmentNode.java @@ -0,0 +1,185 @@ +package com.mqttinsight.ui.component.tree; + +import lombok.Getter; + +import javax.swing.tree.DefaultMutableTreeNode; +import java.util.*; +import java.util.concurrent.atomic.AtomicInteger; + +public class SegmentNode extends DefaultMutableTreeNode { + + private final TopicTree tree; + private final SegmentNode parent; + @Getter + private final String name; + @Getter + private final String fullTopic; + + @Getter + private boolean segmentVisible = true; + + private final AtomicInteger messageCount = new AtomicInteger(0); + + public SegmentNode(TopicTree tree, SegmentNode parent, String name) { + this.tree = tree; + this.parent = parent; + this.name = name; + if (this.parent != null && !this.parent.getName().equals("#")) { + this.fullTopic = this.parent.getName().equals("/") ? + this.parent.getFullTopic() + name + : + this.parent.getFullTopic() + "/" + name; + } else { + this.fullTopic = name; + } + if (this.parent != null && !this.parent.isSegmentVisible()) { + this.segmentVisible = false; + } + } + + public Set getInvisibleTopics() { + if (!isSegmentCompositeVisible()) { + return new HashSet<>(Collections.singletonList(getFullTopic())); + } else { + return getChildren().stream() + .map(SegmentNode::getInvisibleTopics) + .reduce((setA, setB) -> { + setA.addAll(setB); + return setA; + }) + .orElseGet(HashSet::new); + } + } + + public void toggleSegmentVisible(boolean segmentVisible, boolean effectOnChildren, boolean updateParentCompositeVisibleStatus) { + if (effectOnChildren) { + getChildren().forEach(child -> child.toggleSegmentVisible(segmentVisible, true, false)); + } + + this.segmentVisible = segmentVisible; + tree.getTreeModel().nodeChanged(this); + + if (updateParentCompositeVisibleStatus) { + updateSegmentCompositeVisibleStatus(true, true); + } + } + + public boolean isSegmentCompositeVisible() { + return segmentVisible || getChildren().stream().anyMatch(SegmentNode::isSegmentCompositeVisible); + } + + public void updateSegmentCompositeVisibleStatus(boolean updateParent, boolean notify) { + if (updateParent && parent != null) { + parent.updateSegmentCompositeVisibleStatus(true, notify); + } + if (notify && parent == null) { + tree.notifyTopicSegmentsVisibleChange(); + } + } + + public void incrementMessages() { + messageCount.incrementAndGet(); + } + + public void incrementMessages(List topicSegments) { + if (topicSegments.isEmpty()) { + return; + } + String segment = topicSegments.get(0); + + SegmentNode child = getChild(segment).orElseGet(() -> { + SegmentNode newChild = new SegmentNode(tree, this, segment); + addChildSegment(newChild); + return newChild; + }); + if (topicSegments.size() > 1) { + child.incrementMessages(topicSegments.subList(1, topicSegments.size())); + } else { + child.incrementMessages(); + } + } + + private void addChildSegment(SegmentNode child) { + List segments = getChildren(); + for (int i = 0; i < segments.size(); i++) { + SegmentNode existingSegment = segments.get(i); + if (child.getName().compareTo(existingSegment.getName()) <= 0) { + tree.getTreeModel().insertNodeInto(child, this, i); + return; + } + } + tree.getTreeModel().insertNodeInto(child, this, segments.size()); + } + + public void decrementMessages(String topic) { + if (fullTopic.equals(topic)) { + if (messageCount.get() > 0) { + messageCount.decrementAndGet(); + tree.getTreeModel().nodeChanged(this); + } + if (getTopicCount() == 0) { + removeSelf(); + } + } else if (topic.startsWith(fullTopic)) { + getChildren().forEach(segment -> segment.decrementMessages(topic)); + } + } + + public void removeSelf() { + if (parent != null) { + parent.removeChild(this); + } + } + + public void removeChild(SegmentNode child) { + tree.getTreeModel().removeNodeFromParent(child); + if (getTopicCount() == 0) { + removeSelf(); + } + } + + public int getSelfMessageCount() { + return messageCount.get(); + } + + public int getTotalMessageCount() { + return getSelfMessageCount() + getChildren().stream().map(SegmentNode::getTotalMessageCount) + .reduce(0, Integer::sum); + } + + public int getTopicCount() { + int count = 0; + if (getSelfMessageCount() > 0) { + count++; + } + count += getChildren().stream() + .map(SegmentNode::getTopicCount) + .reduce(0, Integer::sum); + return count; + } + + public Optional getChild(String segment) { + return getChildren().stream() + .filter(c -> c.getName().equals(segment)) + .findFirst(); + } + + public List getChildren() { + if (children == null) { + return List.of(); + } else { + return children.stream() + .map(c -> (SegmentNode) c) + .toList(); + } + } + + @Override + public boolean isLeaf() { + return children == null || children.isEmpty(); + } + + public String toString() { + return name; + } +} diff --git a/src/main/java/com/mqttinsight/ui/component/tree/TopicTree.java b/src/main/java/com/mqttinsight/ui/component/tree/TopicTree.java new file mode 100644 index 0000000..ca2ad32 --- /dev/null +++ b/src/main/java/com/mqttinsight/ui/component/tree/TopicTree.java @@ -0,0 +1,272 @@ +package com.mqttinsight.ui.component.tree; + +import cn.hutool.core.util.StrUtil; +import com.formdev.flatlaf.extras.components.FlatPopupMenu; +import com.mqttinsight.mqtt.MqttMessage; +import com.mqttinsight.ui.event.InstanceEventAdapter; +import com.mqttinsight.ui.form.panel.MqttInstance; +import com.mqttinsight.util.Icons; +import com.mqttinsight.util.LangUtil; +import com.mqttinsight.util.Utils; +import org.jdesktop.swingx.JXTree; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeModel; +import javax.swing.tree.DefaultTreeSelectionModel; +import javax.swing.tree.TreePath; +import javax.swing.tree.TreeSelectionModel; +import java.awt.*; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.List; +import java.util.*; +import java.util.function.BiConsumer; + +public class TopicTree extends JXTree { + + private final MqttInstance mqttInstance; + private final SegmentNode rootNode; + private final DefaultTreeModel treeModel; + private FlatPopupMenu popupMenu; + private JMenuItem menuClearMessages; + private JMenuItem menuHideMessages; + private JMenuItem menuHideOtherMessages; + + public TopicTree(MqttInstance mqttInstance) { + super(); + this.mqttInstance = mqttInstance; + TreeSelectionModel selectionModel = new DefaultTreeSelectionModel(); + selectionModel.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); + this.setSelectionModel(selectionModel); + treeModel = new DefaultTreeModel(null, false); + rootNode = new SegmentNode(this, null, "#"); + treeModel.setRoot(rootNode); + this.setModel(treeModel); + this.setRootVisible(false); + this.setShowsRootHandles(true); + this.setUI(new TopicTreeUI()); + + this.setOpenIcon(null); + this.setClosedIcon(null); + this.setLeafIcon(TopicTreeCellRenderer.ICON_LEAF); + this.setExpandedIcon(TopicTreeCellRenderer.ICON_EXPANDED); + this.setCollapsedIcon(TopicTreeCellRenderer.ICON_COLLAPSED); + + TopicTreeCellRenderer renderer = new TopicTreeCellRenderer(); + this.setCellRenderer(renderer); + + popupMenu = new FlatPopupMenu(); + menuHideMessages = Utils.UI.createCheckBoxMenuItem(LangUtil.getString("HideRelatedMessages"), (e) -> toggleSegmentVisible()); + popupMenu.add(menuHideMessages); + menuHideOtherMessages = Utils.UI.createMenuItem(LangUtil.getString("HideAllOtherMessages"), (e) -> toggleOtherSegmentVisible()); + popupMenu.add(menuHideOtherMessages); + popupMenu.addSeparator(); + menuClearMessages = Utils.UI.createMenuItem(LangUtil.getString("ClearMessages"), (e) -> removeSegmentMessages()); + menuClearMessages.setIcon(Icons.CLEAR); + popupMenu.add(menuClearMessages); + + initEventListeners(); + ToolTipManager.sharedInstance().registerComponent(this); + } + + private void initEventListeners() { + mqttInstance.addEventListener(new InstanceEventAdapter() { + @Override + public void onMessage(MqttMessage message, MqttMessage parent) { + SwingUtilities.invokeLater(() -> { + updateSegments(message.getTopic()); + }); + } + + @Override + public void onMessageRemoved(MqttMessage message) { + SwingUtilities.invokeLater(() -> { + removeTopicSegments(message.getTopic()); + }); + } + + @Override + public void requestFocusPreview() { + SwingUtilities.invokeLater(() -> { + mqttInstance.getMessageTable().getSelectedMessage() + .ifPresent(message -> { + locateSegments(message.getTopic()); + }); + }); + } + }); + + this.addMouseListener(new MouseAdapter() { + @Override + public void mousePressed(MouseEvent e) { + if (SwingUtilities.isRightMouseButton(e)) { + final int rowIndex = TopicTree.this.getClosestRowForLocation(e.getX(), e.getY()); + if (rowIndex < 0) { + return; + } + TreePath clickedPath = TopicTree.this.getPathForRow(rowIndex); + if (clickedPath == null) { + return; + } + Rectangle bounds = TopicTree.this.getPathBounds(clickedPath); + if (bounds == null || e.getY() > (bounds.y + bounds.height)) { + return; + } + + TopicTree.this.setSelectionRow(rowIndex); + SegmentNode node = (SegmentNode) clickedPath.getLastPathComponent(); + menuHideMessages.setSelected(!node.isSegmentCompositeVisible()); + popupMenu.show(e.getComponent(), e.getX(), e.getY()); + } + } + }); + } + + public DefaultTreeModel getTreeModel() { + return treeModel; + } + + @Override + public String getToolTipText(MouseEvent e) { + TreePath treePath = getPathForLocation(e.getX(), e.getY()); + if (treePath != null) { + if (treePath.getLastPathComponent() instanceof SegmentNode) { + SegmentNode node = (SegmentNode) treePath.getLastPathComponent(); + return node.getFullTopic(); + } + } + return null; + } + + private void removeSegmentMessages() { + TreePath selectedPath = getSelectionPath(); + if (selectedPath != null) { + final SegmentNode selectNode = (SegmentNode) selectedPath.getLastPathComponent(); + if (selectNode != null) { + removeSegmentMessages(selectNode); + } + } + } + + private void toggleSegmentVisible() { + TreePath selectedPath = getSelectionPath(); + if (selectedPath != null) { + final SegmentNode selectNode = (SegmentNode) selectedPath.getLastPathComponent(); + if (selectNode != null) { + boolean segmentVisible = !selectNode.isSegmentVisible(); + selectNode.toggleSegmentVisible(segmentVisible, true, true); + } + } + } + + private void toggleOtherSegmentVisible() { + rootNode.getChildren().forEach(node -> { + node.toggleSegmentVisible(false, true, false); + }); + TreePath selectedPath = getSelectionPath(); + if (selectedPath != null) { + final SegmentNode selectNode = (SegmentNode) selectedPath.getLastPathComponent(); + if (selectNode != null) { + selectNode.toggleSegmentVisible(true, true, true); + } + } + } + + public void removeSegmentMessages(SegmentNode node) { + SwingUtilities.invokeLater(() -> { + mqttInstance.applyEvent(l -> l.clearMessages(node.getFullTopic())); + }); + } + + public void notifyTopicSegmentsVisibleChange() { + Set invisibleTopics = getRootSegments().stream() + .map(SegmentNode::getInvisibleTopics) + .reduce((setA, setB) -> { + setA.addAll(setB); + return setA; + }) + .orElseGet(HashSet::new); + SwingUtilities.invokeLater(() -> { + mqttInstance.applyEvent(l -> l.applyFilterTopics(invisibleTopics)); + }); + } + + private void extractSegmentAndHandle(String topic, BiConsumer handler) { + String segment, remainTopic; + if (topic.startsWith("/")) { + segment = "/"; + remainTopic = topic.substring(1); + } else { + int slashIndex = topic.indexOf('/'); + if (slashIndex > 0) { + segment = topic.substring(0, slashIndex); + remainTopic = topic.substring(slashIndex + 1); + } else { + segment = topic; + remainTopic = null; + } + } + + if (handler != null) { + handler.accept(segment, remainTopic); + } + } + + public List getRootSegments() { + return Collections.list(rootNode.children()) + .stream() + .map(item -> (SegmentNode) item) + .toList(); + } + + private void updateSegments(String topic) { + extractSegmentAndHandle(topic, (segment, remainTopic) -> { + SegmentNode rootSegment = Collections.list(rootNode.children()).stream() + .map(item -> (SegmentNode) item) + .filter(item -> item.getName().equals(segment)) + .findFirst() + .orElse(null); + + if (rootSegment == null) { + rootSegment = new SegmentNode(this, rootNode, segment); + addRootSegment(rootSegment); + } + if (remainTopic != null) { + rootSegment.incrementMessages(StrUtil.split(remainTopic, '/')); + } else { + rootSegment.incrementMessages(); + } + treeModel.nodeChanged(rootSegment); + }); + } + + private void removeTopicSegments(String topic) { + extractSegmentAndHandle(topic, (segment, remainTopic) -> { + Optional rootSegment = getRootSegments().stream() + .filter(item -> item.getName().equals(segment)) + .findFirst(); + rootSegment.ifPresent((topicSegment) -> { + topicSegment.decrementMessages(topic); + }); + }); + } + + private void addRootSegment(SegmentNode segmentNode) { + List segments = getRootSegments(); + for (int i = 0; i < segments.size(); i++) { + SegmentNode existingSegment = segments.get(i); + if (segmentNode.getName().compareTo(existingSegment.getName()) <= 0) { + treeModel.insertNodeInto(segmentNode, rootNode, i); + return; + } + } + treeModel.insertNodeInto(segmentNode, rootNode, segments.size()); + } + + private void locateSegments(String topic) { + extractSegmentAndHandle(topic, (segment, remainTopic) -> { + + }); + } + +} diff --git a/src/main/java/com/mqttinsight/ui/component/tree/TopicTreeCellRenderer.java b/src/main/java/com/mqttinsight/ui/component/tree/TopicTreeCellRenderer.java new file mode 100644 index 0000000..f93495c --- /dev/null +++ b/src/main/java/com/mqttinsight/ui/component/tree/TopicTreeCellRenderer.java @@ -0,0 +1,82 @@ +package com.mqttinsight.ui.component.tree; + +import com.formdev.flatlaf.extras.FlatSVGIcon; +import com.mqttinsight.util.LangUtil; +import net.miginfocom.swing.MigLayout; +import org.jdesktop.swingx.JXLabel; + +import javax.swing.*; +import javax.swing.tree.DefaultTreeCellRenderer; +import java.awt.*; + +public class TopicTreeCellRenderer extends DefaultTreeCellRenderer { + + public static final Color TEXT_VISIBLE_COLOR = UIManager.getColor("Label.foreground"); + public static final Color TEXT_INVISIBLE_COLOR = UIManager.getColor("Label.disabledForeground"); + public static final Icon ICON_COLLAPSED = UIManager.getIcon("Tree.collapsedIcon"); + public static final Icon ICON_EXPANDED = UIManager.getIcon("Tree.expandedIcon"); + public static final Icon ICON_LEAF = new FlatSVGIcon("svg/icons/dot.svg", ICON_EXPANDED.getIconWidth(), ICON_EXPANDED.getIconHeight()); + + private final JPanel nodePanel; + + private final JXLabel nameLabel; + private final JXLabel descriptionLabel; + + public TopicTreeCellRenderer() { + super(); + nodePanel = new JPanel(); + nodePanel.setLayout(new MigLayout( + "insets 4 4 4 4", + "[]5[grow]", + "[]" + )); + nodePanel.setOpaque(false); + + nameLabel = new JXLabel(""); + nameLabel.setOpaque(false); + nameLabel.putClientProperty("FlatLaf.styleClass", "h4"); + nameLabel.setToolTipText(""); + nodePanel.add(nameLabel, "cell 0 0"); + + descriptionLabel = new JXLabel(); + descriptionLabel.setOpaque(false); + descriptionLabel.setForeground(TEXT_INVISIBLE_COLOR); + nodePanel.add(descriptionLabel, "cell 1 0,wmin 10px,growx"); + } + + @Override + public Component getTreeCellRendererComponent(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) { + if (value instanceof SegmentNode node) { + nameLabel.setText(node.getName()); + Color fg; + if (node.isSegmentVisible()) { + if (selected && hasFocus) { + fg = getTextSelectionColor(); + + } else { + fg = getTextNonSelectionColor(); + } + } else { + fg = TEXT_INVISIBLE_COLOR; + } + nameLabel.setForeground(fg); + String topicsDescription, messagesDescription; + int topicsCount = node.getTopicCount(); + if (topicsCount > 1) { + topicsDescription = LangUtil.getString("SegmentTopicsDescription"); + } else { + topicsDescription = LangUtil.getString("SegmentTopicDescription"); + } + int messagesCount = node.getTotalMessageCount(); + if (messagesCount > 1) { + messagesDescription = LangUtil.getString("SegmentMessagesDescription"); + } else { + messagesDescription = LangUtil.getString("SegmentMessageDescription"); + } + String descriptionTemplate = String.format("(%s, %s)", topicsDescription, messagesDescription); + descriptionLabel.setText(String.format(descriptionTemplate, topicsCount, messagesCount)); + } + return nodePanel; + } + +} diff --git a/src/main/java/com/mqttinsight/ui/component/tree/TopicTreeUI.java b/src/main/java/com/mqttinsight/ui/component/tree/TopicTreeUI.java new file mode 100644 index 0000000..a66a772 --- /dev/null +++ b/src/main/java/com/mqttinsight/ui/component/tree/TopicTreeUI.java @@ -0,0 +1,55 @@ +package com.mqttinsight.ui.component.tree; + +import com.formdev.flatlaf.ui.FlatTreeUI; + +import javax.swing.*; +import javax.swing.tree.TreePath; +import java.awt.*; + +public class TopicTreeUI extends FlatTreeUI { + + @Override + protected boolean shouldPaintExpandControl(TreePath path, int row, + boolean isExpanded, + boolean hasBeenExpanded, + boolean isLeaf) { + return true; + } + + @Override + protected void paintExpandControl(Graphics g, + Rectangle clipBounds, Insets insets, + Rectangle bounds, TreePath path, + int row, boolean isExpanded, + boolean hasBeenExpanded, + boolean isLeaf) { + Object value = path.getLastPathComponent(); + + // Draw icons if not a leaf and either hasn't been loaded, + // or the model child count is > 0. + int middleXOfKnob; + if (tree.getComponentOrientation().isLeftToRight()) { + middleXOfKnob = bounds.x - getRightChildIndent() + 1; + } else { + middleXOfKnob = bounds.x + bounds.width + getRightChildIndent() - 1; + } + int middleYOfKnob = bounds.y + (bounds.height / 2); + + if (isLeaf) { + Icon leafIcon = TopicTreeCellRenderer.ICON_LEAF; + if (leafIcon != null) + drawCentered(tree, g, leafIcon, middleXOfKnob, + middleYOfKnob); + } else if (isExpanded) { + Icon expandedIcon = getExpandedIcon(); + if (expandedIcon != null) + drawCentered(tree, g, expandedIcon, middleXOfKnob, + middleYOfKnob); + } else { + Icon collapsedIcon = getCollapsedIcon(); + if (collapsedIcon != null) + drawCentered(tree, g, collapsedIcon, middleXOfKnob, + middleYOfKnob); + } + } +} diff --git a/src/main/java/com/mqttinsight/ui/form/panel/MessageViewPanel.java b/src/main/java/com/mqttinsight/ui/form/panel/MessageViewPanel.java index ef8a450..2170024 100644 --- a/src/main/java/com/mqttinsight/ui/form/panel/MessageViewPanel.java +++ b/src/main/java/com/mqttinsight/ui/form/panel/MessageViewPanel.java @@ -359,6 +359,7 @@ private void tableSelectionChanged(ListSelectionEvent e) { mqttInstance.applyEvent(l -> l.tableSelectionChanged(message)); } } else { + lastSelectedRow = selectedRow; mqttInstance.applyEvent(l -> l.tableSelectionChanged(null)); } } diff --git a/src/main/java/com/mqttinsight/ui/form/panel/MqttInstanceTabPanel.java b/src/main/java/com/mqttinsight/ui/form/panel/MqttInstanceTabPanel.java index 8abac20..d20e2db 100644 --- a/src/main/java/com/mqttinsight/ui/form/panel/MqttInstanceTabPanel.java +++ b/src/main/java/com/mqttinsight/ui/form/panel/MqttInstanceTabPanel.java @@ -11,6 +11,7 @@ import com.mqttinsight.ui.chart.series.SeriesProperties; import com.mqttinsight.ui.component.*; import com.mqttinsight.ui.component.model.MessageViewMode; +import com.mqttinsight.ui.component.tree.TopicTree; import com.mqttinsight.ui.event.InstanceEventAdapter; import com.mqttinsight.ui.event.InstanceEventListener; import com.mqttinsight.ui.form.MainWindowForm; @@ -76,7 +77,8 @@ public abstract class MqttInstanceTabPanel extends JPanel implements MqttInstanc protected MessagePreviewPanel messagePreviewPanel; protected SubscriptionListPanel subscriptionListPanel; - protected TopicTreePanel topicTreePanel; + protected TopicTree topicTree; + private JScrollPane topicTreeScrollPanel; private final List eventListeners; @@ -114,10 +116,13 @@ private void initComponents() { { // left subscriptionListPanel = new SubscriptionListPanel(this); - topicTreePanel = new TopicTreePanel(this); + topicTree = new TopicTree(this); + topicTreeScrollPanel = new JScrollPane(topicTree); + Border scrollPanelBorder = new SingleLineBorder(UIManager.getColor("Component.borderColor"), true, true, true, true); + topicTreeScrollPanel.setBorder(scrollPanelBorder); leftSplitPanel.setLeftComponent(subscriptionListPanel); - leftSplitPanel.setRightComponent(topicTreePanel); + leftSplitPanel.setRightComponent(topicTreeScrollPanel); Integer divider = Configuration.instance().getInt(ConfKeys.SUBSCRIPTION_VERTICAL_DIVIDER, 430); leftSplitPanel.setDividerLocation(divider); diff --git a/src/main/java/com/mqttinsight/ui/form/panel/TopicTreePanel.java b/src/main/java/com/mqttinsight/ui/form/panel/TopicTreePanel.java deleted file mode 100644 index bc7d8de..0000000 --- a/src/main/java/com/mqttinsight/ui/form/panel/TopicTreePanel.java +++ /dev/null @@ -1,186 +0,0 @@ -package com.mqttinsight.ui.form.panel; - -import cn.hutool.core.util.StrUtil; -import com.mqttinsight.mqtt.MqttMessage; -import com.mqttinsight.ui.component.TopicSegment; -import com.mqttinsight.ui.event.InstanceEventAdapter; -import org.jdesktop.swingx.VerticalLayout; - -import javax.swing.*; -import java.awt.*; -import java.util.List; -import java.util.*; -import java.util.function.BiConsumer; - -/** - * @author ptma - */ -public class TopicTreePanel extends JScrollPane { - - private final MqttInstance mqttInstance; - - private final JPanel segmentsContainer; - - private TopicSegment selectedSegment; - - public TopicTreePanel(final MqttInstance mqttInstance) { - super(); - this.mqttInstance = mqttInstance; - getVerticalScrollBar().setUnitIncrement(30); - segmentsContainer = new JPanel(); - segmentsContainer.setLayout(new VerticalLayout(0)); - segmentsContainer.setBackground(UIManager.getColor("Table.background")); - setViewportView(segmentsContainer); - - initEventListeners(); - - } - - private void initEventListeners() { - mqttInstance.addEventListener(new InstanceEventAdapter() { - @Override - public void onMessage(MqttMessage message, MqttMessage parent) { - SwingUtilities.invokeLater(() -> { - updateSegments(message.getTopic()); - }); - } - - @Override - public void onMessageRemoved(MqttMessage message) { - SwingUtilities.invokeLater(() -> { - removeTopicSegments(message.getTopic()); - }); - } - - @Override - public void requestFocusPreview() { - SwingUtilities.invokeLater(() -> { - mqttInstance.getMessageTable().getSelectedMessage() - .ifPresent(message -> { - locateSegments(message.getTopic()); - }); - }); - } - }); - } - - public void changeSelectedSegment(TopicSegment segment) { - if (selectedSegment != null && selectedSegment != segment) { - selectedSegment.setSelected(false); - } - selectedSegment = segment; - } - - public void notifyTopicSegmentsVisibleChange() { - Set invisibleTopics = getRootSegments().stream() - .map(TopicSegment::getInvisibleTopics) - .reduce((setA, setB) -> { - setA.addAll(setB); - return setA; - }) - .orElseGet(HashSet::new); - mqttInstance.applyEvent(l -> l.applyFilterTopics(invisibleTopics)); - } - - private void extractSegmentAndHandle(String topic, BiConsumer handler) { - String segment, remainTopic; - if (topic.startsWith("/")) { - segment = "/"; - remainTopic = topic.substring(1); - } else { - int slashIndex = topic.indexOf('/'); - if (slashIndex > 0) { - segment = topic.substring(0, slashIndex); - remainTopic = topic.substring(slashIndex + 1); - } else { - segment = topic; - remainTopic = null; - } - } - - if (handler != null) { - handler.accept(segment, remainTopic); - } - } - - private void updateSegments(String topic) { - extractSegmentAndHandle(topic, (segment, remainTopic) -> { - TopicSegment rootSegment = getRootSegments().stream() - .filter(item -> item.getName().equals(segment)) - .findFirst() - .orElse(null); - if (rootSegment == null) { - rootSegment = new TopicSegment(mqttInstance, this, this, segment, 0, true); - addRootSegment(rootSegment); - } - if (remainTopic != null) { - rootSegment.incrementMessages(StrUtil.split(remainTopic, '/')); - } else { - rootSegment.incrementMessages(); - } - }); - - } - - private void removeTopicSegments(String topic) { - extractSegmentAndHandle(topic, (segment, remainTopic) -> { - Optional rootSegment = getRootSegments().stream() - .filter(item -> item.getName().equals(segment)) - .findFirst(); - rootSegment.ifPresent((topicSegment) -> { - topicSegment.decrementMessages(topic); - }); - }); - } - - /** - * When double clicking a message in the message table, locate the topic segment node - * - * @param topic segment - */ - private void locateSegments(String topic) { - extractSegmentAndHandle(topic, (segment, remainTopic) -> { - int height = 0; - for (TopicSegment rootSegment : getRootSegments()) { - if (rootSegment.getName().equals(segment)) { - if (!rootSegment.isExpanded()) { - rootSegment.toggleExpanded(); - } - height += rootSegment.calcSegmentScrollHeight(StrUtil.split(remainTopic, '/')); - getViewport().setViewPosition(new Point(0, height)); - //updateUI(); - break; - } else { - height += rootSegment.getComponentSize().height; - } - } - }); - - } - - public List getRootSegments() { - return Arrays.stream(segmentsContainer.getComponents()) - .map(c -> (TopicSegment) c) - .toList(); - } - - private void addRootSegment(TopicSegment segment) { - List segments = getRootSegments(); - for (int i = 0; i < segments.size(); i++) { - TopicSegment existingSegment = segments.get(i); - if (segment.getName().compareTo(existingSegment.getName()) <= 0) { - segmentsContainer.add(segment, i); - return; - } - } - segmentsContainer.add(segment); - segmentsContainer.revalidate(); - //segmentsContainer.repaint(); - } - - public void removeRootSegment(TopicSegment segment) { - segmentsContainer.remove(segment); - segmentsContainer.revalidate(); - segmentsContainer.repaint(); - } -} diff --git a/src/main/java/com/mqttinsight/ui/frame/MainFrame.java b/src/main/java/com/mqttinsight/ui/frame/MainFrame.java index b2d1623..d7286e4 100644 --- a/src/main/java/com/mqttinsight/ui/frame/MainFrame.java +++ b/src/main/java/com/mqttinsight/ui/frame/MainFrame.java @@ -79,6 +79,8 @@ private void initGlobalComponentStyles() { UIManager.put("TextComponent.arc", 5); UIManager.put("SplitPaneDivider.style", "grip"); UIManager.put("SplitPane.centerOneTouchButtons", true); + UIManager.put("Tree.leftChildIndent", 4); + UIManager.put("Tree.rightChildIndent", 8); UIManager.put("PasswordField.showRevealButton", true); diff --git a/src/main/java/com/mqttinsight/util/Utils.java b/src/main/java/com/mqttinsight/util/Utils.java index 0d48929..9df1d63 100644 --- a/src/main/java/com/mqttinsight/util/Utils.java +++ b/src/main/java/com/mqttinsight/util/Utils.java @@ -278,6 +278,16 @@ public static JMenuItem createMenuItem(String menuText, ActionListener action) { return menuItem; } + public static JMenuItem createCheckBoxMenuItem(String menuText, ActionListener action) { + JMenuItem menuItem = new JCheckBoxMenuItem(); + Utils.UI.buttonText(menuItem, menuText); + + if (action != null) { + menuItem.addActionListener(action); + } + return menuItem; + } + public static JMenuItem createMenuItem(String menuText, Action action) { JMenuItem menuItem = new NormalMenuItem(); if (action != null) { diff --git a/src/main/resources/com/mqttinsight/Lang_en.properties b/src/main/resources/com/mqttinsight/Lang_en.properties index 4b0bfe5..0545c33 100644 --- a/src/main/resources/com/mqttinsight/Lang_en.properties +++ b/src/main/resources/com/mqttinsight/Lang_en.properties @@ -1,371 +1,373 @@ -&File = &File -&ConnectionManager = &Connection Management -Co&decs = Co&decs -&Options = &Options -E&xit = E&xit -&View = &View -Show&Log = Show &Log -&Help = &Help -&About = &About ... -About = About -AboutOpenSource = The MqttInsight uses some fine open source projects: -Log = Log -Options = Options -UserInterface = User Interface -Language = Language -Theme = Theme -MessageEditor = Message Editor -Font = Font -FontSize = Font Size -MessageView = Message View -DefaultView = Default View -TableView = Table View -DialogueView = Dialogue View -MaxMessageRows = Max Message Rows -MaxMessageRowsTip = Set the maximum number of lines for message display in the "Dialogue View" to avoid affecting the display when the Dialogue bubble is too large. \nIf set to 0, there will be no restriction. -TimeFormat = Time Format -InputDialogTitle = Input -InputDialogEmptyInfo = The input content cannot be empty. -Cut = Cut -Copy = Copy -Paste = Paste -SelectAll = Select All -&Ok = &Ok -&Close = &Close -Close = Close -&Cancel = &Cancel -&Detail = &Detail -Question = Question -&New = &New -&Remove = &Remove -Re&load = Re&load -OpenConnection = Open Connection -Connect = Connect -Disconnect = Disconnect -Connecting = Connecting ... -Connected = Connected -Disconnecting = Disconnecting ... -Disconnected = Disconnected -Failed = Connect Failed -MqttReasonCode_-1 = Unknown error -MqttReasonCode_1 = Invalid protocol version -MqttReasonCode_2 = Invalid clientId -MqttReasonCode_3 = Broker unavailable -MqttReasonCode_4 = Bad username or password -MqttReasonCode_5 = Not authorized to connect -MqttReasonCode_6 = Unexpected error -MqttReasonCode_119 = Invalid URI Provided that could not be used to create a NetworkModule: {0} -MqttReasonCode_32000 = Timed out waiting for a response from the server -MqttReasonCode_32001 = Internal error, caused by no new message IDs being available -MqttReasonCode_32002 = Timed out while waiting to write messages to the server -MqttReasonCode_32100 = Client is connected -MqttReasonCode_32101 = Client is disconnected -MqttReasonCode_32102 = Client is currently disconnecting -MqttReasonCode_32103 = Unable to connect to server -MqttReasonCode_32104 = Client is not connected -MqttReasonCode_32105 = The specified SocketFactory type does not match the broker URI -MqttReasonCode_32106 = SSL configuration error -MqttReasonCode_32107 = Disconnecting is not allowed from a callback method -MqttReasonCode_32108 = Unrecognized packet -MqttReasonCode_32109 = Connection lost -MqttReasonCode_32110 = Connect already in progress -MqttReasonCode_32111 = Client is closed -MqttReasonCode_32200 = Persistence already in use -MqttReasonCode_32201 = Token already in use -MqttReasonCode_32202 = Too many publishes in progress -MqttReasonCode_50000 = Invalid Identifier in the IV fields. -MqttReasonCode_50001 = Invalid Return code. -MqttReasonCode_50002 = Packet was somehow malformed and did not comply to the MQTTv5 specification. -MqttReasonCode_50003 = The CONNECT packet did not contain the correct protocol name or version. -MqttReasonCode_50004 = The Server sent a publish message with an invalid topic alias. -MqttReasonCode_50005 = The client attempted to decode a property that had already been decoded, and can only be included once. -MqttReasonCode_51001 = Incoming packet too large. -MqttReasonCode_51002 = Outgoing packet too large. -MqttReasonCode_16 = No matching subscribers. -MqttReasonCode_17 = No subscription existed. -MqttReasonCode_24 = Continue authentication. -MqttReasonCode_25 = Re-authenticate. -MqttReasonCode_128 = Unspecified error. -MqttReasonCode_129 = Malformed packet. -MqttReasonCode_130 = Protocol error. -MqttReasonCode_131 = Implementation specific error. -MqttReasonCode_132 = Unsupported protocol version. -MqttReasonCode_133 = Client identifier not valid. -MqttReasonCode_134 = Bad UserName or Password. -MqttReasonCode_135 = Not authorized. -MqttReasonCode_136 = Server unavailable. -MqttReasonCode_137 = Server busy. -MqttReasonCode_138 = Banned. -MqttReasonCode_139 = Server shutting down. -MqttReasonCode_140 = Bad authentication method. -MqttReasonCode_141 = Keep Alive timeout. -MqttReasonCode_142 = Session taken over. -MqttReasonCode_143 = Topic Filter invalid. -MqttReasonCode_144 = Topic Name invalid. -MqttReasonCode_145 = Packet identifier in use. -MqttReasonCode_146 = Packet identifier not found. -MqttReasonCode_147 = Receive Maximum exceeded. -MqttReasonCode_148 = Topic Alias invalid. -MqttReasonCode_149 = Packet too large. -MqttReasonCode_150 = Message rate too high. -MqttReasonCode_151 = Quota exceeded. -MqttReasonCode_152 = Administrative action. -MqttReasonCode_153 = Payload format invalid. -MqttReasonCode_154 = Retain not supported. -MqttReasonCode_155 = QoS not supported -MqttReasonCode_156 = Use another server. -MqttReasonCode_157 = Server moved. -MqttReasonCode_158 = Shared Subscriptions not supported. -MqttReasonCode_159 = Connection rate exceeded. -MqttReasonCode_160 = Maximum connect time. -MqttReasonCode_161 = Subscription Identifiers not supported. -MqttReasonCode_162 = Wildcard Subscriptions no supported. -NewSubscription = New Subscription -NoSubscriptions = No favorite subscriptions -SubscribeAll = Subscribe All -RemoveFavoriteSubscription = Do you want to remove the favorite subscription "%s"? -MessageIndicator = Message(%d / %d) -SearchHistory = Search History -Empty = -MatchCase = Match Case -WholeWords = Whole Words -RegularExpression = Regular Expression -PreviousOccurrence = Previous Occurrence -NextOccurrence = Next Occurrence -ScrollToEnd = Scroll To End -ClearAll = Clear All -FilterSearchResults = Filter Search Results -GoFirst = Go First -GoPrevious = Go Previous -GoNext = Go Next -GoLast = Go Last -Autoscroll = Autoscroll -More = More... -Script = Script -LoadScript = Load Script ... -JavaScriptFileFilter = JavaScript Files(*.js) -ClearAllMessages = Clear All Messages -ClearVisibleMessages = Clear Visible Messages -ExportAllMessages = Export All Messages ... -PayloadFormat = Message Format -PayloadFormatTip = When "Default" is selected, the default message format set in the connection will be used as the subscription message format.\nAnd the message format can be changed again in the pop-up menu of the subscription item. -Topic = Topic -Payload = Payload -QoS = QoS -Retained = Retained -ReceivedTime = Received Time -Time = Time -Pretty = Pretty -SyntaxHighlighting = Syntax Highlighting -SyntaxHighlightingTips = Enabling syntax highlighting will incur additional performance consumption. It is recommended to disable syntax highlighting when there are a large number of messages and complex content to improve preview performance. -JsonFileFilter = JSON File (*.json) -CsvFileFilter = CSV File (*.csv) -TextFileFilter = Text File (*.txt) -AllFileFilter = All File (*.*) -FileExists = The file "%s" already exists, do you want to overwrite it! -Favorite = Favorite -ShowOrHideMessages = Show/Hide Messages -Unsubscribe = Unsubscribe -Resubscribe = Resubscribe -ClearMessages = Clear Messages -ExportMessages = Export Messages ... -TopicSubscribed = The topic has already been subscribed and cannot be subscribed again. -Color = Color -MoreColor = More Color ... -ChooseColor = Choose Color -Preview = Preview -MessagePreview = Message Preview -PreviewSeparateWindow = Preview in a Separate Window -Publish = Publish -PublishMessage = Publish Message -PublishTips = The message content can use placeholders, which will be replaced with corresponding random values when actually sent:\n${timestamp}: The current system timestamp value in milliseconds;\n${uuid}: a random UUID;\n${int(min,max)}: A random integer value;\n${float(min,max)}: A random float value;\n${string(length)}: A random string of specified length. -Copy&Topic = Copy &Topic -Copy&Payload = Copy Payload -SegmentTopicDescription = %d topic -SegmentTopicsDescription = %d topics -SegmentMessageDescription = %d message -SegmentMessagesDescription = %d messages +&File=&File +&ConnectionManager=&Connection Management +Co&decs=Co&decs +&Options=&Options +E&xit=E&xit +&View=&View +Show&Log=Show &Log +&Help=&Help +&About=&About ... +About=About +AboutOpenSource=The MqttInsight uses some fine open source projects: +Log=Log +Options=Options +UserInterface=User Interface +Language=Language +Theme=Theme +MessageEditor=Message Editor +Font=Font +FontSize=Font Size +MessageView=Message View +DefaultView=Default View +TableView=Table View +DialogueView=Dialogue View +MaxMessageRows=Max Message Rows +MaxMessageRowsTip=Set the maximum number of lines for message display in the "Dialogue View" to avoid affecting the display when the Dialogue bubble is too large. \nIf set to 0, there will be no restriction. +TimeFormat=Time Format +InputDialogTitle=Input +InputDialogEmptyInfo=The input content cannot be empty. +Cut=Cut +Copy=Copy +Paste=Paste +SelectAll=Select All +&Ok=&Ok +&Close=&Close +Close=Close +&Cancel=&Cancel +&Detail=&Detail +Question=Question +&New=&New +&Remove=&Remove +Re&load=Re&load +OpenConnection=Open Connection +Connect=Connect +Disconnect=Disconnect +Connecting=Connecting ... +Connected=Connected +Disconnecting=Disconnecting ... +Disconnected=Disconnected +Failed=Connect Failed +MqttReasonCode_-1=Unknown error +MqttReasonCode_1=Invalid protocol version +MqttReasonCode_2=Invalid clientId +MqttReasonCode_3=Broker unavailable +MqttReasonCode_4=Bad username or password +MqttReasonCode_5=Not authorized to connect +MqttReasonCode_6=Unexpected error +MqttReasonCode_119=Invalid URI Provided that could not be used to create a NetworkModule: {0} +MqttReasonCode_32000=Timed out waiting for a response from the server +MqttReasonCode_32001=Internal error, caused by no new message IDs being available +MqttReasonCode_32002=Timed out while waiting to write messages to the server +MqttReasonCode_32100=Client is connected +MqttReasonCode_32101=Client is disconnected +MqttReasonCode_32102=Client is currently disconnecting +MqttReasonCode_32103=Unable to connect to server +MqttReasonCode_32104=Client is not connected +MqttReasonCode_32105=The specified SocketFactory type does not match the broker URI +MqttReasonCode_32106=SSL configuration error +MqttReasonCode_32107=Disconnecting is not allowed from a callback method +MqttReasonCode_32108=Unrecognized packet +MqttReasonCode_32109=Connection lost +MqttReasonCode_32110=Connect already in progress +MqttReasonCode_32111=Client is closed +MqttReasonCode_32200=Persistence already in use +MqttReasonCode_32201=Token already in use +MqttReasonCode_32202=Too many publishes in progress +MqttReasonCode_50000=Invalid Identifier in the IV fields. +MqttReasonCode_50001=Invalid Return code. +MqttReasonCode_50002=Packet was somehow malformed and did not comply to the MQTTv5 specification. +MqttReasonCode_50003=The CONNECT packet did not contain the correct protocol name or version. +MqttReasonCode_50004=The Server sent a publish message with an invalid topic alias. +MqttReasonCode_50005=The client attempted to decode a property that had already been decoded, and can only be included once. +MqttReasonCode_51001=Incoming packet too large. +MqttReasonCode_51002=Outgoing packet too large. +MqttReasonCode_16=No matching subscribers. +MqttReasonCode_17=No subscription existed. +MqttReasonCode_24=Continue authentication. +MqttReasonCode_25=Re-authenticate. +MqttReasonCode_128=Unspecified error. +MqttReasonCode_129=Malformed packet. +MqttReasonCode_130=Protocol error. +MqttReasonCode_131=Implementation specific error. +MqttReasonCode_132=Unsupported protocol version. +MqttReasonCode_133=Client identifier not valid. +MqttReasonCode_134=Bad UserName or Password. +MqttReasonCode_135=Not authorized. +MqttReasonCode_136=Server unavailable. +MqttReasonCode_137=Server busy. +MqttReasonCode_138=Banned. +MqttReasonCode_139=Server shutting down. +MqttReasonCode_140=Bad authentication method. +MqttReasonCode_141=Keep Alive timeout. +MqttReasonCode_142=Session taken over. +MqttReasonCode_143=Topic Filter invalid. +MqttReasonCode_144=Topic Name invalid. +MqttReasonCode_145=Packet identifier in use. +MqttReasonCode_146=Packet identifier not found. +MqttReasonCode_147=Receive Maximum exceeded. +MqttReasonCode_148=Topic Alias invalid. +MqttReasonCode_149=Packet too large. +MqttReasonCode_150=Message rate too high. +MqttReasonCode_151=Quota exceeded. +MqttReasonCode_152=Administrative action. +MqttReasonCode_153=Payload format invalid. +MqttReasonCode_154=Retain not supported. +MqttReasonCode_155=QoS not supported +MqttReasonCode_156=Use another server. +MqttReasonCode_157=Server moved. +MqttReasonCode_158=Shared Subscriptions not supported. +MqttReasonCode_159=Connection rate exceeded. +MqttReasonCode_160=Maximum connect time. +MqttReasonCode_161=Subscription Identifiers not supported. +MqttReasonCode_162=Wildcard Subscriptions no supported. +NewSubscription=New Subscription +NoSubscriptions=No favorite subscriptions +SubscribeAll=Subscribe All +RemoveFavoriteSubscription=Do you want to remove the favorite subscription "%s"? +MessageIndicator=Message(%d / %d) +SearchHistory=Search History +Empty= +MatchCase=Match Case +WholeWords=Whole Words +RegularExpression=Regular Expression +PreviousOccurrence=Previous Occurrence +NextOccurrence=Next Occurrence +ScrollToEnd=Scroll To End +ClearAll=Clear All +FilterSearchResults=Filter Search Results +GoFirst=Go First +GoPrevious=Go Previous +GoNext=Go Next +GoLast=Go Last +Autoscroll=Autoscroll +More=More... +Script=Script +LoadScript=Load Script ... +JavaScriptFileFilter=JavaScript Files(*.js) +ClearAllMessages=Clear All Messages +ClearVisibleMessages=Clear Visible Messages +ExportAllMessages=Export All Messages ... +PayloadFormat=Message Format +PayloadFormatTip=When "Default" is selected, the default message format set in the connection will be used as the subscription message format.\nAnd the message format can be changed again in the pop-up menu of the subscription item. +Topic=Topic +Payload=Payload +QoS=QoS +Retained=Retained +ReceivedTime=Received Time +Time=Time +Pretty=Pretty +SyntaxHighlighting=Syntax Highlighting +SyntaxHighlightingTips=Enabling syntax highlighting will incur additional performance consumption. It is recommended to disable syntax highlighting when there are a large number of messages and complex content to improve preview performance. +JsonFileFilter=JSON File (*.json) +CsvFileFilter=CSV File (*.csv) +TextFileFilter=Text File (*.txt) +AllFileFilter=All File (*.*) +FileExists=The file "%s" already exists, do you want to overwrite it! +Favorite=Favorite +ShowOrHideMessages=Show/Hide Messages +HideRelatedMessages=Hide Related Messages +HideAllOtherMessages=Hide All Other Messages +Unsubscribe=Unsubscribe +Resubscribe=Resubscribe +ClearMessages=Clear Messages +ExportMessages=Export Messages ... +TopicSubscribed=The topic has already been subscribed and cannot be subscribed again. +Color=Color +MoreColor=More Color ... +ChooseColor=Choose Color +Preview=Preview +MessagePreview=Message Preview +PreviewSeparateWindow=Preview in a Separate Window +Publish=Publish +PublishMessage=Publish Message +PublishTips=The message content can use placeholders, which will be replaced with corresponding random values when actually sent:\n${timestamp}: The current system timestamp value in milliseconds;\n${uuid}: a random UUID;\n${int(min,max)}: A random integer value;\n${float(min,max)}: A random float value;\n${string(length)}: A random string of specified length. +Copy&Topic=Copy &Topic +Copy&Payload=Copy Payload +SegmentTopicDescription=%d topic +SegmentTopicsDescription=%d topics +SegmentMessageDescription=%d message +SegmentMessagesDescription=%d messages # ConnectionManagerForm -ConnectionManagement = Connection Management -&OpenConnection = &Open Connection -New&Group = New &Group -New&RootGroup = New &Root Group -New&Connection = New &Connection -Du&plicate = Du&plicate -&Edit = &Edit -Edit = Edit -&Delete = &Delete -Delete = Delete -NewGroup = New Group -EditGroup = Edit Group -GroupName = Group Name -EnterGroupName = Please enter a group name -NewConnection = New Connection -EditConnection = Edit Connection -ConnectionDeleteConfirm = Do you want to delete connection "%s"? +ConnectionManagement=Connection Management +&OpenConnection=&Open Connection +New&Group=New &Group +New&RootGroup=New &Root Group +New&Connection=New &Connection +Du&plicate=Du&plicate +&Edit=&Edit +Edit=Edit +&Delete=&Delete +Delete=Delete +NewGroup=New Group +EditGroup=Edit Group +GroupName=Group Name +EnterGroupName=Please enter a group name +NewConnection=New Connection +EditConnection=Edit Connection +ConnectionDeleteConfirm=Do you want to delete connection "%s"? # ConnectionEditorForm -TestConnection = Test Connection -General = General -MQTT5Options = MQTT5 Options -TLS/SSL = TLS/SSL -LastWill = Last Will -Other = Other -Generate = Generate -Name = Name -Transport = Transport -Version = Version -Server = Server -Port = Port -ClientId = ClientId -CleanSession = Clean Session -CleanSessionToolTip = Sets whether the client and server should remember state across restarts and reconnects.\nIf set to false both the client and server will maintain state across restarts of the client, the server and the connection. As state is maintained:\nMessage delivery will be reliable meeting the specified QOS even if the client, server or connection are restarted.\nThe server will treat a subscription as durable.\nIf set to true the client and server will not maintain state across restarts of the client, the server or the connection. This means\nMessage delivery to the specified QOS cannot be maintained if the client, server or connection are restarted\nThe server will treat a subscription as non-durable. -AutoReconnect = Auto Reconnect -ConnectionTimeout = Connection Timeout -ConnectionTimeoutToolTip = Sets the connection timeout value. \nThis value, measured in seconds, defines the maximum time interval the client will wait for the network connection to the MQTT server to be established. \nThe default timeout is 30 seconds. \nA value of 0 disables timeout processing meaning the client will wait until the network connection is made successfully or fails. -KeepAliveInterval = Keep Alive Interval -KeepAliveIntervalToolTip = Sets the "keep alive" interval. \nThis value, measured in seconds, defines the maximum time interval between messages sent or received. \nIt enables the client to detect if the server is no longer available, without having to wait for the TCP/IP timeout. \nThe client will ensure that at least one message travels across the network within each keep alive period. \nIn the absence of a data-related message during the time period, the client sends a very small "ping" message, which the server will acknowledge. \nA value of 0 disables keepalive processing in the client. -ReconnectInterval = Reconnect Interval -ReconnectIntervalToolTip = Set the maximum time to wait between reconnects.\nThis value, measured in seconds. -EnableLastWill = Enable Last Will Message -RandomClientId = Random ClientId -Username = Username -Password = Password -CleanStart = Clean Start -CleanStartToolTip = Sets whether the client and server should remember state across restarts and reconnects. -RequestResponseInfo = Request Response Info -RequestResponseInfoToolTip = Sets the Request Response Info Flag.\nIf set to "null", then it will default to false.\nIf set to false, the server will not return any response information in the "CONNACK".\nIf set to true, the server MAY return response information in the "CONNACK". -RequestProblemInfo = Request Problem Info -RequestProblemInfoToolTip = Sets the Request Problem Info flag.\nIf set to "null", then it will default to true.\nIf set to false, the server MAY return a Reason String or User Properties\non a "CONNACK" or "DISCONNECT", but must not send a Reason String or User\nProperties on any packet other than "PUBLISH", "CONNACK" or "DISCONNECT".\nIf set to true, the server MAY return a Reason String or User Properties\non any packet where it is allowed. -SessionExpiryInterval = Session Expiry Interval -SessionExpiryIntervalToolTip = Sets the Session Expiry Interval.\nThis value, measured in seconds, defines the maximum time that the broker will maintain the session for once the client disconnects.\nClients should only connect with a long Session Expiry interval if they intend to connect to the server at some later point in time. -ReceiveMaximum = Receive Maximum -ReceiveMaximumToolTip = Sets the Receive Maximum.This value represents the limit of QoS 1 and QoS 2 publications that the client is willing to process concurrently. \nThere is no mechanism to limit the number of QoS 0 publications that the Server might try to send.\nThe range of values is 1-65535, leave blank to indicate maximum value. -MaximumPacketSize = Maximum Packet Size -MaximumPacketSizeToolTip = Sets the Maximum Packet Size. \nThis value represents the Maximum Packet Size the client is willing to accept.\nThe range of values is 1-2684354656, leave blank without restrictions. -TopicAliasMaximum = Topic Alias Maximum -TopicAliasMaximumToolTip = Sets the Topic Alias Maximum. \nThis value if present represents the highest value that the Client will accept as a Topic Alias sent by the Server.\nIf set to blank, then it will default to to 0.\nIf set to 0, the Client will not accept any Topic Aliases. \nThe Maximum value for this property is 65535. -UserProperties = User Properties -RemoveProperty = Remove Property -AddProperty = Add Property -NewProperty = New Property -NewValue = New value -Property = Property -Value = Value -EnableSSL = Enable TLS/SSL -SslProtocol = Protocol -SslMode = TLS/SSL Mode -SslModeBasic = Certificates & keys provided externally -SslModeServerOnly = CA certificate -SslModeServerKeystore = CA trust store -SslModeServerAndClient = CA certificate & client certificate/key -SslModeServerAndClientKeystore = CA trust store & client key store -SslModeProperties = TLS/SSL properties -SslPropertyNotValid = "%s" is not a valid SSL property key. -ChooseFile = Choose File -CaAndKeysFileFilter = Certificates And Keys Files(*.jks,*.jceks,*.p12,*.pfx,*.bks,*.pem,*.key) -CaCertificateFile = CA certificate file -CaKeystoreFile = CA Keystore File -ClientCertificateFile = Client certificate file -ClientKeyPassword = Client Key Password -ClientKeystoreFile = Client Keystore File -ClientKeystorePassword = Client Keystore Password -ClientKeyFile = Client key file -CaKeystorePassword = CA Keystore Password -PemKey = PEM Key -MaxMessagesStored = Max Messages Stored -DefaultPayloadFormat = Default Message Format -ClearUnsubMessage = Clear messages when closing subscription -FieldRequiredValidation = "%s" is required. -FieldRangeValidation = The range of "%s" is %d - %d -FieldMaxLengthValidation = The length of "%s" cannot exceed %d characters. -InputNotValid = The string "%s" is not a valid %s. -TestConnectionFailed = Test connection failed!\n\nCode: %d\nMessage: %s -TestConnectionSuccessful = Test connection Successful! -TestConnectionError = Test connection failed because of an error occurred:\n%s -Error = Error -Confirm = Confirm -Information = Information -Warning = Warning -ConnectionExists = Connection has been opened. -OpenConnectionError = An error occurred while opening the connection. -InvalidTopicOfMultiSymbol = Invalid format of topic, the multi symbol (#) has to be the last one after a separator. -InvalidSubtopic = Bad format of topic, invalid subtopic name: "%s". -ScriptLoaded = Successfully loaded script: %s -ScriptRemoved = Successfully removed script: %s -ScriptError = An error occurred while executing the script "%s" -ChooseScriptOperation = Please select what action you want to take on the script?\n If you want to cancel the execution of the script, click the "Remove" button.\n If the content of the script has changed, click "Reload" to load the new script content. -ScriptReloadConfirm = Do you want to reload the script "%s"? -Chart = Chart -MessageCountStatisticsChart = Message Count Statistics Chart ... -MessageCountStatisticsChartTitle = Message Count Statistics Chart [%s] -MessageLoadStatisticsChart = Message Load Statistics Chart ... -MessageLoadStatisticsChartTitle = Message Load Statistics Chart [%s] -MessageContentStatisticsChart = Message Content Statistics Chart ... -MessageContentStatisticsChartTitle = Message Content Statistics Chart [%s] -AddSeries = Add Series -RemoveSeries = Remove Series -ResetChart = Reset Chart -Pause = Pause -Resume = Resume -SaveCollectionToFavorites = Save the collection of the current chart series to favorites -EnterCollectionName = Enter the collection name for the series -OverwriteCollection = Do you want to overwrite the existing series collection "%s"? -PieChart = Pie Chart -BarChart = Bar Chart -SaveAs = Save As ... -Print = Print ... -ExportAs = Export As ... -ResetZoom = Reset Zoom -RemoveFavoriteCollection = Do you want to remove the series collection of series "%s"? -SeriesEditor = Series Editor -DynamicSeries = Dynamic Series -SeriesName = Series Name -Dynamic = Dynamic -Match = Match -MatchMode = Match Mode -MatchExpression = Match Expression -MatchExpressionTip = When the "Dynamic Series" checkbox is selected and the "Match Mode" is "Regular Expression", be sure to use grouping constructs delineate the subexpressions of a regular expression and capture the substrings of the input string. \nBy default, the substring that matches the first subexpression will be extracted. \nIf grouping constructs is not used, the complete matching string will be extracted.\n\nFor example: \\$SYS/broker/connection/(.+)/state\nwill match the topic \\$SYS/broker/connection/ACBD/state\n and extract substring ACBD -Wildcards = Wildcards -JsonPath = JsonPath -Equals = Equals -NotEquals = Not equals -Contains = Contains -NotContains = Not contains -StatisticalMethod = Statistical Method -MessageCount = Message Count -AverageMessageSize = AverageMessageSize -SumOfMessageSize = Sum of Message Size -MaximumMessageSize = Maximum Message Size -MinimumMessageSize = Minimum Message Size -MessageSize = Message Size -MessageSizeAxis = Message Size (bytes) -StatisticalWindow = Statistical Window -ExtractingMode = Extracting Mode -PayloadContent = Payload Content -ExtractingExpression = Extracting Expression -ExtractingExpressionTip = When the "Extracting Mode" is a "Regular Expression", be sure to use grouping constructs delineate the subexpressions of a regular expression and capture the substrings of the input string.\nBy default, the substring that matches the first subexpression will be extracted. \nIf grouping constructs is not used, the complete matching string will be extracted.\n\nNote: The extracted content must be numeric, non numeric content will be ignored. -RefreshFrequency = Refresh Frequency -XAxisDataQuantity = X-axis Data Quantity Limit -Unlimited = Unlimited -Seconds = Second(s) -Minutes = Minute(s) -Hours = Hours -DataPoints = Data Point(s) -CloseTabConfirm = There are chart windows related to the current tab that have not been closed yet. Closing the tab will also close these chart windows. Are you sure you want to close them? -Codecs = Codesc -NewCodec = New Codec -EditCodec = Edit Codec -Type = Type -SchemaFile = Schema File -MessageMapping = Message Mapping -MessageMappingToolTip = Providing a message mapping table can help MqttInsight more accurately identify and decode messages. \nOtherwise, MqttInsight can only attempt based on the pattern file, and the decoding results may not be entirely accurate. -AddMapping = Add Mapping -RemoveMapping = Remove Mapping -IncompleteMessageMapping = The row %d row in the message mapping table is not fully filled in. -MappingFieldTopic = Topic (wildcard supported) -ProtobufMessageName = Protobuf Message Name -KryoRecordClass = Kryo Record Class -AvroNamespace = Avro Namespace -AvroName = Avro Name -NoCodec = Selected codec not found: %s -CodecExists = The codec "%s" already exists. Please use a different name or remove it first. +TestConnection=Test Connection +General=General +MQTT5Options=MQTT5 Options +TLS/SSL=TLS/SSL +LastWill=Last Will +Other=Other +Generate=Generate +Name=Name +Transport=Transport +Version=Version +Server=Server +Port=Port +ClientId=ClientId +CleanSession=Clean Session +CleanSessionToolTip=Sets whether the client and server should remember state across restarts and reconnects.\nIf set to false both the client and server will maintain state across restarts of the client, the server and the connection. As state is maintained:\nMessage delivery will be reliable meeting the specified QOS even if the client, server or connection are restarted.\nThe server will treat a subscription as durable.\nIf set to true the client and server will not maintain state across restarts of the client, the server or the connection. This means\nMessage delivery to the specified QOS cannot be maintained if the client, server or connection are restarted\nThe server will treat a subscription as non-durable. +AutoReconnect=Auto Reconnect +ConnectionTimeout=Connection Timeout +ConnectionTimeoutToolTip=Sets the connection timeout value. \nThis value, measured in seconds, defines the maximum time interval the client will wait for the network connection to the MQTT server to be established. \nThe default timeout is 30 seconds. \nA value of 0 disables timeout processing meaning the client will wait until the network connection is made successfully or fails. +KeepAliveInterval=Keep Alive Interval +KeepAliveIntervalToolTip=Sets the "keep alive" interval. \nThis value, measured in seconds, defines the maximum time interval between messages sent or received. \nIt enables the client to detect if the server is no longer available, without having to wait for the TCP/IP timeout. \nThe client will ensure that at least one message travels across the network within each keep alive period. \nIn the absence of a data-related message during the time period, the client sends a very small "ping" message, which the server will acknowledge. \nA value of 0 disables keepalive processing in the client. +ReconnectInterval=Reconnect Interval +ReconnectIntervalToolTip=Set the maximum time to wait between reconnects.\nThis value, measured in seconds. +EnableLastWill=Enable Last Will Message +RandomClientId=Random ClientId +Username=Username +Password=Password +CleanStart=Clean Start +CleanStartToolTip=Sets whether the client and server should remember state across restarts and reconnects. +RequestResponseInfo=Request Response Info +RequestResponseInfoToolTip=Sets the Request Response Info Flag.\nIf set to "null", then it will default to false.\nIf set to false, the server will not return any response information in the "CONNACK".\nIf set to true, the server MAY return response information in the "CONNACK". +RequestProblemInfo=Request Problem Info +RequestProblemInfoToolTip=Sets the Request Problem Info flag.\nIf set to "null", then it will default to true.\nIf set to false, the server MAY return a Reason String or User Properties\non a "CONNACK" or "DISCONNECT", but must not send a Reason String or User\nProperties on any packet other than "PUBLISH", "CONNACK" or "DISCONNECT".\nIf set to true, the server MAY return a Reason String or User Properties\non any packet where it is allowed. +SessionExpiryInterval=Session Expiry Interval +SessionExpiryIntervalToolTip=Sets the Session Expiry Interval.\nThis value, measured in seconds, defines the maximum time that the broker will maintain the session for once the client disconnects.\nClients should only connect with a long Session Expiry interval if they intend to connect to the server at some later point in time. +ReceiveMaximum=Receive Maximum +ReceiveMaximumToolTip=Sets the Receive Maximum.This value represents the limit of QoS 1 and QoS 2 publications that the client is willing to process concurrently. \nThere is no mechanism to limit the number of QoS 0 publications that the Server might try to send.\nThe range of values is 1-65535, leave blank to indicate maximum value. +MaximumPacketSize=Maximum Packet Size +MaximumPacketSizeToolTip=Sets the Maximum Packet Size. \nThis value represents the Maximum Packet Size the client is willing to accept.\nThe range of values is 1-2684354656, leave blank without restrictions. +TopicAliasMaximum=Topic Alias Maximum +TopicAliasMaximumToolTip=Sets the Topic Alias Maximum. \nThis value if present represents the highest value that the Client will accept as a Topic Alias sent by the Server.\nIf set to blank, then it will default to to 0.\nIf set to 0, the Client will not accept any Topic Aliases. \nThe Maximum value for this property is 65535. +UserProperties=User Properties +RemoveProperty=Remove Property +AddProperty=Add Property +NewProperty=New Property +NewValue=New value +Property=Property +Value=Value +EnableSSL=Enable TLS/SSL +SslProtocol=Protocol +SslMode=TLS/SSL Mode +SslModeBasic=Certificates & keys provided externally +SslModeServerOnly=CA certificate +SslModeServerKeystore=CA trust store +SslModeServerAndClient=CA certificate & client certificate/key +SslModeServerAndClientKeystore=CA trust store & client key store +SslModeProperties=TLS/SSL properties +SslPropertyNotValid="%s" is not a valid SSL property key. +ChooseFile=Choose File +CaAndKeysFileFilter=Certificates And Keys Files(*.jks,*.jceks,*.p12,*.pfx,*.bks,*.pem,*.key) +CaCertificateFile=CA certificate file +CaKeystoreFile=CA Keystore File +ClientCertificateFile=Client certificate file +ClientKeyPassword=Client Key Password +ClientKeystoreFile=Client Keystore File +ClientKeystorePassword=Client Keystore Password +ClientKeyFile=Client key file +CaKeystorePassword=CA Keystore Password +PemKey=PEM Key +MaxMessagesStored=Max Messages Stored +DefaultPayloadFormat=Default Message Format +ClearUnsubMessage=Clear messages when closing subscription +FieldRequiredValidation="%s" is required. +FieldRangeValidation=The range of "%s" is %d - %d +FieldMaxLengthValidation=The length of "%s" cannot exceed %d characters. +InputNotValid=The string "%s" is not a valid %s. +TestConnectionFailed=Test connection failed!\n\nCode: %d\nMessage: %s +TestConnectionSuccessful=Test connection Successful! +TestConnectionError=Test connection failed because of an error occurred:\n%s +Error=Error +Confirm=Confirm +Information=Information +Warning=Warning +ConnectionExists=Connection has been opened. +OpenConnectionError=An error occurred while opening the connection. +InvalidTopicOfMultiSymbol=Invalid format of topic, the multi symbol (#) has to be the last one after a separator. +InvalidSubtopic=Bad format of topic, invalid subtopic name: "%s". +ScriptLoaded=Successfully loaded script: %s +ScriptRemoved=Successfully removed script: %s +ScriptError=An error occurred while executing the script "%s" +ChooseScriptOperation=Please select what action you want to take on the script?\n If you want to cancel the execution of the script, click the "Remove" button.\n If the content of the script has changed, click "Reload" to load the new script content. +ScriptReloadConfirm=Do you want to reload the script "%s"? +Chart=Chart +MessageCountStatisticsChart=Message Count Statistics Chart ... +MessageCountStatisticsChartTitle=Message Count Statistics Chart [%s] +MessageLoadStatisticsChart=Message Load Statistics Chart ... +MessageLoadStatisticsChartTitle=Message Load Statistics Chart [%s] +MessageContentStatisticsChart=Message Content Statistics Chart ... +MessageContentStatisticsChartTitle=Message Content Statistics Chart [%s] +AddSeries=Add Series +RemoveSeries=Remove Series +ResetChart=Reset Chart +Pause=Pause +Resume=Resume +SaveCollectionToFavorites=Save the collection of the current chart series to favorites +EnterCollectionName=Enter the collection name for the series +OverwriteCollection=Do you want to overwrite the existing series collection "%s"? +PieChart=Pie Chart +BarChart=Bar Chart +SaveAs=Save As ... +Print=Print ... +ExportAs=Export As ... +ResetZoom=Reset Zoom +RemoveFavoriteCollection=Do you want to remove the series collection of series "%s"? +SeriesEditor=Series Editor +DynamicSeries=Dynamic Series +SeriesName=Series Name +Dynamic=Dynamic +Match=Match +MatchMode=Match Mode +MatchExpression=Match Expression +MatchExpressionTip=When the "Dynamic Series" checkbox is selected and the "Match Mode" is "Regular Expression", be sure to use grouping constructs delineate the subexpressions of a regular expression and capture the substrings of the input string. \nBy default, the substring that matches the first subexpression will be extracted. \nIf grouping constructs is not used, the complete matching string will be extracted.\n\nFor example: \\$SYS/broker/connection/(.+)/state\nwill match the topic \\$SYS/broker/connection/ACBD/state\n and extract substring ACBD +Wildcards=Wildcards +JsonPath=JsonPath +Equals=Equals +NotEquals=Not equals +Contains=Contains +NotContains=Not contains +StatisticalMethod=Statistical Method +MessageCount=Message Count +AverageMessageSize=AverageMessageSize +SumOfMessageSize=Sum of Message Size +MaximumMessageSize=Maximum Message Size +MinimumMessageSize=Minimum Message Size +MessageSize=Message Size +MessageSizeAxis=Message Size (bytes) +StatisticalWindow=Statistical Window +ExtractingMode=Extracting Mode +PayloadContent=Payload Content +ExtractingExpression=Extracting Expression +ExtractingExpressionTip=When the "Extracting Mode" is a "Regular Expression", be sure to use grouping constructs delineate the subexpressions of a regular expression and capture the substrings of the input string.\nBy default, the substring that matches the first subexpression will be extracted. \nIf grouping constructs is not used, the complete matching string will be extracted.\n\nNote: The extracted content must be numeric, non numeric content will be ignored. +RefreshFrequency=Refresh Frequency +XAxisDataQuantity=X-axis Data Quantity Limit +Unlimited=Unlimited +Seconds=Second(s) +Minutes=Minute(s) +Hours=Hours +DataPoints=Data Point(s) +CloseTabConfirm=There are chart windows related to the current tab that have not been closed yet. Closing the tab will also close these chart windows. Are you sure you want to close them? +Codecs=Codesc +NewCodec=New Codec +EditCodec=Edit Codec +Type=Type +SchemaFile=Schema File +MessageMapping=Message Mapping +MessageMappingToolTip=Providing a message mapping table can help MqttInsight more accurately identify and decode messages. \nOtherwise, MqttInsight can only attempt based on the pattern file, and the decoding results may not be entirely accurate. +AddMapping=Add Mapping +RemoveMapping=Remove Mapping +IncompleteMessageMapping=The row %d row in the message mapping table is not fully filled in. +MappingFieldTopic=Topic (wildcard supported) +ProtobufMessageName=Protobuf Message Name +KryoRecordClass=Kryo Record Class +AvroNamespace=Avro Namespace +AvroName=Avro Name +NoCodec=Selected codec not found: %s +CodecExists=The codec "%s" already exists. Please use a different name or remove it first. diff --git a/src/main/resources/com/mqttinsight/Lang_zh_CN.properties b/src/main/resources/com/mqttinsight/Lang_zh_CN.properties index fb9d101..c07fb5e 100644 --- a/src/main/resources/com/mqttinsight/Lang_zh_CN.properties +++ b/src/main/resources/com/mqttinsight/Lang_zh_CN.properties @@ -1,371 +1,373 @@ -&File = \u6587\u4EF6(&F) -&ConnectionManager = \u8FDE\u63A5\u7BA1\u7406(&C) -Co&decs = \u7F16\u89E3\u7801\u8BBE\u7F6E(&D) -&Options = \u9009\u9879(&O) -E&xit = \u9000\u51FA(&X) -&View = \u67E5\u770B(&V) -Show&Log = \u663E\u793A\u65E5\u5FD7(&L) -&Help = \u5E2E\u52A9(&H) -&About = \u5173\u4E8E ... -About = \u5173\u4E8E -AboutOpenSource = MqttInsight \u4F7F\u7528\u4E86\u4E00\u4E9B\u4F18\u79C0\u7684\u5F00\u6E90\u9879\u76EE: -Log = \u65E5\u5FD7 -Options = \u9009\u9879 -UserInterface = \u7528\u6237\u754C\u9762 -Language = \u8BED\u8A00 -Theme = \u4E3B\u9898 -MessageEditor = \u6D88\u606F\u7F16\u8F91\u5668 -Font = \u5B57\u4F53 -FontSize = \u5B57\u4F53\u5927\u5C0F -MessageView = \u6D88\u606F\u89C6\u56FE -DefaultView = \u9ED8\u8BA4\u89C6\u56FE -TableView = \u8868\u683C\u89C6\u56FE -DialogueView = \u5BF9\u8BDD\u89C6\u56FE -MaxMessageRows = \u6D88\u606F\u6700\u5927\u884C\u6570 -MaxMessageRowsTip = \u5728"\u5BF9\u8BDD\u89C6\u56FE"\u4E2D\u6D88\u606F\u663E\u793A\u7684\u6700\u5927\u884C\u6570, \u8BBE\u7F6E\u6700\u5927\u884C\u6570\u4EE5\u514D\u4F1A\u8BDD\u6C14\u6CE1\u8FC7\u5927\u65F6\u5F71\u54CD\u663E\u793A\u3002\n\u8BBE\u7F6E\u4E3A 0 \u5219\u4E0D\u4F5C\u9650\u5236\u3002 -TimeFormat = \u65F6\u95F4\u683C\u5F0F -InputDialogTitle = \u8F93\u5165 -InputDialogEmptyInfo = \u8F93\u5165\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A\u3002 -Cut = \u526A\u5207 -Copy = \u590D\u5236 -Paste = \u7C98\u8D34 -SelectAll = \u5168\u9009 -&Ok = \u786E\u5B9A(&O) -&Close = \u5173\u95ED(&C) -Close = \u5173\u95ED -&Cancel = \u53D6\u6D88(&C) -&Detail = \u8BE6\u60C5(&D) -Question = \u8BE2\u95EE -&New = \u65B0\u5EFA(&N) -&Remove = \u79FB\u9664(&R) -Re&load = \u91CD\u884C\u8F7D\u5165(&L) -OpenConnection = \u6253\u5F00\u8FDE\u63A5 -Connect = \u8FDE\u63A5 -Disconnect = \u65AD\u5F00 -Connecting = \u6B63\u5728\u8FDE\u63A5 ... -Connected = \u5DF2\u8FDE\u63A5 -Disconnecting = \u65AD\u5F00\u8FDE\u63A5 ... -Disconnected = \u5DF2\u65AD\u5F00 -Failed = \u8FDE\u63A5\u5931\u8D25 -MqttReasonCode_-1 = \u672A\u77E5\u9519\u8BEF -MqttReasonCode_1 = \u65E0\u6548\u534F\u8BAE\u7248\u672C -MqttReasonCode_2 = \u65E0\u6548\u5BA2\u6237\u673A\u6807\u8BC6 -MqttReasonCode_3 = \u4EE3\u7406\u7A0B\u5E8F\u4E0D\u53EF\u7528 -MqttReasonCode_4 = \u9519\u8BEF\u7684\u7528\u6237\u540D\u6216\u5BC6\u7801 -MqttReasonCode_5 = \u65E0\u6743\u8FDE\u63A5 -MqttReasonCode_6 = \u610F\u5916\u9519\u8BEF -MqttReasonCode_119 = \u65E0\u6548\u7684 URI -MqttReasonCode_32000 = \u7B49\u5F85\u6765\u81EA\u670D\u52A1\u5668\u7684\u54CD\u5E94\u65F6\u8D85\u65F6 -MqttReasonCode_32001 = \u5185\u90E8\u9519\u8BEF\uFF0C\u6CA1\u6709\u53EF\u7528\u7684\u65B0\u6D88\u606F ID -MqttReasonCode_32002 = \u5411\u670D\u52A1\u5668\u5199\u5165\u6D88\u606F\u8D85\u65F6 -MqttReasonCode_32100 = \u5DF2\u8FDE\u63A5\u5BA2\u6237\u673A -MqttReasonCode_32101 = \u5DF2\u65AD\u5F00\u5BA2\u6237\u673A\u8FDE\u63A5 -MqttReasonCode_32102 = \u5BA2\u6237\u673A\u6B63\u5728\u65AD\u5F00\u8FDE\u63A5 -MqttReasonCode_32103 = \u65E0\u6CD5\u8FDE\u63A5\u81F3\u670D\u52A1\u5668 -MqttReasonCode_32104 = \u5BA2\u6237\u673A\u672A\u8FDE\u63A5 -MqttReasonCode_32105 = \u6307\u5B9A\u7684 SocketFactory \u7C7B\u578B\u4E0E\u4EE3\u7406\u7A0B\u5E8F URI \u4E0D\u5339\u914D -MqttReasonCode_32106 = SSL \u914D\u7F6E\u9519\u8BEF -MqttReasonCode_32107 = \u4E0D\u5141\u8BB8\u901A\u8FC7\u56DE\u8C03\u65B9\u6CD5\u65AD\u5F00\u8FDE\u63A5 -MqttReasonCode_32108 = \u4E0D\u53EF\u8BC6\u522B\u7684\u5305 -MqttReasonCode_32109 = \u4E0E\u670D\u52A1\u5668\u7684\u8FDE\u63A5\u4E22\u5931 -MqttReasonCode_32110 = \u5DF2\u5728\u8FDB\u884C\u8FDE\u63A5 -MqttReasonCode_32111 = \u5BA2\u6237\u673A\u5DF2\u5173\u95ED -MqttReasonCode_32200 = \u6301\u4E45\u6027\u5DF2\u5728\u4F7F\u7528\u4E2D -MqttReasonCode_32201 = \u4EE4\u724C\u5DF2\u5728\u4F7F\u7528\u4E2D -MqttReasonCode_32202 = \u6B63\u5728\u8FDB\u884C\u8FC7\u591A\u7684\u53D1\u5E03 -MqttReasonCode_50000 = \u65E0\u6548\u7684 IV \u5B57\u6BB5\u6807\u8BC6\u7B26 -MqttReasonCode_50001 = \u65E0\u6548\u7684\u8FD4\u56DE\u7801 -MqttReasonCode_50002 = \u6570\u636E\u5305\u7684\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u4E0D\u7B26\u5408MQTTv5\u89C4\u8303 -MqttReasonCode_50003 = CONNECT \u6570\u636E\u5305\u4E0D\u542B\u6B63\u786E\u7684\u534F\u8BAE\u540D\u79F0\u6216\u7248\u672C. -MqttReasonCode_50004 = \u670D\u52A1\u5668\u53D1\u9001\u4E86\u4E3B\u9898\u522B\u540D\u65E0\u6548\u7684\u53D1\u5E03\u6D88\u606F. -MqttReasonCode_50005 = \u5BA2\u6237\u7AEF\u5C1D\u8BD5\u89E3\u7801\u5DF2\u89E3\u7801\u7684\u5C5E\u6027\uFF0C\u8BE5\u5C5E\u6027\u53EA\u80FD\u5305\u542B\u4E00\u6B21. -MqttReasonCode_51001 = \u4F20\u5165\u6570\u636E\u5305\u592A\u5927. -MqttReasonCode_51002 = \u4F20\u51FA\u6570\u636E\u5305\u592A\u5927. -MqttReasonCode_16 = \u6CA1\u6709\u5339\u914D\u7684\u8BA2\u9605\u8005. -MqttReasonCode_17 = \u4E0D\u5B58\u5728\u7684\u8BA2\u9605. -MqttReasonCode_24 = \u7EE7\u7EED\u8EAB\u4EFD\u9A8C\u8BC1. -MqttReasonCode_25 = \u91CD\u65B0\u8EAB\u4EFD\u9A8C\u8BC1. -MqttReasonCode_128 = \u672A\u6307\u5B9A\u7684\u9519\u8BEF. -MqttReasonCode_129 = \u9519\u8BEF\u7684\u6570\u636E\u5305. -MqttReasonCode_130 = \u534F\u8BAE\u9519\u8BEF. -MqttReasonCode_131 = \u5B9E\u73B0\u7279\u5B9A\u9519\u8BEF. -MqttReasonCode_132 = \u4E0D\u652F\u6301\u7684\u534F\u8BAE\u7248\u672C. -MqttReasonCode_133 = \u5BA2\u6237\u7AEF\u6807\u8BC6\u65E0\u6548. -MqttReasonCode_134 = \u9519\u8BEF\u7684\u7528\u6237\u540D\u6216\u5BC6\u7801. -MqttReasonCode_135 = \u65E0\u6743\u8FDE\u63A5. -MqttReasonCode_136 = \u670D\u52A1\u5668\u4E0D\u53EF\u7528. -MqttReasonCode_137 = \u670D\u52A1\u5668\u5FD9. -MqttReasonCode_138 = \u5DF2\u7981\u6B62. -MqttReasonCode_139 = \u670D\u52A1\u5668\u5DF2\u5173\u95ED. -MqttReasonCode_140 = \u9519\u8BEF\u7684\u8BA4\u8BC1\u65B9\u6CD5. -MqttReasonCode_141 = \u4FDD\u6301\u6D3B\u52A8\u8D85\u65F6. -MqttReasonCode_142 = \u4F1A\u8BDD\u5DF2\u63A5\u7BA1. -MqttReasonCode_143 = \u65E0\u6548\u7684\u4E3B\u9898\u8FC7\u6EE4\u5668. -MqttReasonCode_144 = \u65E0\u6548\u7684\u4E3B\u9898\u540D. -MqttReasonCode_145 = \u6570\u636E\u5305\u6807\u8BC6\u7B26\u6B63\u88AB\u4F7F\u7528. -MqttReasonCode_146 = \u627E\u4E0D\u5230\u6570\u636E\u5305\u6807\u8BC6\u7B26. -MqttReasonCode_147 = \u8D85\u8FC7\u63A5\u6536\u6700\u5927\u503C. -MqttReasonCode_148 = \u4E3B\u9898\u522B\u540D\u65E0\u6548. -MqttReasonCode_149 = \u6570\u636E\u5305\u592A\u5927. -MqttReasonCode_150 = \u6D88\u606F\u901F\u7387\u8FC7\u9AD8. -MqttReasonCode_151 = \u8D85\u51FA\u914D\u989D. -MqttReasonCode_152 = \u7BA1\u7406\u5458\u884C\u4E3A. -MqttReasonCode_153 = \u8F7D\u8377\u683C\u5F0F\u65E0\u6548. -MqttReasonCode_154 = \u4E0D\u652F\u6301\u4FDD\u7559. -MqttReasonCode_155 = \u4E0D\u652F\u6301QoS -MqttReasonCode_156 = \u4F7F\u7528\u5176\u4ED6\u670D\u52A1\u5668. -MqttReasonCode_157 = \u670D\u52A1\u5DF2\u8FC1\u79FB. -MqttReasonCode_158 = \u4E0D\u652F\u6301\u5171\u4EAB\u8BA2\u9605. -MqttReasonCode_159 = \u8D85\u8FC7\u8FDE\u63A5\u901F\u7387. -MqttReasonCode_160 = \u6700\u957F\u8FDE\u63A5\u65F6\u95F4. -MqttReasonCode_161 = \u4E0D\u652F\u6301\u8BA2\u9605\u6807\u8BC6\u7B26. -MqttReasonCode_162 = \u4E0D\u652F\u6301\u7684\u901A\u914D\u7B26\u8BA2\u9605. -NewSubscription = \u6DFB\u52A0\u8BA2\u9605 -NoSubscriptions = \u6CA1\u6709\u5DF2\u6536\u85CF\u7684\u8BA2\u9605 -SubscribeAll = \u8BA2\u9605\u6240\u6709 -RemoveFavoriteSubscription = \u4F60\u60F3\u8981\u79FB\u9664\u6536\u85CF\u7684\u8BA2\u9605 "%s" \u5417? -MessageIndicator = \u6D88\u606F\u6570(%d / %d) -SearchHistory = \u641C\u7D22\u5386\u53F2 -Empty = <\u7A7A> -MatchCase = \u533A\u5206\u5927\u5C0F\u5199 -WholeWords = \u5339\u914D\u5355\u8BCD -RegularExpression = \u6B63\u5219\u8868\u8FBE\u5F0F -PreviousOccurrence = \u4E0A\u4E00\u5904 -NextOccurrence = \u4E0B\u4E00\u5904 -ScrollToEnd = \u81EA\u52A8\u6EDA\u5230\u6700\u540E -ClearAll = \u5168\u90E8\u6E05\u9664 -FilterSearchResults = \u8FC7\u6EE4\u641C\u7D22\u7ED3\u679C -GoFirst = \u8F6C\u5230\u7B2C\u4E00\u6761\u6D88\u606F -GoPrevious = \u8F6C\u5230\u4E0A\u4E00\u6761\u6D88\u606F -GoNext = \u8F6C\u5230\u4E0B\u4E00\u6761\u6D88\u606F -GoLast = \u8F6C\u5230\u6700\u540E\u4E00\u6761\u6D88\u606F -Autoscroll = \u81EA\u52A8\u6EDA\u52A8 -More = \u66F4\u591A... -Script = \u811A\u672C -LoadScript = \u52A0\u8F7D\u811A\u672C ... -JavaScriptFileFilter = JavaScript \u811A\u672C\u6587\u4EF6 (*.js) -ClearAllMessages = \u6E05\u9664\u5168\u90E8\u6D88\u606F -ClearVisibleMessages = \u6E05\u9664\u53EF\u89C1\u7684\u6D88\u606F -ExportAllMessages = \u5BFC\u51FA\u5168\u90E8\u6D88\u606F ... -PayloadFormat = \u6D88\u606F\u683C\u5F0F -PayloadFormatTip = \u6D88\u606F\u683C\u5F0F\u9009\u62E9 "Default" \u65F6\uFF0C\u5C06\u91C7\u7528\u8FDE\u63A5\u4E2D\u8BBE\u7F6E\u7684\u9ED8\u8BA4\u6D88\u606F\u683C\u5F0F\u4F5C\u4E3A\u8BA2\u9605\u7684\u6D88\u606F\u683C\u5F0F\u3002\n\u5E76\u53EF\u5728\u8BA2\u9605\u9879\u7684\u5F39\u51FA\u83DC\u5355\u4E2D\u518D\u6B21\u66F4\u6539\u6D88\u606F\u683C\u5F0F\u3002 -Topic = \u4E3B\u9898 -Payload = \u6D88\u606F -QoS = QoS -Retained = \u4FDD\u7559 -ReceivedTime = \u63A5\u6536\u65F6\u95F4 -Time = \u65F6\u95F4 -Pretty = \u683C\u5F0F\u5316 -SyntaxHighlighting = \u8BED\u6CD5\u9AD8\u4EAE -SyntaxHighlightingTips = \u5F00\u542F\u8BED\u6CD5\u9AD8\u4EAE\u4F1A\u4EA7\u751F\u989D\u5916\u7684\u6027\u80FD\u6D88\u8017\uFF0C\u5EFA\u8BAE\u5728\u6D88\u606F\u91CF\u591A\u4E14\u5185\u5BB9\u590D\u6742\u65F6\u5173\u95ED\u8BED\u6CD5\u9AD8\u4EAE\u4EE5\u63D0\u5347\u9884\u89C8\u6027\u80FD\u3002 -JsonFileFilter = JSON \u6587\u4EF6 (*.json) -CsvFileFilter = CSV \u6587\u4EF6 (*.csv) -TextFileFilter = \u6587\u672C\u6587\u4EF6 (*.txt) -AllFileFilter = \u5168\u90E8\u6587\u4EF6 (*.*) -FileExists = \u6587\u4EF6 "%s" \u5DF2\u7ECF\u5B58\u5728, \u662F\u5426\u8986\u76D6! -Favorite = \u6536\u85CF -ShowOrHideMessages = \u663E\u793A/\u9690\u85CF\u6D88\u606F -Unsubscribe = \u53D6\u6D88\u8BA2\u9605 -Resubscribe = \u91CD\u65B0\u8BA2\u9605 -ClearMessages = \u6E05\u9664\u6D88\u606F -ExportMessages = \u5BFC\u51FA\u6D88\u606F ... -TopicSubscribed = \u4E3B\u9898\u5DF2\u8BA2\u9605, \u4E0D\u53EF\u91CD\u590D\u8BA2\u9605\u3002 -Color = \u989C\u8272 -MoreColor = \u66F4\u591A\u989C\u8272 ... -ChooseColor = \u9009\u62E9\u989C\u8272 -Preview = \u9884\u89C8 -MessagePreview = \u6D88\u606F\u9884\u89C8 -PreviewSeparateWindow = \u5728\u72EC\u7ACB\u7A97\u53E3\u9884\u89C8 -Publish = \u53D1\u5E03 -PublishMessage = \u53D1\u5E03\u6D88\u606F -PublishTips = \u6D88\u606F\u5185\u5BB9\u53EF\u4EE5\u4F7F\u7528\u5360\u4F4D\u7B26, \u5B9E\u9645\u53D1\u9001\u65F6\u5C06\u88AB\u66FF\u6362\u4E3A\u76F8\u5E94\u7684\u968F\u673A\u503C\uFF1A\n${timestamp} : \u5F53\u524D\u7CFB\u7EDF\u65F6\u95F4\u6233\u6BEB\u79D2\u503C\uFF1B\n${uuid} : \u968F\u673A UUID\uFF1B\n${int(min,max)} : \u968F\u673A\u6574\u6570\u503C\uFF1B\n${float(min,max)} : \u968F\u673A\u6D6E\u70B9\u503C\uFF1B\n${string(length)} : \u968F\u673A\u6307\u5B9A\u957F\u5EA6\u7684\u5B57\u7B26\u4E32\u3002 -Copy&Topic = \u590D\u5236\u4E3B\u9898(&T) -Copy&Payload = \u590D\u5236\u6D88\u606F -SegmentTopicDescription = %d \u4E2A\u4E3B\u9898 -SegmentTopicsDescription = %d \u4E2A\u4E3B\u9898 -SegmentMessageDescription = %d \u6761\u6D88\u606F -SegmentMessagesDescription = %d \u6761\u6D88\u606F +&File=\u6587\u4EF6(&F) +&ConnectionManager=\u8FDE\u63A5\u7BA1\u7406(&C) +Co&decs=\u7F16\u89E3\u7801\u8BBE\u7F6E(&D) +&Options=\u9009\u9879(&O) +E&xit=\u9000\u51FA(&X) +&View=\u67E5\u770B(&V) +Show&Log=\u663E\u793A\u65E5\u5FD7(&L) +&Help=\u5E2E\u52A9(&H) +&About=\u5173\u4E8E ... +About=\u5173\u4E8E +AboutOpenSource=MqttInsight \u4F7F\u7528\u4E86\u4E00\u4E9B\u4F18\u79C0\u7684\u5F00\u6E90\u9879\u76EE: +Log=\u65E5\u5FD7 +Options=\u9009\u9879 +UserInterface=\u7528\u6237\u754C\u9762 +Language=\u8BED\u8A00 +Theme=\u4E3B\u9898 +MessageEditor=\u6D88\u606F\u7F16\u8F91\u5668 +Font=\u5B57\u4F53 +FontSize=\u5B57\u4F53\u5927\u5C0F +MessageView=\u6D88\u606F\u89C6\u56FE +DefaultView=\u9ED8\u8BA4\u89C6\u56FE +TableView=\u8868\u683C\u89C6\u56FE +DialogueView=\u5BF9\u8BDD\u89C6\u56FE +MaxMessageRows=\u6D88\u606F\u6700\u5927\u884C\u6570 +MaxMessageRowsTip=\u5728"\u5BF9\u8BDD\u89C6\u56FE"\u4E2D\u6D88\u606F\u663E\u793A\u7684\u6700\u5927\u884C\u6570, \u8BBE\u7F6E\u6700\u5927\u884C\u6570\u4EE5\u514D\u4F1A\u8BDD\u6C14\u6CE1\u8FC7\u5927\u65F6\u5F71\u54CD\u663E\u793A\u3002\n\u8BBE\u7F6E\u4E3A 0 \u5219\u4E0D\u4F5C\u9650\u5236\u3002 +TimeFormat=\u65F6\u95F4\u683C\u5F0F +InputDialogTitle=\u8F93\u5165 +InputDialogEmptyInfo=\u8F93\u5165\u5185\u5BB9\u4E0D\u80FD\u4E3A\u7A7A\u3002 +Cut=\u526A\u5207 +Copy=\u590D\u5236 +Paste=\u7C98\u8D34 +SelectAll=\u5168\u9009 +&Ok=\u786E\u5B9A(&O) +&Close=\u5173\u95ED(&C) +Close=\u5173\u95ED +&Cancel=\u53D6\u6D88(&C) +&Detail=\u8BE6\u60C5(&D) +Question=\u8BE2\u95EE +&New=\u65B0\u5EFA(&N) +&Remove=\u79FB\u9664(&R) +Re&load=\u91CD\u884C\u8F7D\u5165(&L) +OpenConnection=\u6253\u5F00\u8FDE\u63A5 +Connect=\u8FDE\u63A5 +Disconnect=\u65AD\u5F00 +Connecting=\u6B63\u5728\u8FDE\u63A5 ... +Connected=\u5DF2\u8FDE\u63A5 +Disconnecting=\u65AD\u5F00\u8FDE\u63A5 ... +Disconnected=\u5DF2\u65AD\u5F00 +Failed=\u8FDE\u63A5\u5931\u8D25 +MqttReasonCode_-1=\u672A\u77E5\u9519\u8BEF +MqttReasonCode_1=\u65E0\u6548\u534F\u8BAE\u7248\u672C +MqttReasonCode_2=\u65E0\u6548\u5BA2\u6237\u673A\u6807\u8BC6 +MqttReasonCode_3=\u4EE3\u7406\u7A0B\u5E8F\u4E0D\u53EF\u7528 +MqttReasonCode_4=\u9519\u8BEF\u7684\u7528\u6237\u540D\u6216\u5BC6\u7801 +MqttReasonCode_5=\u65E0\u6743\u8FDE\u63A5 +MqttReasonCode_6=\u610F\u5916\u9519\u8BEF +MqttReasonCode_119=\u65E0\u6548\u7684 URI +MqttReasonCode_32000=\u7B49\u5F85\u6765\u81EA\u670D\u52A1\u5668\u7684\u54CD\u5E94\u65F6\u8D85\u65F6 +MqttReasonCode_32001=\u5185\u90E8\u9519\u8BEF\uFF0C\u6CA1\u6709\u53EF\u7528\u7684\u65B0\u6D88\u606F ID +MqttReasonCode_32002=\u5411\u670D\u52A1\u5668\u5199\u5165\u6D88\u606F\u8D85\u65F6 +MqttReasonCode_32100=\u5DF2\u8FDE\u63A5\u5BA2\u6237\u673A +MqttReasonCode_32101=\u5DF2\u65AD\u5F00\u5BA2\u6237\u673A\u8FDE\u63A5 +MqttReasonCode_32102=\u5BA2\u6237\u673A\u6B63\u5728\u65AD\u5F00\u8FDE\u63A5 +MqttReasonCode_32103=\u65E0\u6CD5\u8FDE\u63A5\u81F3\u670D\u52A1\u5668 +MqttReasonCode_32104=\u5BA2\u6237\u673A\u672A\u8FDE\u63A5 +MqttReasonCode_32105=\u6307\u5B9A\u7684 SocketFactory \u7C7B\u578B\u4E0E\u4EE3\u7406\u7A0B\u5E8F URI \u4E0D\u5339\u914D +MqttReasonCode_32106=SSL \u914D\u7F6E\u9519\u8BEF +MqttReasonCode_32107=\u4E0D\u5141\u8BB8\u901A\u8FC7\u56DE\u8C03\u65B9\u6CD5\u65AD\u5F00\u8FDE\u63A5 +MqttReasonCode_32108=\u4E0D\u53EF\u8BC6\u522B\u7684\u5305 +MqttReasonCode_32109=\u4E0E\u670D\u52A1\u5668\u7684\u8FDE\u63A5\u4E22\u5931 +MqttReasonCode_32110=\u5DF2\u5728\u8FDB\u884C\u8FDE\u63A5 +MqttReasonCode_32111=\u5BA2\u6237\u673A\u5DF2\u5173\u95ED +MqttReasonCode_32200=\u6301\u4E45\u6027\u5DF2\u5728\u4F7F\u7528\u4E2D +MqttReasonCode_32201=\u4EE4\u724C\u5DF2\u5728\u4F7F\u7528\u4E2D +MqttReasonCode_32202=\u6B63\u5728\u8FDB\u884C\u8FC7\u591A\u7684\u53D1\u5E03 +MqttReasonCode_50000=\u65E0\u6548\u7684 IV \u5B57\u6BB5\u6807\u8BC6\u7B26 +MqttReasonCode_50001=\u65E0\u6548\u7684\u8FD4\u56DE\u7801 +MqttReasonCode_50002=\u6570\u636E\u5305\u7684\u683C\u5F0F\u4E0D\u6B63\u786E\uFF0C\u4E0D\u7B26\u5408MQTTv5\u89C4\u8303 +MqttReasonCode_50003=CONNECT \u6570\u636E\u5305\u4E0D\u542B\u6B63\u786E\u7684\u534F\u8BAE\u540D\u79F0\u6216\u7248\u672C. +MqttReasonCode_50004=\u670D\u52A1\u5668\u53D1\u9001\u4E86\u4E3B\u9898\u522B\u540D\u65E0\u6548\u7684\u53D1\u5E03\u6D88\u606F. +MqttReasonCode_50005=\u5BA2\u6237\u7AEF\u5C1D\u8BD5\u89E3\u7801\u5DF2\u89E3\u7801\u7684\u5C5E\u6027\uFF0C\u8BE5\u5C5E\u6027\u53EA\u80FD\u5305\u542B\u4E00\u6B21. +MqttReasonCode_51001=\u4F20\u5165\u6570\u636E\u5305\u592A\u5927. +MqttReasonCode_51002=\u4F20\u51FA\u6570\u636E\u5305\u592A\u5927. +MqttReasonCode_16=\u6CA1\u6709\u5339\u914D\u7684\u8BA2\u9605\u8005. +MqttReasonCode_17=\u4E0D\u5B58\u5728\u7684\u8BA2\u9605. +MqttReasonCode_24=\u7EE7\u7EED\u8EAB\u4EFD\u9A8C\u8BC1. +MqttReasonCode_25=\u91CD\u65B0\u8EAB\u4EFD\u9A8C\u8BC1. +MqttReasonCode_128=\u672A\u6307\u5B9A\u7684\u9519\u8BEF. +MqttReasonCode_129=\u9519\u8BEF\u7684\u6570\u636E\u5305. +MqttReasonCode_130=\u534F\u8BAE\u9519\u8BEF. +MqttReasonCode_131=\u5B9E\u73B0\u7279\u5B9A\u9519\u8BEF. +MqttReasonCode_132=\u4E0D\u652F\u6301\u7684\u534F\u8BAE\u7248\u672C. +MqttReasonCode_133=\u5BA2\u6237\u7AEF\u6807\u8BC6\u65E0\u6548. +MqttReasonCode_134=\u9519\u8BEF\u7684\u7528\u6237\u540D\u6216\u5BC6\u7801. +MqttReasonCode_135=\u65E0\u6743\u8FDE\u63A5. +MqttReasonCode_136=\u670D\u52A1\u5668\u4E0D\u53EF\u7528. +MqttReasonCode_137=\u670D\u52A1\u5668\u5FD9. +MqttReasonCode_138=\u5DF2\u7981\u6B62. +MqttReasonCode_139=\u670D\u52A1\u5668\u5DF2\u5173\u95ED. +MqttReasonCode_140=\u9519\u8BEF\u7684\u8BA4\u8BC1\u65B9\u6CD5. +MqttReasonCode_141=\u4FDD\u6301\u6D3B\u52A8\u8D85\u65F6. +MqttReasonCode_142=\u4F1A\u8BDD\u5DF2\u63A5\u7BA1. +MqttReasonCode_143=\u65E0\u6548\u7684\u4E3B\u9898\u8FC7\u6EE4\u5668. +MqttReasonCode_144=\u65E0\u6548\u7684\u4E3B\u9898\u540D. +MqttReasonCode_145=\u6570\u636E\u5305\u6807\u8BC6\u7B26\u6B63\u88AB\u4F7F\u7528. +MqttReasonCode_146=\u627E\u4E0D\u5230\u6570\u636E\u5305\u6807\u8BC6\u7B26. +MqttReasonCode_147=\u8D85\u8FC7\u63A5\u6536\u6700\u5927\u503C. +MqttReasonCode_148=\u4E3B\u9898\u522B\u540D\u65E0\u6548. +MqttReasonCode_149=\u6570\u636E\u5305\u592A\u5927. +MqttReasonCode_150=\u6D88\u606F\u901F\u7387\u8FC7\u9AD8. +MqttReasonCode_151=\u8D85\u51FA\u914D\u989D. +MqttReasonCode_152=\u7BA1\u7406\u5458\u884C\u4E3A. +MqttReasonCode_153=\u8F7D\u8377\u683C\u5F0F\u65E0\u6548. +MqttReasonCode_154=\u4E0D\u652F\u6301\u4FDD\u7559. +MqttReasonCode_155=\u4E0D\u652F\u6301QoS +MqttReasonCode_156=\u4F7F\u7528\u5176\u4ED6\u670D\u52A1\u5668. +MqttReasonCode_157=\u670D\u52A1\u5DF2\u8FC1\u79FB. +MqttReasonCode_158=\u4E0D\u652F\u6301\u5171\u4EAB\u8BA2\u9605. +MqttReasonCode_159=\u8D85\u8FC7\u8FDE\u63A5\u901F\u7387. +MqttReasonCode_160=\u6700\u957F\u8FDE\u63A5\u65F6\u95F4. +MqttReasonCode_161=\u4E0D\u652F\u6301\u8BA2\u9605\u6807\u8BC6\u7B26. +MqttReasonCode_162=\u4E0D\u652F\u6301\u7684\u901A\u914D\u7B26\u8BA2\u9605. +NewSubscription=\u6DFB\u52A0\u8BA2\u9605 +NoSubscriptions=\u6CA1\u6709\u5DF2\u6536\u85CF\u7684\u8BA2\u9605 +SubscribeAll=\u8BA2\u9605\u6240\u6709 +RemoveFavoriteSubscription=\u4F60\u60F3\u8981\u79FB\u9664\u6536\u85CF\u7684\u8BA2\u9605 "%s" \u5417? +MessageIndicator=\u6D88\u606F\u6570(%d / %d) +SearchHistory=\u641C\u7D22\u5386\u53F2 +Empty=<\u7A7A> +MatchCase=\u533A\u5206\u5927\u5C0F\u5199 +WholeWords=\u5339\u914D\u5355\u8BCD +RegularExpression=\u6B63\u5219\u8868\u8FBE\u5F0F +PreviousOccurrence=\u4E0A\u4E00\u5904 +NextOccurrence=\u4E0B\u4E00\u5904 +ScrollToEnd=\u81EA\u52A8\u6EDA\u5230\u6700\u540E +ClearAll=\u5168\u90E8\u6E05\u9664 +FilterSearchResults=\u8FC7\u6EE4\u641C\u7D22\u7ED3\u679C +GoFirst=\u8F6C\u5230\u7B2C\u4E00\u6761\u6D88\u606F +GoPrevious=\u8F6C\u5230\u4E0A\u4E00\u6761\u6D88\u606F +GoNext=\u8F6C\u5230\u4E0B\u4E00\u6761\u6D88\u606F +GoLast=\u8F6C\u5230\u6700\u540E\u4E00\u6761\u6D88\u606F +Autoscroll=\u81EA\u52A8\u6EDA\u52A8 +More=\u66F4\u591A... +Script=\u811A\u672C +LoadScript=\u52A0\u8F7D\u811A\u672C ... +JavaScriptFileFilter=JavaScript \u811A\u672C\u6587\u4EF6 (*.js) +ClearAllMessages=\u6E05\u9664\u5168\u90E8\u6D88\u606F +ClearVisibleMessages=\u6E05\u9664\u53EF\u89C1\u7684\u6D88\u606F +ExportAllMessages=\u5BFC\u51FA\u5168\u90E8\u6D88\u606F ... +PayloadFormat=\u6D88\u606F\u683C\u5F0F +PayloadFormatTip=\u6D88\u606F\u683C\u5F0F\u9009\u62E9 "Default" \u65F6\uFF0C\u5C06\u91C7\u7528\u8FDE\u63A5\u4E2D\u8BBE\u7F6E\u7684\u9ED8\u8BA4\u6D88\u606F\u683C\u5F0F\u4F5C\u4E3A\u8BA2\u9605\u7684\u6D88\u606F\u683C\u5F0F\u3002\n\u5E76\u53EF\u5728\u8BA2\u9605\u9879\u7684\u5F39\u51FA\u83DC\u5355\u4E2D\u518D\u6B21\u66F4\u6539\u6D88\u606F\u683C\u5F0F\u3002 +Topic=\u4E3B\u9898 +Payload=\u6D88\u606F +QoS=QoS +Retained=\u4FDD\u7559 +ReceivedTime=\u63A5\u6536\u65F6\u95F4 +Time=\u65F6\u95F4 +Pretty=\u683C\u5F0F\u5316 +SyntaxHighlighting=\u8BED\u6CD5\u9AD8\u4EAE +SyntaxHighlightingTips=\u5F00\u542F\u8BED\u6CD5\u9AD8\u4EAE\u4F1A\u4EA7\u751F\u989D\u5916\u7684\u6027\u80FD\u6D88\u8017\uFF0C\u5EFA\u8BAE\u5728\u6D88\u606F\u91CF\u591A\u4E14\u5185\u5BB9\u590D\u6742\u65F6\u5173\u95ED\u8BED\u6CD5\u9AD8\u4EAE\u4EE5\u63D0\u5347\u9884\u89C8\u6027\u80FD\u3002 +JsonFileFilter=JSON \u6587\u4EF6 (*.json) +CsvFileFilter=CSV \u6587\u4EF6 (*.csv) +TextFileFilter=\u6587\u672C\u6587\u4EF6 (*.txt) +AllFileFilter=\u5168\u90E8\u6587\u4EF6 (*.*) +FileExists=\u6587\u4EF6 "%s" \u5DF2\u7ECF\u5B58\u5728, \u662F\u5426\u8986\u76D6! +Favorite=\u6536\u85CF +ShowOrHideMessages=\u663E\u793A/\u9690\u85CF\u6D88\u606F +HideRelatedMessages=\u9690\u85CF\u6B64\u4E3B\u9898\u7684\u6D88\u606F +HideAllOtherMessages=\u9690\u85CF\u5176\u5B83\u4E3B\u9898\u7684\u6D88\u606F +Unsubscribe=\u53D6\u6D88\u8BA2\u9605 +Resubscribe=\u91CD\u65B0\u8BA2\u9605 +ClearMessages=\u6E05\u9664\u6D88\u606F +ExportMessages=\u5BFC\u51FA\u6D88\u606F ... +TopicSubscribed=\u4E3B\u9898\u5DF2\u8BA2\u9605, \u4E0D\u53EF\u91CD\u590D\u8BA2\u9605\u3002 +Color=\u989C\u8272 +MoreColor=\u66F4\u591A\u989C\u8272 ... +ChooseColor=\u9009\u62E9\u989C\u8272 +Preview=\u9884\u89C8 +MessagePreview=\u6D88\u606F\u9884\u89C8 +PreviewSeparateWindow=\u5728\u72EC\u7ACB\u7A97\u53E3\u9884\u89C8 +Publish=\u53D1\u5E03 +PublishMessage=\u53D1\u5E03\u6D88\u606F +PublishTips=\u6D88\u606F\u5185\u5BB9\u53EF\u4EE5\u4F7F\u7528\u5360\u4F4D\u7B26, \u5B9E\u9645\u53D1\u9001\u65F6\u5C06\u88AB\u66FF\u6362\u4E3A\u76F8\u5E94\u7684\u968F\u673A\u503C\uFF1A\n${timestamp} : \u5F53\u524D\u7CFB\u7EDF\u65F6\u95F4\u6233\u6BEB\u79D2\u503C\uFF1B\n${uuid} : \u968F\u673A UUID\uFF1B\n${int(min,max)} : \u968F\u673A\u6574\u6570\u503C\uFF1B\n${float(min,max)} : \u968F\u673A\u6D6E\u70B9\u503C\uFF1B\n${string(length)} : \u968F\u673A\u6307\u5B9A\u957F\u5EA6\u7684\u5B57\u7B26\u4E32\u3002 +Copy&Topic=\u590D\u5236\u4E3B\u9898(&T) +Copy&Payload=\u590D\u5236\u6D88\u606F +SegmentTopicDescription=%d \u4E2A\u4E3B\u9898 +SegmentTopicsDescription=%d \u4E2A\u4E3B\u9898 +SegmentMessageDescription=%d \u6761\u6D88\u606F +SegmentMessagesDescription=%d \u6761\u6D88\u606F # ConnectionManagerForm -ConnectionManagement = \u8FDE\u63A5\u7BA1\u7406 -&OpenConnection = \u6253\u5F00\u8FDE\u63A5(&O) -New&Group = \u65B0\u5EFA\u5206\u7EC4(&G) -New&RootGroup = \u65B0\u5EFA\u6839\u5206\u7EC4(&R) -New&Connection = \u65B0\u5EFA\u8FDE\u63A5(&C) -Du&plicate = \u521B\u5EFA\u526F\u672C(&P) -&Edit = \u7F16\u8F91(&E) -Edit = \u7F16\u8F91 -&Delete = \u5220\u9664(&D) -Delete = \u5220\u9664 -NewGroup = \u65B0\u5EFA\u5206\u7EC4 -EditGroup = \u7F16\u8F91\u5206\u7EC4 -GroupName = \u5206\u7EC4\u540D\u79F0 -EnterGroupName = \u8BF7\u8F93\u5165\u5206\u7EC4\u540D\u79F0 -NewConnection = \u65B0\u5EFA\u8FDE\u63A5 -EditConnection = \u7F16\u8F91\u8FDE\u63A5 -ConnectionDeleteConfirm = \u60A8\u60F3\u8981\u5220\u9664\u8FDE\u63A5 "%s" \u5417? +ConnectionManagement=\u8FDE\u63A5\u7BA1\u7406 +&OpenConnection=\u6253\u5F00\u8FDE\u63A5(&O) +New&Group=\u65B0\u5EFA\u5206\u7EC4(&G) +New&RootGroup=\u65B0\u5EFA\u6839\u5206\u7EC4(&R) +New&Connection=\u65B0\u5EFA\u8FDE\u63A5(&C) +Du&plicate=\u521B\u5EFA\u526F\u672C(&P) +&Edit=\u7F16\u8F91(&E) +Edit=\u7F16\u8F91 +&Delete=\u5220\u9664(&D) +Delete=\u5220\u9664 +NewGroup=\u65B0\u5EFA\u5206\u7EC4 +EditGroup=\u7F16\u8F91\u5206\u7EC4 +GroupName=\u5206\u7EC4\u540D\u79F0 +EnterGroupName=\u8BF7\u8F93\u5165\u5206\u7EC4\u540D\u79F0 +NewConnection=\u65B0\u5EFA\u8FDE\u63A5 +EditConnection=\u7F16\u8F91\u8FDE\u63A5 +ConnectionDeleteConfirm=\u60A8\u60F3\u8981\u5220\u9664\u8FDE\u63A5 "%s" \u5417? # ConnectionEditorForm -TestConnection = \u6D4B\u8BD5\u8FDE\u63A5 -General = \u5E38\u89C4 -MQTT5Options = MQTT5 \u9009\u9879 -TLS/SSL = TLS/SSL -LastWill = \u9057\u5631 -Other = \u5176\u5B83 -Generate = \u751F\u6210 -Name = \u540D\u79F0 -Transport = \u4F20\u8F93\u534F\u8BAE -Version = \u7248\u672C -Server = \u670D\u52A1\u5668 -Port = \u7AEF\u53E3 -ClientId = ClientId -CleanSession = \u6E05\u9664\u4F1A\u8BDD -CleanSessionToolTip = \u8BBE\u7F6E\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u662F\u5426\u5E94\u5728\u91CD\u65B0\u542F\u52A8\u548C\u91CD\u65B0\u8FDE\u63A5\u65F6\u8BB0\u4F4F\u72B6\u6001\u3002\n1\u3001\u5982\u679C\u8BBE\u7F6E\u4E3A false\uFF0C\u5219\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u5C06\u5728\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u548C\u8FDE\u63A5\u65F6\u4FDD\u6301\u72B6\u6001\u3002\u5F53\u72B6\u6001\u4FDD\u6301\u65F6\uFF1A\n - \u5373\u4F7F\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u6216\u8FDE\u63A5\uFF0C\u6D88\u606F\u4F20\u9012\u4E5F\u5C06\u53EF\u9760\u5730\u6EE1\u8DB3\u6307\u5B9A\u7684QOS\u3002\n - \u670D\u52A1\u5668\u4F1A\u5C06\u8BA2\u9605\u89C6\u4E3A\u6301\u4E45\u8BA2\u9605\u3002\n2\u3001\u5982\u679C\u8BBE\u7F6E\u4E3A true\uFF0C\u5219\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u5C06\u4E0D\u4F1A\u5728\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u6216\u8FDE\u63A5\u65F6\u4FDD\u6301\u72B6\u6001\u3002\u8FD9\u610F\u5473\u7740\n - \u5982\u679C\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u6216\u8FDE\u63A5\uFF0C\u5219\u65E0\u6CD5\u7EF4\u6301\u5411\u6307\u5B9AQOS\u7684\u6D88\u606F\u4F20\u9012\n - \u670D\u52A1\u5668\u5C06\u8BA2\u9605\u89C6\u4E3A\u975E\u6301\u4E45\u8BA2\u9605\u3002 -AutoReconnect = \u81EA\u52A8\u91CD\u8FDE -ConnectionTimeout = \u8FDE\u63A5\u8D85\u65F6 -ConnectionTimeoutToolTip = \u8BBE\u7F6E\u8FDE\u63A5\u8D85\u65F6\u95F4\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\uFF0C\u5B9A\u4E49\u5BA2\u6237\u7AEF\u4E0E MQTT \u670D\u52A1\u5668\u5EFA\u7ACB\u7F51\u7EDC\u8FDE\u63A5\u7684\u6700\u5927\u7B49\u5F85\u65F6\u95F4\u3002\n\u9ED8\u8BA4\u8D85\u65F6\u4E3A 30 \u79D2\u3002\n\u8BBE\u7F6E\u4E3A 0 \u5C06\u7981\u7528\u8D85\u65F6\u5904\u7406\uFF0C\u8FD9\u610F\u5473\u7740\u5BA2\u6237\u7AEF\u5C06\u7B49\u5F85\u7F51\u7EDC\u8FDE\u63A5\u6210\u529F\u6216\u5931\u8D25\u3002 -KeepAliveInterval = \u4FDD\u6301\u6D3B\u52A8\u95F4\u9694 -KeepAliveIntervalToolTip = \u8BBE\u7F6E\u201C\u4FDD\u6301\u6D3B\u52A8\u95F4\u9694\u201D\u65F6\u957F\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\uFF0C\u5B9A\u4E49\u53D1\u9001\u6216\u63A5\u6536\u6D88\u606F\u4E4B\u95F4\u7684\u6700\u5927\u65F6\u95F4\u95F4\u9694\u3002\n\u5B83\u4F7F\u5BA2\u6237\u7AEF\u80FD\u591F\u68C0\u6D4B\u670D\u52A1\u5668\u662F\u5426\u4E0D\u518D\u53EF\u7528\uFF0C\u800C\u65E0\u9700\u7B49\u5F85TCP/IP\u8D85\u65F6\u3002\n\u5BA2\u6237\u7AEF\u5C06\u786E\u4FDD\u5728\u6BCF\u4E2A\u4FDD\u6D3B\u5468\u671F\u5185\u81F3\u5C11\u6709\u4E00\u6761\u6D88\u606F\u5728\u7F51\u7EDC\u4E0A\u4F20\u8F93\u3002\n\u5728\u8FD9\u6BB5\u65F6\u95F4\u5185\u6CA1\u6709\u76F8\u5173\u6D88\u606F\u7684\u60C5\u51B5\u4E0B\uFF0C\u5BA2\u6237\u7AEF\u4F1A\u53D1\u9001\u4E00\u6761\u201Cping\u201D\u6D88\u606F\uFF0C\u670D\u52A1\u5668\u4F1A\u5BF9\u6B64\u8FDB\u884C\u786E\u8BA4\u3002\n\u8BBE\u7F6E\u4E3A 0 \u5C06\u7981\u7528\u5BA2\u6237\u7AEF\u4E2D\u7684\u4FDD\u6301\u6D3B\u52A8\u5904\u7406\u3002 -ReconnectInterval = \u91CD\u8FDE\u95F4\u9694 -ReconnectIntervalToolTip = \u8BBE\u7F6E\u81EA\u52A8\u91CD\u65B0\u8FDE\u63A5\u7684\u6700\u5927\u65F6\u95F4\u95F4\u9694\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\u3002 -EnableLastWill = \u542F\u7528\u9057\u8A00\u6D88\u606F -RandomClientId = \u968F\u673A ClientId -Username = \u7528\u6237\u540D -Password = \u5BC6\u7801 -CleanStart = Clean Start -CleanStartToolTip = \u8BBE\u7F6E\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u662F\u5426\u5E94\u5728\u91CD\u65B0\u542F\u52A8\u548C\u91CD\u65B0\u8FDE\u63A5\u65F6\u8BB0\u4F4F\u72B6\u6001\u3002 -RequestResponseInfo = \u8BF7\u6C42\u54CD\u5E94\u4FE1\u606F -RequestResponseInfoToolTip = \u8BBE\u7F6E\u201C\u8BF7\u6C42\u54CD\u5E94\u4FE1\u606F\u201C\u6807\u5FD7\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A\u7A7A\uFF0C\u5219\u9ED8\u8BA4\u4E3A false\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A false\uFF0C\u5219\u670D\u52A1\u5668\u5C06\u4E0D\u4F1A\u5728 CONNACK \u4E2D\u8FD4\u56DE\u4EFB\u4F55\u54CD\u5E94\u4FE1\u606F\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A true\uFF0C\u5219\u670D\u52A1\u5668\u53EF\u4EE5\u5728 CONNACK \u4E2D\u8FD4\u56DE\u54CD\u5E94\u4FE1\u606F\u3002 -RequestProblemInfo = \u8BF7\u6C42\u95EE\u9898\u4FE1\u606F -RequestProblemInfoToolTip = \u8BBE\u7F6E\u201C\u8BF7\u6C42\u95EE\u9898\u4FE1\u606F\u201D\u6807\u5FD7\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A\u7A7A\uFF0C\u5219\u9ED8\u8BA4\u4E3A true\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A false\uFF0C\u670D\u52A1\u5668\u53EF\u80FD\u4F1A\u5728 CONNACK \u6216 DISCONNECT \u62A5\u6587\u4E0A\u8FD4\u56DE\u539F\u56E0\u5B57\u7B26\u4E32\u6216\u7528\u6237\u5C5E\u6027\uFF0C\u4F46\u4E0D\u4F1A\u5728 PUBLISH\u3001CONNACK \u6216 DISCONNECT \u4EE5\u5916\u7684\u4EFB\u4F55\u62A5\u6587\u4E0A\u53D1\u9001\u539F\u56E0\u5B57\u7B26\u4E32\u6216\u7528\u6237\u5C5E\u6027\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A true\uFF0C\u670D\u52A1\u5668\u53EF\u80FD\u4F1A\u5728\u4EFB\u4F55\u534F\u8BAE\u5141\u8BB8\u7684\u62A5\u6587\u4E0A\u8FD4\u56DE\u539F\u56E0\u5B57\u7B26\u4E32\u6216\u7528\u6237\u5C5E\u6027\u3002 -SessionExpiryInterval = \u4F1A\u8BDD\u8FC7\u671F\u95F4\u9694 -SessionExpiryIntervalToolTip = \u8BBE\u7F6E\u4F1A\u8BDD\u5230\u671F\u95F4\u9694\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\uFF0C\u5B9A\u4E49\u4E86\u4E00\u65E6\u5BA2\u6237\u7AEF\u65AD\u5F00\u8FDE\u63A5\uFF0C\u4EE3\u7406\u5C06\u7EF4\u62A4\u4F1A\u8BDD\u7684\u6700\u957F\u65F6\u95F4\u3002\n\u5982\u679C\u5BA2\u6237\u7AEF\u6253\u7B97\u5728\u4EE5\u540E\u67D0\u4E2A\u65F6\u95F4\u70B9\u8FDE\u63A5\u5230\u670D\u52A1\u5668\uFF0C\u5219\u53EA\u5E94\u4F7F\u7528\u8F83\u957F\u7684\u4F1A\u8BDD\u5230\u671F\u95F4\u9694\u8FDB\u884C\u8FDE\u63A5\u3002 -ReceiveMaximum = \u63A5\u6536\u6700\u5927\u503C -ReceiveMaximumToolTip = \u8BBE\u7F6E\u63A5\u6536\u6700\u5927\u503C\u3002\n\u8BE5\u503C\u8868\u793A\u5BA2\u6237\u7AEF\u613F\u610F\u540C\u65F6\u5904\u7406\u7684 QoS 1 \u548C QoS 2 \u53D1\u5E03\u7684\u9650\u5236\u3002\n\u6CA1\u6709\u9650\u5236\u670D\u52A1\u5668\u53EF\u80FD\u5C1D\u8BD5\u53D1\u9001\u7684 QoS 0 \u53D1\u5E03\u6570\u91CF\u7684\u673A\u5236\u3002\n\u53D6\u503C\u8303\u56F4\u4E3A 1 - 65535\uFF0C \u7559\u7A7A\u8868\u793A\u6700\u5927\u503C\u3002 -MaximumPacketSize = \u6570\u636E\u5305\u6700\u5927\u503C -MaximumPacketSizeToolTip = \u8BBE\u7F6E\u6700\u5927\u6570\u636E\u5305\u5927\u5C0F\u3002\n\u6B64\u503C\u8868\u793A\u5BA2\u6237\u7AEF\u613F\u610F\u63A5\u53D7\u7684\u6700\u5927\u6570\u636E\u5305\u5927\u5C0F\u3002\n\u53D6\u503C\u8303\u56F4\u4E3A 1-2684354656\uFF0C\u7559\u7A7A\u5219\u4E0D\u505A\u9650\u5236\u3002 -TopicAliasMaximum = \u4E3B\u9898\u522B\u540D\u6700\u5927\u503C -TopicAliasMaximumToolTip = \u6B64\u503C\uFF08\u5982\u679C\u5B58\u5728\uFF09\u8868\u793A\u5BA2\u6237\u7AEF\u5C06\u63A5\u53D7\u4F5C\u4E3A\u670D\u52A1\u5668\u53D1\u9001\u7684\u4E3B\u9898\u522B\u540D\u7684\u6700\u9AD8\u503C\u3002 \n\u5982\u679C\u8BBE\u7F6E\u4E3A\u7A7A\uFF0C\u5219\u9ED8\u8BA4\u4E3A 0\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A 0\uFF0C\u5219\u5BA2\u6237\u7AEF\u5C06\u4E0D\u63A5\u53D7\u4EFB\u4F55\u4E3B\u9898\u522B\u540D\u3002\u6B64\u5C5E\u6027\u7684\u6700\u5927\u503C\u4E3A 65535\u3002 -UserProperties = \u7528\u6237\u5C5E\u6027 -RemoveProperty = \u5220\u9664\u5C5E\u6027 -AddProperty = \u6DFB\u52A0\u5C5E\u6027 -NewProperty = \u65B0\u589E\u5C5E\u6027 -NewValue = \u65B0\u589E\u503C -Property = \u5C5E\u6027 -Value = \u503C -EnableSSL = \u542F\u7528 TLS/SSL -SslProtocol = \u534F\u8BAE -SslMode = TLS/SSL \u6A21\u5F0F -SslModeBasic = \u57FA\u7840 -SslModeServerOnly = CA \u8BC1\u4E66 -SslModeServerKeystore = CA \u4FE1\u4EFB\u5E93 -SslModeServerAndClient = CA \u8BC1\u4E66\u548C\u5BA2\u6237\u7AEF\u8BC1\u4E66/\u5BC6\u94A5 -SslModeServerAndClientKeystore = CA \u4FE1\u4EFB\u5E93\u548C\u5BA2\u6237\u7AEF\u5BC6\u94A5\u5E93 -SslModeProperties = TLS/SSL \u5C5E\u6027 -SslPropertyNotValid = "%s" \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684 SSL \u5C5E\u6027\u540D\u3002 -ChooseFile = \u9009\u62E9\u6587\u4EF6 -CaAndKeysFileFilter = \u8BC1\u4E66\u548C\u5BC6\u94A5\u6587\u4EF6(*.jks,*.jceks,*.p12,*.pfx,*.bks,*.pem,*.key) -CaCertificateFile = CA \u8BC1\u4E66\u6587\u4EF6 -CaKeystoreFile = CA \u5BC6\u94A5\u5E93\u6587\u4EF6 -ClientCertificateFile = \u5BA2\u6237\u7AEF\u8BC1\u4E66\u6587\u4EF6 -ClientKeyPassword = \u5BA2\u6237\u7AEF\u5BC6\u94A5\u5BC6\u7801 -ClientKeystoreFile = \u5BA2\u6237\u7AEF\u5BC6\u94A5\u5B58\u5E93\u6587\u4EF6 -ClientKeystorePassword = \u5BA2\u6237\u7AEF\u5BC6\u94A5\u5E93\u5BC6\u7801 -ClientKeyFile = \u5BA2\u6237\u7AEF\u5BC6\u94A5\u6587\u4EF6 -CaKeystorePassword = CA \u5BC6\u94A5\u5E93\u5BC6\u7801 -PemKey = PEM \u683C\u5F0F -MaxMessagesStored = \u5B58\u50A8\u6D88\u606F\u6700\u5927\u6570\u91CF -DefaultPayloadFormat = \u6D88\u606F\u9ED8\u8BA4\u683C\u5F0F -ClearUnsubMessage = \u5173\u95ED\u8BA2\u9605\u65F6\u6E05\u9664\u6D88\u606F -FieldRequiredValidation = "%s" \u4E3A\u5FC5\u586B\u9879\u3002 -FieldRangeValidation = "%s" \u7684\u53D6\u503C\u8303\u56F4\u4E3A %d - %d\u3002 -FieldMaxLengthValidation = "%s" \u7684\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 %d \u4E2A\u5B57\u7B26\u3002 -InputNotValid = \u8F93\u5165\u7684\u5B57\u7B26\u4E32 "%s" \u4E0D\u662F\u6709\u6548\u7684 %s\u3002 -TestConnectionFailed = \u8FDE\u63A5\u5931\u8D25!\n\n\u4EE3\u7801:%d\n\u6D88\u606F:%s -TestConnectionSuccessful = \u6D4B\u8BD5\u8FDE\u63A5\u6210\u529F! -TestConnectionError = \u6D4B\u8BD5\u8FDE\u63A5\u65F6\u53D1\u751F\u9519\u8BEF:\n%s -Error = \u9519\u8BEF -Confirm = \u8BE2\u95EE -Information = \u4FE1\u606F -Warning = \u8B66\u544A -ConnectionExists = \u8FDE\u63A5\u5DF2\u88AB\u6253\u5F00\u3002 -OpenConnectionError = \u6253\u5F00\u8FDE\u63A5\u65F6\u53D1\u751F\u9519\u8BEF. -InvalidTopicOfMultiSymbol = \u65E0\u6548\u7684\u4E3B\u9898\u683C\u5F0F, \u591A\u5C42\u901A\u914D\u7B26(#)\u53EA\u80FD\u5904\u4E8E\u4E3B\u9898\u7684\u5C3E\u90E8\u3002 -InvalidSubtopic = \u65E0\u6548\u7684\u4E3B\u9898\u683C\u5F0F, \u5B50\u4E3B\u9898: %s \u65E0\u6548\u3002 -ScriptLoaded = \u8F7D\u5165\u811A\u672C %s \u6210\u529F -ScriptRemoved = \u79FB\u9664\u811A\u672C %s \u6210\u529F\u3002 -ScriptError = \u6267\u884C\u811A\u672C %s \u65F6\u53D1\u751F\u9519\u8BEF -ChooseScriptOperation = \u8BF7\u9009\u62E9\u60A8\u8981\u5BF9\u811A\u672C\u8FDB\u884C\u4F55\u79CD\u64CD\u4F5C?\n \u5982\u679C\u4F60\u60F3\u53D6\u6D88\u8BE5\u811A\u672C\u7684\u6267\u884C\u53EF\u70B9\u51FB"\u79FB\u9664"\u6309\u94AE\u3002\n \u5982\u679C\u811A\u672C\u7684\u5185\u5BB9\u5DF2\u7ECF\u53D1\u751F\u6539\u53D8\uFF0C\u60A8\u53EF\u4EE5\u70B9\u51FB"\u91CD\u65B0\u8F7D\u5165"\u4EE5\u4FBF\u52A0\u8F7D\u65B0\u7684\u811A\u672C\u5185\u5BB9\u3002 -ScriptReloadConfirm = \u60A8\u60F3\u8981\u91CD\u65B0\u8F7D\u5165\u811A\u672C "%s" \u5417? -Chart = \u56FE\u8868 -MessageCountStatisticsChart = \u6D88\u606F\u6570\u7EDF\u8BA1\u56FE\u8868 ... -MessageCountStatisticsChartTitle = \u6D88\u606F\u6570\u7EDF\u8BA1\u56FE\u8868 [%s] -MessageLoadStatisticsChart = \u6D88\u606F\u8D1F\u8F7D\u7EDF\u8BA1\u56FE\u8868 ... -MessageLoadStatisticsChartTitle = \u6D88\u606F\u8D1F\u8F7D\u7EDF\u8BA1\u56FE\u8868 [%s] -MessageContentStatisticsChart = \u6D88\u606F\u5185\u5BB9\u7EDF\u8BA1\u56FE\u8868 ... -MessageContentStatisticsChartTitle = \u6D88\u606F\u5185\u5BB9\u7EDF\u8BA1\u56FE\u8868 [%s] -AddSeries = \u6DFB\u52A0\u7CFB\u5217 -RemoveSeries = \u5220\u9664\u7CFB\u5217 -ResetChart = \u91CD\u7F6E\u56FE\u8868 -Pause = \u6682\u505C -Resume = \u6062\u590D -SaveCollectionToFavorites = \u4FDD\u5B58\u5F53\u524D\u7CFB\u5217\u96C6\u5230\u6536\u85CF -EnterCollectionName = \u8F93\u5165\u7CFB\u5217\u96C6\u540D\u79F0 -OverwriteCollection = \u540C\u540D\u7684\u7CFB\u5217\u96C6"%s"\u5DF2\u7ECF\u5B58\u5728, \u4F60\u60F3\u8981\u8986\u76D6\u5417? -PieChart = \u997C\u56FE -BarChart = \u67F1\u72B6\u56FE -SaveAs = \u4FDD\u5B58\u4E3A ... -Print = \u6253\u5370 ... -ExportAs = \u5BFC\u51FA ... -ResetZoom = \u91CD\u7F6E\u7F29\u653E -RemoveFavoriteCollection = \u4F60\u786E\u5B9A\u8981\u5220\u9664\u5DF2\u6536\u85CF\u7684\u7CFB\u5217\u96C6 "%s"? -SeriesEditor = \u7CFB\u5217\u7F16\u8F91\u5668 -DynamicSeries = \u52A8\u6001\u7CFB\u5217 -SeriesName = \u7CFB\u5217\u540D -Dynamic = \u52A8\u6001 -Match = \u5339\u914D -MatchMode = \u5339\u914D\u6A21\u5F0F -MatchExpression = \u5339\u914D\u8868\u8FBE\u5F0F -MatchExpressionTip = \u5F53\u52A8\u6001\u7CFB\u5217\u590D\u9009\u6846\u88AB\u52FE\u9009\uFF0C\u5E76\u4E14\u5339\u914D\u65B9\u5F0F\u4E3A\u6B63\u5219\u8868\u8FBE\u5F0F\u65F6\uFF0C\u8BF7\u52A1\u5FC5\u4F7F\u7528\u5206\u7EC4\u6784\u9020\u63CF\u8FF0\u6B63\u5219\u8868\u8FBE\u5F0F\u7684\u5B50\u8868\u8FBE\u5F0F\u5E76\u6355\u83B7\u8F93\u5165\u5B57\u7B26\u4E32\u7684\u5B50\u5B57\u7B26\u4E32\u3002\n\u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u5339\u914D\u7B2C\u4E00\u4E2A\u5B50\u8868\u8FBE\u5F0F\u7684\u5B50\u5B57\u7B26\u4E32\u4F1A\u88AB\u63D0\u53D6\u3002\n\u5982\u679C\u6CA1\u6709\u4F7F\u7528\u5206\u7EC4\u6784\u9020\uFF0C\u5219\u4F1A\u63D0\u53D6\u5B8C\u6574\u7684\u5339\u914D\u5B57\u7B26\u4E32\u3002\n\n\u4F8B\u5982: \\$SYS/broker/connection/(.+)/state\n\u53EF\u4EE5\u5339\u914D\u4E3B\u9898 \\$SYS/broker/connection/ACBD/state\n\u5E76\u63D0\u53D6\u5B50\u5B57\u7B26\u4E32 ACBD -Wildcards = \u901A\u914D\u7B26 -JsonPath = JsonPath -Equals = \u7B49\u4E8E -NotEquals = \u4E0D\u7B49\u4E8E -Contains = \u5305\u542B -NotContains = \u4E0D\u5305\u542B -StatisticalMethod = \u7EDF\u8BA1\u65B9\u6CD5 -MessageCount = \u6D88\u606F\u6570\u91CF -AverageMessageSize = \u6D88\u606F\u5927\u5C0F\u5E73\u5747\u503C -SumOfMessageSize = \u6D88\u606F\u5927\u5C0F\u5408\u8BA1\u503C -MaximumMessageSize = \u6D88\u606F\u5927\u5C0F\u6700\u5927\u503C -MinimumMessageSize = \u6D88\u606F\u5927\u5C0F\u6700\u5C0F\u503C -MessageSize = \u6D88\u606F\u5927\u5C0F -MessageSizeAxis = \u6D88\u606F\u5927\u5C0F (\u5B57\u8282) -StatisticalWindow = \u7EDF\u8BA1\u7A97\u53E3 -ExtractingMode = \u53D6\u503C\u6A21\u5F0F -PayloadContent = \u6D88\u606F\u5185\u5BB9 -ExtractingExpression = \u53D6\u503C\u8868\u8FBE\u5F0F -ExtractingExpressionTip = \u5F53\u53D6\u503C\u6A21\u5F0F\u6B63\u5219\u8868\u8FBE\u5F0F\u65F6\uFF0C\u8BF7\u52A1\u5FC5\u4F7F\u7528\u5206\u7EC4\u6784\u9020\u63CF\u8FF0\u6B63\u5219\u8868\u8FBE\u5F0F\u7684\u5B50\u8868\u8FBE\u5F0F\u4EE5\u63D0\u53D6\u8F93\u5165\u5B57\u7B26\u4E32\u7684\u5B50\u5B57\u7B26\u4E32\u3002\n\u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u5339\u914D\u7B2C\u4E00\u4E2A\u5B50\u8868\u8FBE\u5F0F\u7684\u5B50\u5B57\u7B26\u4E32\u4F1A\u88AB\u63D0\u53D6\u3002\n\u5982\u679C\u6CA1\u6709\u4F7F\u7528\u5206\u7EC4\u6784\u9020\uFF0C\u5219\u4F1A\u63D0\u53D6\u5B8C\u6574\u7684\u5339\u914D\u5B57\u7B26\u4E32\u3002\n\n\u6CE8\u610F: \u63D0\u53D6\u7684\u5185\u5BB9\u5FC5\u987B\u662F\u6570\u5B57\uFF0C\u975E\u6570\u5B57\u7684\u5185\u5BB9\u5C06\u4F1A\u88AB\u5FFD\u7565\u3002 -RefreshFrequency = \u5237\u65B0\u9891\u7387 -XAxisDataQuantity = X\u8F74\u6570\u636E\u6570\u91CF\u9650\u5236 -Unlimited = \u65E0\u9650\u5236 -Seconds = \u79D2 -Minutes = \u5206\u949F -Hours = \u5C0F\u65F6 -DataPoints = \u6570\u636E\u70B9 -CloseTabConfirm = \u5B58\u5728\u4E0E\u5F53\u524D\u6807\u7B7E\u9875\u76F8\u5173\u7684\u56FE\u8868\u7A97\u53E3\u5C1A\u672A\u5173\u95ED\uFF0C \u5173\u95ED\u6807\u7B7E\u9875\u65F6\u4E5F\u5C06\u5173\u95ED\u8FD9\u4E9B\u56FE\u8868\u7A97\u53E3\uFF0C\u4F60\u662F\u5426\u786E\u5B9A\u8981\u5173\u95ED\uFF1F -Codecs = \u7F16\u89E3\u7801\u5668 -NewCodec = \u6DFB\u52A0\u7F16\u89E3\u7801\u5668 -EditCodec = \u4FEE\u6539\u7F16\u89E3\u7801\u5668 -Type = \u7C7B\u578B -SchemaFile = \u6A21\u5F0F\u6587\u4EF6 -MessageMapping = \u6D88\u606F\u6620\u5C04 -MessageMappingToolTip = \u586B\u5199\u6D88\u606F\u6620\u5C04\u8868\u53EF\u4EE5\u5E2E\u52A9 MqttInsight \u66F4\u4E3A\u51C6\u786E\u5730\u8BC6\u522B\u5E76\u89E3\u7801\u6D88\u606F\u3002\n\u5426\u5219 MqttInsight \u53EA\u80FD\u57FA\u4E8E\u6A21\u5F0F\u6587\u4EF6\u8FDB\u884C\u5C1D\u8BD5, \u89E3\u7801\u7684\u7ED3\u679C\u4E5F\u53EF\u80FD\u5E76\u4E0D\u5B8C\u5168\u51C6\u786E\u3002 -AddMapping = \u6DFB\u52A0\u6620\u5C04 -RemoveMapping = \u5220\u9664\u6620\u5C04 -IncompleteMessageMapping = \u6D88\u606F\u6620\u5C04\u8868\u683C\u4E2D\u7B2C %d \u884C\u672A\u5B8C\u6574\u586B\u5199\u3002 -MappingFieldTopic = \u4E3B\u9898(\u652F\u6301\u901A\u914D\u7B26) -ProtobufMessageName = Protobuf \u6D88\u606F\u540D\u79F0 -KryoRecordClass = Kryo \u5BF9\u8C61\u7C7B\u540D -AvroNamespace = Avro \u5BF9\u8C61\u547D\u540D\u7A7A\u95F4 -AvroName = Avro \u5BF9\u8C61\u540D\u79F0 -NoCodec = \u627E\u4E0D\u5230\u9009\u62E9\u7684\u7F16\u89E3\u7801\u5668\u7C7B\u578B: %s -CodecExists = \u7F16\u89E3\u7801\u5668 "%s" \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528\u5176\u5B83\u7684\u540D\u79F0\uFF0C\u6216\u8005\u5148\u5C06\u5176\u5220\u9664! +TestConnection=\u6D4B\u8BD5\u8FDE\u63A5 +General=\u5E38\u89C4 +MQTT5Options=MQTT5 \u9009\u9879 +TLS/SSL=TLS/SSL +LastWill=\u9057\u5631 +Other=\u5176\u5B83 +Generate=\u751F\u6210 +Name=\u540D\u79F0 +Transport=\u4F20\u8F93\u534F\u8BAE +Version=\u7248\u672C +Server=\u670D\u52A1\u5668 +Port=\u7AEF\u53E3 +ClientId=ClientId +CleanSession=\u6E05\u9664\u4F1A\u8BDD +CleanSessionToolTip=\u8BBE\u7F6E\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u662F\u5426\u5E94\u5728\u91CD\u65B0\u542F\u52A8\u548C\u91CD\u65B0\u8FDE\u63A5\u65F6\u8BB0\u4F4F\u72B6\u6001\u3002\n1\u3001\u5982\u679C\u8BBE\u7F6E\u4E3A false\uFF0C\u5219\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u5C06\u5728\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u548C\u8FDE\u63A5\u65F6\u4FDD\u6301\u72B6\u6001\u3002\u5F53\u72B6\u6001\u4FDD\u6301\u65F6\uFF1A\n - \u5373\u4F7F\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u6216\u8FDE\u63A5\uFF0C\u6D88\u606F\u4F20\u9012\u4E5F\u5C06\u53EF\u9760\u5730\u6EE1\u8DB3\u6307\u5B9A\u7684QOS\u3002\n - \u670D\u52A1\u5668\u4F1A\u5C06\u8BA2\u9605\u89C6\u4E3A\u6301\u4E45\u8BA2\u9605\u3002\n2\u3001\u5982\u679C\u8BBE\u7F6E\u4E3A true\uFF0C\u5219\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u5C06\u4E0D\u4F1A\u5728\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u6216\u8FDE\u63A5\u65F6\u4FDD\u6301\u72B6\u6001\u3002\u8FD9\u610F\u5473\u7740\n - \u5982\u679C\u91CD\u65B0\u542F\u52A8\u5BA2\u6237\u7AEF\u3001\u670D\u52A1\u5668\u6216\u8FDE\u63A5\uFF0C\u5219\u65E0\u6CD5\u7EF4\u6301\u5411\u6307\u5B9AQOS\u7684\u6D88\u606F\u4F20\u9012\n - \u670D\u52A1\u5668\u5C06\u8BA2\u9605\u89C6\u4E3A\u975E\u6301\u4E45\u8BA2\u9605\u3002 +AutoReconnect=\u81EA\u52A8\u91CD\u8FDE +ConnectionTimeout=\u8FDE\u63A5\u8D85\u65F6 +ConnectionTimeoutToolTip=\u8BBE\u7F6E\u8FDE\u63A5\u8D85\u65F6\u95F4\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\uFF0C\u5B9A\u4E49\u5BA2\u6237\u7AEF\u4E0E MQTT \u670D\u52A1\u5668\u5EFA\u7ACB\u7F51\u7EDC\u8FDE\u63A5\u7684\u6700\u5927\u7B49\u5F85\u65F6\u95F4\u3002\n\u9ED8\u8BA4\u8D85\u65F6\u4E3A 30 \u79D2\u3002\n\u8BBE\u7F6E\u4E3A 0 \u5C06\u7981\u7528\u8D85\u65F6\u5904\u7406\uFF0C\u8FD9\u610F\u5473\u7740\u5BA2\u6237\u7AEF\u5C06\u7B49\u5F85\u7F51\u7EDC\u8FDE\u63A5\u6210\u529F\u6216\u5931\u8D25\u3002 +KeepAliveInterval=\u4FDD\u6301\u6D3B\u52A8\u95F4\u9694 +KeepAliveIntervalToolTip=\u8BBE\u7F6E\u201C\u4FDD\u6301\u6D3B\u52A8\u95F4\u9694\u201D\u65F6\u957F\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\uFF0C\u5B9A\u4E49\u53D1\u9001\u6216\u63A5\u6536\u6D88\u606F\u4E4B\u95F4\u7684\u6700\u5927\u65F6\u95F4\u95F4\u9694\u3002\n\u5B83\u4F7F\u5BA2\u6237\u7AEF\u80FD\u591F\u68C0\u6D4B\u670D\u52A1\u5668\u662F\u5426\u4E0D\u518D\u53EF\u7528\uFF0C\u800C\u65E0\u9700\u7B49\u5F85TCP/IP\u8D85\u65F6\u3002\n\u5BA2\u6237\u7AEF\u5C06\u786E\u4FDD\u5728\u6BCF\u4E2A\u4FDD\u6D3B\u5468\u671F\u5185\u81F3\u5C11\u6709\u4E00\u6761\u6D88\u606F\u5728\u7F51\u7EDC\u4E0A\u4F20\u8F93\u3002\n\u5728\u8FD9\u6BB5\u65F6\u95F4\u5185\u6CA1\u6709\u76F8\u5173\u6D88\u606F\u7684\u60C5\u51B5\u4E0B\uFF0C\u5BA2\u6237\u7AEF\u4F1A\u53D1\u9001\u4E00\u6761\u201Cping\u201D\u6D88\u606F\uFF0C\u670D\u52A1\u5668\u4F1A\u5BF9\u6B64\u8FDB\u884C\u786E\u8BA4\u3002\n\u8BBE\u7F6E\u4E3A 0 \u5C06\u7981\u7528\u5BA2\u6237\u7AEF\u4E2D\u7684\u4FDD\u6301\u6D3B\u52A8\u5904\u7406\u3002 +ReconnectInterval=\u91CD\u8FDE\u95F4\u9694 +ReconnectIntervalToolTip=\u8BBE\u7F6E\u81EA\u52A8\u91CD\u65B0\u8FDE\u63A5\u7684\u6700\u5927\u65F6\u95F4\u95F4\u9694\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\u3002 +EnableLastWill=\u542F\u7528\u9057\u8A00\u6D88\u606F +RandomClientId=\u968F\u673A ClientId +Username=\u7528\u6237\u540D +Password=\u5BC6\u7801 +CleanStart=Clean Start +CleanStartToolTip=\u8BBE\u7F6E\u5BA2\u6237\u7AEF\u548C\u670D\u52A1\u5668\u662F\u5426\u5E94\u5728\u91CD\u65B0\u542F\u52A8\u548C\u91CD\u65B0\u8FDE\u63A5\u65F6\u8BB0\u4F4F\u72B6\u6001\u3002 +RequestResponseInfo=\u8BF7\u6C42\u54CD\u5E94\u4FE1\u606F +RequestResponseInfoToolTip=\u8BBE\u7F6E\u201C\u8BF7\u6C42\u54CD\u5E94\u4FE1\u606F\u201C\u6807\u5FD7\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A\u7A7A\uFF0C\u5219\u9ED8\u8BA4\u4E3A false\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A false\uFF0C\u5219\u670D\u52A1\u5668\u5C06\u4E0D\u4F1A\u5728 CONNACK \u4E2D\u8FD4\u56DE\u4EFB\u4F55\u54CD\u5E94\u4FE1\u606F\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A true\uFF0C\u5219\u670D\u52A1\u5668\u53EF\u4EE5\u5728 CONNACK \u4E2D\u8FD4\u56DE\u54CD\u5E94\u4FE1\u606F\u3002 +RequestProblemInfo=\u8BF7\u6C42\u95EE\u9898\u4FE1\u606F +RequestProblemInfoToolTip=\u8BBE\u7F6E\u201C\u8BF7\u6C42\u95EE\u9898\u4FE1\u606F\u201D\u6807\u5FD7\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A\u7A7A\uFF0C\u5219\u9ED8\u8BA4\u4E3A true\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A false\uFF0C\u670D\u52A1\u5668\u53EF\u80FD\u4F1A\u5728 CONNACK \u6216 DISCONNECT \u62A5\u6587\u4E0A\u8FD4\u56DE\u539F\u56E0\u5B57\u7B26\u4E32\u6216\u7528\u6237\u5C5E\u6027\uFF0C\u4F46\u4E0D\u4F1A\u5728 PUBLISH\u3001CONNACK \u6216 DISCONNECT \u4EE5\u5916\u7684\u4EFB\u4F55\u62A5\u6587\u4E0A\u53D1\u9001\u539F\u56E0\u5B57\u7B26\u4E32\u6216\u7528\u6237\u5C5E\u6027\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A true\uFF0C\u670D\u52A1\u5668\u53EF\u80FD\u4F1A\u5728\u4EFB\u4F55\u534F\u8BAE\u5141\u8BB8\u7684\u62A5\u6587\u4E0A\u8FD4\u56DE\u539F\u56E0\u5B57\u7B26\u4E32\u6216\u7528\u6237\u5C5E\u6027\u3002 +SessionExpiryInterval=\u4F1A\u8BDD\u8FC7\u671F\u95F4\u9694 +SessionExpiryIntervalToolTip=\u8BBE\u7F6E\u4F1A\u8BDD\u5230\u671F\u95F4\u9694\u3002\n\u4EE5\u79D2\u4E3A\u5355\u4F4D\uFF0C\u5B9A\u4E49\u4E86\u4E00\u65E6\u5BA2\u6237\u7AEF\u65AD\u5F00\u8FDE\u63A5\uFF0C\u4EE3\u7406\u5C06\u7EF4\u62A4\u4F1A\u8BDD\u7684\u6700\u957F\u65F6\u95F4\u3002\n\u5982\u679C\u5BA2\u6237\u7AEF\u6253\u7B97\u5728\u4EE5\u540E\u67D0\u4E2A\u65F6\u95F4\u70B9\u8FDE\u63A5\u5230\u670D\u52A1\u5668\uFF0C\u5219\u53EA\u5E94\u4F7F\u7528\u8F83\u957F\u7684\u4F1A\u8BDD\u5230\u671F\u95F4\u9694\u8FDB\u884C\u8FDE\u63A5\u3002 +ReceiveMaximum=\u63A5\u6536\u6700\u5927\u503C +ReceiveMaximumToolTip=\u8BBE\u7F6E\u63A5\u6536\u6700\u5927\u503C\u3002\n\u8BE5\u503C\u8868\u793A\u5BA2\u6237\u7AEF\u613F\u610F\u540C\u65F6\u5904\u7406\u7684 QoS 1 \u548C QoS 2 \u53D1\u5E03\u7684\u9650\u5236\u3002\n\u6CA1\u6709\u9650\u5236\u670D\u52A1\u5668\u53EF\u80FD\u5C1D\u8BD5\u53D1\u9001\u7684 QoS 0 \u53D1\u5E03\u6570\u91CF\u7684\u673A\u5236\u3002\n\u53D6\u503C\u8303\u56F4\u4E3A 1 - 65535\uFF0C \u7559\u7A7A\u8868\u793A\u6700\u5927\u503C\u3002 +MaximumPacketSize=\u6570\u636E\u5305\u6700\u5927\u503C +MaximumPacketSizeToolTip=\u8BBE\u7F6E\u6700\u5927\u6570\u636E\u5305\u5927\u5C0F\u3002\n\u6B64\u503C\u8868\u793A\u5BA2\u6237\u7AEF\u613F\u610F\u63A5\u53D7\u7684\u6700\u5927\u6570\u636E\u5305\u5927\u5C0F\u3002\n\u53D6\u503C\u8303\u56F4\u4E3A 1-2684354656\uFF0C\u7559\u7A7A\u5219\u4E0D\u505A\u9650\u5236\u3002 +TopicAliasMaximum=\u4E3B\u9898\u522B\u540D\u6700\u5927\u503C +TopicAliasMaximumToolTip=\u6B64\u503C\uFF08\u5982\u679C\u5B58\u5728\uFF09\u8868\u793A\u5BA2\u6237\u7AEF\u5C06\u63A5\u53D7\u4F5C\u4E3A\u670D\u52A1\u5668\u53D1\u9001\u7684\u4E3B\u9898\u522B\u540D\u7684\u6700\u9AD8\u503C\u3002 \n\u5982\u679C\u8BBE\u7F6E\u4E3A\u7A7A\uFF0C\u5219\u9ED8\u8BA4\u4E3A 0\u3002\n\u5982\u679C\u8BBE\u7F6E\u4E3A 0\uFF0C\u5219\u5BA2\u6237\u7AEF\u5C06\u4E0D\u63A5\u53D7\u4EFB\u4F55\u4E3B\u9898\u522B\u540D\u3002\u6B64\u5C5E\u6027\u7684\u6700\u5927\u503C\u4E3A 65535\u3002 +UserProperties=\u7528\u6237\u5C5E\u6027 +RemoveProperty=\u5220\u9664\u5C5E\u6027 +AddProperty=\u6DFB\u52A0\u5C5E\u6027 +NewProperty=\u65B0\u589E\u5C5E\u6027 +NewValue=\u65B0\u589E\u503C +Property=\u5C5E\u6027 +Value=\u503C +EnableSSL=\u542F\u7528 TLS/SSL +SslProtocol=\u534F\u8BAE +SslMode=TLS/SSL \u6A21\u5F0F +SslModeBasic=\u57FA\u7840 +SslModeServerOnly=CA \u8BC1\u4E66 +SslModeServerKeystore=CA \u4FE1\u4EFB\u5E93 +SslModeServerAndClient=CA \u8BC1\u4E66\u548C\u5BA2\u6237\u7AEF\u8BC1\u4E66/\u5BC6\u94A5 +SslModeServerAndClientKeystore=CA \u4FE1\u4EFB\u5E93\u548C\u5BA2\u6237\u7AEF\u5BC6\u94A5\u5E93 +SslModeProperties=TLS/SSL \u5C5E\u6027 +SslPropertyNotValid="%s" \u4E0D\u662F\u4E00\u4E2A\u6709\u6548\u7684 SSL \u5C5E\u6027\u540D\u3002 +ChooseFile=\u9009\u62E9\u6587\u4EF6 +CaAndKeysFileFilter=\u8BC1\u4E66\u548C\u5BC6\u94A5\u6587\u4EF6(*.jks,*.jceks,*.p12,*.pfx,*.bks,*.pem,*.key) +CaCertificateFile=CA \u8BC1\u4E66\u6587\u4EF6 +CaKeystoreFile=CA \u5BC6\u94A5\u5E93\u6587\u4EF6 +ClientCertificateFile=\u5BA2\u6237\u7AEF\u8BC1\u4E66\u6587\u4EF6 +ClientKeyPassword=\u5BA2\u6237\u7AEF\u5BC6\u94A5\u5BC6\u7801 +ClientKeystoreFile=\u5BA2\u6237\u7AEF\u5BC6\u94A5\u5B58\u5E93\u6587\u4EF6 +ClientKeystorePassword=\u5BA2\u6237\u7AEF\u5BC6\u94A5\u5E93\u5BC6\u7801 +ClientKeyFile=\u5BA2\u6237\u7AEF\u5BC6\u94A5\u6587\u4EF6 +CaKeystorePassword=CA \u5BC6\u94A5\u5E93\u5BC6\u7801 +PemKey=PEM \u683C\u5F0F +MaxMessagesStored=\u5B58\u50A8\u6D88\u606F\u6700\u5927\u6570\u91CF +DefaultPayloadFormat=\u6D88\u606F\u9ED8\u8BA4\u683C\u5F0F +ClearUnsubMessage=\u5173\u95ED\u8BA2\u9605\u65F6\u6E05\u9664\u6D88\u606F +FieldRequiredValidation="%s" \u4E3A\u5FC5\u586B\u9879\u3002 +FieldRangeValidation="%s" \u7684\u53D6\u503C\u8303\u56F4\u4E3A %d - %d\u3002 +FieldMaxLengthValidation="%s" \u7684\u957F\u5EA6\u4E0D\u80FD\u8D85\u8FC7 %d \u4E2A\u5B57\u7B26\u3002 +InputNotValid=\u8F93\u5165\u7684\u5B57\u7B26\u4E32 "%s" \u4E0D\u662F\u6709\u6548\u7684 %s\u3002 +TestConnectionFailed=\u8FDE\u63A5\u5931\u8D25!\n\n\u4EE3\u7801:%d\n\u6D88\u606F:%s +TestConnectionSuccessful=\u6D4B\u8BD5\u8FDE\u63A5\u6210\u529F! +TestConnectionError=\u6D4B\u8BD5\u8FDE\u63A5\u65F6\u53D1\u751F\u9519\u8BEF:\n%s +Error=\u9519\u8BEF +Confirm=\u8BE2\u95EE +Information=\u4FE1\u606F +Warning=\u8B66\u544A +ConnectionExists=\u8FDE\u63A5\u5DF2\u88AB\u6253\u5F00\u3002 +OpenConnectionError=\u6253\u5F00\u8FDE\u63A5\u65F6\u53D1\u751F\u9519\u8BEF. +InvalidTopicOfMultiSymbol=\u65E0\u6548\u7684\u4E3B\u9898\u683C\u5F0F, \u591A\u5C42\u901A\u914D\u7B26(#)\u53EA\u80FD\u5904\u4E8E\u4E3B\u9898\u7684\u5C3E\u90E8\u3002 +InvalidSubtopic=\u65E0\u6548\u7684\u4E3B\u9898\u683C\u5F0F, \u5B50\u4E3B\u9898: %s \u65E0\u6548\u3002 +ScriptLoaded=\u8F7D\u5165\u811A\u672C %s \u6210\u529F +ScriptRemoved=\u79FB\u9664\u811A\u672C %s \u6210\u529F\u3002 +ScriptError=\u6267\u884C\u811A\u672C %s \u65F6\u53D1\u751F\u9519\u8BEF +ChooseScriptOperation=\u8BF7\u9009\u62E9\u60A8\u8981\u5BF9\u811A\u672C\u8FDB\u884C\u4F55\u79CD\u64CD\u4F5C?\n \u5982\u679C\u4F60\u60F3\u53D6\u6D88\u8BE5\u811A\u672C\u7684\u6267\u884C\u53EF\u70B9\u51FB"\u79FB\u9664"\u6309\u94AE\u3002\n \u5982\u679C\u811A\u672C\u7684\u5185\u5BB9\u5DF2\u7ECF\u53D1\u751F\u6539\u53D8\uFF0C\u60A8\u53EF\u4EE5\u70B9\u51FB"\u91CD\u65B0\u8F7D\u5165"\u4EE5\u4FBF\u52A0\u8F7D\u65B0\u7684\u811A\u672C\u5185\u5BB9\u3002 +ScriptReloadConfirm=\u60A8\u60F3\u8981\u91CD\u65B0\u8F7D\u5165\u811A\u672C "%s" \u5417? +Chart=\u56FE\u8868 +MessageCountStatisticsChart=\u6D88\u606F\u6570\u7EDF\u8BA1\u56FE\u8868 ... +MessageCountStatisticsChartTitle=\u6D88\u606F\u6570\u7EDF\u8BA1\u56FE\u8868 [%s] +MessageLoadStatisticsChart=\u6D88\u606F\u8D1F\u8F7D\u7EDF\u8BA1\u56FE\u8868 ... +MessageLoadStatisticsChartTitle=\u6D88\u606F\u8D1F\u8F7D\u7EDF\u8BA1\u56FE\u8868 [%s] +MessageContentStatisticsChart=\u6D88\u606F\u5185\u5BB9\u7EDF\u8BA1\u56FE\u8868 ... +MessageContentStatisticsChartTitle=\u6D88\u606F\u5185\u5BB9\u7EDF\u8BA1\u56FE\u8868 [%s] +AddSeries=\u6DFB\u52A0\u7CFB\u5217 +RemoveSeries=\u5220\u9664\u7CFB\u5217 +ResetChart=\u91CD\u7F6E\u56FE\u8868 +Pause=\u6682\u505C +Resume=\u6062\u590D +SaveCollectionToFavorites=\u4FDD\u5B58\u5F53\u524D\u7CFB\u5217\u96C6\u5230\u6536\u85CF +EnterCollectionName=\u8F93\u5165\u7CFB\u5217\u96C6\u540D\u79F0 +OverwriteCollection=\u540C\u540D\u7684\u7CFB\u5217\u96C6"%s"\u5DF2\u7ECF\u5B58\u5728, \u4F60\u60F3\u8981\u8986\u76D6\u5417? +PieChart=\u997C\u56FE +BarChart=\u67F1\u72B6\u56FE +SaveAs=\u4FDD\u5B58\u4E3A ... +Print=\u6253\u5370 ... +ExportAs=\u5BFC\u51FA ... +ResetZoom=\u91CD\u7F6E\u7F29\u653E +RemoveFavoriteCollection=\u4F60\u786E\u5B9A\u8981\u5220\u9664\u5DF2\u6536\u85CF\u7684\u7CFB\u5217\u96C6 "%s"? +SeriesEditor=\u7CFB\u5217\u7F16\u8F91\u5668 +DynamicSeries=\u52A8\u6001\u7CFB\u5217 +SeriesName=\u7CFB\u5217\u540D +Dynamic=\u52A8\u6001 +Match=\u5339\u914D +MatchMode=\u5339\u914D\u6A21\u5F0F +MatchExpression=\u5339\u914D\u8868\u8FBE\u5F0F +MatchExpressionTip=\u5F53\u52A8\u6001\u7CFB\u5217\u590D\u9009\u6846\u88AB\u52FE\u9009\uFF0C\u5E76\u4E14\u5339\u914D\u65B9\u5F0F\u4E3A\u6B63\u5219\u8868\u8FBE\u5F0F\u65F6\uFF0C\u8BF7\u52A1\u5FC5\u4F7F\u7528\u5206\u7EC4\u6784\u9020\u63CF\u8FF0\u6B63\u5219\u8868\u8FBE\u5F0F\u7684\u5B50\u8868\u8FBE\u5F0F\u5E76\u6355\u83B7\u8F93\u5165\u5B57\u7B26\u4E32\u7684\u5B50\u5B57\u7B26\u4E32\u3002\n\u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u5339\u914D\u7B2C\u4E00\u4E2A\u5B50\u8868\u8FBE\u5F0F\u7684\u5B50\u5B57\u7B26\u4E32\u4F1A\u88AB\u63D0\u53D6\u3002\n\u5982\u679C\u6CA1\u6709\u4F7F\u7528\u5206\u7EC4\u6784\u9020\uFF0C\u5219\u4F1A\u63D0\u53D6\u5B8C\u6574\u7684\u5339\u914D\u5B57\u7B26\u4E32\u3002\n\n\u4F8B\u5982: \\$SYS/broker/connection/(.+)/state\n\u53EF\u4EE5\u5339\u914D\u4E3B\u9898 \\$SYS/broker/connection/ACBD/state\n\u5E76\u63D0\u53D6\u5B50\u5B57\u7B26\u4E32 ACBD +Wildcards=\u901A\u914D\u7B26 +JsonPath=JsonPath +Equals=\u7B49\u4E8E +NotEquals=\u4E0D\u7B49\u4E8E +Contains=\u5305\u542B +NotContains=\u4E0D\u5305\u542B +StatisticalMethod=\u7EDF\u8BA1\u65B9\u6CD5 +MessageCount=\u6D88\u606F\u6570\u91CF +AverageMessageSize=\u6D88\u606F\u5927\u5C0F\u5E73\u5747\u503C +SumOfMessageSize=\u6D88\u606F\u5927\u5C0F\u5408\u8BA1\u503C +MaximumMessageSize=\u6D88\u606F\u5927\u5C0F\u6700\u5927\u503C +MinimumMessageSize=\u6D88\u606F\u5927\u5C0F\u6700\u5C0F\u503C +MessageSize=\u6D88\u606F\u5927\u5C0F +MessageSizeAxis=\u6D88\u606F\u5927\u5C0F (\u5B57\u8282) +StatisticalWindow=\u7EDF\u8BA1\u7A97\u53E3 +ExtractingMode=\u53D6\u503C\u6A21\u5F0F +PayloadContent=\u6D88\u606F\u5185\u5BB9 +ExtractingExpression=\u53D6\u503C\u8868\u8FBE\u5F0F +ExtractingExpressionTip=\u5F53\u53D6\u503C\u6A21\u5F0F\u6B63\u5219\u8868\u8FBE\u5F0F\u65F6\uFF0C\u8BF7\u52A1\u5FC5\u4F7F\u7528\u5206\u7EC4\u6784\u9020\u63CF\u8FF0\u6B63\u5219\u8868\u8FBE\u5F0F\u7684\u5B50\u8868\u8FBE\u5F0F\u4EE5\u63D0\u53D6\u8F93\u5165\u5B57\u7B26\u4E32\u7684\u5B50\u5B57\u7B26\u4E32\u3002\n\u9ED8\u8BA4\u60C5\u51B5\u4E0B\uFF0C\u5339\u914D\u7B2C\u4E00\u4E2A\u5B50\u8868\u8FBE\u5F0F\u7684\u5B50\u5B57\u7B26\u4E32\u4F1A\u88AB\u63D0\u53D6\u3002\n\u5982\u679C\u6CA1\u6709\u4F7F\u7528\u5206\u7EC4\u6784\u9020\uFF0C\u5219\u4F1A\u63D0\u53D6\u5B8C\u6574\u7684\u5339\u914D\u5B57\u7B26\u4E32\u3002\n\n\u6CE8\u610F: \u63D0\u53D6\u7684\u5185\u5BB9\u5FC5\u987B\u662F\u6570\u5B57\uFF0C\u975E\u6570\u5B57\u7684\u5185\u5BB9\u5C06\u4F1A\u88AB\u5FFD\u7565\u3002 +RefreshFrequency=\u5237\u65B0\u9891\u7387 +XAxisDataQuantity=X\u8F74\u6570\u636E\u6570\u91CF\u9650\u5236 +Unlimited=\u65E0\u9650\u5236 +Seconds=\u79D2 +Minutes=\u5206\u949F +Hours=\u5C0F\u65F6 +DataPoints=\u6570\u636E\u70B9 +CloseTabConfirm=\u5B58\u5728\u4E0E\u5F53\u524D\u6807\u7B7E\u9875\u76F8\u5173\u7684\u56FE\u8868\u7A97\u53E3\u5C1A\u672A\u5173\u95ED\uFF0C \u5173\u95ED\u6807\u7B7E\u9875\u65F6\u4E5F\u5C06\u5173\u95ED\u8FD9\u4E9B\u56FE\u8868\u7A97\u53E3\uFF0C\u4F60\u662F\u5426\u786E\u5B9A\u8981\u5173\u95ED\uFF1F +Codecs=\u7F16\u89E3\u7801\u5668 +NewCodec=\u6DFB\u52A0\u7F16\u89E3\u7801\u5668 +EditCodec=\u4FEE\u6539\u7F16\u89E3\u7801\u5668 +Type=\u7C7B\u578B +SchemaFile=\u6A21\u5F0F\u6587\u4EF6 +MessageMapping=\u6D88\u606F\u6620\u5C04 +MessageMappingToolTip=\u586B\u5199\u6D88\u606F\u6620\u5C04\u8868\u53EF\u4EE5\u5E2E\u52A9 MqttInsight \u66F4\u4E3A\u51C6\u786E\u5730\u8BC6\u522B\u5E76\u89E3\u7801\u6D88\u606F\u3002\n\u5426\u5219 MqttInsight \u53EA\u80FD\u57FA\u4E8E\u6A21\u5F0F\u6587\u4EF6\u8FDB\u884C\u5C1D\u8BD5, \u89E3\u7801\u7684\u7ED3\u679C\u4E5F\u53EF\u80FD\u5E76\u4E0D\u5B8C\u5168\u51C6\u786E\u3002 +AddMapping=\u6DFB\u52A0\u6620\u5C04 +RemoveMapping=\u5220\u9664\u6620\u5C04 +IncompleteMessageMapping=\u6D88\u606F\u6620\u5C04\u8868\u683C\u4E2D\u7B2C %d \u884C\u672A\u5B8C\u6574\u586B\u5199\u3002 +MappingFieldTopic=\u4E3B\u9898(\u652F\u6301\u901A\u914D\u7B26) +ProtobufMessageName=Protobuf \u6D88\u606F\u540D\u79F0 +KryoRecordClass=Kryo \u5BF9\u8C61\u7C7B\u540D +AvroNamespace=Avro \u5BF9\u8C61\u547D\u540D\u7A7A\u95F4 +AvroName=Avro \u5BF9\u8C61\u540D\u79F0 +NoCodec=\u627E\u4E0D\u5230\u9009\u62E9\u7684\u7F16\u89E3\u7801\u5668\u7C7B\u578B: %s +CodecExists=\u7F16\u89E3\u7801\u5668 "%s" \u5DF2\u5B58\u5728\uFF0C\u8BF7\u4F7F\u7528\u5176\u5B83\u7684\u540D\u79F0\uFF0C\u6216\u8005\u5148\u5C06\u5176\u5220\u9664! diff --git a/src/main/resources/version.json b/src/main/resources/version.json index a4c7e1e..d7b0b6d 100644 --- a/src/main/resources/version.json +++ b/src/main/resources/version.json @@ -1,3 +1,3 @@ { - "version": "1.1.3" + "version": "1.1.4" }