小程序[邮箱提取器-EmailSplider]总结
1、背景情况
学东西做快的是付诸实践,写这个小程序的目的就是为了综合运用各个知识点,从而提升学习的效果。
2、涉及知识
A、Swing 的布局
B、Swing中,线程访问UI
C、URLConnection 读取网页源码
D、IO流的基本操作
E、正则表达式的基本使用
F、Window Builder插件的发现和使用
G、jar包的制作和双击jar运行的修复
H、jdk1.8的新特性,优雅的 lambda 语法
3、效果图
1、windows上运行效果 ↓
2、linux上运行效果 ↓
4、源代码
package test; import java.awt.EventQueue; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.MalformedURLException; import java.net.URL; import java.net.URLConnection; import java.util.regex.Matcher; import java.util.regex.Pattern; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.SwingUtilities; public class EmailSplider extends JFrame { private static final long serialVersionUID = -2498717483036732605L; private JTextField txtHttpvtiebabaiducomp; private JTextArea txtrn; /** * Launch the application. */ public static void main(String[] args) { EventQueue.invokeLater(new Runnable() { public void run() { try { EmailSplider frame = new EmailSplider(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }); } private String ReadHtml(URL txtUrl){ StringBuffer sb = new StringBuffer(); try { URLConnection conn =txtUrl.openConnection(); BufferedReader bf = new BufferedReader( new InputStreamReader( conn.getInputStream(),"utf-8")); String str = null; while((str = bf.readLine()) != null){ sb.append(str); } bf.close(); } catch (IOException e1) { e1.printStackTrace(); } return sb.toString(); } /** * Create the frame. */ public EmailSplider() { setResizable(false); setTitle("\u90AE\u7BB1\u63D0\u53D6\u5668"); setSize(663, 507); this.setLocationRelativeTo(null); //居中窗体 getContentPane().setLayout(null); JLabel label = new JLabel("\u8BF7\u8F93\u5165\u7F51\u5740"); label.setBounds(10, 10, 71, 15); getContentPane().add(label); txtHttpvtiebabaiducomp = new JTextField(); txtHttpvtiebabaiducomp.setText("http://v.tieba.baidu.com/p/3349997454"); txtHttpvtiebabaiducomp.setBounds(82, 7, 493, 21); getContentPane().add(txtHttpvtiebabaiducomp); txtHttpvtiebabaiducomp.setColumns(10); JButton button = new JButton("\u63D0\u53D6"); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { new Thread( () -> { try { URL txtUrl = new URL(txtHttpvtiebabaiducomp.getText()); String html = ReadHtml(txtUrl); Pattern p =Pattern.compile("[a-zA-Z0-9_-]+@\\w+\\.[a-z]+(\\.[a-z]+)?"); Matcher m = p.matcher(html); while(m.find()){ //System.out.println(m.group()); try { SwingUtilities.invokeAndWait(()->{ txtrn.append(System.getProperty("line.separator")+m.group()); txtrn.setCaretPosition(txtrn.getText().length()); }); } catch (Exception e1) { e1.printStackTrace(); } } } catch (MalformedURLException e1) { JOptionPane.showMessageDialog(null, "请输入合法的网址!\n 必须以http:// 开头", "操作提示", JOptionPane.ERROR_MESSAGE); return; } }).start(); } }); button.setBounds(585, 6, 62, 23); getContentPane().add(button); txtrn = new JTextArea(); txtrn.setText("\u8FD9\u91CC\u663E\u793A\u63D0\u53D6\u7684\u90AE\u7BB1"); txtrn.setLineWrap(true); JScrollPane jScrollPane = new JScrollPane(txtrn); jScrollPane.setBounds(10, 35, 637, 432); getContentPane().add(jScrollPane ); jScrollPane.setVerticalScrollBarPolicy( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED); } }
5、jar包附件
6、总结
Q1:SwingUtilities.invokeLater()和SwingUtilities.invokeAndWait()的区别(有什么区别)?
A1:invokeAndWait:后面的程序必须等这个线程(参数中的线程)的东西执行完才能执行;
invokeLater:后面的程序和这个参数的线程对象可以并行,异步地执行。
如果本程序代码里面由 invokeAndWait() 改为 invokeLater() 在ui上更新出来的结果会错乱的很离谱,但是控制台输出不会出现问题。
Q2:下面的代码,用jdk1.8 的 lambda 怎么写?
SwingUtilities.invokeLater( new Runnable() { @Override public void run() { txtrn.append(m.group()+System.getProperty("line.separator")); txtrn.setCaretPosition(txtrn.getText().length()); } } });
A2:写法如下,相当优雅!
-
SwingUtilities.invokeAndWait(()->{ txtrn.append(System.getProperty("line.separator")+m.group()); txtrn.setCaretPosition(txtrn.getText().length()); });
-
Q3:怎么给JTextArea添加垂直滚动条?
A3:看代码里面和注释
txtrn = new JTextArea(); txtrn.setText("这里是内容"); txtrn.setLineWrap(true); //设置自动换行,让横向滚动条不显示 //用txtrn对象作为JScrollPane的构造方法的参数 JScrollPane jScrollPane = new JScrollPane(txtrn); //下面setBounds很重要 jScrollPane.setBounds(10, 35, 637, 432); //只需要把jScrollPane 添加到窗体,如果再添加txtrn对象就会乱。 getContentPane().add(jScrollPane );
Q4:提取邮箱的正则表达式怎么写?
A4:"[a-zA-Z0-9_-]+@\\w+\\.[a-z]+(\\.[a-z]+)?"
Q5、子线程如何更改UI?
A5、Swing中,提供了 SwingUtilities.invokeLater 和 SwingUtilities.invokeAndWait 方法来访问。
不过还是得注意这2个方法的区别!
Q6:如何导出jar包? 如何修复双击jar报错?如何安装比VE更强的Window Builder插件?
比你优秀的人不可怕,可怕的是比你优秀的人比你更努力