在上一讲中,我们介绍了如何使用DotNet客户端开发包,在带UI的项目中搭建一个客户端。
而这一讲,我们再回过头来看看如何使用Java客户端开发包,也在带UI的项目中搭建一个客户端。
在本例中,我们将会使用比较常见的 Java UI 框架:Swing。
而在网络通信方面,我们还是继续使用核心类:
TcpDataClient(org.lazyboots.cli.net.TcpDataClient)。
下面是完整的代码:
整个代码的结构跟DotNet版本的客户端基本一致。
而对比起第一个无UI的Java客户端示例,
这里主要想呈现的是网络通信操作的异步执行效果。
对于Java版的 TcpDataClient,
它所有与网络相关的函数操作也都是异步执行的。
虽然在Java中,没有神奇的 async/await 关键字,
但从那些与网络通信相关的代码块中,
大家仍然能找到类似在DotNet中的连贯的代码书写结构。
这是Java版的 TcpDataClient 有趣的地方:
它模拟了 async/await 关键字实现的效果。
不过,这种模拟并不完美。
因为目前所有相关的代码都必须写在 Thread.run() 函数中。
而这一讲,我们再回过头来看看如何使用Java客户端开发包,也在带UI的项目中搭建一个客户端。
在本例中,我们将会使用比较常见的 Java UI 框架:Swing。
而在网络通信方面,我们还是继续使用核心类:
TcpDataClient(org.lazyboots.cli.net.TcpDataClient)。
下面是完整的代码:
package org.lazyboots.cli.swing.app;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.JButton;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import org.lazyboots.cli.net.TcpDataClient;
public class SimpleSwingClient {
public static final int STRING_ACTION = 1002;
public static final int UPPERCASE_FUNC = 1;
private JFrame frame;
private JLabel lblNewLabel;
private JTextField textField;
private JButton btnNewButton;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
SimpleSwingClient window = new SimpleSwingClient();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public SimpleSwingClient() {
initialize();
// 初始化界面控件的状态
btnNewButton.setEnabled(false);
textField.setEnabled(false);
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowOpened(WindowEvent arg0) { // 主窗体打开事件
new Thread() { public void run() {
// 创建一个 TcpDataClient,用于连接服务器
TcpDataClient client = new TcpDataClient();
// 连接服务器
client.connect("127.0.0.1", 9090);
if (client.getCode() == 0) // 如果连接成功,就让按钮可以点击
{
btnNewButton.setEnabled(true);
textField.setEnabled(true);
}
else lblNewLabel.setText(client.getMessage()); // 如果连接失败,则显示错误信息
}}.start();
}
@Override
public void windowClosing(WindowEvent e) { // 主窗体关闭事件
// 创建一个 TcpDataClient,用于关闭连接
TcpDataClient client = new TcpDataClient();
// 关闭连接
client.disconnect();
}
});
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
lblNewLabel = new JLabel("New label");
lblNewLabel.setBounds(45, 52, 346, 15);
frame.getContentPane().add(lblNewLabel);
textField = new JTextField();
textField.setBounds(45, 73, 228, 21);
frame.getContentPane().add(textField);
textField.setColumns(10);
btnNewButton = new JButton("New button");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { // 按钮点击事件
new Thread() { public void run() {
String str = textField.getText();
if (str.length() <= 0) return;
// 参数中的“STRING_ACTION(1002)”表示“请求字串转换指令”,
// 参数中的“UPPERCASE_FUNC(1)”则表示“请求大写转换功能”
TcpDataClient client = new TcpDataClient(STRING_ACTION, UPPERCASE_FUNC);
// 获取并显示结果
lblNewLabel.setText(client.getString(str));
}}.start();
}
});
btnNewButton.setBounds(283, 72, 110, 23);
frame.getContentPane().add(btnNewButton);
}
}
整个代码的结构跟DotNet版本的客户端基本一致。
而对比起第一个无UI的Java客户端示例,
这里主要想呈现的是网络通信操作的异步执行效果。
对于Java版的 TcpDataClient,
它所有与网络相关的函数操作也都是异步执行的。
虽然在Java中,没有神奇的 async/await 关键字,
但从那些与网络通信相关的代码块中,
大家仍然能找到类似在DotNet中的连贯的代码书写结构。
这是Java版的 TcpDataClient 有趣的地方:
它模拟了 async/await 关键字实现的效果。
不过,这种模拟并不完美。
因为目前所有相关的代码都必须写在 Thread.run() 函数中。
我们希望Java会在以后直接支持类似 async/await 的异步操作关键字。