feat: initial commit for device-to-db application with serial communication and GUI
This commit is contained in:
1 parent
a67e7c86cf
commit
e01d6dd2cc
45 files changed
+3459
No files matched your search
Generated
+1
@@ -0,0 +1 @@
|
|||||||
|
devicetodb2
|
||||||
Generated
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="CompilerConfiguration">
|
||||||
|
<annotationProcessing>
|
||||||
|
<profile name="Maven default annotation processors profile" enabled="true">
|
||||||
|
<sourceOutputDir name="target/generated-sources/annotations" />
|
||||||
|
<sourceTestOutputDir name="target/generated-test-sources/test-annotations" />
|
||||||
|
<outputRelativeToContentRoot value="true" />
|
||||||
|
<module name="device-to-db2" />
|
||||||
|
</profile>
|
||||||
|
</annotationProcessing>
|
||||||
|
<bytecodeTargetLevel target="8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+6
@@ -0,0 +1,6 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Encoding" addBOMForNewFiles="with NO BOM">
|
||||||
|
<file url="file://$PROJECT_DIR$" charset="UTF-8" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+14
@@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ExternalStorageConfigurationManager" enabled="true" />
|
||||||
|
<component name="MavenProjectsManager">
|
||||||
|
<option name="originalFiles">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
|
||||||
|
<output url="file://$PROJECT_DIR$/out" />
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+124
@@ -0,0 +1,124 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="Palette2">
|
||||||
|
<group name="Swing">
|
||||||
|
<item class="com.intellij.uiDesigner.HSpacer" tooltip-text="Horizontal Spacer" icon="/com/intellij/uiDesigner/icons/hspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="1" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="com.intellij.uiDesigner.VSpacer" tooltip-text="Vertical Spacer" icon="/com/intellij/uiDesigner/icons/vspacer.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="1" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPanel" icon="/com/intellij/uiDesigner/icons/panel.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollPane" icon="/com/intellij/uiDesigner/icons/scrollPane.png" removable="false" auto-create-binding="false" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="7" hsize-policy="7" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JButton" icon="/com/intellij/uiDesigner/icons/button.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="0" fill="1" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Button" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JRadioButton" icon="/com/intellij/uiDesigner/icons/radioButton.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="RadioButton" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JCheckBox" icon="/com/intellij/uiDesigner/icons/checkBox.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="3" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="CheckBox" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JLabel" icon="/com/intellij/uiDesigner/icons/label.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="8" fill="0" />
|
||||||
|
<initial-values>
|
||||||
|
<property name="text" value="Label" />
|
||||||
|
</initial-values>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextField" icon="/com/intellij/uiDesigner/icons/textField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JPasswordField" icon="/com/intellij/uiDesigner/icons/passwordField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JFormattedTextField" icon="/com/intellij/uiDesigner/icons/formattedTextField.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1">
|
||||||
|
<preferred-size width="150" height="-1" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextArea" icon="/com/intellij/uiDesigner/icons/textArea.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTextPane" icon="/com/intellij/uiDesigner/icons/textPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JEditorPane" icon="/com/intellij/uiDesigner/icons/editorPane.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JComboBox" icon="/com/intellij/uiDesigner/icons/comboBox.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="2" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTable" icon="/com/intellij/uiDesigner/icons/table.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JList" icon="/com/intellij/uiDesigner/icons/list.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="2" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTree" icon="/com/intellij/uiDesigner/icons/tree.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3">
|
||||||
|
<preferred-size width="150" height="50" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JTabbedPane" icon="/com/intellij/uiDesigner/icons/tabbedPane.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSplitPane" icon="/com/intellij/uiDesigner/icons/splitPane.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="3" hsize-policy="3" anchor="0" fill="3">
|
||||||
|
<preferred-size width="200" height="200" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSpinner" icon="/com/intellij/uiDesigner/icons/spinner.png" removable="false" auto-create-binding="true" can-attach-label="true">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSlider" icon="/com/intellij/uiDesigner/icons/slider.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="8" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JSeparator" icon="/com/intellij/uiDesigner/icons/separator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="6" anchor="0" fill="3" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JProgressBar" icon="/com/intellij/uiDesigner/icons/progressbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar" icon="/com/intellij/uiDesigner/icons/toolbar.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="6" anchor="0" fill="1">
|
||||||
|
<preferred-size width="-1" height="20" />
|
||||||
|
</default-constraints>
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JToolBar$Separator" icon="/com/intellij/uiDesigner/icons/toolbarSeparator.png" removable="false" auto-create-binding="false" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="0" hsize-policy="0" anchor="0" fill="1" />
|
||||||
|
</item>
|
||||||
|
<item class="javax.swing.JScrollBar" icon="/com/intellij/uiDesigner/icons/scrollbar.png" removable="false" auto-create-binding="true" can-attach-label="false">
|
||||||
|
<default-constraints vsize-policy="6" hsize-policy="0" anchor="0" fill="2" />
|
||||||
|
</item>
|
||||||
|
</group>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Generated
+619
@@ -0,0 +1,619 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project version="4">
|
||||||
|
<component name="ChangeListManager">
|
||||||
|
<list default="true" id="ef60f6bb-7ec2-4c54-b55c-e648c142cdeb" name="Default Changelist" comment="" />
|
||||||
|
<ignored path="$PROJECT_DIR$/out/" />
|
||||||
|
<ignored path="$PROJECT_DIR$/target/" />
|
||||||
|
<option name="EXCLUDED_CONVERTED_TO_IGNORED" value="true" />
|
||||||
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||||
|
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||||
|
</component>
|
||||||
|
<component name="DatabaseView">
|
||||||
|
<option name="SHOW_INTERMEDIATE" value="true" />
|
||||||
|
<option name="GROUP_DATA_SOURCES" value="true" />
|
||||||
|
<option name="GROUP_SCHEMA" value="true" />
|
||||||
|
<option name="GROUP_CONTENTS" value="false" />
|
||||||
|
<option name="SORT_POSITIONED" value="false" />
|
||||||
|
<option name="SHOW_EMPTY_GROUPS" value="false" />
|
||||||
|
<option name="AUTO_SCROLL_FROM_SOURCE" value="false" />
|
||||||
|
<option name="HIDDEN_KINDS">
|
||||||
|
<set />
|
||||||
|
</option>
|
||||||
|
<expand />
|
||||||
|
<select />
|
||||||
|
</component>
|
||||||
|
<component name="FileEditorManager">
|
||||||
|
<leaf SIDE_TABS_SIZE_LIMIT_KEY="300">
|
||||||
|
<file pinned="false" current-in-tab="true">
|
||||||
|
<entry file="file://$PROJECT_DIR$/pom.xml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="370">
|
||||||
|
<caret line="86" column="40" selection-start-line="86" selection-start-column="40" selection-end-line="86" selection-end-column="40" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/utils/HttpUtil.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="3825">
|
||||||
|
<caret line="176" column="36" selection-start-line="176" selection-start-column="36" selection-end-line="176" selection-end-column="36" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/SerialDeviceInfoApp.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1225">
|
||||||
|
<caret line="61" column="13" selection-start-line="61" selection-start-column="13" selection-end-line="61" selection-end-column="13" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/Demo1.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="475">
|
||||||
|
<caret line="502" column="47" selection-start-line="502" selection-start-column="47" selection-end-line="502" selection-end-column="47" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/HubForm3.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="-356">
|
||||||
|
<caret line="127" column="40" selection-start-line="127" selection-start-column="40" selection-end-line="127" selection-end-column="40" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
<file pinned="false" current-in-tab="false">
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/utils/AESUtil.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="100">
|
||||||
|
<caret line="10" selection-start-line="10" selection-end-line="10" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</file>
|
||||||
|
</leaf>
|
||||||
|
</component>
|
||||||
|
<component name="FileTemplateManagerImpl">
|
||||||
|
<option name="RECENT_TEMPLATES">
|
||||||
|
<list>
|
||||||
|
<option value="Class" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="FindInProjectRecents">
|
||||||
|
<findStrings>
|
||||||
|
<find>getSystemLookAndFeel</find>
|
||||||
|
<find>release</find>
|
||||||
|
<find>doInBackground</find>
|
||||||
|
<find>btnPrint</find>
|
||||||
|
<find>波特率</find>
|
||||||
|
<find>mem</find>
|
||||||
|
<find>serialPort</find>
|
||||||
|
<find>onRecCom</find>
|
||||||
|
<find>chkRead</find>
|
||||||
|
<find>11</find>
|
||||||
|
<find>resultData</find>
|
||||||
|
</findStrings>
|
||||||
|
</component>
|
||||||
|
<component name="IdeDocumentHistory">
|
||||||
|
<option name="CHANGED_PATHS">
|
||||||
|
<list>
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/HubForm.java" />
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/HubForm2.java" />
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/HubForm3.java" />
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/SerialDeviceInfoApp.java" />
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/PrintDemo.java" />
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/utils/AESUtil.java" />
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/utils/HttpUtil.java" />
|
||||||
|
<option value="$PROJECT_DIR$/src/main/java/unizk/Demo1.java" />
|
||||||
|
<option value="$PROJECT_DIR$/pom.xml" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="MavenImportPreferences">
|
||||||
|
<option name="generalSettings">
|
||||||
|
<MavenGeneralSettings>
|
||||||
|
<option name="localRepository" value="D:\maven\repository" />
|
||||||
|
<option name="mavenHome" value="D:/apache/apache-maven-3.5.4" />
|
||||||
|
<option name="userSettingsFile" value="D:\apache\apache-maven-3.5.4\conf\settings.xml" />
|
||||||
|
</MavenGeneralSettings>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="MavenProjectNavigator">
|
||||||
|
<treeState>
|
||||||
|
<expand />
|
||||||
|
<select />
|
||||||
|
</treeState>
|
||||||
|
</component>
|
||||||
|
<component name="ProjectFrameBounds" extendedState="6">
|
||||||
|
<option name="x" value="-8" />
|
||||||
|
<option name="y" value="-8" />
|
||||||
|
<option name="width" value="1934" />
|
||||||
|
<option name="height" value="1037" />
|
||||||
|
</component>
|
||||||
|
<component name="ProjectView">
|
||||||
|
<navigator proportions="" version="1">
|
||||||
|
<foldersAlwaysOnTop value="true" />
|
||||||
|
</navigator>
|
||||||
|
<panes>
|
||||||
|
<pane id="Scope" />
|
||||||
|
<pane id="PackagesPane" />
|
||||||
|
<pane id="ProjectPane">
|
||||||
|
<subPane>
|
||||||
|
<expand>
|
||||||
|
<path>
|
||||||
|
<item name="devicetodb2" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="device-to-db2" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="devicetodb2" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="device-to-db2" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="devicetodb2" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="device-to-db2" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="main" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="devicetodb2" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="device-to-db2" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="main" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="java" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
<path>
|
||||||
|
<item name="devicetodb2" type="b2602c69:ProjectViewProjectNode" />
|
||||||
|
<item name="device-to-db2" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="src" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="main" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="java" type="462c0819:PsiDirectoryNode" />
|
||||||
|
<item name="unizk" type="462c0819:PsiDirectoryNode" />
|
||||||
|
</path>
|
||||||
|
</expand>
|
||||||
|
<select />
|
||||||
|
</subPane>
|
||||||
|
</pane>
|
||||||
|
</panes>
|
||||||
|
</component>
|
||||||
|
<component name="PropertiesComponent">
|
||||||
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
|
<property name="aspect.path.notification.shown" value="true" />
|
||||||
|
<property name="com.android.tools.idea.instantapp.provision.ProvisionBeforeRunTaskProvider.myTimeStamp" value="1786587666971" />
|
||||||
|
<property name="last_opened_file_path" value="$PROJECT_DIR$" />
|
||||||
|
<property name="nodejs_interpreter_path.stuck_in_default_project" value="undefined stuck path" />
|
||||||
|
<property name="nodejs_npm_path_reset_for_default_project" value="true" />
|
||||||
|
<property name="nodejs_package_manager_path" value="npm" />
|
||||||
|
<property name="project.structure.last.edited" value="Project" />
|
||||||
|
<property name="project.structure.proportion" value="0.0" />
|
||||||
|
<property name="project.structure.side.proportion" value="0.2" />
|
||||||
|
<property name="settings.editor.selected.configurable" value="MavenSettings" />
|
||||||
|
</component>
|
||||||
|
<component name="RunDashboard">
|
||||||
|
<option name="ruleStates">
|
||||||
|
<list>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="ConfigurationTypeDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
<RuleState>
|
||||||
|
<option name="name" value="StatusDashboardGroupingRule" />
|
||||||
|
</RuleState>
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="RunManager" selected="Application.Demo1">
|
||||||
|
<configuration name="Demo1" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="unizk.Demo1" />
|
||||||
|
<module name="device-to-db2" />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="unizk.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<configuration name="HubForm" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="unizk.HubForm" />
|
||||||
|
<module name="device-to-db2" />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="unizk.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<configuration name="HubForm3" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="unizk.HubForm3" />
|
||||||
|
<module name="device-to-db2" />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="unizk.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<configuration name="PrintDemo" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="unizk.PrintDemo" />
|
||||||
|
<module name="device-to-db2" />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="unizk.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<configuration name="SerialDeviceInfoApp" type="Application" factoryName="Application" temporary="true" nameIsGenerated="true">
|
||||||
|
<option name="MAIN_CLASS_NAME" value="unizk.SerialDeviceInfoApp" />
|
||||||
|
<module name="device-to-db2" />
|
||||||
|
<extension name="coverage">
|
||||||
|
<pattern>
|
||||||
|
<option name="PATTERN" value="unizk.*" />
|
||||||
|
<option name="ENABLED" value="true" />
|
||||||
|
</pattern>
|
||||||
|
</extension>
|
||||||
|
<method v="2">
|
||||||
|
<option name="Make" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
<recent_temporary>
|
||||||
|
<list>
|
||||||
|
<item itemvalue="Application.Demo1" />
|
||||||
|
<item itemvalue="Application.PrintDemo" />
|
||||||
|
<item itemvalue="Application.SerialDeviceInfoApp" />
|
||||||
|
<item itemvalue="Application.HubForm3" />
|
||||||
|
<item itemvalue="Application.HubForm" />
|
||||||
|
</list>
|
||||||
|
</recent_temporary>
|
||||||
|
</component>
|
||||||
|
<component name="SvnConfiguration">
|
||||||
|
<configuration />
|
||||||
|
</component>
|
||||||
|
<component name="TaskManager">
|
||||||
|
<task active="true" id="Default" summary="Default task">
|
||||||
|
<changelist id="ef60f6bb-7ec2-4c54-b55c-e648c142cdeb" name="Default Changelist" comment="" />
|
||||||
|
<created>1759031074613</created>
|
||||||
|
<option name="number" value="Default" />
|
||||||
|
<option name="presentableId" value="Default" />
|
||||||
|
<updated>1759031074613</updated>
|
||||||
|
<workItem from="1759031084492" duration="5367000" />
|
||||||
|
<workItem from="1760691468633" duration="9277000" />
|
||||||
|
<workItem from="1760926748924" duration="5041000" />
|
||||||
|
<workItem from="1760941099638" duration="1800000" />
|
||||||
|
<workItem from="1760949880737" duration="1899000" />
|
||||||
|
<workItem from="1784894996773" duration="2614000" />
|
||||||
|
<workItem from="1785120641614" duration="18351000" />
|
||||||
|
<workItem from="1785290668497" duration="2143000" />
|
||||||
|
<workItem from="1785317494212" duration="595000" />
|
||||||
|
<workItem from="1785463701690" duration="10959000" />
|
||||||
|
<workItem from="1785722636862" duration="104000" />
|
||||||
|
<workItem from="1785753360666" duration="14871000" />
|
||||||
|
<workItem from="1785922159388" duration="1320000" />
|
||||||
|
<workItem from="1786161091693" duration="2148000" />
|
||||||
|
<workItem from="1786360469136" duration="84000" />
|
||||||
|
<workItem from="1786587502987" duration="400000" />
|
||||||
|
<workItem from="1789710470762" duration="647000" />
|
||||||
|
</task>
|
||||||
|
<servers />
|
||||||
|
</component>
|
||||||
|
<component name="TimeTrackingManager">
|
||||||
|
<option name="totallyTimeSpent" value="77620000" />
|
||||||
|
</component>
|
||||||
|
<component name="ToolWindowManager">
|
||||||
|
<frame x="-8" y="-8" width="1936" height="1056" extended-state="6" />
|
||||||
|
<editor active="true" />
|
||||||
|
<layout>
|
||||||
|
<window_info active="true" content_ui="combo" id="Project" order="0" visible="true" weight="0.21002132" />
|
||||||
|
<window_info id="Structure" order="1" side_tool="true" weight="0.25" />
|
||||||
|
<window_info id="Image Layers" order="2" />
|
||||||
|
<window_info id="Designer" order="3" />
|
||||||
|
<window_info id="UI Designer" order="4" />
|
||||||
|
<window_info id="Capture Tool" order="5" />
|
||||||
|
<window_info id="Favorites" order="6" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Message" order="0" />
|
||||||
|
<window_info anchor="bottom" id="Find" order="1" weight="0.32956153" />
|
||||||
|
<window_info anchor="bottom" id="Run" order="2" weight="0.25460455" />
|
||||||
|
<window_info anchor="bottom" id="Debug" order="3" weight="0.39886847" />
|
||||||
|
<window_info anchor="bottom" id="Cvs" order="4" weight="0.25" />
|
||||||
|
<window_info anchor="bottom" id="Inspection" order="5" weight="0.4" />
|
||||||
|
<window_info anchor="bottom" id="TODO" order="6" />
|
||||||
|
<window_info anchor="bottom" id="Docker" order="7" show_stripe_button="false" />
|
||||||
|
<window_info anchor="bottom" id="Version Control" order="8" />
|
||||||
|
<window_info anchor="bottom" id="Database Changes" order="9" />
|
||||||
|
<window_info anchor="bottom" id="Terminal" order="10" />
|
||||||
|
<window_info anchor="bottom" id="Event Log" order="11" side_tool="true" />
|
||||||
|
<window_info anchor="bottom" id="Messages" order="12" weight="0.4002829" />
|
||||||
|
<window_info anchor="right" id="Commander" internal_type="SLIDING" order="0" type="SLIDING" weight="0.4" />
|
||||||
|
<window_info anchor="right" id="Ant Build" order="1" weight="0.25" />
|
||||||
|
<window_info anchor="right" content_ui="combo" id="Hierarchy" order="2" weight="0.25" />
|
||||||
|
<window_info anchor="right" id="Palette" order="3" />
|
||||||
|
<window_info anchor="right" id="Database" order="4" weight="0.32995737" />
|
||||||
|
<window_info anchor="right" id="Theme Preview" order="5" />
|
||||||
|
<window_info anchor="right" id="Maven" order="6" visible="true" weight="0.21695095" />
|
||||||
|
<window_info anchor="right" id="Capture Analysis" order="7" />
|
||||||
|
<window_info anchor="right" id="Palette	" order="8" />
|
||||||
|
</layout>
|
||||||
|
</component>
|
||||||
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
<option name="version" value="1" />
|
||||||
|
</component>
|
||||||
|
<component name="editorHistoryManager">
|
||||||
|
<entry file="jar://C:/Program Files/Java/jdk1.8.0_101/src.zip!/java/time/format/DateTimeFormatter.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="226">
|
||||||
|
<caret line="1371" column="4" selection-start-line="1371" selection-start-column="4" selection-end-line="1371" selection-end-column="4" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://C:/Program Files/Java/jdk1.8.0_101/src.zip!/javax/swing/UIManager.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="209">
|
||||||
|
<caret line="599" column="45" selection-start-line="599" selection-start-column="25" selection-end-line="599" selection-end-column="45" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/test/java/unizk/AppTest.java" />
|
||||||
|
<entry file="jar://C:/Program Files/Java/jdk1.8.0_101/src.zip!/javax/swing/text/JTextComponent.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="226">
|
||||||
|
<caret line="1692" column="18" selection-start-line="1692" selection-start-column="18" selection-end-line="1692" selection-end-column="18" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://$MAVEN_REPOSITORY$/org/rxtx/rxtx/2.1.7/rxtx-2.1.7.jar!/gnu/io/CommPortIdentifier.class">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="131">
|
||||||
|
<caret line="106" column="30" selection-start-line="106" selection-start-column="30" selection-end-line="106" selection-end-column="30" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/HubForm2.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="2925">
|
||||||
|
<caret line="117" column="97" selection-end-line="342" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://D:/apache/apache-maven-3.5.4/lib/maven-model-builder-3.5.4.jar!/org/apache/maven/model/pom-4.0.0.xml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1950">
|
||||||
|
<caret line="78" column="8" selection-start-line="78" selection-start-column="8" selection-end-line="78" selection-end-column="8" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://$MAVEN_REPOSITORY$/com/fazecast/jSerialComm/2.10.4/jSerialComm-2.10.4.jar!/com/fazecast/jSerialComm/SerialPort.class">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="175">
|
||||||
|
<caret line="25" column="28" selection-start-line="25" selection-start-column="28" selection-end-line="25" selection-end-column="28" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://C:/Program Files/Java/jdk1.8.0_101/src.zip!/javax/swing/SwingWorker.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="13550">
|
||||||
|
<caret line="600" column="19" selection-start-line="600" selection-start-column="19" selection-end-line="600" selection-end-column="19" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/HubForm.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="3172">
|
||||||
|
<caret line="300" column="48" selection-start-line="300" selection-start-column="48" selection-end-line="300" selection-end-column="48" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://C:/Program Files/Java/jdk1.8.0_101/src.zip!/java/awt/print/Printable.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="224">
|
||||||
|
<caret line="114" column="8" selection-start-line="114" selection-start-column="8" selection-end-line="114" selection-end-column="8" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://C:/Program Files/Java/jdk1.8.0_101/src.zip!/java/awt/Frame.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="299">
|
||||||
|
<caret line="508" column="16" selection-start-line="508" selection-start-column="16" selection-end-line="508" selection-end-column="16" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="jar://C:/Program Files/Java/jdk1.8.0_101/src.zip!/java/awt/Container.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="224">
|
||||||
|
<caret line="971" column="16" selection-start-line="971" selection-start-column="16" selection-end-line="971" selection-end-column="16" />
|
||||||
|
<folding>
|
||||||
|
<element signature="e#37566#37567#0" expanded="true" />
|
||||||
|
<element signature="e#37612#37613#0" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/PrintDemo.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="2949">
|
||||||
|
<caret line="225" column="27" selection-start-line="225" selection-start-column="27" selection-end-line="225" selection-end-column="27" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/utils/HttpUtil.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="3825">
|
||||||
|
<caret line="176" column="36" selection-start-line="176" selection-start-column="36" selection-end-line="176" selection-end-column="36" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/SerialDeviceInfoApp.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="1225">
|
||||||
|
<caret line="61" column="13" selection-start-line="61" selection-start-column="13" selection-end-line="61" selection-end-column="13" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/utils/AESUtil.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="100">
|
||||||
|
<caret line="10" selection-start-line="10" selection-end-line="10" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/Demo1.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="475">
|
||||||
|
<caret line="502" column="47" selection-start-line="502" selection-start-column="47" selection-end-line="502" selection-end-column="47" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/src/main/java/unizk/HubForm3.java">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="-356">
|
||||||
|
<caret line="127" column="40" selection-start-line="127" selection-start-column="40" selection-end-line="127" selection-end-column="40" />
|
||||||
|
<folding>
|
||||||
|
<element signature="imports" expanded="true" />
|
||||||
|
</folding>
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
<entry file="file://$PROJECT_DIR$/pom.xml">
|
||||||
|
<provider selected="true" editor-type-id="text-editor">
|
||||||
|
<state relative-caret-position="370">
|
||||||
|
<caret line="86" column="40" selection-start-line="86" selection-start-column="40" selection-end-line="86" selection-end-column="40" />
|
||||||
|
</state>
|
||||||
|
</provider>
|
||||||
|
</entry>
|
||||||
|
</component>
|
||||||
|
<component name="masterDetails">
|
||||||
|
<states>
|
||||||
|
<state key="ArtifactsStructureConfigurable.UI">
|
||||||
|
<settings>
|
||||||
|
<artifact-editor />
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
<state key="FacetStructureConfigurable.UI">
|
||||||
|
<settings>
|
||||||
|
<last-edited>No facets are configured</last-edited>
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
<state key="GlobalLibrariesConfigurable.UI">
|
||||||
|
<settings>
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
<state key="JdkListConfigurable.UI">
|
||||||
|
<settings>
|
||||||
|
<last-edited>1.8</last-edited>
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
<state key="ModuleStructureConfigurable.UI">
|
||||||
|
<settings>
|
||||||
|
<last-edited>device-to-db2</last-edited>
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
<option value="0.6" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
<state key="ProjectJDKs.UI">
|
||||||
|
<settings>
|
||||||
|
<last-edited>1.8</last-edited>
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
<state key="ProjectLibrariesConfigurable.UI">
|
||||||
|
<settings>
|
||||||
|
<last-edited>Maven: com.fazecast:jSerialComm:2.10.4</last-edited>
|
||||||
|
<splitter-proportions>
|
||||||
|
<option name="proportions">
|
||||||
|
<list>
|
||||||
|
<option value="0.2" />
|
||||||
|
</list>
|
||||||
|
</option>
|
||||||
|
</splitter-proportions>
|
||||||
|
</settings>
|
||||||
|
</state>
|
||||||
|
</states>
|
||||||
|
</component>
|
||||||
|
</project>
|
||||||
Whitespace-only changes.
Whitespace-only changes.
@@ -0,0 +1,111 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
|
<groupId>unizk</groupId>
|
||||||
|
<artifactId>device-to-db2</artifactId>
|
||||||
|
<version>1.0.0</version>
|
||||||
|
|
||||||
|
<name>device-to-db2</name>
|
||||||
|
<!-- FIXME change it to the project's website -->
|
||||||
|
<url>http://www.example.com</url>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.source>8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>8</maven.compiler.target>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<!-- https://mvnrepository.com/artifact/com.fazecast/jSerialComm -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.fazecast</groupId>
|
||||||
|
<artifactId>jSerialComm</artifactId>
|
||||||
|
<version>2.10.4</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.squareup.okhttp3</groupId>
|
||||||
|
<artifactId>okhttp</artifactId>
|
||||||
|
<version>4.9.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Source: https://mvnrepository.com/artifact/com.google.zxing/core -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.zxing</groupId>
|
||||||
|
<artifactId>core</artifactId>
|
||||||
|
<version>3.5.3</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- Source: https://mvnrepository.com/artifact/com.google.zxing/javase -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.zxing</groupId>
|
||||||
|
<artifactId>javase</artifactId>
|
||||||
|
<version>3.5.3</version>
|
||||||
|
<scope>compile</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.httpcomponents</groupId>
|
||||||
|
<artifactId>httpclient</artifactId>
|
||||||
|
<version>4.5.14</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba.fastjson2</groupId>
|
||||||
|
<artifactId>fastjson2</artifactId>
|
||||||
|
<version>2.0.34</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<pluginManagement><!-- lock down plugins versions to avoid using Maven defaults (may be moved to parent pom) -->
|
||||||
|
<plugins>
|
||||||
|
|
||||||
|
</plugins>
|
||||||
|
</pluginManagement>
|
||||||
|
|
||||||
|
<plugins>
|
||||||
|
<!-- Compiler Plugin -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
|
<version>3.11.0</version>
|
||||||
|
<configuration>
|
||||||
|
<source>8</source>
|
||||||
|
<target>8</target>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
|
||||||
|
<!-- Maven Assembly Plugin -->
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-assembly-plugin</artifactId>
|
||||||
|
<version>3.6.0</version>
|
||||||
|
<configuration>
|
||||||
|
<archive>
|
||||||
|
<manifest>
|
||||||
|
<!-- 指定主类为 Demo1 -->
|
||||||
|
<mainClass>unizk.Demo1</mainClass>
|
||||||
|
</manifest>
|
||||||
|
</archive>
|
||||||
|
<descriptorRefs>
|
||||||
|
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||||
|
</descriptorRefs>
|
||||||
|
|
||||||
|
<!-- 输出文件名:serial-device-info-app-1.0.0-jar-with-dependencies.jar -->
|
||||||
|
<finalName>${project.artifactId}-${project.version}</finalName>
|
||||||
|
<appendAssemblyId>true</appendAssemblyId>
|
||||||
|
<outputDirectory>${project.basedir}/target</outputDirectory>
|
||||||
|
</configuration>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>make-assembly</id>
|
||||||
|
<phase>package</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>single</goal>
|
||||||
|
</goals>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
</project>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
USB烧录器接线:
|
||||||
|
|
||||||
|
烧录器的TXD接主板的RX2,烧录器的RXD接主板的TX2,GND接GND
|
||||||
|
|
||||||
|
|
||||||
|
device-to-db2运行:
|
||||||
|
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\Demo1.java
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
@echo off
|
||||||
|
chcp 65001 >nul
|
||||||
|
title 云理疗设备入库系统
|
||||||
|
echo 正在启动程序...
|
||||||
|
start javaw -jar "%~dp0target\device-to-db2-1.0.0-jar-with-dependencies.jar"
|
||||||
|
exit
|
||||||
@@ -0,0 +1,678 @@
|
|||||||
|
package unizk;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import com.fazecast.jSerialComm.SerialPortDataListener;
|
||||||
|
import com.fazecast.jSerialComm.SerialPortEvent;
|
||||||
|
import com.google.zxing.BarcodeFormat;
|
||||||
|
import com.google.zxing.WriterException;
|
||||||
|
import com.google.zxing.client.j2se.MatrixToImageWriter;
|
||||||
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
|
import unizk.utils.AESUtil;
|
||||||
|
import unizk.utils.HttpUtil;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.print.PageFormat;
|
||||||
|
import java.awt.print.Printable;
|
||||||
|
import java.awt.print.PrinterException;
|
||||||
|
import java.awt.print.PrinterJob;
|
||||||
|
import javax.print.PrintService;
|
||||||
|
import javax.print.PrintServiceLookup;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.awt.print.Paper;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class Demo1 extends JFrame {
|
||||||
|
private JComboBox<String> portComboBox;
|
||||||
|
private JTextField baudRateField;
|
||||||
|
private JButton connectButton;
|
||||||
|
private JButton sendCommandButton;
|
||||||
|
private JButton printBtn;
|
||||||
|
private JTextArea logArea;
|
||||||
|
private SerialPort selectedPort;
|
||||||
|
private final Object portLock = new Object();
|
||||||
|
private StringBuilder resultData = new StringBuilder();
|
||||||
|
private String printMsg;
|
||||||
|
private String DEVICE_ID;
|
||||||
|
private String warehousingUrl = "https://369.peaktcm.com/api/equipment/warehousing";
|
||||||
|
|
||||||
|
// 添加打印机选择组件
|
||||||
|
private JComboBox<String> printerComboBox;
|
||||||
|
private JCheckBox showPrintDialogCheckBox;
|
||||||
|
|
||||||
|
public Demo1() {
|
||||||
|
setTitle("云理疗设备入库系统");
|
||||||
|
setSize(800, 500);
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
// 顶部面板:串口设置
|
||||||
|
JPanel topPanel = new JPanel();
|
||||||
|
topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("串口:"));
|
||||||
|
portComboBox = new JComboBox<>();
|
||||||
|
refreshPorts();
|
||||||
|
topPanel.add(portComboBox);
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("波特率:"));
|
||||||
|
baudRateField = new JTextField("115200", 10);
|
||||||
|
topPanel.add(baudRateField);
|
||||||
|
|
||||||
|
connectButton = new JButton("打开串口");
|
||||||
|
connectButton.addActionListener(e -> toggleConnect());
|
||||||
|
topPanel.add(connectButton);
|
||||||
|
|
||||||
|
sendCommandButton = new JButton("设备入库");
|
||||||
|
sendCommandButton.addActionListener(e -> sendCommand());
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
topPanel.add(sendCommandButton);
|
||||||
|
|
||||||
|
JButton refreshButton = new JButton("刷新串口");
|
||||||
|
refreshButton.addActionListener(e -> refreshPorts());
|
||||||
|
topPanel.add(refreshButton);
|
||||||
|
|
||||||
|
add(topPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// 中间面板:打印机设置 + 日志
|
||||||
|
JPanel centerPanel = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
|
// 打印机设置面板
|
||||||
|
JPanel printerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||||
|
printerPanel.setBorder(BorderFactory.createTitledBorder("打印设置"));
|
||||||
|
|
||||||
|
printerPanel.add(new JLabel("打印机:"));
|
||||||
|
printerComboBox = new JComboBox<>();
|
||||||
|
loadPrinters();
|
||||||
|
printerPanel.add(printerComboBox);
|
||||||
|
|
||||||
|
JButton refreshPrinterBtn = new JButton("刷新打印机");
|
||||||
|
refreshPrinterBtn.addActionListener(e -> loadPrinters());
|
||||||
|
printerPanel.add(refreshPrinterBtn);
|
||||||
|
|
||||||
|
printBtn = new JButton("打印二维码");
|
||||||
|
printBtn.addActionListener(e -> printQRCode(printMsg,DEVICE_ID));
|
||||||
|
printBtn.setEnabled(false);
|
||||||
|
printerPanel.add(printBtn);
|
||||||
|
|
||||||
|
/*showPrintDialogCheckBox = new JCheckBox("显示打印对话框", true);
|
||||||
|
printerPanel.add(showPrintDialogCheckBox);*/
|
||||||
|
|
||||||
|
centerPanel.add(printerPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// 日志区域
|
||||||
|
logArea = new JTextArea();
|
||||||
|
logArea.setEditable(false);
|
||||||
|
centerPanel.add(new JScrollPane(logArea), BorderLayout.CENTER);
|
||||||
|
|
||||||
|
add(centerPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
log("请选择串口并点击【打开串口】");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshPorts() {
|
||||||
|
portComboBox.removeAllItems();
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
for (SerialPort port : ports) {
|
||||||
|
portComboBox.addItem(port.getSystemPortName() + " - " + port.getDescriptivePortName());
|
||||||
|
}
|
||||||
|
if (ports.length == 0) {
|
||||||
|
portComboBox.addItem("未找到串口");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 加载系统打印机列表
|
||||||
|
*/
|
||||||
|
private void loadPrinters() {
|
||||||
|
printerComboBox.removeAllItems();
|
||||||
|
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
|
||||||
|
for (PrintService service : printServices) {
|
||||||
|
printerComboBox.addItem(service.getName());
|
||||||
|
}
|
||||||
|
if (printServices.length == 0) {
|
||||||
|
printerComboBox.addItem("未找到打印机");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleConnect() {
|
||||||
|
if (selectedPort != null && selectedPort.isOpen()) {
|
||||||
|
selectedPort.closePort();
|
||||||
|
selectedPort.removeDataListener();
|
||||||
|
selectedPort = null;
|
||||||
|
connectButton.setText("打开串口");
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
log("串口已关闭");
|
||||||
|
} else {
|
||||||
|
int selectedIndex = portComboBox.getSelectedIndex();
|
||||||
|
if (selectedIndex < 0) return;
|
||||||
|
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
if (selectedIndex >= ports.length) {
|
||||||
|
JOptionPane.showMessageDialog(this, "无效的串口选择");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedPort = ports[selectedIndex];
|
||||||
|
int baudRate;
|
||||||
|
try {
|
||||||
|
baudRate = Integer.parseInt(baudRateField.getText().trim());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
JOptionPane.showMessageDialog(this, "波特率格式错误");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPort.openPort()) {
|
||||||
|
selectedPort.setBaudRate(baudRate);
|
||||||
|
selectedPort.setNumDataBits(8);
|
||||||
|
selectedPort.setNumStopBits(1);
|
||||||
|
selectedPort.setParity(SerialPort.NO_PARITY);
|
||||||
|
selectedPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
|
||||||
|
|
||||||
|
// 添加监听器
|
||||||
|
selectedPort.addDataListener(new SerialPortDataListener() {
|
||||||
|
@Override
|
||||||
|
public int getListeningEvents() {
|
||||||
|
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialEvent(SerialPortEvent event) {
|
||||||
|
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) return;
|
||||||
|
|
||||||
|
synchronized (portLock) {
|
||||||
|
byte[] newData = new byte[selectedPort.bytesAvailable()];
|
||||||
|
int len = selectedPort.readBytes(newData, newData.length);
|
||||||
|
String data = new String(newData, 0, len, StandardCharsets.UTF_8);
|
||||||
|
log("收到: " + data.trim());
|
||||||
|
resultData.append(data.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connectButton.setText("关闭串口");
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
log("串口 " + selectedPort.getSystemPortName() + " 打开成功,波特率: " + baudRate);
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(this, "无法打开串口");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("-----reslut1==="+resultData.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void sendCommand() {
|
||||||
|
if (selectedPort == null || !selectedPort.isOpen()) {
|
||||||
|
log("串口未打开");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 清空之前的数据
|
||||||
|
resultData.setLength(0);
|
||||||
|
|
||||||
|
// 禁用按钮,防止重复点击
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
log("正在发送命令...");
|
||||||
|
|
||||||
|
// 使用 SwingWorker 在后台线程执行串口操作
|
||||||
|
SwingWorker<String, String> worker = new SwingWorker<String, String>() {
|
||||||
|
@Override
|
||||||
|
protected String doInBackground() throws Exception {
|
||||||
|
String command = "$05||*05\r\n";
|
||||||
|
byte[] commandBytes = command.getBytes(StandardCharsets.US_ASCII);
|
||||||
|
|
||||||
|
// 发送命令
|
||||||
|
publish("selectedPort="+selectedPort.getNumDataBits());
|
||||||
|
int bytesWritten = selectedPort.writeBytes(commandBytes, commandBytes.length);
|
||||||
|
publish("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
|
||||||
|
|
||||||
|
// 设置超时时间(毫秒)
|
||||||
|
long timeout = 10000; // 10秒
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
|
||||||
|
// 循环读取,直到超时或收到完整响应
|
||||||
|
while (System.currentTimeMillis() - startTime < timeout) {
|
||||||
|
synchronized (portLock) {
|
||||||
|
if (selectedPort.bytesAvailable() > 0) {
|
||||||
|
byte[] buffer = new byte[selectedPort.bytesAvailable()];
|
||||||
|
int len = selectedPort.readBytes(buffer, buffer.length);
|
||||||
|
String data = new String(buffer, 0, len, StandardCharsets.UTF_8);
|
||||||
|
response.append(data);
|
||||||
|
|
||||||
|
// 假设设备以换行符结束响应,可提前退出
|
||||||
|
if (data.contains("\r\n")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 小延迟避免 CPU 占用过高
|
||||||
|
Thread.sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.length() == 0) {
|
||||||
|
return "ERROR_TIMEOUT";
|
||||||
|
}
|
||||||
|
return response.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void process(List<String> chunks) {
|
||||||
|
for (String message : chunks) {
|
||||||
|
log(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
log("-----reslut2===" + resultData.toString());
|
||||||
|
String qrContent = resultData.toString().trim();
|
||||||
|
if (!qrContent.contains("*")){
|
||||||
|
JOptionPane.showMessageDialog( null,"获取设备信息失败,请重试");
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String[] split = qrContent.split("\\|");
|
||||||
|
String un = null,mu = null;
|
||||||
|
for (String s : split) {
|
||||||
|
if (s.startsWith("MU")){
|
||||||
|
mu = s.substring(2);
|
||||||
|
}
|
||||||
|
if (s.startsWith("UN")){
|
||||||
|
un = s;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (mu == null || un == null){
|
||||||
|
JOptionPane.showMessageDialog( null,"获取设备信息失败,请重试");
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
String encrypt;
|
||||||
|
try {
|
||||||
|
encrypt = AESUtil.encrypt(mu);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log("数据加密出错!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Map<String,String> header = new HashMap<>();
|
||||||
|
header.put("s-key",encrypt);
|
||||||
|
Map<String,String> param = new HashMap<>();
|
||||||
|
param.put("mu",mu);
|
||||||
|
param.put("un",un);
|
||||||
|
log("准备执行设备入库请求");
|
||||||
|
String s = null;
|
||||||
|
try {
|
||||||
|
s = HttpUtil.doGet(warehousingUrl, header, param);
|
||||||
|
}catch (Exception e){
|
||||||
|
log("http请求超时...");
|
||||||
|
JOptionPane.showMessageDialog( null,"请求超时,请检查网络是否正常!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log("入库返回数据:"+ s);
|
||||||
|
JSONObject jsonObject = JSONObject.parseObject(s);
|
||||||
|
Integer rescode = jsonObject.getInteger("rescode");
|
||||||
|
if (rescode != 200){
|
||||||
|
JOptionPane.showMessageDialog( null,"入库失败,请稍后重试");
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
JSONObject data = jsonObject.getJSONObject("data");
|
||||||
|
String deviceId = data.getString("deviceId");
|
||||||
|
String muid = data.getString("muid");
|
||||||
|
printMsg = deviceId + "|" + muid + "||1.0";
|
||||||
|
DEVICE_ID = deviceId;
|
||||||
|
JOptionPane.showMessageDialog( null,"入库成功!请打印二维码");
|
||||||
|
printBtn.setEnabled(true);
|
||||||
|
// 重新启用按钮
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
|
||||||
|
/* try {
|
||||||
|
String result = get(); // 获取 doInBackground 的返回值
|
||||||
|
log("result=" + result);
|
||||||
|
|
||||||
|
if ("ERROR_TIMEOUT".equals(result)) {
|
||||||
|
log("设备无响应,通信超时(10秒)");
|
||||||
|
JOptionPane.showMessageDialog(Demo1.this,
|
||||||
|
"设备未响应,请检查连接或设备是否正常运行。",
|
||||||
|
"通信超时", JOptionPane.WARNING_MESSAGE);
|
||||||
|
} else {
|
||||||
|
log("响应: " + result);
|
||||||
|
|
||||||
|
// 如果 resultData 不为空,打印二维码
|
||||||
|
String qrContent = resultData.toString().trim();
|
||||||
|
if (!qrContent.isEmpty()) {
|
||||||
|
log("准备打印二维码,内容: " + qrContent);
|
||||||
|
printQRCode(qrContent);
|
||||||
|
} else {
|
||||||
|
log("没有数据可打印");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log("通信异常: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// 启动后台任务
|
||||||
|
worker.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印二维码
|
||||||
|
* @param content 二维码内容
|
||||||
|
*/
|
||||||
|
private void printQRCode(String content,String deviceID) {
|
||||||
|
if (content == null || content.length() == 0){
|
||||||
|
JOptionPane.showMessageDialog( this,"打印内容不能为空!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
// 1. 生成二维码图片
|
||||||
|
BufferedImage qrImage = generateQRCode(content, 200, 200);
|
||||||
|
log("二维码生成成功,尺寸: 20x20");
|
||||||
|
|
||||||
|
// 2. 获取选中的打印机
|
||||||
|
String printerName = (String) printerComboBox.getSelectedItem();
|
||||||
|
if (printerName == null || printerName.equals("未找到打印机")) {
|
||||||
|
int choice = JOptionPane.showConfirmDialog(this,
|
||||||
|
"未选择有效打印机,是否使用默认打印机继续?",
|
||||||
|
"打印机提示",
|
||||||
|
JOptionPane.YES_NO_OPTION);
|
||||||
|
if (choice != JOptionPane.YES_OPTION) {
|
||||||
|
log("用户取消打印");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printerName = null; // 使用默认打印机
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 执行打印
|
||||||
|
// boolean showDialog = showPrintDialogCheckBox.isSelected();
|
||||||
|
if (false) {
|
||||||
|
printQRCodeWithDialog(qrImage, printerName);
|
||||||
|
} else {
|
||||||
|
printQRCodeDirectly(qrImage, printerName,deviceID);
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (WriterException e) {
|
||||||
|
log("生成二维码失败: " + e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
"生成二维码失败: " + e.getMessage(),
|
||||||
|
"二维码生成错误",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
} catch (PrinterException e) {
|
||||||
|
log("打印失败: " + e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
"打印失败: " + e.getMessage() + "\n请检查打印机是否连接正常。",
|
||||||
|
"打印错误",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log("打印过程异常: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
"打印过程异常: " + e.getMessage(),
|
||||||
|
"异常",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成二维码图片
|
||||||
|
*/
|
||||||
|
private BufferedImage generateQRCode(String content, int width, int height) throws WriterException {
|
||||||
|
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||||
|
BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height);
|
||||||
|
return MatrixToImageWriter.toBufferedImage(bitMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 优化后的,解决标签打印机驱动返回可打印区域异常的问题
|
||||||
|
* @param qrImage
|
||||||
|
* @param printerName
|
||||||
|
* @param serialNumber
|
||||||
|
* @throws PrinterException
|
||||||
|
*/
|
||||||
|
|
||||||
|
private void printQRCodeDirectly(BufferedImage qrImage, String printerName, String serialNumber) throws PrinterException {
|
||||||
|
PrinterJob job = PrinterJob.getPrinterJob();
|
||||||
|
|
||||||
|
// 1. 选择打印机
|
||||||
|
if (printerName != null && !printerName.isEmpty()) {
|
||||||
|
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
|
||||||
|
for (PrintService service : printServices) {
|
||||||
|
if (service.getName().equals(printerName)) {
|
||||||
|
job.setPrintService(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. 【核心修复】:强制设置纸张属性,绕过标签打印机驱动的异常边距
|
||||||
|
// 假设你的标签纸是 40mm x 30mm,你可以根据实际情况修改这两个数字
|
||||||
|
double labelWidthMM = 50.0;
|
||||||
|
double labelHeightMM = 30.0;
|
||||||
|
|
||||||
|
// 将毫米转换为 Java 打印使用的磅 (1 inch = 25.4 mm = 72 points)
|
||||||
|
double widthInPoints = (labelWidthMM / 25.4) * 72;
|
||||||
|
double heightInPoints = (labelHeightMM / 25.4) * 72;
|
||||||
|
|
||||||
|
// 创建自定义纸张对象
|
||||||
|
Paper paper = new Paper();
|
||||||
|
paper.setSize(widthInPoints, heightInPoints);
|
||||||
|
// 强制将页边距设为0,让可打印区域等于纸张物理大小
|
||||||
|
paper.setImageableArea(0, 0, widthInPoints, heightInPoints);
|
||||||
|
|
||||||
|
// 获取默认页面格式并应用我们自定义的纸张
|
||||||
|
PageFormat pageFormat = job.defaultPage();
|
||||||
|
pageFormat.setPaper(paper);
|
||||||
|
pageFormat.setOrientation(PageFormat.PORTRAIT); // 纵向打印
|
||||||
|
|
||||||
|
// 3. 设置打印内容
|
||||||
|
job.setPrintable(new Printable() {
|
||||||
|
@Override
|
||||||
|
public int print(Graphics graphics, PageFormat pf, int pageIndex) throws PrinterException {
|
||||||
|
if (pageIndex > 0) return NO_SUCH_PAGE;
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) graphics;
|
||||||
|
// 使用我们强制设置的无边界坐标
|
||||||
|
g2d.translate(pf.getImageableX(), pf.getImageableY());
|
||||||
|
|
||||||
|
double imgWidth = pf.getImageableWidth();
|
||||||
|
double imgHeight = pf.getImageableHeight();
|
||||||
|
|
||||||
|
// 4. 绘制文字(序列号)
|
||||||
|
String text = "序列号:" + serialNumber;
|
||||||
|
g2d.setColor(Color.BLACK);
|
||||||
|
g2d.setFont(new Font("SansSerif", Font.PLAIN, 8));
|
||||||
|
|
||||||
|
FontMetrics fm = g2d.getFontMetrics();
|
||||||
|
int textWidth = fm.stringWidth(text);
|
||||||
|
int textHeight = fm.getHeight();
|
||||||
|
|
||||||
|
int textX = (int) ((imgWidth - textWidth) / 2);
|
||||||
|
// int textY = textHeight + 2;
|
||||||
|
int textY = 7 + fm.getAscent();
|
||||||
|
g2d.drawString(text, textX, textY);
|
||||||
|
|
||||||
|
// 5. 绘制二维码
|
||||||
|
int qrWidth = qrImage.getWidth();
|
||||||
|
int qrHeight = qrImage.getHeight();
|
||||||
|
// double availableHeight = imgHeight - textHeight - 5;
|
||||||
|
double availableHeight = imgHeight - (textHeight + 2);
|
||||||
|
|
||||||
|
if (qrWidth > imgWidth || qrHeight > availableHeight) {
|
||||||
|
double scaleX = imgWidth / qrWidth * 0.95;
|
||||||
|
double scaleY = availableHeight / qrHeight * 0.95;
|
||||||
|
double scale = Math.min(scaleX, scaleY);
|
||||||
|
qrWidth = (int) (qrWidth * scale);
|
||||||
|
qrHeight = (int) (qrHeight * scale);
|
||||||
|
}
|
||||||
|
|
||||||
|
int qrX = (int) ((imgWidth - qrWidth) / 2);
|
||||||
|
// int qrY = textY + 5;
|
||||||
|
int qrY = textY + fm.getDescent() + 1;
|
||||||
|
g2d.drawImage(qrImage, qrX, qrY, qrWidth, qrHeight, null);
|
||||||
|
|
||||||
|
return PAGE_EXISTS;
|
||||||
|
}
|
||||||
|
}, pageFormat); // 注意:这里把修改后的 pageFormat 传给了 setPrintable
|
||||||
|
|
||||||
|
// 6. 执行打印
|
||||||
|
job.print();
|
||||||
|
log("直接打印任务已提交(无对话框)");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 打印二维码(显示打印对话框)
|
||||||
|
*/
|
||||||
|
private void printQRCodeWithDialog(BufferedImage qrImage, String printerName) throws PrinterException {
|
||||||
|
PrinterJob job = PrinterJob.getPrinterJob();
|
||||||
|
|
||||||
|
// 选择打印机
|
||||||
|
if (printerName != null && !printerName.isEmpty()) {
|
||||||
|
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
|
||||||
|
for (PrintService service : printServices) {
|
||||||
|
if (service.getName().equals(printerName)) {
|
||||||
|
job.setPrintService(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置打印内容
|
||||||
|
job.setPrintable(new Printable() {
|
||||||
|
@Override
|
||||||
|
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
|
||||||
|
if (pageIndex > 0) {
|
||||||
|
return NO_SUCH_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) graphics;
|
||||||
|
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
|
||||||
|
|
||||||
|
// 计算二维码在页面中的位置(居中)
|
||||||
|
double pageWidth = pageFormat.getImageableWidth();
|
||||||
|
double pageHeight = pageFormat.getImageableHeight();
|
||||||
|
int qrWidth = qrImage.getWidth();
|
||||||
|
int qrHeight = qrImage.getHeight();
|
||||||
|
|
||||||
|
// 如果二维码太大,按比例缩放
|
||||||
|
if (qrWidth > pageWidth || qrHeight > pageHeight) {
|
||||||
|
double scaleX = pageWidth / qrWidth * 0.9;
|
||||||
|
double scaleY = pageHeight / qrHeight * 0.9;
|
||||||
|
double scale = Math.min(scaleX, scaleY);
|
||||||
|
int newWidth = (int) (qrWidth * scale);
|
||||||
|
int newHeight = (int) (qrHeight * scale);
|
||||||
|
int x = (int) ((pageWidth - newWidth) / 2);
|
||||||
|
int y = (int) ((pageHeight - newHeight) / 2);
|
||||||
|
g2d.drawImage(qrImage, x, y, newWidth, newHeight, null);
|
||||||
|
} else {
|
||||||
|
int x = (int) ((pageWidth - qrWidth) / 2);
|
||||||
|
int y = (int) ((pageHeight - qrHeight) / 2);
|
||||||
|
g2d.drawImage(qrImage, x, y, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 添加底部文字说明
|
||||||
|
/* g2d.setFont(new Font("宋体", Font.PLAIN, 12));
|
||||||
|
String content = "设备信息: " + resultData.toString().substring(0, Math.min(20, resultData.length()));
|
||||||
|
g2d.drawString(content, 10, (int) pageHeight - 20);*/
|
||||||
|
|
||||||
|
return PAGE_EXISTS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 显示打印对话框
|
||||||
|
if (job.printDialog()) {
|
||||||
|
job.print();
|
||||||
|
log("✅ 打印任务已提交(显示对话框)");
|
||||||
|
} else {
|
||||||
|
log("ℹ️ 用户取消打印");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 直接打印(不显示对话框)
|
||||||
|
*/
|
||||||
|
private void printQRCodeDirectly(BufferedImage qrImage, String printerName) throws PrinterException {
|
||||||
|
PrinterJob job = PrinterJob.getPrinterJob();
|
||||||
|
|
||||||
|
// 选择打印机
|
||||||
|
if (printerName != null && !printerName.isEmpty()) {
|
||||||
|
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
|
||||||
|
for (PrintService service : printServices) {
|
||||||
|
if (service.getName().equals(printerName)) {
|
||||||
|
job.setPrintService(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置打印内容
|
||||||
|
job.setPrintable(new Printable() {
|
||||||
|
@Override
|
||||||
|
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
|
||||||
|
if (pageIndex > 0) {
|
||||||
|
return NO_SUCH_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) graphics;
|
||||||
|
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
|
||||||
|
|
||||||
|
double pageWidth = pageFormat.getImageableWidth();
|
||||||
|
double pageHeight = pageFormat.getImageableHeight();
|
||||||
|
int qrWidth = qrImage.getWidth();
|
||||||
|
int qrHeight = qrImage.getHeight();
|
||||||
|
|
||||||
|
if (qrWidth > pageWidth || qrHeight > pageHeight) {
|
||||||
|
double scaleX = pageWidth / qrWidth * 0.9;
|
||||||
|
double scaleY = pageHeight / qrHeight * 0.9;
|
||||||
|
double scale = Math.min(scaleX, scaleY);
|
||||||
|
int newWidth = (int) (qrWidth * scale);
|
||||||
|
int newHeight = (int) (qrHeight * scale);
|
||||||
|
int x = (int) ((pageWidth - newWidth) / 2);
|
||||||
|
int y = (int) ((pageHeight - newHeight) / 2);
|
||||||
|
g2d.drawImage(qrImage, x, y, newWidth, newHeight, null);
|
||||||
|
} else {
|
||||||
|
int x = (int) ((pageWidth - qrWidth) / 2);
|
||||||
|
int y = (int) ((pageHeight - qrHeight) / 2);
|
||||||
|
g2d.drawImage(qrImage, x, y, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_EXISTS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 直接打印
|
||||||
|
job.print();
|
||||||
|
log("直接打印任务已提交(无对话框)");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void log(String message) {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String format = LocalDateTime.now().format(formatter);
|
||||||
|
logArea.append("[" + format + "] " + message + "\n");
|
||||||
|
logArea.setCaretPosition(logArea.getDocument().getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 使用 SwingUtilities 确保线程安全
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
// 设置系统外观
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
new Demo1().setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,397 @@
|
|||||||
|
package unizk;
|
||||||
|
|
||||||
|
import com.fazecast.jSerialComm.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.*;
|
||||||
|
import javax.swing.*;
|
||||||
|
|
||||||
|
public class HubForm extends JFrame {
|
||||||
|
private JComboBox<String> cmbCom;
|
||||||
|
private JComboBox<String> cmbBaud;
|
||||||
|
private JTextArea memPrinted;
|
||||||
|
private JTextArea memo1;
|
||||||
|
private JButton btnPrint;
|
||||||
|
|
||||||
|
private SerialPort serialPort;
|
||||||
|
private String comResult = "";
|
||||||
|
private boolean chkRead = false;
|
||||||
|
private int hubQty = 0;
|
||||||
|
|
||||||
|
public HubForm() {
|
||||||
|
initComponents();
|
||||||
|
loadSettings();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initComponents() {
|
||||||
|
setTitle("Hub Form");
|
||||||
|
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
// Main panel
|
||||||
|
JPanel mainPanel = new JPanel(new BorderLayout());
|
||||||
|
mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
|
|
||||||
|
// GroupBox 1 (Serial Settings)
|
||||||
|
JPanel groupBox1 = new JPanel(new GridBagLayout());
|
||||||
|
groupBox1.setBorder(BorderFactory.createTitledBorder("Serial Settings"));
|
||||||
|
|
||||||
|
GridBagConstraints gbc = new GridBagConstraints();
|
||||||
|
gbc.insets = new Insets(5, 5, 5, 5);
|
||||||
|
gbc.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
|
||||||
|
// COM Port selection
|
||||||
|
gbc.gridx = 0; gbc.gridy = 0;
|
||||||
|
groupBox1.add(new JLabel("COM Port:"), gbc);
|
||||||
|
|
||||||
|
gbc.gridx = 1; gbc.gridy = 0;
|
||||||
|
cmbCom = new JComboBox<>();
|
||||||
|
groupBox1.add(cmbCom, gbc);
|
||||||
|
|
||||||
|
// Baud Rate selection
|
||||||
|
gbc.gridx = 0; gbc.gridy = 1;
|
||||||
|
groupBox1.add(new JLabel("Baud Rate:"), gbc);
|
||||||
|
|
||||||
|
gbc.gridx = 1; gbc.gridy = 1;
|
||||||
|
cmbBaud = new JComboBox<>(new String[]{"115200"});
|
||||||
|
cmbBaud.setSelectedItem("115200");
|
||||||
|
groupBox1.add(cmbBaud, gbc);
|
||||||
|
|
||||||
|
// Print button
|
||||||
|
gbc.gridx = 0; gbc.gridy = 2; gbc.gridwidth = 2;
|
||||||
|
btnPrint = new JButton("Print");
|
||||||
|
groupBox1.add(btnPrint, gbc);
|
||||||
|
|
||||||
|
mainPanel.add(groupBox1, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// Text areas
|
||||||
|
JPanel textPanel = new JPanel(new GridLayout(1, 2, 10, 0));
|
||||||
|
|
||||||
|
memPrinted = new JTextArea(15, 30);
|
||||||
|
memPrinted.setEditable(false);
|
||||||
|
JScrollPane scroll1 = new JScrollPane(memPrinted);
|
||||||
|
scroll1.setBorder(BorderFactory.createTitledBorder("Output"));
|
||||||
|
|
||||||
|
memo1 = new JTextArea(15, 30);
|
||||||
|
memo1.setEditable(false);
|
||||||
|
JScrollPane scroll2 = new JScrollPane(memo1);
|
||||||
|
scroll2.setBorder(BorderFactory.createTitledBorder("Data"));
|
||||||
|
|
||||||
|
textPanel.add(scroll1);
|
||||||
|
textPanel.add(scroll2);
|
||||||
|
|
||||||
|
mainPanel.add(textPanel, BorderLayout.CENTER);
|
||||||
|
add(mainPanel);
|
||||||
|
|
||||||
|
// Event listeners
|
||||||
|
btnPrint.addActionListener(e -> btnPrintClick());
|
||||||
|
addWindowListener(new WindowAdapter() {
|
||||||
|
@Override
|
||||||
|
public void windowClosing(WindowEvent e) {
|
||||||
|
closeSerialPort();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
pack();
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSettings() {
|
||||||
|
// Load hub quantity from settings (simplified)
|
||||||
|
Properties props = new Properties();
|
||||||
|
try {
|
||||||
|
props.load(new FileInputStream("app.ini"));
|
||||||
|
hubQty = Integer.parseInt(props.getProperty("hubqty", "1")) - 1;
|
||||||
|
} catch (Exception e) {
|
||||||
|
hubQty = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Get available COM ports
|
||||||
|
getComPorts();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getComPorts() {
|
||||||
|
cmbCom.removeAllItems();
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
|
||||||
|
for (SerialPort port : ports) {
|
||||||
|
cmbCom.addItem(port.getSystemPortName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cmbCom.getItemCount() == 1) {
|
||||||
|
cmbCom.setSelectedIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void btnPrintClick() {
|
||||||
|
String selectedCom = (String) cmbCom.getSelectedItem();
|
||||||
|
btnPrint.setEnabled(false);
|
||||||
|
|
||||||
|
if (selectedCom == null || selectedCom.isEmpty()) {
|
||||||
|
JOptionPane.showMessageDialog(this, "Please select COM port", "Information",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
int baudRate = 115200;
|
||||||
|
|
||||||
|
// Open serial port
|
||||||
|
if (!openSerialPort(selectedCom, baudRate)) {
|
||||||
|
memPrinted.append("Failed to open serial port\n");
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read MUID
|
||||||
|
String muid = readMUID();
|
||||||
|
if (muid == null || muid.isEmpty()) {
|
||||||
|
memPrinted.append("Failed to read MUID\n");
|
||||||
|
closeSerialPort();
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse device information
|
||||||
|
DeviceInfo deviceInfo = parseDeviceInfo(muid);
|
||||||
|
if (deviceInfo == null) {
|
||||||
|
memPrinted.append("Failed to parse device information\n");
|
||||||
|
closeSerialPort();
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Submit to server and print
|
||||||
|
submitToServerAndPrint(deviceInfo);
|
||||||
|
|
||||||
|
} catch (Exception ex) {
|
||||||
|
memPrinted.append("Error: " + ex.getMessage() + "\n");
|
||||||
|
ex.printStackTrace();
|
||||||
|
} finally {
|
||||||
|
closeSerialPort();
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean openSerialPort(String portName, int baudRate) {
|
||||||
|
try {
|
||||||
|
serialPort = SerialPort.getCommPort(portName);
|
||||||
|
serialPort.setBaudRate(baudRate);
|
||||||
|
serialPort.setNumDataBits(8);
|
||||||
|
serialPort.setNumStopBits(1);
|
||||||
|
serialPort.setParity(SerialPort.NO_PARITY);
|
||||||
|
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 1000, 0);
|
||||||
|
|
||||||
|
if (serialPort.openPort()) {
|
||||||
|
memPrinted.append("Successfully opened port: " + portName + "\n");
|
||||||
|
|
||||||
|
// Set up data listener
|
||||||
|
serialPort.addDataListener(new SerialPortDataListener() {
|
||||||
|
@Override
|
||||||
|
public int getListeningEvents() {
|
||||||
|
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialEvent(SerialPortEvent event) {
|
||||||
|
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
onRecCom();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
memPrinted.append("Failed to open port: " + portName + "\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
memPrinted.append("Error opening serial port: " + e.getMessage() + "\n");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void closeSerialPort() {
|
||||||
|
if (serialPort != null && serialPort.isOpen()) {
|
||||||
|
serialPort.removeDataListener();
|
||||||
|
serialPort.closePort();
|
||||||
|
memPrinted.append("Serial port closed\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readMUID() {
|
||||||
|
int retryCount = 0;
|
||||||
|
final int maxRetries = 3;
|
||||||
|
|
||||||
|
while (retryCount < maxRetries) {
|
||||||
|
retryCount++;
|
||||||
|
chkRead = true;
|
||||||
|
comResult = "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Send command
|
||||||
|
String command = "$05||*05\r\n";
|
||||||
|
byte[] commandBytes = command.getBytes();
|
||||||
|
int bytesWritten = serialPort.writeBytes(commandBytes, commandBytes.length);
|
||||||
|
|
||||||
|
if (bytesWritten == -1) {
|
||||||
|
memPrinted.append("Failed to write command\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
memPrinted.append("Command sent: " + command);
|
||||||
|
|
||||||
|
// Wait for response with timeout
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
while (chkRead && (System.currentTimeMillis() - startTime) < 2000) {
|
||||||
|
Thread.sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
String response = comResult.trim();
|
||||||
|
memPrinted.append("Serial response: " + response + "\n");
|
||||||
|
|
||||||
|
// Validate response
|
||||||
|
if (response.contains("$05|") && response.contains("\r")) {
|
||||||
|
// Extract and validate CRC
|
||||||
|
int pos5 = response.indexOf("$05|");
|
||||||
|
String data = response.substring(pos5);
|
||||||
|
int pos13 = data.indexOf("\r");
|
||||||
|
|
||||||
|
if (pos13 > 0) {
|
||||||
|
data = data.substring(0, pos13);
|
||||||
|
String trimmedData = data.trim();
|
||||||
|
|
||||||
|
int crcPos = trimmedData.indexOf("*");
|
||||||
|
if (crcPos > 0) {
|
||||||
|
String dataPart = trimmedData.substring(2, crcPos - 1);
|
||||||
|
String receivedCrc = trimmedData.substring(crcPos + 1, crcPos + 3);
|
||||||
|
|
||||||
|
// TODO: Implement CRC validation
|
||||||
|
// if (getCRCForNmea(dataPart).equals(receivedCrc)) {
|
||||||
|
return data;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memPrinted.append("Retry " + retryCount + " - Invalid response\n");
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
memPrinted.append("Error reading MUID: " + e.getMessage() + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
memPrinted.append("Failed to read MUID after " + maxRetries + " attempts\n");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onRecCom() {
|
||||||
|
if (!chkRead) return;
|
||||||
|
|
||||||
|
try {
|
||||||
|
byte[] buffer = new byte[1024];
|
||||||
|
int bytesRead = serialPort.readBytes(buffer, buffer.length);
|
||||||
|
|
||||||
|
if (bytesRead > 0) {
|
||||||
|
String data = new String(buffer, 0, bytesRead);
|
||||||
|
comResult += data.toUpperCase();
|
||||||
|
memPrinted.append("comResult="+comResult);
|
||||||
|
|
||||||
|
if (comResult.endsWith("\r") || comResult.contains("\r\n")) {
|
||||||
|
memPrinted.append("串口连接成功");
|
||||||
|
chkRead = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private DeviceInfo parseDeviceInfo(String data) {
|
||||||
|
try {
|
||||||
|
// Example data: "$05|MU00220051045504DC00002942|UN01|HWUN01-B1.0|SWA1.0.12|CF2|*3C"
|
||||||
|
String[] parts = data.split("\\|");
|
||||||
|
|
||||||
|
DeviceInfo info = new DeviceInfo();
|
||||||
|
|
||||||
|
for (String part : parts) {
|
||||||
|
if (part.startsWith("MU")) {
|
||||||
|
info.muId = part;
|
||||||
|
} else if (part.startsWith("UN")) {
|
||||||
|
info.unId = "UN" + part.substring(2);
|
||||||
|
} else if (part.startsWith("HW")) {
|
||||||
|
info.hw = part.substring(2);
|
||||||
|
} else if (part.startsWith("SW")) {
|
||||||
|
info.sw = part.substring(2);
|
||||||
|
} else if (part.startsWith("BT")) {
|
||||||
|
info.bt = part.substring(2);
|
||||||
|
} else if (part.startsWith("CF")) {
|
||||||
|
info.cf = part.substring(2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return info;
|
||||||
|
|
||||||
|
} catch (Exception e) {
|
||||||
|
memPrinted.append("Error parsing device info: " + e.getMessage() + "\n");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void submitToServerAndPrint(DeviceInfo deviceInfo) {
|
||||||
|
// TODO: Implement HTTP submission to server
|
||||||
|
// This would involve sending the device info to a web service
|
||||||
|
// and handling the response
|
||||||
|
|
||||||
|
memPrinted.append("Submitting device info to server...\n");
|
||||||
|
memPrinted.append("MU: " + deviceInfo.muId + "\n");
|
||||||
|
memPrinted.append("UN: " + deviceInfo.unId + "\n");
|
||||||
|
memPrinted.append("HW: " + deviceInfo.hw + "\n");
|
||||||
|
memPrinted.append("SW: " + deviceInfo.sw + "\n");
|
||||||
|
memPrinted.append("BT: " + deviceInfo.bt + "\n");
|
||||||
|
memPrinted.append("CF: " + deviceInfo.cf + "\n");
|
||||||
|
|
||||||
|
// Simulate successful response
|
||||||
|
String sbxlh = "SB123456789";
|
||||||
|
String responseMsg = "Device registered successfully";
|
||||||
|
|
||||||
|
memPrinted.append("Device serial: " + sbxlh + " | " + deviceInfo.muId +
|
||||||
|
" | " + deviceInfo.bt + "QRv1.0 (" + responseMsg + ")\n");
|
||||||
|
|
||||||
|
// Print QR codes
|
||||||
|
for (int i = 0; i <= hubQty; i++) {
|
||||||
|
printQRCode(sbxlh, sbxlh + "|" + deviceInfo.muId + "|" + deviceInfo.bt + "QRv1.0");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printQRCode(String sbxlh, String qrData) {
|
||||||
|
// TODO: Implement QR code printing
|
||||||
|
memPrinted.append("Printing QR Code: " + qrData + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper class to store device information
|
||||||
|
private static class DeviceInfo {
|
||||||
|
String muId;
|
||||||
|
String unId;
|
||||||
|
String hw;
|
||||||
|
String sw;
|
||||||
|
String bt;
|
||||||
|
String cf;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
new HubForm().setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,342 @@
|
|||||||
|
/*
|
||||||
|
package unizk;
|
||||||
|
|
||||||
|
|
||||||
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import okhttp3.OkHttpClient;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
public class HubForm2 extends JFrame {
|
||||||
|
private JComboBox<String> cmbCom;
|
||||||
|
private JComboBox<String> cmbBaud;
|
||||||
|
private JButton btnPrint;
|
||||||
|
private JTextArea memPrinted;
|
||||||
|
|
||||||
|
private SerialPort serialPort;
|
||||||
|
private StringBuilder comResult = new StringBuilder();
|
||||||
|
private volatile boolean chkRead = true;
|
||||||
|
private int hubQty = 1; // 默认1,从配置读取时减1
|
||||||
|
|
||||||
|
// 网络配置(示例)
|
||||||
|
private static final String F_WEB_HOST = "http://yourserver.com";
|
||||||
|
private static final String SUBMIT_PUTSTORE = "/pc/device/submitputstore";
|
||||||
|
private static String F_LOGIN_TOKEN_NAME = "Authorization";
|
||||||
|
private static String F_LOGIN_TOKEN_VALUE = "Bearer your_token_here";
|
||||||
|
|
||||||
|
private final OkHttpClient client = new OkHttpClient();
|
||||||
|
|
||||||
|
public HubForm2() {
|
||||||
|
initializeUI();
|
||||||
|
loadSettings();
|
||||||
|
scanSerialPorts();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initializeUI() {
|
||||||
|
setTitle("Hub 通信工具");
|
||||||
|
setSize(600, 500);
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
JPanel topPanel = new JPanel(new GridLayout(2, 4, 5, 5));
|
||||||
|
topPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("串口:"));
|
||||||
|
cmbCom = new JComboBox<>();
|
||||||
|
topPanel.add(cmbCom);
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("波特率:"));
|
||||||
|
cmbBaud = new JComboBox<>(new String[]{"9600", "115200"});
|
||||||
|
cmbBaud.setSelectedItem("115200");
|
||||||
|
topPanel.add(cmbBaud);
|
||||||
|
|
||||||
|
btnPrint = new JButton("开始打印");
|
||||||
|
btnPrint.addActionListener(e -> btnPrintClick());
|
||||||
|
topPanel.add(btnPrint);
|
||||||
|
|
||||||
|
add(topPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
memPrinted = new JTextArea();
|
||||||
|
memPrinted.setFont(new Font("Monospaced", Font.PLAIN, 12));
|
||||||
|
memPrinted.setEditable(false);
|
||||||
|
add(new JScrollPane(memPrinted), BorderLayout.CENTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadSettings() {
|
||||||
|
// 模拟从 ini 文件读取 hubqty
|
||||||
|
// 实际可用 Properties 加载 app.ini
|
||||||
|
hubQty = getSettingAsInt("setting", "hubqty", 1) - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getSettingAsInt(String section, String key, int defaultValue) {
|
||||||
|
// 这里简化处理,实际应读取 app.ini
|
||||||
|
return defaultValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void scanSerialPorts() {
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
cmbCom.removeAllItems();
|
||||||
|
for (SerialPort port : ports) {
|
||||||
|
cmbCom.addItem(port.getSystemPortName());
|
||||||
|
}
|
||||||
|
if (ports.length == 1) {
|
||||||
|
cmbCom.setSelectedIndex(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === 按钮点击事件 ===
|
||||||
|
private void btnPrintClick() {
|
||||||
|
String selectedPortName = (String) cmbCom.getSelectedItem();
|
||||||
|
if (selectedPortName == null || selectedPortName.isEmpty()) {
|
||||||
|
JOptionPane.showMessageDialog(this, "请选择串口号!", "错误", JOptionPane.ERROR_MESSAGE);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
btnPrint.setEnabled(false);
|
||||||
|
memPrinted.append("正在连接串口: " + selectedPortName + "\n");
|
||||||
|
|
||||||
|
// 打开串口
|
||||||
|
if (serialPort == null || !serialPort.isOpen()) {
|
||||||
|
serialPort = SerialPort.getCommPort(selectedPortName);
|
||||||
|
serialPort.setBaudRate(Integer.parseInt((String) cmbBaud.getSelectedItem()));
|
||||||
|
serialPort.setNumDataBits(8);
|
||||||
|
serialPort.setNumStopBits(1);
|
||||||
|
serialPort.setParity(SerialPort.NO_PARITY);
|
||||||
|
serialPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
|
||||||
|
|
||||||
|
// 设置数据接收监听
|
||||||
|
serialPort.addDataListener((SerialPortEvent event) -> {
|
||||||
|
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE || !chkRead) return;
|
||||||
|
|
||||||
|
byte[] newData = new byte[serialPort.bytesAvailable()];
|
||||||
|
serialPort.readBytes(newData, newData.length);
|
||||||
|
|
||||||
|
String dataStr = new String(newData, StandardCharsets.UTF_8);
|
||||||
|
comResult.append(dataStr.toUpperCase());
|
||||||
|
|
||||||
|
// 检查是否收到回车符(\r)
|
||||||
|
if (dataStr.contains("\r")) {
|
||||||
|
chkRead = false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!serialPort.openPort()) {
|
||||||
|
memPrinted.append("无法打开串口!\n");
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (Exception ex) {
|
||||||
|
memPrinted.append("打开串口异常: " + ex.getMessage() + "\n");
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 尝试最多3次读取设备信息
|
||||||
|
String comResultStr = null;
|
||||||
|
for (int i = 1; i <= 3; i++) {
|
||||||
|
chkRead = true;
|
||||||
|
comResult.setLength(0); // 清空
|
||||||
|
|
||||||
|
serialPort.flushIOStreams();
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
|
||||||
|
// 发送指令
|
||||||
|
String command = "$05||*05\r\n";
|
||||||
|
serialPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
|
||||||
|
|
||||||
|
// 等待最多2秒
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
while (chkRead && (System.currentTimeMillis() - startTime < 2000)) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(10);
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
comResultStr = comResult.toString().trim();
|
||||||
|
memPrinted.append("第 " + i + " 次响应: " + comResultStr + "\n");
|
||||||
|
|
||||||
|
if (comResultStr.contains("$05|") && comResultStr.contains("\r")) {
|
||||||
|
|
||||||
|
break; // 成功收到
|
||||||
|
} else {
|
||||||
|
if (i == 3) {
|
||||||
|
memPrinted.append("三次均未收到有效响应!\n");
|
||||||
|
serialPort.closePort();
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// === 解析响应并 CRC 校验 ===
|
||||||
|
String raw = extractBetween(comResultStr, "$05|", "\r");
|
||||||
|
if (raw == null) {
|
||||||
|
memPrinted.append("解析失败:未找到有效数据段\n");
|
||||||
|
serialPort.closePort();
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String dataPart = extractBetween(raw, "", "*");
|
||||||
|
String crcReceived = raw.substring(raw.lastIndexOf("*") + 1, raw.lastIndexOf("*") + 3);
|
||||||
|
|
||||||
|
String crcCalculated = calculateNmeaCrc(dataPart);
|
||||||
|
if (!crcCalculated.equalsIgnoreCase(crcReceived)) {
|
||||||
|
memPrinted.append("CRC 校验失败!计算值: " + crcCalculated + ", 实际值: " + crcReceived + "\n");
|
||||||
|
serialPort.closePort();
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// === 提取字段 ===
|
||||||
|
String muId = getDataDict(raw, "MU");
|
||||||
|
String unId = getDataDict(raw, "UN");
|
||||||
|
String hw = getDataDict(raw, "HW");
|
||||||
|
String sw = getDataDict(raw, "SW");
|
||||||
|
String bt = getDataDict(raw, "BT");
|
||||||
|
String cf = getDataDict(raw, "CF");
|
||||||
|
|
||||||
|
if (muId.isEmpty()) {
|
||||||
|
memPrinted.append("未获取到 MU ID!\n");
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (unId.isEmpty()) {
|
||||||
|
memPrinted.append("未获取到 UN ID!\n");
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
unId = "UN" + unId;
|
||||||
|
|
||||||
|
// === 提交到服务器(最多重试3次)===
|
||||||
|
boolean success = false;
|
||||||
|
for (int i = 1; i <= 3; i++) {
|
||||||
|
try {
|
||||||
|
RequestBody formBody = new MultipartBody.Builder()
|
||||||
|
.setType(MultipartBody.FORM)
|
||||||
|
.addFormDataPart("un", unId)
|
||||||
|
.addFormDataPart("mu", "MU" + muId)
|
||||||
|
.addFormDataPart("hw", hw)
|
||||||
|
.addFormDataPart("sw", sw)
|
||||||
|
.addFormDataPart("bt", bt)
|
||||||
|
.addFormDataPart("cf", cf)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Request request = new Request.Builder()
|
||||||
|
.url(F_WEB_HOST + SUBMIT_PUTSTORE)
|
||||||
|
.header("JSON", "true")
|
||||||
|
.header(F_LOGIN_TOKEN_NAME, F_LOGIN_TOKEN_VALUE)
|
||||||
|
.post(formBody)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
try (Response response = client.newCall(request).execute()) {
|
||||||
|
if (!response.isSuccessful()) {
|
||||||
|
memPrinted.append("HTTP 请求失败: " + response.code() + "\n");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
String responseBody = response.body().string();
|
||||||
|
JSONObject json = new JSONObject(responseBody);
|
||||||
|
|
||||||
|
if (json.optBoolean("success", false)) {
|
||||||
|
JSONObject data = json.optJSONObject("data");
|
||||||
|
if (data != null) {
|
||||||
|
String sbxlh = data.optString("sbxlh");
|
||||||
|
String muid = data.optString("muid");
|
||||||
|
String msg = json.optString("resmsg", "");
|
||||||
|
String qrText = sbxlh + "|" + muid + "|" + bt + "V1.0(" + msg + ")";
|
||||||
|
|
||||||
|
memPrinted.append("设备编码: " + sbxlh + " | " + muid + " | " + bt + "\n");
|
||||||
|
// 模拟打印二维码
|
||||||
|
for (int j = 0; j <= hubQty; j++) {
|
||||||
|
printQRCode(sbxlh, qrText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
success = true;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
int rescode = json.optInt("rescode", 0);
|
||||||
|
if (rescode == 403) {
|
||||||
|
refreshToken();
|
||||||
|
memPrinted.append("Token 过期,已刷新,第 " + i + " 次重试...\n");
|
||||||
|
continue;
|
||||||
|
} else {
|
||||||
|
memPrinted.append("提交失败: " + responseBody + "\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
memPrinted.append("网络请求异常: " + e.getMessage() + "\n");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!success) {
|
||||||
|
memPrinted.append("提交失败,已达最大重试次数。\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
serialPort.closePort();
|
||||||
|
btnPrint.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// === 工具方法 ===
|
||||||
|
|
||||||
|
private String extractBetween(String src, String start, String end) {
|
||||||
|
int s = src.indexOf(start);
|
||||||
|
if (s == -1) return null;
|
||||||
|
s += start.length();
|
||||||
|
int e = src.indexOf(end, s);
|
||||||
|
if (e == -1) return null;
|
||||||
|
return src.substring(s, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
private String getDataDict(String data, String prefix) {
|
||||||
|
Pattern pattern = Pattern.compile("\\|" + prefix + "([^|]+)");
|
||||||
|
Matcher matcher = pattern.matcher(data);
|
||||||
|
return matcher.find() ? matcher.group(1).trim() : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
private String calculateNmeaCrc(String sentence) {
|
||||||
|
int crc = 0;
|
||||||
|
for (char c : sentence.toCharArray()) {
|
||||||
|
crc ^= (int) c;
|
||||||
|
}
|
||||||
|
return String.format("%02X", crc);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printQRCode(String sbxlh, String qrText) {
|
||||||
|
memPrinted.append("打印二维码: " + qrText + "\n");
|
||||||
|
// 实际调用打印机 SDK
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshToken() {
|
||||||
|
// 模拟刷新 Token
|
||||||
|
F_LOGIN_TOKEN_VALUE = "Bearer new_token_123";
|
||||||
|
memPrinted.append("Token 已刷新\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
// === 主函数 ===
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeel());
|
||||||
|
} catch (Exception ignored) {}
|
||||||
|
new HubForm().setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
@@ -0,0 +1,311 @@
|
|||||||
|
package unizk;
|
||||||
|
|
||||||
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import com.fazecast.jSerialComm.SerialPortDataListener;
|
||||||
|
import com.fazecast.jSerialComm.SerialPortEvent;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class HubForm3 extends JFrame {
|
||||||
|
private JComboBox<String> portComboBox;
|
||||||
|
private JTextField baudRateField;
|
||||||
|
private JButton connectButton;
|
||||||
|
private JButton sendCommandButton;
|
||||||
|
private JTextArea logArea;
|
||||||
|
private SerialPort selectedPort;
|
||||||
|
private final Object portLock = new Object();
|
||||||
|
private StringBuilder comResult = new StringBuilder();
|
||||||
|
private volatile boolean chkRead = true;
|
||||||
|
|
||||||
|
public HubForm3() {
|
||||||
|
// setTitle("云理疗设备入库系统");
|
||||||
|
setSize(800, 400);
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
// 顶部面板:串口设置
|
||||||
|
JPanel topPanel = new JPanel();
|
||||||
|
topPanel.setLayout(new FlowLayout());
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("串口:"));
|
||||||
|
portComboBox = new JComboBox<>();
|
||||||
|
refreshPorts();
|
||||||
|
topPanel.add(portComboBox);
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("波特率:"));
|
||||||
|
baudRateField = new JTextField("115200", 10);
|
||||||
|
topPanel.add(baudRateField);
|
||||||
|
|
||||||
|
connectButton = new JButton("打开串口");
|
||||||
|
connectButton.addActionListener(e -> toggleConnect());
|
||||||
|
topPanel.add(connectButton);
|
||||||
|
|
||||||
|
sendCommandButton = new JButton("获取设备信息");
|
||||||
|
sendCommandButton.addActionListener(e -> sendCommand());
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
topPanel.add(sendCommandButton);
|
||||||
|
|
||||||
|
JButton refreshButton = new JButton("刷新串口");
|
||||||
|
refreshButton.addActionListener(e -> refreshPorts());
|
||||||
|
topPanel.add(refreshButton);
|
||||||
|
|
||||||
|
add(topPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// 中间:日志显示
|
||||||
|
logArea = new JTextArea();
|
||||||
|
logArea.setEditable(false);
|
||||||
|
add(new JScrollPane(logArea), BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
log("请选择串口并点击【打开串口】");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshPorts() {
|
||||||
|
portComboBox.removeAllItems();
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
for (SerialPort port : ports) {
|
||||||
|
portComboBox.addItem(port.getSystemPortName() + " - " + port.getDescriptivePortName());
|
||||||
|
}
|
||||||
|
if (ports.length == 0) {
|
||||||
|
portComboBox.addItem("未找到串口");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleConnect() {
|
||||||
|
log("进入toggleConnect");
|
||||||
|
if (selectedPort != null && selectedPort.isOpen()) {
|
||||||
|
selectedPort.closePort();
|
||||||
|
selectedPort.removeDataListener();
|
||||||
|
selectedPort = null;
|
||||||
|
connectButton.setText("打开串口");
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
log("串口已关闭");
|
||||||
|
} else {
|
||||||
|
int selectedIndex = portComboBox.getSelectedIndex();
|
||||||
|
if (selectedIndex < 0) return;
|
||||||
|
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
if (selectedIndex >= ports.length) {
|
||||||
|
JOptionPane.showMessageDialog(this, "无效的串口选择");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedPort = ports[selectedIndex];
|
||||||
|
int baudRate;
|
||||||
|
try {
|
||||||
|
baudRate = Integer.parseInt(baudRateField.getText().trim());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
JOptionPane.showMessageDialog(this, "波特率格式错误");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPort.openPort()) {
|
||||||
|
selectedPort.setBaudRate(baudRate);
|
||||||
|
selectedPort.setNumDataBits(8);
|
||||||
|
selectedPort.setNumStopBits(1);
|
||||||
|
selectedPort.setParity(SerialPort.NO_PARITY);
|
||||||
|
selectedPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
|
||||||
|
|
||||||
|
// 添加监听器
|
||||||
|
selectedPort.addDataListener(new SerialPortDataListener() {
|
||||||
|
@Override
|
||||||
|
public int getListeningEvents() {
|
||||||
|
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialEvent(SerialPortEvent event) {
|
||||||
|
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE || !chkRead) return;
|
||||||
|
|
||||||
|
log("99999999");
|
||||||
|
|
||||||
|
byte[] newData = new byte[selectedPort.bytesAvailable()];
|
||||||
|
selectedPort.readBytes(newData, newData.length);
|
||||||
|
|
||||||
|
String dataStr = new String(newData, StandardCharsets.UTF_8);
|
||||||
|
comResult.append(dataStr.toUpperCase());
|
||||||
|
|
||||||
|
// 检查是否收到回车符(\r)
|
||||||
|
if (dataStr.contains("\r")) {
|
||||||
|
log("检查收到回车符");
|
||||||
|
chkRead = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connectButton.setText("关闭串口");
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
// log("串口 " + selectedPort.getSystemPortName() + " 打开成功,波特率: " + baudRate);
|
||||||
|
log("ababababab");
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(this, "无法打开串口");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logArea.append("尝试最多3次读取设备信息");
|
||||||
|
// 尝试最多3次读取设备信息
|
||||||
|
String comResultStr = null;
|
||||||
|
for (int i = 1; i <= 3; i++) {
|
||||||
|
chkRead = true;
|
||||||
|
comResult.setLength(0); // 清空
|
||||||
|
|
||||||
|
selectedPort.flushIOBuffers();
|
||||||
|
try {
|
||||||
|
Thread.sleep(100);
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
|
||||||
|
// 发送指令
|
||||||
|
String command = "$05||*05\r\n";
|
||||||
|
selectedPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
|
||||||
|
|
||||||
|
// 等待最多2秒
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
while (chkRead && (System.currentTimeMillis() - startTime < 2000)) {
|
||||||
|
try {
|
||||||
|
Thread.sleep(10);
|
||||||
|
} catch (InterruptedException ignored) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
comResultStr = comResult.toString().trim();
|
||||||
|
log("第 " + i + " 次响应: " + comResultStr + "\n");
|
||||||
|
|
||||||
|
if (comResultStr.contains("$05|") && comResultStr.contains("\r")) {
|
||||||
|
log("收到响应:"+comResultStr);
|
||||||
|
break; // 成功收到
|
||||||
|
} else {
|
||||||
|
if (i == 3) {
|
||||||
|
log("三次均未收到有效响应!\n");
|
||||||
|
selectedPort.closePort();
|
||||||
|
// btnPrint.setEnabled(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private void sendCommand() {
|
||||||
|
if (selectedPort == null || !selectedPort.isOpen()) {
|
||||||
|
log("串口未打开");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String command = "$05||*05\\r\\n"; // 根据设备协议修改命令
|
||||||
|
synchronized (portLock) {
|
||||||
|
int bytesWritten = selectedPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
|
||||||
|
log("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private void sendCommand() {
|
||||||
|
if (selectedPort == null || !selectedPort.isOpen()) {
|
||||||
|
log("串口未打开");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 禁用按钮,防止重复点击
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
log("正在发送命令...");
|
||||||
|
|
||||||
|
// 使用 SwingWorker 在后台线程执行串口操作
|
||||||
|
SwingWorker<String, String> worker = new SwingWorker<String, String>() {
|
||||||
|
@Override
|
||||||
|
protected String doInBackground() throws Exception {
|
||||||
|
String command = "$05||*05\r\n";
|
||||||
|
byte[] commandBytes = command.getBytes(StandardCharsets.US_ASCII);
|
||||||
|
|
||||||
|
// 发送命令
|
||||||
|
publish("selectedPort="+selectedPort.getNumDataBits());
|
||||||
|
int bytesWritten = selectedPort.writeBytes(commandBytes, commandBytes.length);
|
||||||
|
publish("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
|
||||||
|
|
||||||
|
// 设置超时时间(毫秒)
|
||||||
|
long timeout = 10000; // 10秒
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
|
||||||
|
// 循环读取,直到超时或收到完整响应(可根据协议优化)
|
||||||
|
while (System.currentTimeMillis() - startTime < timeout) {
|
||||||
|
synchronized (portLock) {
|
||||||
|
if (selectedPort.bytesAvailable() > 0) {
|
||||||
|
byte[] buffer = new byte[selectedPort.bytesAvailable()];
|
||||||
|
int len = selectedPort.readBytes(buffer, buffer.length);
|
||||||
|
String data = new String(buffer, 0, len, StandardCharsets.UTF_8);
|
||||||
|
response.append(data);
|
||||||
|
|
||||||
|
// 假设设备以换行符结束响应,可提前退出
|
||||||
|
if (data.contains("\r\n")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 小延迟避免 CPU 占用过高
|
||||||
|
Thread.sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.length() == 0) {
|
||||||
|
return "ERROR_TIMEOUT";
|
||||||
|
}
|
||||||
|
return response.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void process(List<String> chunks) {
|
||||||
|
for (String message : chunks) {
|
||||||
|
log(message); // 调用你的 log 方法(操作 JTextArea)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
// 重新启用按钮
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
|
||||||
|
try {
|
||||||
|
String result = get(); // 获取 doInBackground 的返回值
|
||||||
|
if ("ERROR_TIMEOUT".equals(result)) {
|
||||||
|
log("❌ 设备无响应,通信超时(10秒)");
|
||||||
|
JOptionPane.showMessageDialog(HubForm3.this,
|
||||||
|
"设备未响应,请检查连接或设备是否正常运行。",
|
||||||
|
"通信超时", JOptionPane.WARNING_MESSAGE);
|
||||||
|
} else {
|
||||||
|
log("✅ 响应: " + result);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log("❌ 通信异常: " + e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 启动后台任务
|
||||||
|
worker.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void log(String message) {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String format = LocalDateTime.now().format(formatter);
|
||||||
|
logArea.append("[" + format + "] " + message + "\n");
|
||||||
|
logArea.setCaretPosition(logArea.getDocument().getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 使用 SwingUtilities 确保线程安全
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
// 设置系统外观
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
new HubForm3().setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,230 @@
|
|||||||
|
package unizk;
|
||||||
|
|
||||||
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import com.google.zxing.BarcodeFormat;
|
||||||
|
import com.google.zxing.WriterException;
|
||||||
|
import com.google.zxing.client.j2se.MatrixToImageWriter;
|
||||||
|
import com.google.zxing.common.BitMatrix;
|
||||||
|
import com.google.zxing.qrcode.QRCodeWriter;
|
||||||
|
|
||||||
|
import javax.print.PrintService;
|
||||||
|
import javax.print.PrintServiceLookup;
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.print.PageFormat;
|
||||||
|
import java.awt.print.Printable;
|
||||||
|
import java.awt.print.PrinterException;
|
||||||
|
import java.awt.print.PrinterJob;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Author hao
|
||||||
|
* @Date 2026/7/28 15:51
|
||||||
|
* @Version 1.0
|
||||||
|
**/
|
||||||
|
public class PrintDemo extends JFrame {
|
||||||
|
private JComboBox<String> portComboBox;
|
||||||
|
private JTextField baudRateField;
|
||||||
|
private JButton connectButton;
|
||||||
|
private JButton printButton;
|
||||||
|
private JTextArea logArea;
|
||||||
|
private SerialPort selectedPort;
|
||||||
|
private final Object portLock = new Object();
|
||||||
|
private StringBuilder resultData = new StringBuilder();
|
||||||
|
|
||||||
|
// 添加打印机选择组件
|
||||||
|
private JComboBox<String> printerComboBox;
|
||||||
|
private JCheckBox showPrintDialogCheckBox;
|
||||||
|
|
||||||
|
public PrintDemo() {
|
||||||
|
setTitle("云理疗设备入库系统");
|
||||||
|
setSize(800, 500);
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
// 顶部面板:串口设置
|
||||||
|
JPanel topPanel = new JPanel();
|
||||||
|
topPanel.setLayout(new FlowLayout(FlowLayout.LEFT));
|
||||||
|
|
||||||
|
|
||||||
|
add(topPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// 中间面板:打印机设置 + 日志
|
||||||
|
JPanel centerPanel = new JPanel(new BorderLayout());
|
||||||
|
|
||||||
|
// 打印机设置面板
|
||||||
|
JPanel printerPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
|
||||||
|
printerPanel.setBorder(BorderFactory.createTitledBorder("打印设置"));
|
||||||
|
|
||||||
|
printerPanel.add(new JLabel("打印机:"));
|
||||||
|
printerComboBox = new JComboBox<>();
|
||||||
|
loadPrinters();
|
||||||
|
printerPanel.add(printerComboBox);
|
||||||
|
|
||||||
|
JButton refreshPrinterBtn = new JButton("刷新打印机");
|
||||||
|
refreshPrinterBtn.addActionListener(e -> loadPrinters());
|
||||||
|
printerPanel.add(refreshPrinterBtn);
|
||||||
|
|
||||||
|
printButton = new JButton("打印");
|
||||||
|
printButton.addActionListener(e -> printQRCode("hello"));
|
||||||
|
printerPanel.add(printButton);
|
||||||
|
|
||||||
|
/*showPrintDialogCheckBox = new JCheckBox("显示打印对话框", true);
|
||||||
|
printerPanel.add(showPrintDialogCheckBox);*/
|
||||||
|
|
||||||
|
centerPanel.add(printerPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// 日志区域
|
||||||
|
logArea = new JTextArea();
|
||||||
|
logArea.setEditable(false);
|
||||||
|
centerPanel.add(new JScrollPane(logArea), BorderLayout.CENTER);
|
||||||
|
|
||||||
|
add(centerPanel, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
log("请选择打印机打印");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void log(String message) {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String format = LocalDateTime.now().format(formatter);
|
||||||
|
logArea.append("[" + format + "] " + message + "\n");
|
||||||
|
logArea.setCaretPosition(logArea.getDocument().getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void loadPrinters() {
|
||||||
|
printerComboBox.removeAllItems();
|
||||||
|
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
|
||||||
|
for (PrintService service : printServices) {
|
||||||
|
printerComboBox.addItem(service.getName());
|
||||||
|
}
|
||||||
|
if (printServices.length == 0) {
|
||||||
|
printerComboBox.addItem("未找到打印机");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void printQRCode(String content) {
|
||||||
|
try {
|
||||||
|
// 1. 生成二维码图片
|
||||||
|
BufferedImage qrImage = generateQRCode(content, 300, 300);
|
||||||
|
log("二维码生成成功,尺寸: 300x300");
|
||||||
|
|
||||||
|
// 2. 获取选中的打印机
|
||||||
|
String printerName = (String) printerComboBox.getSelectedItem();
|
||||||
|
if (printerName == null || printerName.equals("未找到打印机")) {
|
||||||
|
int choice = JOptionPane.showConfirmDialog(this,
|
||||||
|
"未选择有效打印机,是否使用默认打印机继续?",
|
||||||
|
"打印机提示",
|
||||||
|
JOptionPane.YES_NO_OPTION);
|
||||||
|
if (choice != JOptionPane.YES_OPTION) {
|
||||||
|
log("用户取消打印");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
printerName = null; // 使用默认打印机
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 执行打印
|
||||||
|
// boolean showDialog = showPrintDialogCheckBox.isSelected();
|
||||||
|
printQRCodeDirectly(qrImage, printerName);
|
||||||
|
|
||||||
|
} catch (WriterException e) {
|
||||||
|
log("生成二维码失败: " + e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
"生成二维码失败: " + e.getMessage(),
|
||||||
|
"二维码生成错误",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
} catch (PrinterException e) {
|
||||||
|
log("打印失败: " + e.getMessage());
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
"打印失败: " + e.getMessage() + "\n请检查打印机是否连接正常。",
|
||||||
|
"打印错误",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log("打印过程异常: " + e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
JOptionPane.showMessageDialog(this,
|
||||||
|
"打印过程异常: " + e.getMessage(),
|
||||||
|
"异常",
|
||||||
|
JOptionPane.ERROR_MESSAGE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成二维码图片
|
||||||
|
*/
|
||||||
|
private BufferedImage generateQRCode(String content, int width, int height) throws WriterException {
|
||||||
|
QRCodeWriter qrCodeWriter = new QRCodeWriter();
|
||||||
|
BitMatrix bitMatrix = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height);
|
||||||
|
return MatrixToImageWriter.toBufferedImage(bitMatrix);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printQRCodeDirectly(BufferedImage qrImage, String printerName) throws PrinterException {
|
||||||
|
PrinterJob job = PrinterJob.getPrinterJob();
|
||||||
|
|
||||||
|
// 选择打印机
|
||||||
|
if (printerName != null && !printerName.isEmpty()) {
|
||||||
|
PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null);
|
||||||
|
for (PrintService service : printServices) {
|
||||||
|
if (service.getName().equals(printerName)) {
|
||||||
|
job.setPrintService(service);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 设置打印内容
|
||||||
|
job.setPrintable(new Printable() {
|
||||||
|
@Override
|
||||||
|
public int print(Graphics graphics, PageFormat pageFormat, int pageIndex) throws PrinterException {
|
||||||
|
if (pageIndex > 0) {
|
||||||
|
return NO_SUCH_PAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
Graphics2D g2d = (Graphics2D) graphics;
|
||||||
|
g2d.translate(pageFormat.getImageableX(), pageFormat.getImageableY());
|
||||||
|
|
||||||
|
double pageWidth = pageFormat.getImageableWidth();
|
||||||
|
double pageHeight = pageFormat.getImageableHeight();
|
||||||
|
int qrWidth = qrImage.getWidth();
|
||||||
|
int qrHeight = qrImage.getHeight();
|
||||||
|
|
||||||
|
if (qrWidth > pageWidth || qrHeight > pageHeight) {
|
||||||
|
double scaleX = pageWidth / qrWidth * 0.9;
|
||||||
|
double scaleY = pageHeight / qrHeight * 0.9;
|
||||||
|
double scale = Math.min(scaleX, scaleY);
|
||||||
|
int newWidth = (int) (qrWidth * scale);
|
||||||
|
int newHeight = (int) (qrHeight * scale);
|
||||||
|
int x = (int) ((pageWidth - newWidth) / 2);
|
||||||
|
int y = (int) ((pageHeight - newHeight) / 2);
|
||||||
|
g2d.drawImage(qrImage, x, y, newWidth, newHeight, null);
|
||||||
|
} else {
|
||||||
|
int x = (int) ((pageWidth - qrWidth) / 2);
|
||||||
|
int y = (int) ((pageHeight - qrHeight) / 2);
|
||||||
|
g2d.drawImage(qrImage, x, y, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
return PAGE_EXISTS;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// 直接打印
|
||||||
|
job.print();
|
||||||
|
log("直接打印任务已提交(无对话框)");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
// 设置系统外观
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
new PrintDemo().setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,265 @@
|
|||||||
|
package unizk;
|
||||||
|
|
||||||
|
import com.fazecast.jSerialComm.SerialPort;
|
||||||
|
import com.fazecast.jSerialComm.SerialPortDataListener;
|
||||||
|
import com.fazecast.jSerialComm.SerialPortEvent;
|
||||||
|
|
||||||
|
import javax.swing.*;
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
import java.time.format.DateTimeFormatter;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
|
public class SerialDeviceInfoApp extends JFrame {
|
||||||
|
private JComboBox<String> portComboBox;
|
||||||
|
private JTextField baudRateField;
|
||||||
|
private JButton connectButton;
|
||||||
|
private JButton sendCommandButton;
|
||||||
|
private JTextArea logArea;
|
||||||
|
private SerialPort selectedPort;
|
||||||
|
private final Object portLock = new Object();
|
||||||
|
private StringBuilder resultData = new StringBuilder();
|
||||||
|
|
||||||
|
public SerialDeviceInfoApp() {
|
||||||
|
setTitle("云理疗设备入库系统");
|
||||||
|
setSize(800, 400);
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setLayout(new BorderLayout());
|
||||||
|
|
||||||
|
// 顶部面板:串口设置
|
||||||
|
JPanel topPanel = new JPanel();
|
||||||
|
topPanel.setLayout(new FlowLayout());
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("串口:"));
|
||||||
|
portComboBox = new JComboBox<>();
|
||||||
|
refreshPorts();
|
||||||
|
topPanel.add(portComboBox);
|
||||||
|
|
||||||
|
topPanel.add(new JLabel("波特率:"));
|
||||||
|
baudRateField = new JTextField("115200", 10);
|
||||||
|
topPanel.add(baudRateField);
|
||||||
|
|
||||||
|
connectButton = new JButton("打开串口");
|
||||||
|
connectButton.addActionListener(e -> toggleConnect());
|
||||||
|
topPanel.add(connectButton);
|
||||||
|
|
||||||
|
sendCommandButton = new JButton("获取设备信息");
|
||||||
|
sendCommandButton.addActionListener(e -> sendCommand());
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
topPanel.add(sendCommandButton);
|
||||||
|
|
||||||
|
JButton refreshButton = new JButton("刷新串口");
|
||||||
|
refreshButton.addActionListener(e -> refreshPorts());
|
||||||
|
topPanel.add(refreshButton);
|
||||||
|
|
||||||
|
add(topPanel, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
// 中间:日志显示
|
||||||
|
logArea = new JTextArea();
|
||||||
|
logArea.setEditable(false);
|
||||||
|
add(new JScrollPane(logArea), BorderLayout.CENTER);
|
||||||
|
|
||||||
|
// 初始化
|
||||||
|
log("请选择串口并点击【打开串口】");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void refreshPorts() {
|
||||||
|
portComboBox.removeAllItems();
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
for (SerialPort port : ports) {
|
||||||
|
portComboBox.addItem(port.getSystemPortName() + " - " + port.getDescriptivePortName());
|
||||||
|
}
|
||||||
|
if (ports.length == 0) {
|
||||||
|
portComboBox.addItem("未找到串口");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void toggleConnect() {
|
||||||
|
if (selectedPort != null && selectedPort.isOpen()) {
|
||||||
|
selectedPort.closePort();
|
||||||
|
selectedPort.removeDataListener();
|
||||||
|
selectedPort = null;
|
||||||
|
connectButton.setText("打开串口");
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
log("串口已关闭");
|
||||||
|
} else {
|
||||||
|
int selectedIndex = portComboBox.getSelectedIndex();
|
||||||
|
if (selectedIndex < 0) return;
|
||||||
|
|
||||||
|
SerialPort[] ports = SerialPort.getCommPorts();
|
||||||
|
if (selectedIndex >= ports.length) {
|
||||||
|
JOptionPane.showMessageDialog(this, "无效的串口选择");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedPort = ports[selectedIndex];
|
||||||
|
int baudRate;
|
||||||
|
try {
|
||||||
|
baudRate = Integer.parseInt(baudRateField.getText().trim());
|
||||||
|
} catch (NumberFormatException e) {
|
||||||
|
JOptionPane.showMessageDialog(this, "波特率格式错误");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (selectedPort.openPort()) {
|
||||||
|
selectedPort.setBaudRate(baudRate);
|
||||||
|
selectedPort.setNumDataBits(8);
|
||||||
|
selectedPort.setNumStopBits(1);
|
||||||
|
selectedPort.setParity(SerialPort.NO_PARITY);
|
||||||
|
selectedPort.setComPortTimeouts(SerialPort.TIMEOUT_READ_SEMI_BLOCKING, 2000, 0);
|
||||||
|
|
||||||
|
// 添加监听器
|
||||||
|
selectedPort.addDataListener(new SerialPortDataListener() {
|
||||||
|
@Override
|
||||||
|
public int getListeningEvents() {
|
||||||
|
return SerialPort.LISTENING_EVENT_DATA_AVAILABLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void serialEvent(SerialPortEvent event) {
|
||||||
|
if (event.getEventType() != SerialPort.LISTENING_EVENT_DATA_AVAILABLE) return;
|
||||||
|
|
||||||
|
synchronized (portLock) {
|
||||||
|
byte[] newData = new byte[selectedPort.bytesAvailable()];
|
||||||
|
int len = selectedPort.readBytes(newData, newData.length);
|
||||||
|
String data = new String(newData, 0, len, StandardCharsets.UTF_8);
|
||||||
|
log("收到: " + data.trim());
|
||||||
|
resultData.append(data.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
connectButton.setText("关闭串口");
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
log("串口 " + selectedPort.getSystemPortName() + " 打开成功,波特率: " + baudRate);
|
||||||
|
} else {
|
||||||
|
JOptionPane.showMessageDialog(this, "无法打开串口");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
log("-----reslut1==="+resultData.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private void sendCommand() {
|
||||||
|
if (selectedPort == null || !selectedPort.isOpen()) {
|
||||||
|
log("串口未打开");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
String command = "$05||*05\\r\\n"; // 根据设备协议修改命令
|
||||||
|
synchronized (portLock) {
|
||||||
|
int bytesWritten = selectedPort.writeBytes(command.getBytes(StandardCharsets.UTF_8), command.length());
|
||||||
|
log("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
private void sendCommand() {
|
||||||
|
if (selectedPort == null || !selectedPort.isOpen()) {
|
||||||
|
log("串口未打开");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 禁用按钮,防止重复点击
|
||||||
|
sendCommandButton.setEnabled(false);
|
||||||
|
log("正在发送命令...");
|
||||||
|
|
||||||
|
// 使用 SwingWorker 在后台线程执行串口操作
|
||||||
|
SwingWorker<String, String> worker = new SwingWorker<String, String>() {
|
||||||
|
@Override
|
||||||
|
protected String doInBackground() throws Exception {
|
||||||
|
String command = "$05||*05\r\n";
|
||||||
|
byte[] commandBytes = command.getBytes(StandardCharsets.US_ASCII);
|
||||||
|
|
||||||
|
// 发送命令
|
||||||
|
publish("selectedPort="+selectedPort.getNumDataBits());
|
||||||
|
int bytesWritten = selectedPort.writeBytes(commandBytes, commandBytes.length);
|
||||||
|
publish("发送: " + command.trim() + " (" + bytesWritten + " 字节)");
|
||||||
|
|
||||||
|
// 设置超时时间(毫秒)
|
||||||
|
long timeout = 10000; // 10秒
|
||||||
|
long startTime = System.currentTimeMillis();
|
||||||
|
StringBuilder response = new StringBuilder();
|
||||||
|
|
||||||
|
// 循环读取,直到超时或收到完整响应(可根据协议优化)
|
||||||
|
while (System.currentTimeMillis() - startTime < timeout) {
|
||||||
|
synchronized (portLock) {
|
||||||
|
if (selectedPort.bytesAvailable() > 0) {
|
||||||
|
byte[] buffer = new byte[selectedPort.bytesAvailable()];
|
||||||
|
int len = selectedPort.readBytes(buffer, buffer.length);
|
||||||
|
String data = new String(buffer, 0, len, StandardCharsets.UTF_8);
|
||||||
|
response.append(data);
|
||||||
|
|
||||||
|
// 假设设备以换行符结束响应,可提前退出
|
||||||
|
if (data.contains("\r\n")) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 小延迟避免 CPU 占用过高
|
||||||
|
Thread.sleep(10);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (response.length() == 0) {
|
||||||
|
return "ERROR_TIMEOUT";
|
||||||
|
}
|
||||||
|
return response.toString().trim();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void process(List<String> chunks) {
|
||||||
|
for (String message : chunks) {
|
||||||
|
log(message); // 调用你的 log 方法(操作 JTextArea)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void done() {
|
||||||
|
log("-----reslut2==="+resultData.toString());
|
||||||
|
// 重新启用按钮
|
||||||
|
sendCommandButton.setEnabled(true);
|
||||||
|
|
||||||
|
/* try {
|
||||||
|
String result = get(); // 获取 doInBackground 的返回值
|
||||||
|
log("result=" + result);
|
||||||
|
if ("ERROR_TIMEOUT".equals(result)) {
|
||||||
|
log("❌ 设备无响应,通信超时(10秒)");
|
||||||
|
JOptionPane.showMessageDialog(SerialDeviceInfoApp.this,
|
||||||
|
"设备未响应,请检查连接或设备是否正常运行。",
|
||||||
|
"通信超时", JOptionPane.WARNING_MESSAGE);
|
||||||
|
} else {
|
||||||
|
log("✅ 响应: " + result);
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
log("❌ 通信异常: " + e.getMessage());
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
// 启动后台任务
|
||||||
|
worker.execute();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void log(String message) {
|
||||||
|
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
|
||||||
|
String format = LocalDateTime.now().format(formatter);
|
||||||
|
logArea.append("[" + format + "] " + message + "\n");
|
||||||
|
logArea.setCaretPosition(logArea.getDocument().getLength());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// 使用 SwingUtilities 确保线程安全
|
||||||
|
SwingUtilities.invokeLater(() -> {
|
||||||
|
try {
|
||||||
|
// 设置系统外观
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
new SerialDeviceInfoApp().setVisible(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,60 @@
|
|||||||
|
package unizk.utils;
|
||||||
|
|
||||||
|
import javax.crypto.Cipher;
|
||||||
|
import javax.crypto.KeyGenerator;
|
||||||
|
import javax.crypto.SecretKey;
|
||||||
|
import javax.crypto.spec.SecretKeySpec;
|
||||||
|
import javax.crypto.spec.IvParameterSpec;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.Base64;
|
||||||
|
|
||||||
|
|
||||||
|
public class AESUtil {
|
||||||
|
|
||||||
|
private static final String ALGORITHM = "AES";
|
||||||
|
private static final String TRANSFORMATION = "AES/CBC/PKCS5Padding"; // 模式:CBC + 填充
|
||||||
|
|
||||||
|
// 注意:密钥必须是 16/24/32 字节,对应 128/192/256 位
|
||||||
|
private static final String SECRET_KEY = "Unizk.&jkzy@2025"; // 16 字节 = 128 位
|
||||||
|
private static final String IV = "2vCnQxrSXMlLzsen"; // 初始化向量,16 字节
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 加密
|
||||||
|
*/
|
||||||
|
public static String encrypt(String plainText) throws Exception {
|
||||||
|
// 创建密钥
|
||||||
|
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes("UTF-8"), ALGORITHM);
|
||||||
|
|
||||||
|
// 创建初始化向量
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
// 获取 Cipher 实例
|
||||||
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
|
cipher.init(Cipher.ENCRYPT_MODE, keySpec, ivSpec);
|
||||||
|
|
||||||
|
// 执行加密
|
||||||
|
byte[] encrypted = cipher.doFinal(plainText.getBytes("UTF-8"));
|
||||||
|
|
||||||
|
// Base64 编码返回
|
||||||
|
return Base64.getEncoder().encodeToString(encrypted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* AES 解密
|
||||||
|
*/
|
||||||
|
public static String decrypt(String encryptedText) throws Exception {
|
||||||
|
SecretKeySpec keySpec = new SecretKeySpec(SECRET_KEY.getBytes(StandardCharsets.UTF_8), ALGORITHM);
|
||||||
|
IvParameterSpec ivSpec = new IvParameterSpec(IV.getBytes(StandardCharsets.UTF_8));
|
||||||
|
|
||||||
|
Cipher cipher = Cipher.getInstance(TRANSFORMATION);
|
||||||
|
cipher.init(Cipher.DECRYPT_MODE, keySpec, ivSpec);
|
||||||
|
|
||||||
|
// Base64 解码
|
||||||
|
byte[] decoded = Base64.getDecoder().decode(encryptedText);
|
||||||
|
byte[] decrypted = cipher.doFinal(decoded);
|
||||||
|
|
||||||
|
return new String(decrypted, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,241 @@
|
|||||||
|
package unizk.utils;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson2.JSONObject;
|
||||||
|
import org.apache.http.HttpEntity;
|
||||||
|
import org.apache.http.NameValuePair;
|
||||||
|
import org.apache.http.client.config.RequestConfig;
|
||||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity;
|
||||||
|
import org.apache.http.client.methods.CloseableHttpResponse;
|
||||||
|
import org.apache.http.client.methods.HttpGet;
|
||||||
|
import org.apache.http.client.methods.HttpPost;
|
||||||
|
import org.apache.http.client.methods.HttpRequestBase;
|
||||||
|
import org.apache.http.client.utils.URIBuilder;
|
||||||
|
import org.apache.http.entity.ContentType;
|
||||||
|
import org.apache.http.entity.StringEntity;
|
||||||
|
import org.apache.http.impl.client.CloseableHttpClient;
|
||||||
|
import org.apache.http.impl.client.HttpClients;
|
||||||
|
import org.apache.http.message.BasicNameValuePair;
|
||||||
|
import org.apache.http.util.EntityUtils;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.net.URISyntaxException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
public class HttpUtil {
|
||||||
|
|
||||||
|
private static final String URL_CONCATENATION = "url-concatenation";
|
||||||
|
private static final String FORM_URLENCODED = "form-urlencoded";
|
||||||
|
private static final String JSON_BODY = "json";
|
||||||
|
|
||||||
|
public static final String STATUS_CODE = "code";
|
||||||
|
public static final String RESPONSE = "res";
|
||||||
|
|
||||||
|
// 私有构造器防止实例化
|
||||||
|
private HttpUtil() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET 请求(带 headers 和 params)
|
||||||
|
*/
|
||||||
|
public static String doGet(String url, Map<String, String> headers, Map<String, String> params) {
|
||||||
|
return doHttpRequest(url, headers, params, HttpMethod.GET, URL_CONCATENATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST 请求 - 默认以 JSON 格式发送 body
|
||||||
|
*/
|
||||||
|
public static String doPost(String url, Map<String, String> headers, Map<String, String> params) {
|
||||||
|
return doHttpRequest(url, headers, params, HttpMethod.POST, JSON_BODY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST 请求 - 使用 URL 拼接方式传递参数
|
||||||
|
*/
|
||||||
|
public static String doPostWithUrlParams(String url, Map<String, String> headers, Map<String, String> params) {
|
||||||
|
return doHttpRequest(url, headers, params, HttpMethod.POST, URL_CONCATENATION);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST 请求 - 使用 application/x-www-form-urlencoded 格式
|
||||||
|
*/
|
||||||
|
public static String doPostFormUrlencoded(String url, Map<String, String> headers, Map<String, String> params) {
|
||||||
|
return doHttpRequest(url, headers, params, HttpMethod.POST, FORM_URLENCODED);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST 请求 - 发送原始 JSON 字符串(适合复杂结构)
|
||||||
|
*/
|
||||||
|
public static String doPostJson(String url, Map<String, String> headers, JSONObject jsonObject) {
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost post = new HttpPost(url);
|
||||||
|
addHeaders(post, headers);
|
||||||
|
|
||||||
|
StringEntity entity = new StringEntity(
|
||||||
|
jsonObject.toString(),
|
||||||
|
ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
|
||||||
|
);
|
||||||
|
post.setEntity(entity);
|
||||||
|
|
||||||
|
try (CloseableHttpResponse response = httpClient.execute(post)) {
|
||||||
|
if (response.getEntity() == null){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
return EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("HTTP POST JSON request error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static byte[] postRtnBytes(String url, Map<String, String> headers, JSONObject jsonObject){
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost request = new HttpPost(url);
|
||||||
|
StringEntity entity = new StringEntity(
|
||||||
|
jsonObject.toString(),
|
||||||
|
ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
|
||||||
|
);
|
||||||
|
request.setEntity(entity);
|
||||||
|
|
||||||
|
try (CloseableHttpResponse response = httpClient.execute(request)) {
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode(); // HTTP 状态码
|
||||||
|
if (statusCode == 200) {
|
||||||
|
// 获取响应体输入流
|
||||||
|
InputStream inputStream = response.getEntity().getContent();
|
||||||
|
|
||||||
|
// 将输入流读取为 byte[]
|
||||||
|
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
|
||||||
|
int nRead;
|
||||||
|
byte[] data = new byte[4096];
|
||||||
|
while ((nRead = inputStream.read(data, 0, data.length)) != -1) {
|
||||||
|
buffer.write(data, 0, nRead);
|
||||||
|
}
|
||||||
|
buffer.flush();
|
||||||
|
|
||||||
|
return buffer.toByteArray(); // 返回 byte[] 缓冲区
|
||||||
|
} else {
|
||||||
|
throw new IOException("HTTP error: " + statusCode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}catch (IOException e){
|
||||||
|
throw new RuntimeException("HTTP POST JSON request error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 返回状态码
|
||||||
|
* @param url
|
||||||
|
* @param headers
|
||||||
|
* @param jsonObject
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static JSONObject postJsonCarryStatusCode(String url, Map<String, String> headers, JSONObject jsonObject) {
|
||||||
|
try (CloseableHttpClient httpClient = HttpClients.createDefault()) {
|
||||||
|
HttpPost post = new HttpPost(url);
|
||||||
|
addHeaders(post, headers);
|
||||||
|
|
||||||
|
StringEntity entity = new StringEntity(
|
||||||
|
jsonObject.toString(),
|
||||||
|
ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
|
||||||
|
);
|
||||||
|
post.setEntity(entity);
|
||||||
|
|
||||||
|
try (CloseableHttpResponse response = httpClient.execute(post)) {
|
||||||
|
int statusCode = response.getStatusLine().getStatusCode();
|
||||||
|
if (response.getEntity() != null){
|
||||||
|
String data = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
|
||||||
|
return JSONObject.of(HttpUtil.STATUS_CODE,statusCode,HttpUtil.RESPONSE,data);
|
||||||
|
}
|
||||||
|
return JSONObject.of(HttpUtil.STATUS_CODE,statusCode,HttpUtil.RESPONSE,null);
|
||||||
|
}
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("HTTP POST JSON request error", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 通用 HTTP 请求方法
|
||||||
|
*/
|
||||||
|
private static String doHttpRequest(String url, Map<String, String> headers,
|
||||||
|
Map<String, String> params, HttpMethod method, String paramType) {
|
||||||
|
List<NameValuePair> pairList = new ArrayList<>();
|
||||||
|
if (params != null && !params.isEmpty()) {
|
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
|
pairList.add(new BasicNameValuePair(entry.getKey(), entry.getValue()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RequestConfig requestConfig = RequestConfig.custom()
|
||||||
|
.setConnectTimeout(5000) // 连接超时 5秒
|
||||||
|
.setSocketTimeout(10000) // 读取超时 10秒
|
||||||
|
.setConnectionRequestTimeout(2000) // 从连接池获取连接超时 2秒
|
||||||
|
.build();
|
||||||
|
try (CloseableHttpClient client = HttpClients.createDefault()) {
|
||||||
|
HttpRequestBase request = createHttpRequest(url, method, params, pairList, paramType);
|
||||||
|
addHeaders(request, headers);
|
||||||
|
request.setConfig(requestConfig);
|
||||||
|
|
||||||
|
try (CloseableHttpResponse response = client.execute(request)) {
|
||||||
|
HttpEntity entity = response.getEntity();
|
||||||
|
return entity == null ? null : EntityUtils.toString(entity, StandardCharsets.UTF_8);
|
||||||
|
}
|
||||||
|
} catch (IOException | URISyntaxException e) {
|
||||||
|
throw new RuntimeException("HTTP request error: " + url, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 构建 HTTP 请求对象(GET / POST)
|
||||||
|
*/
|
||||||
|
private static HttpRequestBase createHttpRequest(String url, HttpMethod method,
|
||||||
|
Map<String, String> params,
|
||||||
|
List<NameValuePair> pairList,
|
||||||
|
String paramType) throws URISyntaxException {
|
||||||
|
if (method == HttpMethod.GET) {
|
||||||
|
URIBuilder uriBuilder = new URIBuilder(url);
|
||||||
|
if (paramType.equals(URL_CONCATENATION) && params != null && !params.isEmpty()) {
|
||||||
|
for (Map.Entry<String, String> entry : params.entrySet()) {
|
||||||
|
uriBuilder.addParameter(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new HttpGet(uriBuilder.build());
|
||||||
|
} else if (method == HttpMethod.POST) {
|
||||||
|
HttpPost post = new HttpPost(url);
|
||||||
|
|
||||||
|
if (paramType.equals(FORM_URLENCODED)) {
|
||||||
|
post.setEntity(new UrlEncodedFormEntity(pairList, StandardCharsets.UTF_8));
|
||||||
|
} else if (paramType.equals(JSON_BODY)) {
|
||||||
|
JSONObject json = new JSONObject(params);
|
||||||
|
StringEntity entity = new StringEntity(
|
||||||
|
json.toString(),
|
||||||
|
ContentType.APPLICATION_JSON.withCharset(StandardCharsets.UTF_8)
|
||||||
|
);
|
||||||
|
post.setEntity(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
return post;
|
||||||
|
}
|
||||||
|
throw new IllegalArgumentException("Unsupported HTTP method: " + method);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 添加请求头
|
||||||
|
*/
|
||||||
|
private static void addHeaders(HttpRequestBase request, Map<String, String> headers) {
|
||||||
|
if (headers != null && !headers.isEmpty()) {
|
||||||
|
for (Map.Entry<String, String> entry : headers.entrySet()) {
|
||||||
|
request.addHeader(entry.getKey(), entry.getValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 枚举类型定义
|
||||||
|
public enum HttpMethod {
|
||||||
|
GET, POST
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,3 @@
|
|||||||
|
artifactId=device-to-db2
|
||||||
|
groupId=unizk
|
||||||
|
version=1.0.0
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
unizk\HubForm$1.class
|
||||||
|
unizk\Demo1$4.class
|
||||||
|
unizk\SerialDeviceInfoApp.class
|
||||||
|
unizk\Demo1$3.class
|
||||||
|
unizk\Demo1$2.class
|
||||||
|
unizk\HubForm3$2.class
|
||||||
|
unizk\HubForm$2.class
|
||||||
|
unizk\HubForm$DeviceInfo.class
|
||||||
|
unizk\utils\HttpUtil.class
|
||||||
|
unizk\Demo1.class
|
||||||
|
unizk\SerialDeviceInfoApp$2.class
|
||||||
|
unizk\HubForm3$1.class
|
||||||
|
unizk\SerialDeviceInfoApp$1.class
|
||||||
|
unizk\HubForm3.class
|
||||||
|
unizk\utils\HttpUtil$HttpMethod.class
|
||||||
|
unizk\Demo1$1.class
|
||||||
|
unizk\PrintDemo.class
|
||||||
|
unizk\Demo1$5.class
|
||||||
|
unizk\HubForm.class
|
||||||
|
unizk\utils\AESUtil.class
|
||||||
|
unizk\PrintDemo$1.class
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\Demo1.java
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\utils\HttpUtil.java
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\HubForm2.java
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\PrintDemo.java
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\SerialDeviceInfoApp.java
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\utils\AESUtil.java
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\HubForm.java
|
||||||
|
D:\Workspace\uniaihealth\device-to-db2\src\main\java\unizk\HubForm3.java
|
||||||
Reference in new issue
Block a user