diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/ReadMe.md" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/ReadMe.md"
new file mode 100644
index 0000000000000000000000000000000000000000..f2f45816668b80d03309dba94f1f704da1ab34b7
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/ReadMe.md"
@@ -0,0 +1,21 @@
+# 二维码应用工程
+
+
+## 一、文件版二维码生成
+
+ 1. 选择需要生成二维码图片的原始文本文件,主要包含包含xml、java、yaml、md等
+ 2. 读取选择的文件文本内容,转换成二维码图片
+
+
+
+
+
+
+## 注意
+
+如JFrame打成jar后,系统图标不显示,请确认在jar根目录下是否存在 /img/icon.gif, 原因可能为resources文件夹设置有问题,eg: Excluded:*
+
+## 二、文字版二维码生成
+
+
+
\ No newline at end of file
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr001.png" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr001.png"
new file mode 100644
index 0000000000000000000000000000000000000000..34ea2789367ff9c2014d755f94b3910c6273dc37
Binary files /dev/null and "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr001.png" differ
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr002.png" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr002.png"
new file mode 100644
index 0000000000000000000000000000000000000000..d5bf0ccb8f28f5dd091707e761cc597c8282525a
Binary files /dev/null and "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr002.png" differ
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr003.png" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr003.png"
new file mode 100644
index 0000000000000000000000000000000000000000..b6dc2e8d7376d0d0a3c8ee89e6f479b0215d2953
Binary files /dev/null and "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/images/qr003.png" differ
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/pom-simple.xml" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/pom-simple.xml"
new file mode 100644
index 0000000000000000000000000000000000000000..8f807196c951e4a1aa1c163f90c1f7583e178f8b
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/pom-simple.xml"
@@ -0,0 +1,83 @@
+
+
+ 4.0.0
+ com.fly
+ qrcode-ui
+ 0.0.1
+ file-to-qrcode
+ http://maven.apache.org
+ jar
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 2.12.1
+
+
+
+ com.google.zxing
+ core
+ 3.4.1
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ ${log4j.version}
+
+
+ org.projectlombok
+ lombok
+ 1.18.12
+ provided
+
+
+ commons-io
+ commons-io
+ 2.6
+
+
+ org.apache.commons
+ commons-lang3
+ 3.5
+
+
+
+
+ qrcode-simple
+
+
+ maven-compiler-plugin
+ 3.7.0
+
+ 1.8
+ 1.8
+
+
+
+ maven-assembly-plugin
+ 3.5.0
+
+ false
+
+
+ com.fly.ui.SimpleQrCodeUI
+
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/pom.xml" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/pom.xml"
new file mode 100644
index 0000000000000000000000000000000000000000..d157f6bd10458ae26a09886eeab87e374158073c
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/pom.xml"
@@ -0,0 +1,83 @@
+
+
+ 4.0.0
+ com.fly
+ qrcode-ui
+ 0.0.1
+ file-to-qrcode
+ http://maven.apache.org
+ jar
+
+
+ UTF-8
+ UTF-8
+ 1.8
+ 2.12.1
+
+
+
+ com.google.zxing
+ core
+ 3.4.1
+
+
+ org.apache.logging.log4j
+ log4j-slf4j-impl
+ ${log4j.version}
+
+
+ org.projectlombok
+ lombok
+ 1.18.12
+ provided
+
+
+ commons-io
+ commons-io
+ 2.6
+
+
+ org.apache.commons
+ commons-lang3
+ 3.5
+
+
+
+
+ ${project.artifactId}-${project.version}
+
+
+ maven-compiler-plugin
+ 3.7.0
+
+ 1.8
+ 1.8
+
+
+
+ maven-assembly-plugin
+ 3.5.0
+
+ false
+
+
+ com.fly.MainRun
+
+
+
+ jar-with-dependencies
+
+
+
+
+ make-assembly
+ package
+
+ single
+
+
+
+
+
+
+
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/MainRun.java" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/MainRun.java"
new file mode 100644
index 0000000000000000000000000000000000000000..6a8e1566d087c8484062ef736180dccece58cbf7
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/MainRun.java"
@@ -0,0 +1,30 @@
+package com.fly;
+
+import javax.swing.SwingUtilities;
+
+import org.apache.commons.lang3.RandomUtils;
+
+import com.fly.ui.QrCodeUI;
+import com.fly.ui.SimpleQrCodeUI;
+
+/**
+ *
+ * MainRun
+ *
+ * @author 00fly
+ * @version [版本号, 2023年3月5日]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+public class MainRun
+{
+ public static void main(String[] args)
+ {
+ if (RandomUtils.nextBoolean())
+ {
+ SwingUtilities.invokeLater(() -> new QrCodeUI());
+ return;
+ }
+ SwingUtilities.invokeLater(() -> new SimpleQrCodeUI());
+ }
+}
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/QrCodeUI.java" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/QrCodeUI.java"
new file mode 100644
index 0000000000000000000000000000000000000000..fb44c170d720c791f70b86f3d13a6b3fba8670b1
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/QrCodeUI.java"
@@ -0,0 +1,245 @@
+package com.fly.ui;
+
+import java.awt.Dimension;
+import java.awt.Image;
+import java.awt.event.ActionEvent;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.io.IOException;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.stream.Stream;
+
+import javax.swing.JButton;
+import javax.swing.JFileChooser;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JMenu;
+import javax.swing.JMenuBar;
+import javax.swing.JMenuItem;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+import javax.swing.filechooser.FileFilter;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.commons.lang3.StringUtils;
+
+import com.fly.utils.QRCodeUtil;
+
+/*****
+ * 界面操作展示类
+ */
+public class QrCodeUI extends JFrame
+{
+ private static final long serialVersionUID = -9154321945329564644L;
+
+ // 界面组件
+ JPanel panel = new JPanel();
+
+ JTextArea textArea = new JTextArea();
+
+ JTextField fileText = new JTextField(null, 40);
+
+ JButton fileDirBrowse = new JButton("请选择");
+
+ JButton removeButton = new JButton("清除空白行及空格");
+
+ JButton qrButton = new JButton(" 生 成 二 维 码 ");
+
+ JButton clearButton = new JButton(" 清 除 内 容 ");
+
+ String[] acceptSuffix = {".xml", ".java", ".yml", ".yaml", ".md", ".txt"};
+
+ // 构造函数
+ public QrCodeUI()
+ {
+ // 加载图标
+ URL imgURL = getClass().getResource("/img/icon.gif");
+ if (imgURL != null)
+ {
+ Image image = getToolkit().createImage(imgURL);
+ setIconImage(image);
+ }
+ setTitle("二维码应用工具 V1.0");
+ setSize(900, 550);
+ Dimension screenSize = getToolkit().getScreenSize();
+ Dimension frameSize = this.getSize();
+ frameSize.height = Math.min(screenSize.height, frameSize.height);
+ frameSize.width = Math.min(screenSize.width, frameSize.width);
+ setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2);
+ addMenu();
+ addButton();
+ try
+ {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+ SwingUtilities.updateComponentTreeUI(this);
+ }
+ catch (Exception e)
+ {
+ }
+ setResizable(false);
+ setVisible(true);
+ setDefaultCloseOperation(EXIT_ON_CLOSE);
+ fileText.setFocusable(false);
+ }
+
+ // Menu set
+ private void addMenu()
+ {
+ JMenuBar mb = new JMenuBar();
+ // 一级菜单
+ JMenu conf = new JMenu(" 系 统 ");
+ // 子菜单
+ JMenuItem exit = new JMenuItem("退出");
+ exit.addActionListener(event -> System.exit(0));
+ conf.add(exit);
+ mb.add(conf);
+ JMenu help = new JMenu(" 帮 助 ");
+ JMenuItem about = new JMenuItem("关于工具");
+ about.addActionListener((ActionEvent event) -> JOptionPane.showMessageDialog(null, "二维码应用工具 V1.0,00fly 于2023年3月。\n", "关于本工具", JOptionPane.INFORMATION_MESSAGE));
+ help.add(about);
+ mb.add(help);
+ setJMenuBar(mb);
+ }
+
+ // JButton set
+ private void addButton()
+ {
+ panel.setLayout(null);
+ getContentPane().add(panel);
+
+ JLabel textLabel = new JLabel("文件内容");
+ textLabel.setBounds(20, 10, 120, 18);
+ panel.add(textLabel);
+
+ JLabel fileLabel = new JLabel(" 待生成QR原始文件");
+ fileLabel.setBounds(30, 410, 240, 18);
+ panel.add(fileLabel);
+
+ textArea.setEditable(false);
+
+ JScrollPane scroll = new JScrollPane(textArea);
+ scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+ scroll.setBounds(20, 30, 850, 360);
+ panel.add(scroll);
+
+ fileText.setBounds(150, 410, 450, 24);
+ fileText.setText(new File(" ").getAbsolutePath().trim());
+ fileText.setToolTipText("选择需要生成二维码图片的原始文本文件,包含xml、java、yaml、md等");
+ panel.add(fileText);
+ fileDirBrowse.setBounds(610, 410, 80, 25);
+ fileDirBrowse.setToolTipText("选择需要生成二维码图片的原始文本文件,包含xml、java、yaml、md等");
+ fileDirBrowse.addActionListener(event -> {
+ String path = fileText.getText();
+ File xmlfile = new File(path);
+ if (new File(fileText.getText()).exists())
+ {
+ xmlfile = new File(path).getParentFile();
+ }
+ JFileChooser fc = new JFileChooser(xmlfile);
+ fc.setFileSelectionMode(JFileChooser.FILES_ONLY);
+ fc.setDialogTitle("原始文件选择");
+ if (fc.showOpenDialog(null) == JFileChooser.CANCEL_OPTION)
+ {
+ return;
+ }
+ fc.setFileFilter(new FileFilter()
+ {
+ @Override
+ public boolean accept(File file)
+ {
+ String name = file.getName().toLowerCase();
+ return Stream.of(acceptSuffix).anyMatch(t -> name.endsWith(t));
+ }
+
+ @Override
+ public String getDescription()
+ {
+ return "";
+ }
+ });
+ File f = fc.getSelectedFile();
+ if (f != null && f.isFile())
+ {
+ fileText.setText(f.getAbsolutePath());
+ try
+ {
+ textArea.setText(FileUtils.readFileToString(f, StandardCharsets.UTF_8));
+ qrButton.setEnabled(true);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ });
+ panel.add(fileDirBrowse);
+
+ removeButton.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ String content = textArea.getText();
+ if (StringUtils.isNotBlank(content))
+ {
+ content = content.replaceAll("\t", " ").replaceAll("((\r\n)|\n)[\\s\t ]*(\\1)+", "$1");
+ textArea.setText(content);
+ }
+ }
+ });
+ removeButton.setBounds(100, 450, 160, 30);
+ removeButton.add(qrButton);
+ panel.add(removeButton);
+
+ qrButton.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ if (!qrButton.isEnabled())
+ {
+ return;
+ }
+ try
+ {
+ String content = textArea.getText();
+ BufferedImage image = QRCodeUtil.createImage(content, null, false);
+ new ShowDialog(image);
+ }
+ catch (Exception e1)
+ {
+ JOptionPane.showMessageDialog(null, "失败原因: " + e1.getMessage(), "二维码生成失败", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ });
+ qrButton.setBounds(350, 450, 160, 30);
+ qrButton.setEnabled(false);
+ panel.add(qrButton);
+
+ clearButton.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ textArea.setText(null);
+ qrButton.setEnabled(false);
+ }
+ });
+ clearButton.setBounds(600, 450, 160, 30);
+ panel.add(clearButton);
+ }
+
+ // Run
+ public static void main(String[] args)
+ {
+ SwingUtilities.invokeLater(() -> new QrCodeUI());
+ }
+}
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/ShowDialog.java" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/ShowDialog.java"
new file mode 100644
index 0000000000000000000000000000000000000000..67359fbb6ccb998beb9d75d24c6ad4e85de2ef2a
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/ShowDialog.java"
@@ -0,0 +1,51 @@
+package com.fly.ui;
+
+import java.awt.Dimension;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+
+import javax.swing.ImageIcon;
+import javax.swing.JDialog;
+import javax.swing.JLabel;
+
+/**
+ *
+ * qr显示弹出窗口
+ *
+ * @author 00fly
+ * @version [版本号, 2023年3月3日]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+public class ShowDialog extends JDialog
+{
+ private static final long serialVersionUID = 8010838747205419843L;
+
+ public ShowDialog(BufferedImage image)
+ {
+ super();
+ // 加载图标
+ URL imgURL = getClass().getResource("/img/icon.gif");
+ if (imgURL != null)
+ {
+ setIconImage(getToolkit().createImage(imgURL));
+ }
+ setTitle("请扫描二维码");
+ setSize(510, 530);
+
+ // 自适应居中处理
+ Dimension screenSize = getToolkit().getScreenSize();
+ Dimension dialogSize = getSize();
+ dialogSize.height = Math.min(screenSize.height, dialogSize.height);
+ dialogSize.width = Math.min(screenSize.width, dialogSize.width);
+ setLocation((screenSize.width - dialogSize.width) / 2, (screenSize.height - dialogSize.height) / 2);
+
+ // 生成二维码图片
+ add(new JLabel(new ImageIcon(image)));
+
+ setVisible(true);
+ setResizable(false);
+ setAlwaysOnTop(true);
+ setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+ }
+}
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/SimpleQrCodeUI.java" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/SimpleQrCodeUI.java"
new file mode 100644
index 0000000000000000000000000000000000000000..60366e0e54dcab8889836daaad63c673e17cc0b6
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/ui/SimpleQrCodeUI.java"
@@ -0,0 +1,112 @@
+package com.fly.ui;
+
+import java.awt.BorderLayout;
+import java.awt.HeadlessException;
+import java.awt.Image;
+import java.awt.event.MouseAdapter;
+import java.awt.event.MouseEvent;
+import java.awt.image.BufferedImage;
+import java.net.URL;
+
+import javax.swing.JButton;
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.JScrollPane;
+import javax.swing.JTextArea;
+import javax.swing.SwingUtilities;
+import javax.swing.UIManager;
+
+import org.apache.commons.lang3.StringUtils;
+
+import com.fly.utils.QRCodeUtil;
+
+/**
+ *
+ * 文本二维码生成简化版本
+ *
+ * @author 00fly
+ * @version [版本号, 2023年3月3日]
+ * @see [相关类/方法]
+ * @since [产品/模块版本]
+ */
+public class SimpleQrCodeUI extends JFrame
+{
+ private static final long serialVersionUID = -708209618541039567L;
+
+ JTextArea textArea = new JTextArea();
+
+ JButton qrButton = new JButton("生 成 二 维 码");
+
+ public SimpleQrCodeUI()
+ throws HeadlessException
+ {
+ initComponent();
+
+ // 设定用户界面的外观
+ try
+ {
+ UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
+ SwingUtilities.updateComponentTreeUI(this);
+ }
+ catch (Exception e)
+ {
+ }
+
+ // 加载图标
+ URL imgURL = getClass().getResource("/img/icon.gif");
+ if (imgURL != null)
+ {
+ Image image = getToolkit().createImage(imgURL);
+ setIconImage(image);
+ }
+ this.setTitle("二维码应用工具 V1.0");
+ this.setBounds(400, 200, 1200, 550);
+ this.setResizable(true);
+ this.setVisible(true);
+ this.setDefaultCloseOperation(EXIT_ON_CLOSE);
+ }
+
+ /**
+ * 组件初始化
+ *
+ * @see [类、类#方法、类#成员]
+ */
+ private void initComponent()
+ {
+ textArea.setToolTipText("输入需要生成二维码图片的原始文本内容");
+
+ // JTextArea不自带滚动条,因此就需要把文本区放到一个滚动窗格中
+ JScrollPane scroll = new JScrollPane(textArea);
+ scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
+ scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
+
+ this.add(scroll, BorderLayout.CENTER);
+ this.add(qrButton, BorderLayout.SOUTH);
+ qrButton.addMouseListener(new MouseAdapter()
+ {
+ @Override
+ public void mouseClicked(MouseEvent e)
+ {
+ try
+ {
+ String content = textArea.getText();
+ if (StringUtils.isNotBlank(content))
+ {
+ content = content.replaceAll("\t", " ").replaceAll("((\r\n)|\n)[\\s\t ]*(\\1)+", "$1");
+ BufferedImage image = QRCodeUtil.createImage(content, null, false);
+ new ShowDialog(image);
+ }
+ }
+ catch (Exception e1)
+ {
+ JOptionPane.showMessageDialog(null, e1.getMessage(), "二维码生成失败", JOptionPane.ERROR_MESSAGE);
+ }
+ }
+ });
+ }
+
+ public static void main(String[] args)
+ {
+ SwingUtilities.invokeLater(() -> new SimpleQrCodeUI());
+ }
+}
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/utils/BufferedImageLuminanceSource.java" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/utils/BufferedImageLuminanceSource.java"
new file mode 100644
index 0000000000000000000000000000000000000000..9183262bb33acc367744c14f8318c0a1cab1fb5e
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/utils/BufferedImageLuminanceSource.java"
@@ -0,0 +1,108 @@
+package com.fly.utils;
+
+import java.awt.Graphics2D;
+import java.awt.geom.AffineTransform;
+import java.awt.image.BufferedImage;
+
+import com.google.zxing.LuminanceSource;
+
+public class BufferedImageLuminanceSource extends LuminanceSource
+{
+ private final BufferedImage image;
+
+ private final int left;
+
+ private final int top;
+
+ public BufferedImageLuminanceSource(BufferedImage image)
+ {
+ this(image, 0, 0, image.getWidth(), image.getHeight());
+ }
+
+ public BufferedImageLuminanceSource(BufferedImage image, int left, int top, int width, int height)
+ {
+ super(width, height);
+
+ int sourceWidth = image.getWidth();
+ int sourceHeight = image.getHeight();
+ if (left + width > sourceWidth || top + height > sourceHeight)
+ {
+ throw new IllegalArgumentException("Crop rectangle does not fit within image data.");
+ }
+
+ for (int y = top; y < top + height; y++)
+ {
+ for (int x = left; x < left + width; x++)
+ {
+ if ((image.getRGB(x, y) & 0xFF000000) == 0)
+ {
+ image.setRGB(x, y, 0xFFFFFFFF); // = white
+ }
+ }
+ }
+
+ this.image = new BufferedImage(sourceWidth, sourceHeight, BufferedImage.TYPE_BYTE_GRAY);
+ this.image.getGraphics().drawImage(image, 0, 0, null);
+ this.left = left;
+ this.top = top;
+ }
+
+ @Override
+ public byte[] getRow(int y, byte[] row)
+ {
+ if (y < 0 || y >= getHeight())
+ {
+ throw new IllegalArgumentException("Requested row is outside the image: " + y);
+ }
+ int width = getWidth();
+ if (row == null || row.length < width)
+ {
+ row = new byte[width];
+ }
+ image.getRaster().getDataElements(left, top + y, width, 1, row);
+ return row;
+ }
+
+ @Override
+ public byte[] getMatrix()
+ {
+ int width = getWidth();
+ int height = getHeight();
+ int area = width * height;
+ byte[] matrix = new byte[area];
+ image.getRaster().getDataElements(left, top, width, height, matrix);
+ return matrix;
+ }
+
+ @Override
+ public boolean isCropSupported()
+ {
+ return true;
+ }
+
+ @Override
+ public LuminanceSource crop(int left, int top, int width, int height)
+ {
+ return new BufferedImageLuminanceSource(image, this.left + left, this.top + top, width, height);
+ }
+
+ @Override
+ public boolean isRotateSupported()
+ {
+ return true;
+ }
+
+ @Override
+ public LuminanceSource rotateCounterClockwise()
+ {
+ int sourceWidth = image.getWidth();
+ int sourceHeight = image.getHeight();
+ AffineTransform transform = new AffineTransform(0.0, -1.0, 1.0, 0.0, 0.0, sourceWidth);
+ BufferedImage rotatedImage = new BufferedImage(sourceHeight, sourceWidth, BufferedImage.TYPE_BYTE_GRAY);
+ Graphics2D g = rotatedImage.createGraphics();
+ g.drawImage(image, transform, null);
+ g.dispose();
+ int width = getWidth();
+ return new BufferedImageLuminanceSource(rotatedImage, top, sourceWidth - (left + width), getHeight(), width);
+ }
+}
\ No newline at end of file
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/utils/QRCodeUtil.java" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/utils/QRCodeUtil.java"
new file mode 100644
index 0000000000000000000000000000000000000000..cab01acf3f73999d08f9e2ef8269f6eceaa8c2e3
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/java/com/fly/utils/QRCodeUtil.java"
@@ -0,0 +1,153 @@
+package com.fly.utils;
+
+import java.awt.BasicStroke;
+import java.awt.Graphics;
+import java.awt.Graphics2D;
+import java.awt.Image;
+import java.awt.Shape;
+import java.awt.geom.RoundRectangle2D;
+import java.awt.image.BufferedImage;
+import java.io.File;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.util.Hashtable;
+
+import javax.imageio.ImageIO;
+
+import com.google.zxing.BarcodeFormat;
+import com.google.zxing.BinaryBitmap;
+import com.google.zxing.DecodeHintType;
+import com.google.zxing.EncodeHintType;
+import com.google.zxing.MultiFormatReader;
+import com.google.zxing.MultiFormatWriter;
+import com.google.zxing.Result;
+import com.google.zxing.common.BitMatrix;
+import com.google.zxing.common.HybridBinarizer;
+import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
+
+public class QRCodeUtil
+{
+ /**
+ * 二维码尺寸
+ */
+ private static final int QRCODE_SIZE = 500;
+
+ /**
+ * LOGO宽度
+ */
+ private static final int WIDTH = 60;
+
+ /**
+ * LOGO高度
+ */
+ private static final int HEIGHT = 60;
+
+ /**
+ * 给定内容、图标生成二维码图片
+ *
+ * @param content 內容
+ * @param imgURL 图标
+ * @param needCompress 是否压缩尺寸
+ * @return
+ * @throws Exception
+ * @see [类、类#方法、类#成员]
+ */
+ public static BufferedImage createImage(String content, URL imgURL, boolean needCompress)
+ throws Exception
+ {
+ Hashtable hints = new Hashtable<>();
+ hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
+ hints.put(EncodeHintType.CHARACTER_SET, StandardCharsets.UTF_8);
+ hints.put(EncodeHintType.MARGIN, 1);
+ BitMatrix bitMatrix = new MultiFormatWriter().encode(content, BarcodeFormat.QR_CODE, QRCODE_SIZE, QRCODE_SIZE, hints);
+ int width = bitMatrix.getWidth();
+ int height = bitMatrix.getHeight();
+ BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ for (int x = 0; x < width; x++)
+ {
+ for (int y = 0; y < height; y++)
+ {
+ image.setRGB(x, y, bitMatrix.get(x, y) ? 0xFF000000 : 0xFFFFFFFF);
+ }
+ }
+ if (imgURL == null)
+ {
+ return image;
+ }
+ // 插入图片
+ insertImage(image, imgURL, needCompress);
+ return image;
+ }
+
+ private static void insertImage(BufferedImage source, URL imgURL, boolean needCompress)
+ throws Exception
+ {
+ if (imgURL == null)
+ {
+ System.err.println("文件不存在!");
+ return;
+ }
+ Image src = ImageIO.read(imgURL);
+ int width = src.getWidth(null);
+ int height = src.getHeight(null);
+ if (needCompress)
+ {
+ // 压缩LOGO
+ width = Math.min(width, WIDTH);
+ height = Math.min(height, HEIGHT);
+ Image image = src.getScaledInstance(width, height, Image.SCALE_SMOOTH);
+ BufferedImage tag = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
+ Graphics g = tag.getGraphics();
+ g.drawImage(image, 0, 0, null);
+ g.dispose();
+ src = image;
+ }
+ // 插入LOGO
+ Graphics2D graph = source.createGraphics();
+ int x = (QRCODE_SIZE - width) / 2;
+ int y = (QRCODE_SIZE - height) / 2;
+ graph.drawImage(src, x, y, width, height, null);
+ Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
+ graph.setStroke(new BasicStroke(3f));
+ graph.draw(shape);
+ graph.dispose();
+ }
+
+ /**
+ * 解析二维码图
+ *
+ * @param file
+ * @return
+ * @throws Exception
+ * @see [类、类#方法、类#成员]
+ */
+ public static String decode(File file)
+ throws Exception
+ {
+ BufferedImage image = ImageIO.read(file);
+ if (image == null)
+ {
+ return null;
+ }
+ BufferedImageLuminanceSource source = new BufferedImageLuminanceSource(image);
+ BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
+ Hashtable hints = new Hashtable<>();
+ hints.put(DecodeHintType.CHARACTER_SET, StandardCharsets.UTF_8.name());
+ Result result = new MultiFormatReader().decode(bitmap, hints);
+ return result.getText();
+ }
+
+ /**
+ * 解析二维码图
+ *
+ * @param path
+ * @return
+ * @throws Exception
+ * @see [类、类#方法、类#成员]
+ */
+ public static String decode(String path)
+ throws Exception
+ {
+ return decode(new File(path));
+ }
+}
\ No newline at end of file
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/resources/img/icon.gif" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/resources/img/icon.gif"
new file mode 100644
index 0000000000000000000000000000000000000000..8a108d9533617797078de136cb96a826941f8f85
Binary files /dev/null and "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/resources/img/icon.gif" differ
diff --git "a/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/resources/log4j2.xml" "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/resources/log4j2.xml"
new file mode 100644
index 0000000000000000000000000000000000000000..6f92a68617566e13a094682c8623fcc1c5b82408
--- /dev/null
+++ "b/\347\216\251\350\275\254\344\272\214\347\273\264\347\240\201-\346\262\241\347\275\221\347\273\234\344\271\237\350\203\275\344\274\240\346\226\207\345\255\227/src/main/resources/log4j2.xml"
@@ -0,0 +1,87 @@
+
+
+
+
+ logs
+ qrcode
+ %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file