📄 client.java
字号:
package s;
import java.io.*;
import java.net.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class Client extends JFrame implements KeyListener,ActionListener{
private JTextArea text1;
private JTextArea text2;
private Socket so;
private PrintStream ps;//像服务器发送数据的流
private BufferedReader br;//从服务器读取数据的流
private String name = "zhang";
private boolean connect;//表示联接上与否的标志位
private boolean keyMode;//记录快捷键的标志位,默认<Enter>+<Shift>
public Client(){
super("聊天室客户端");
this.construct();
this.setSize(400,400);
this.setLocation(250,250);
this.setVisible(true);
this.addListener();//为各组件增加监听器
}
public void construct(){
text1 = new JTextArea(" Please connect to server first!\n");
text2 = new JTextArea(5,15);
JScrollPane pane1 = new JScrollPane(text1);
JScrollPane pane2 = new JScrollPane(text2);
//text1.setBackground(new Color(200,200,225));
// text2.setBackground(new Color(200,200,225));
this.getContentPane().add(pane1,BorderLayout.CENTER);
this.getContentPane().add(pane2,BorderLayout.SOUTH);
text1.setEditable(false);text2.setEditable(false);
JMenuBar bar = new JMenuBar();
this.setJMenuBar(bar);
JMenu menu = new JMenu("Connect");//Connect菜单
String[] items = {"Connect to Server","About"};//联接服务器,关于
menu = this.makeMenu(menu, items, this);
bar.add(menu);
//用菜单改变发送信息的快捷键
String[] items2 = {"SEND MESSAGE with <ENTER>",//改变快捷键
"SEND MESSAGE with " +
"<ENTER><SHIFT>","Save Chating Record","Exit"};
JMenu menu2 = new JMenu("Edit");
menu2 = this.makeMenu(menu2, items2, this);
bar.add(menu2);
}
public JMenu makeMenu(JMenu parent,String[] items,ActionListener target){
if(parent==null || items.length==0)
return null;
JMenu menu = parent;
for(int i=0;i<items.length;i++){
// System.out.println("44");
JMenuItem item = new JMenuItem(items[i]);
menu.add(item);
if(target!=null)
item.addActionListener(target);
}
return menu;
}
public void exit(){//退出方法
if(text2.isEditable() && JOptionPane.showConfirmDialog(null,
"是否保存聊天记录")==JOptionPane.YES_OPTION)
save();
JOptionPane.showMessageDialog(null,
"The frame is closing! See you");
if(ps!=null)
sent(ps, br, "\n (Server note : user < "+
name+" > exited from the chating!)",false);
System.exit(0);
}
public void addListener(){
text2.addKeyListener(this);
this.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
try {
exit();
} catch (Exception e1) {
e1.printStackTrace();
}
}
});
}
//发送方法,其实没有必要写PrintStream ps,BufferedReader br
//我想以后拷贝,所以写了
public void sent(PrintStream ps,BufferedReader br,String temp,boolean stat){
try{
text2.setText("");
if(stat){
ps.println("<"+name+">says: "+temp.trim());
return ;
}
ps.println(temp.trim());
}catch(Exception e){
e.printStackTrace();
}
}
//ReceiveThread的类,每隔1秒刷新页面
class ReceiveThread extends Thread{
public void run(){
try {
for(;;){
Thread.sleep(1000);
String s;
while(br.ready()){//把缓冲流中的信息都读过来
s = br.readLine();
text1.append(s+"\n");
this.resetPosition(text1);
}
}
} catch (Exception e) {
text1.append("Error exist on Server!!");
e.printStackTrace();
}
}
public void resetPosition(JTextArea text){//让垂直滚动条在最下面
int pos = text.getText().length();
text.setSelectionStart(pos);
text.setSelectionEnd(pos);
}
}
//联接服务器方法
public void connect(){
try {
name = JOptionPane.showInputDialog("Plase enter your name:");
if(name==null || name.trim().length()==0){
name = "zhang";
return;
}
String ip ;
ip = JOptionPane.showInputDialog("Server IP(defalt IP: 192.168.3.34):");
if(ip==null || ip.trim().length()==0){
ip = "192.168.3.34";//默认的IP
text1.setText("Can not connect to server\n");
}
String regex = "^\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}[.]\\d{1,3}$";
if(!ip.matches(regex)){
JOptionPane.showMessageDialog(null, "IP格式不正确!");
return;
}
this.setTitle(name+" 's chating frame__F-Chat ");
so = new Socket(ip,2000);
ps = new PrintStream(so.getOutputStream());//输出信息的流
//读取从服务器传来的信息
br = new BufferedReader(new
InputStreamReader(so.getInputStream()));
text2.setEditable(true);
text2.setText("");
text1.setText("Welcom to the world of the F-Chat!\n" +
" Press <Enter>with<Shift>down to send message\n" +
"You can change to <Enter>only \n");
this.sent(ps, br,"Welcome < "+name+" > to join in our chating\n",false);
connect = true;//把状态位设置为已经联接上,防止再次联接
new ReceiveThread().start();
} catch (Exception e) {
text1.setText(" Can not connect to server\n");
text1.append(" maybe your IP is incorrect\n");
e.printStackTrace();
}
}
public void save(){
File file=null;
JFileChooser chooser = new JFileChooser();
chooser.showSaveDialog(this);
file = chooser.getSelectedFile();
if(file==null){
JOptionPane.showConfirmDialog(null, "NOT saved!!");
return;
}
try{
FileWriter writer = new FileWriter(file);
writer.write(text1.getText());
writer.close();//关闭流
}catch(IOException e){
e.printStackTrace();
}
}
public void keyPressed(KeyEvent e) {
// if(key = )
if(keyMode==false && e.getKeyCode()==KeyEvent.VK_ENTER
&& e.isShiftDown()==true){
this.sent(ps, br,text2.getText(),true);
return;
}
if(keyMode==true && e.getKeyCode()==KeyEvent.VK_ENTER){
this.sent(ps, br,text2.getText(),true);
}
}
public void keyReleased(KeyEvent e) {}
public void keyTyped(KeyEvent e) {}
public void actionPerformed(ActionEvent e) {//事件监听
String temp = e.getActionCommand();
if("Connect to Server".equals(temp)){
if(!connect){
this.connect();
return;
}
JOptionPane.showConfirmDialog(null, "connected to already");
}else if("SEND MESSAGE with <ENTER>".equals(temp)){
keyMode = true;//表示<ENTER>发送信息
}else if("SEND MESSAGE with <ENTER><SHIFT>".equals(temp)){
keyMode = false;//表示<ENTER><shift>发送信息
}else if("Exit".equals(temp)){
exit();
}else if("About".equals(temp)){
new About();
}else if("Save Chating Record".equals(temp)){
save();
}
}
private class About extends JFrame{
public About(){
super("关于F-Chat");
this.setLayout(new GridLayout(2,1));
this.add(new JLabel("作者:zyh0532@126.com tarena sd_sd080126"));
this.add(new JLabel(" 3.29.2008 19:00 Verson: 1.2"));
this.setSize(400,200);
this.setLocation(250,150);
this.setVisible(true);
}
}
public static void main(String[] args) {
new Client();
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -