java textarea?java官网jdk下载
大家好,感谢邀请,今天来为大家分享一下java textarea的问题,以及和java官网jdk下载的一些困惑,大家要是还不太明白的话,也没有关系,因为接下来将为大家分享,希望可以帮助到大家,解决大家的问题,下面就开始吧!
java编译文本编辑器
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class EditorJFrame extends JFrame implements ActionListener, ItemListener, MouseListener
{
private JTextField text_size;//字号文本行
private JCheckBox checkbox_bold, checkbox_italic;//粗体、斜体复选框
private JButton button_cut, button_copy, button_paste;//剪切、复制、粘贴按钮
private JTextArea textarea;//文本区
private JPopupMenu popupmenu;//快捷菜单
private JDialog dialog;//出错提示对话框
private JLabel label_dialog;//对话框中的标签
public EditorJFrame()
{
super("文本编辑器");//默认BorderLayout布局
this.setSize(500,300);
this.setLocation(300,240);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);//单击窗口关闭按钮时,结束程序运行
textarea= new JTextArea("TextArea");
textarea.addMouseListener(this);//为文本区注册鼠标事件监听器
this.add(textarea);//文本区添加到框架的中部
JPanel panel= new JPanel(new FlowLayout(FlowLayout.LEFT));//面板为流布局,左对齐
this.add(panel,"North");//面板添加到框架的北部
text_size= new JTextField("12",10);
panel.add(text_size);
text_size.addActionListener(this);//注册文本行的单击事件监听器
checkbox_bold= new JCheckBox("粗体");//复选框
panel.add(checkbox_bold);
checkbox_bold.addItemListener(this);//注册复选框的选择事件监听器
checkbox_italic= new JCheckBox("斜体");
panel.add(checkbox_italic);
checkbox_italic.addItemListener(this);
this.addmyMenu();//调用自定义方法,添加菜单
this.setVisible(true);
}
private void addmyMenu()//添加主菜单、快捷菜单、对话框
{
JMenuBar menubar= new JMenuBar();//菜单栏
this.setJMenuBar(menubar);//框架上添加菜单栏
JMenu menu_file= new JMenu("文件");//菜单
menubar.add(menu_file);//菜单栏中加入菜单
menu_file.add(new JMenuItem("打开"));//生成菜单项并加入到菜单
menu_file.add(new JMenuItem("保存"));
menu_file.addSeparator();//加分隔线
JMenuItem menuitem_exit= new JMenuItem("退出");
menu_file.add(menuitem_exit);
menuitem_exit.addActionListener(this);//为菜单项注册单击事件监听器
JMenu menu_edit= new JMenu("编辑");
menubar.add(menu_edit);
JMenu menu_style= new JMenu("字形");
menu_style.add(new JCheckBoxMenuItem("粗体"));//复选菜单项
menu_style.add(new JCheckBoxMenuItem("斜体"));
menu_edit.add(menu_style);//菜单加入到菜单中成为二级菜单
JMenu menu_color= new JMenu("颜色");
menu_edit.add(menu_color);
ButtonGroup buttongroup= new ButtonGroup();//按钮组
JRadioButtonMenuItem rbmi_red= new JRadioButtonMenuItem("红",true);//单选菜单项
buttongroup.add(rbmi_red);//单选菜单项添加到按钮组
menu_color.add(rbmi_red);//单选菜单项添加到菜单
JRadioButtonMenuItem rbmi_green= new JRadioButtonMenuItem("绿",true);
buttongroup.add(rbmi_green);
menu_color.add(rbmi_green);
JRadioButtonMenuItem rbmi_blue= new JRadioButtonMenuItem("蓝",true);
buttongroup.add(rbmi_blue);
menu_color.add(rbmi_blue);
menubar.add(new JMenu("帮助"));
popupmenu= new JPopupMenu();//弹出式菜单对象
JMenuItem menuitem_cut= new JMenuItem("剪切");
menuitem_cut.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,InputEvent.CTRL_MASK));//设置快捷键Ctrl+X
popupmenu.add(menuitem_cut);//加入剪切菜单项
menuitem_cut.addActionListener(this);
JMenuItem menuitem_copy= new JMenuItem("复制");
menuitem_copy.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_C,InputEvent.CTRL_MASK));//设置快捷键Ctrl+C
popupmenu.add(menuitem_copy);
menuitem_copy.addActionListener(this);
JMenuItem menuitem_paste= new JMenuItem("粘贴");
menuitem_paste.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_V,InputEvent.CTRL_MASK));//设置快捷键Ctrl+V
popupmenu.add(menuitem_paste);
menuitem_paste.addActionListener(this);
textarea.add(popupmenu);//文本区添加快捷菜单
dialog= new JDialog(this,"提示");
dialog.setSize(240,80);
label_dialog= new JLabel("",JLabel.CENTER);
dialog.add(label_dialog);
dialog.setDefaultCloseOperation(HIDE_ON_CLOSE);//单击对话框的关闭按钮时,隐藏对话框而不结束程序运行
}
public void actionPerformed(ActionEvent e)//单击事件处理程序
{
if(e.getActionCommand()=="退出")//不能用switch(int)语句
System.exit(0);//单击菜单项时结束程序
if(e.getActionCommand()=="剪切")
textarea.cut();//将选中文本剪切送系统剪贴板
if(e.getActionCommand()=="复制")
textarea.copy();
if(e.getActionCommand()=="粘贴")
textarea.paste();
if(e.getSource()==text_size)//单击文本行时,改变字号
{
int size=0;
try
{
size= Integer.parseInt(text_size.getText());
if(size<=0|| size>72)
throw new Exception("SizeException");//抛出异常对象
java.awt.Font font= textarea.getFont();
textarea.setFont(new Font(font.getName(),font.getStyle(),size));
}
catch(NumberFormatException nfe)
{
label_dialog.setText("\""+text_size.getText()+"\"不能转换成整数,请重新输入!");
dialog.setLocation(this.getX()+100,this.getY()+100);
dialog.setVisible(true);
}
catch(Exception ex)
{
if(ex.getMessage()=="SizeException")//捕获自己抛出的异常对象
{
label_dialog.setText(size+"字号不合适,请重新输入!");
dialog.setLocation(this.getX()+100,this.getY()+100);
dialog.setVisible(true);
}
}
finally{}
}
}
public void itemStateChanged(ItemEvent e)//复选框选择事件处理程序
{//实现ItemListener接口中的方法
Font font= textarea.getFont();
int style= font.getStyle();
if(e.getSource()==checkbox_bold)
style= style ^ 1;//整数的位运算,异或^
if(e.getSource()==checkbox_italic)
style= style ^ 2;
textarea.setFont(new Font(font.getName(),style,font.getSize()));
}
public void mouseClicked(MouseEvent mec)//单击鼠标时触发
{//实现MouseListener接口中的方法
if(mec.getModifiers()==mec.BUTTON3_MASK)//单击的是鼠标右键
popupmenu.show(textarea,mec.getX(),mec.getY());//在鼠标单击处显示快捷菜单
}
public void mousePressed(MouseEvent mep){}
public void mouseReleased(MouseEvent mer){}
public void mouseEntered(MouseEvent mee){}
public void mouseExited(MouseEvent mex){}
public void mouseDragged(MouseEvent med){}
public static void main(String arg[])
{
new EditorJFrame();
}
}
用Java语言设计一个界面,
首先:采用什么技术实现
java语言可以使用awt和swing等技术实现图形界面
推荐使用Swing,因为Swing比AWT更专业,更漂亮,组件更丰富,功能更强大。
2.其次:分析采用什么布局
边界布局BorderLayout,配合表格布局GridLayout,既简单又美观
3.最后:分析需求中需要用的组件
学生姓名学号显示信息需要用到文本框JTextField
单选按钮需要用到组件JRadioButton
复选框需要用到组件JCheckBox
组合框需要用到组件JComboBox
图片效果
参考代码如下
//导入所需要的包
importjava.awt.event.*;
importjavax.swing.border.*;
importjavax.swing.*;
importjava.awt.*;
publicclassClassFrameextendsJFrame{//写一个类继承自JFrame窗体
//定义组件
privatestaticfinallongserialVersionUID=1L;
privateJPanelcontentPane;
privateJTextFieldtfName,tfNum,allInfo;
privateJRadioButtonrb1,rb2;
privateJCheckBoxcb1,cb2,cb3;
privateJComboBox<String>t1,t2,t3;
publicstaticvoidmain(String[]args){
EventQueue.invokeLater(newRunnable(){
publicvoidrun(){
try{
ClassFrameframe=newClassFrame();//创建一个窗口实例
frame.setVisible(true);//让该窗口实例可见
}catch(Exceptione){
e.printStackTrace();
}
}
});
}
/**
*窗口属性的设置,内部组件的初始化
*/
publicClassFrame(){
setTitle("选课ing...");//标题
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//设置关闭是退出JVM
setSize(450,339);//设置窗体大小
setLocationRelativeTo(null);//窗体居中
contentPane=newJPanel();//内容面板
contentPane.setBorder(newEmptyBorder(5,5,5,5));
contentPane.setLayout(newBorderLayout(0,0));//设置布局
setContentPane(contentPane);
JPanelpanel=newJPanel(newGridLayout(5,1,5,10));//5行1列的表格布局
panel.setBorder(newTitledBorder(null,"",TitledBorder.LEADING,TitledBorder.TOP,null,null));
contentPane.add(panel,BorderLayout.CENTER);//给panel添加边框
JPanelpanel_1=newJPanel();
panel.add(panel_1);
JLabellabel=newJLabel("姓名");
panel_1.add(label);
tfName=newJTextField();
panel_1.add(tfName);
tfName.setColumns(10);
JLabellabel_2=newJLabel("学号");
panel_1.add(label_2);
tfNum=newJTextField();
tfNum.setColumns(10);
panel_1.add(tfNum);
rb1=newJRadioButton("男");
panel_1.add(rb1);
rb1.setSelected(true);//设置单选按钮中,默认选择的按钮
rb2=newJRadioButton("女");
panel_1.add(rb2);
ButtonGroupbts=newButtonGroup();//单选按钮需要加入同一个ButonGroup中才能生效
bts.add(rb1);
bts.add(rb2);
JPanelpanel_2=newJPanel();
panel.add(panel_2);
cb1=newJCheckBox("高等数学");
panel_2.add(cb1);
t1=newJComboBox<String>();
t1.setModel(newDefaultComboBoxModel<String>(newString[]{"林老师","赵老师","孙老师"}));
panel_2.add(t1);
JPanelpanel_3=newJPanel();
panel.add(panel_3);
cb2=newJCheckBox("世界经济");
panel_3.add(cb2);
t2=newJComboBox<String>();
t2.setModel(newDefaultComboBoxModel<String>(newString[]{"张老师","刘老师"}));
panel_3.add(t2);
JPanelpanel_4=newJPanel();
panel.add(panel_4);
cb3=newJCheckBox("音乐赏析");
panel_4.add(cb3);
t3=newJComboBox<String>();
t3.setModel(newDefaultComboBoxModel<String>(newString[]{"王老师","周老师"}));
panel_4.add(t3);
JPanelpanel_5=newJPanel();
panel.add(panel_5);
JButtonjbOk=newJButton("确定");
panel_5.add(jbOk);
JButtonjbRest=newJButton("重填");
panel_5.add(jbRest);
JPanelpanelSouth=newJPanel();
contentPane.add(panelSouth,BorderLayout.SOUTH);
JLabellabe=newJLabel("选课信息");
labe.setHorizontalAlignment(SwingConstants.LEFT);
panelSouth.add(labe);
allInfo=newJTextField();
allInfo.setColumns(30);
panelSouth.add(allInfo);
JPanelpanelNorth=newJPanel();
contentPane.add(panelNorth,BorderLayout.NORTH);
JLabellabelTitle=newJLabel("学生选课界面");
labelTitle.setForeground(Color.DARK_GRAY);
labelTitle.setFont(newFont("宋体",Font.BOLD,20));
panelNorth.add(labelTitle);
//给确定按钮添加事件处理代码
jbOk.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){
StringBuilderinfo=newStringBuilder();
Stringname=tfName.getText();
Stringnum=tfNum.getText();
Stringsex;
if(rb1.isSelected()){
sex="男";
}else{
sex="女";
}
info.append(name+num+sex);
if(cb1.isSelected()){
Stringc=cb1.getText();
Stringt=t1.getSelectedItem().toString();
info.append(""+c+t);
}
if(cb2.isSelected()){
Stringc=cb2.getText();
Stringt=t2.getSelectedItem().toString();
info.append(""+c+t);
}
if(cb3.isSelected()){
Stringc=cb3.getText();
Stringt=t3.getSelectedItem().toString();
info.append(""+c+t);
}
allInfo.setText(info.toString());//把学生信息和选课信息放到文本框
}
});
//给重填按钮设置事件处理代码
jbRest.addActionListener(newActionListener(){
publicvoidactionPerformed(ActionEvente){
tfName.setText("");
tfNum.setText("");
rb1.setSelected(true);
cb1.setSelected(false);
t1.setSelectedIndex(0);
cb2.setSelected(false);
t2.setSelectedIndex(0);
cb3.setSelected(false);
t3.setSelectedIndex(0);
allInfo.setText("");
}
});
}
}
java五子棋代码带详细解释
浩大的工程你有五子棋程序如果你水平还行的话你参照这个聊天室程序应该也比较容易写出人人对战的
package Chat;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.InetAddress;
import java.net.Socket;
import java.util.StringTokenizer;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
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.border.TitledBorder;
/**
*聊天室的客户端程序,GUI界面。
*/
public class ChatClient extends JFrame implements ActionListener{
//登陆聊天室的名字标签和输入框
JLabel nameLabel= new JLabel();
JTextField nameTextField= new JTextField(15);
//连接和断开连接的按钮
JButton connectButton= new JButton();
JButton disConnectButton= new JButton();
//聊天室内容的文本域
JTextArea chatContentTextArea= new JTextArea(9, 30);
//发送消息的按钮
JButton sendMsgButton= new JButton();
//消息输入框
JTextField msgTextField= new JTextField(20);
JLabel msglabel= new JLabel();
//聊天室用户列表
java.awt.List peopleList= new java.awt.List(10);
/*以下定义数据流和网络变量*/
Socket soc= null;
PrintStream ps= null;
//客户端侦听服务器消息的线程
ClentListener listener= null;
public ChatClient(){
init();
}
//初始化图形界面
public void init(){
this.setTitle("聊天室客户端");
//初始化按钮和标签
nameLabel.setText("姓名:");
connectButton.setText("连接");
connectButton.addActionListener(this);
disConnectButton.setText("断开");
disConnectButton.addActionListener(this);
//设置聊天内容不可编辑
chatContentTextArea.setEditable(false);
sendMsgButton.setText("发送");
sendMsgButton.addActionListener(this);
msgTextField.setText("请输入聊天信息");
//panel1放置输入姓名和连接两个按钮
JPanel panel1= new JPanel();
panel1.setLayout(new FlowLayout());
panel1.add(nameLabel);
panel1.add(nameTextField);
panel1.add(connectButton);
panel1.add(disConnectButton);
//用于放置聊天信息显示和聊天人员列表
JPanel panel2= new JPanel();
panel2.setLayout(new FlowLayout());
JScrollPane pane1= new JScrollPane(chatContentTextArea);
pane1.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(
Color.white, new Color(134, 134, 134)),"聊天内容"));
panel2.add(pane1);
JScrollPane pane2= new JScrollPane(peopleList);
pane2.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(
Color.white, new Color(134, 134, 134)),"用户列表"));
panel2.add(pane2);
//用于放置发送信息区域
JPanel panel3= new JPanel();
panel3.setLayout(new FlowLayout());
panel3.add(msglabel);
panel3.add(msgTextField);
panel3.add(sendMsgButton);
//将组件添加到界面
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(panel1, BorderLayout.NORTH);
this.getContentPane().add(panel2, BorderLayout.CENTER);
this.getContentPane().add(panel3, BorderLayout.SOUTH);
this.pack();
try{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.updateComponentTreeUI(this);
} catch(Exception e){
e.printStackTrace();
}
}
/**
*关闭聊天室客户端事件
*/
protected void processWindowEvent(WindowEvent e){
super.processWindowEvent(e);
if(e.getID()== WindowEvent.WINDOW_CLOSING){
//如果是关闭聊天室客户端,则断开连接
disconnect();
dispose();
System.exit(0);
}
}
/**
*处理按钮事件
*/
public void actionPerformed(ActionEvent event){
Object source= event.getSource();
if(source== connectButton){
//如果点击连接按钮
if(soc== null){
try{
//使用端口2525实例化一个本地套接字
soc= new Socket(InetAddress.getLocalHost(), Constants.SERVER_PORT);
//在控制台打印实例化的结果
System.out.println(soc);
//将ps指向soc的输出流
ps= new PrintStream(soc.getOutputStream());
//定义一个字符缓冲存储发送信息
StringBuffer info= new StringBuffer(Constants.CONNECT_IDENTIFER).append(Constants.SEPERATOR);
//其中INFO为关键字让服务器识别为连接信息
//并将name和ip用":"分开,在服务器端将用一个
//StringTokenizer类来读取数据
String userinfo= nameTextField.getText()+ Constants.SEPERATOR
+ InetAddress.getLocalHost().getHostAddress();
ps.println(info.append(userinfo));
ps.flush();
//将客户端线程实例化,并启动
listener= new ClentListener(this, nameTextField.getText(), soc);
listener.start();
} catch(IOException e){
System.out.println("Error:"+ e);
disconnect();
}
}
} else if(source== disConnectButton){
//如果点击断开连接按钮
disconnect();
} else if(source== sendMsgButton){
//如果点击发送按钮
if(soc!= null){
//定义并实例化一个字符缓冲存储发送的聊天信息
StringBuffer msg= new StringBuffer(Constants.MSG_IDENTIFER).append(Constants.SEPERATOR);
//用打印流发送聊天信息
ps.println(msg.append(msgTextField.getText()));
ps.flush();
}
}
}
/**
*断开与服务器的连接
*/
public void disconnect(){
if(soc!= null){
try{
//用打印流发送QUIT信息通知服务器断开此次通信
ps.println(Constants.QUIT_IDENTIFER);
ps.flush();
soc.close();//关闭套接字
listener.toStop();
soc= null;
} catch(IOException e){
System.out.println("Error:"+ e);
}
}
}
public static void main(String[] args){
ChatClient client= new ChatClient();
client.setVisible(true);
}
/**
*客户端线程类用来监听服务器传来的信息
*/
class ClentListener extends Thread{
//存储客户端连接后的name信息
String name= null;
//客户端接受服务器数据的输入流
BufferedReader br= null;
//实现从客户端发送数据到服务器的打印流
PrintStream ps= null;
//存储客户端的socket信息
Socket socket= null;
//存储当前运行的ChatClient实例
ChatClient parent= null;
boolean running= true;
//构造方法
public ClentListener(ChatClient p, String n, Socket s){
//接受参数
parent= p;
name= n;
socket= s;
try{
//实例化两个数据流
br= new BufferedReader(new InputStreamReader(s
.getInputStream()));
ps= new PrintStream(s.getOutputStream());
} catch(IOException e){
System.out.println("Error:"+ e);
parent.disconnect();
}
}
//停止侦听
public void toStop(){
this.running= false;
}
//线程运行方法
public void run(){
String msg= null;
while(running){
msg= null;
try{
//读取从服务器传来的信息
msg= br.readLine();
System.out.println("receive msg:"+ msg);
} catch(IOException e){
System.out.println("Error:"+ e);
parent.disconnect();
}
//如果从服务器传来的信息为空则断开此次连接
if(msg== null){
parent.listener= null;
parent.soc= null;
parent.peopleList.removeAll();
running= false;
return;
}
//用StringTokenizer类来实现读取分段字符
StringTokenizer st= new StringTokenizer(msg, Constants.SEPERATOR);
//读取信息头即关键字用来识别是何种信息
String keyword= st.nextToken();
if(keyword.equals(Constants.PEOPLE_IDENTIFER)){
//如果是PEOPLE则是服务器发来的客户连接信息
//主要用来刷新客户端的用户列表
parent.peopleList.removeAll();
//遍历st取得目前所连接的客户
while(st.hasMoreTokens()){
String str= st.nextToken();
parent.peopleList.add(str);
}
} else if(keyword.equals(Constants.MSG_IDENTIFER)){
//如果关键字是MSG则是服务器传来的聊天信息,
//主要用来刷新客户端聊天信息区将每个客户的聊天内容显示出来
String usr= st.nextToken();
parent.chatContentTextArea.append(usr);
parent.chatContentTextArea.append(st.nextToken("\0"));
parent.chatContentTextArea.append("\r\n");
} else if(keyword.equals(Constants.QUIT_IDENTIFER)){
//如果关键字是QUIT则是服务器关闭的信息,切断此次连接
System.out.println("Quit");
try{
running= false;
parent.listener= null;
parent.soc.close();
parent.soc= null;
} catch(IOException e){
System.out.println("Error:"+ e);
} finally{
parent.soc= null;
parent.peopleList.removeAll();
}
break;
}
}
//清除用户列表
parent.peopleList.removeAll();
}
}
}
package Chat;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.StringTokenizer;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.border.TitledBorder;
/**
*聊天室的服务器端程序,GUI界面
*/
public class ChatServer extends JFrame{
//状态栏标签
static JLabel statusBar= new JLabel();
//显示客户端的连接信息的列表
static java.awt.List connectInfoList= new java.awt.List(10);
//保存当前处理客户端请求的处理器线程
static Vector clientProcessors= new Vector(10);
//当前的连接数
static int activeConnects= 0;
//构造方法
public ChatServer(){
init();
try{
//设置界面为系统默认外观
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
SwingUtilities.updateComponentTreeUI(this);
} catch(Exception e){
e.printStackTrace();
}
}
private void init(){
this.setTitle("聊天室服务器");
statusBar.setText("");
//初始化菜单
JMenu fileMenu= new JMenu();
fileMenu.setText("文件");
JMenuItem exitMenuItem= new JMenuItem();
exitMenuItem.setText("退出");
exitMenuItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
exitActionPerformed(e);
}
});
fileMenu.add(exitMenuItem);
JMenuBar menuBar= new JMenuBar();
menuBar.add(fileMenu);
this.setJMenuBar(menuBar);
//将组件进行布局
JPanel jPanel1= new JPanel();
jPanel1.setLayout(new BorderLayout());
JScrollPane pane= new JScrollPane(connectInfoList);
pane.setBorder(new TitledBorder(BorderFactory.createEtchedBorder(
Color.white, new Color(134, 134, 134)),"客户端连接信息"));
jPanel1.add(new JScrollPane(pane), BorderLayout.CENTER);
this.getContentPane().setLayout(new BorderLayout());
this.getContentPane().add(statusBar, BorderLayout.SOUTH);
this.getContentPane().add(jPanel1, BorderLayout.CENTER);
this.pack();
}
/**
*退出菜单项事件
*@param e
*/
public void exitActionPerformed(ActionEvent e){
//向客户端发送断开连接信息
sendMsgToClients(new StringBuffer(Constants.QUIT_IDENTIFER));
//关闭所有的连接
closeAll();
System.exit(0);
}
/**
*处理窗口关闭事件
*/
protected void processWindowEvent(WindowEvent e){
super.processWindowEvent(e);
if(e.getID()== WindowEvent.WINDOW_CLOSING){
exitActionPerformed(null);
}
}
/**
*刷新聊天室,不断刷新clientProcessors,制造最新的用户列表
*/
public static void notifyRoomPeople(){
StringBuffer people= new StringBuffer(Constants.PEOPLE_IDENTIFER);
for(int i= 0; i< clientProcessors.size(); i++){
ClientProcessor c=(ClientProcessor) clientProcessors.elementAt(i);
people.append(Constants.SEPERATOR).append(c.clientName);
}
//用sendClients方法向客户端发送用户列表的信息
sendMsgToClients(people);
}
/**
*向所有客户端群发消息
*@param msg
*/
public static synchronized void sendMsgToClients(StringBuffer msg){
for(int i= 0; i< clientProcessors.size(); i++){
ClientProcessor c=(ClientProcessor) clientProcessors.elementAt(i);
System.out.println("send msg:"+ msg);
c.send(msg);
}
}
/**
*关闭所有连接
*/
public static void closeAll(){
while(clientProcessors.size()> 0){
ClientProcessor c=(ClientProcessor) clientProcessors.firstElement();
try{
//关闭socket连接和处理线程
c.socket.close();
c.toStop();
} catch(IOException e){
System.out.println("Error:"+ e);
} finally{
clientProcessors.removeElement(c);
}
}
}
/**
*判断客户端是否合法。
*不允许同一客户端重复登陆,所谓同一客户端是指IP和名字都相同。
*@param newclient
*@return
*/
public static boolean checkClient(ClientProcessor newclient){
if(clientProcessors.contains(newclient)){
return false;
} else{
return true;
}
}
/**
*断开某个连接,并且从连接列表中删除
*@param client
*/
public static void disconnect(ClientProcessor client){
disconnect(client, true);
}
/**
*断开某个连接,根据要求决定是否从连接列表中删除
*@param client
*@param toRemoveFromList
*/
public static synchronized void disconnect(ClientProcessor client, boolean toRemoveFromList){
try{
//在服务器端程序的list框中显示断开信息
connectInfoList.add(client.clientIP+"断开连接");
ChatServer.activeConnects--;//将连接数减1
String constr="目前有"+ ChatServer.activeConnects+"客户相连";
statusBar.setText(constr);
//向客户发送断开连接信息
client.send(new StringBuffer(Constants.QUIT_IDENTIFER));
client.socket.close();
} catch(IOException e){
System.out.println("Error:"+ e);
} finally{
//从clients数组中删除此客户的相关socket等信息,并停止线程。
if(toRemoveFromList){
clientProcessors.removeElement(client);
client.toStop();
}
}
}
public static void main(String[] args){
ChatServer chatServer1= new ChatServer();
chatServer1.setVisible(true);
System.out.println("Server starting...");
ServerSocket server= null;
try{
//服务器端开始侦听
server= new ServerSocket(Constants.SERVER_PORT);
} catch(IOException e){
System.out.println("Error:"+ e);
System.exit(1);
}
while(true){
//如果当前客户端数小于MAX_CLIENT个时接受连接请求
if(clientProcessors.size()< Constants.MAX_CLIENT){
Socket socket= null;
try{
//收到客户端的请求
socket= server.accept();
if(socket!= null){
System.out.println(socket+"连接");
}
} catch(IOException e){
System.out.println("Error:"+ e);
}
//定义并实例化一个ClientProcessor线程类,用于处理客户端的消息
ClientProcessor c= new ClientProcessor(socket);
if(checkClient(c)){
//添加到列表
clientProcessors.addElement(c);
//如果客户端合法,则继续
int connum=++ChatServer.activeConnects;
//在状态栏里显示连接数
String constr="目前有"+ connum+"客户相连";
ChatServer.statusBar.setText(constr);
//将客户socket信息写入list框
ChatServer.connectInfoList.add(c.clientIP+"连接");
c.start();
//通知所有客户端用户列表发生变化
notifyRoomPeople();
} else{
//如果客户端不合法
c.ps.println("不允许重复登陆");
disconnect(c, false);
}
} else{
//如果客户端超过了MAX_CLIENT个,则等待一段时间再尝试接受请求
try{
Thread.sleep(200);
} catch(InterruptedException e){
}
}
}
}
}
/**
*处理客户端发送的请求的线程
*/
class ClientProcessor extends Thread{
//存储一个连接客户端的socket信息
Socket socket;
//存储客户端的连接姓名
String clientName;
//存储客户端的ip信息
String clientIP;
//用来实现接受从客户端发来的数据流
BufferedReader br;
//用来实现向客户端发送信息的打印流
PrintStream ps;
boolean running= true;
/**
*构造方法
*@param s
*/
public ClientProcessor(Socket s){
socket= s;
try{
//初始化输入输出流
br= new BufferedReader(new InputStreamReader(socket.getInputStream()));
ps= new PrintStream(socket.getOutputStream());
//读取收到的信息,第一条信息是客户端的名字、IP信息
String clientInfo= br.readLine();
//读取信息,根据消息分隔符解析消息
StringTokenizer stinfo= new StringTokenizer(clientInfo, Constants.SEPERATOR);
String head= stinfo.nextToken();
if(head.equals(Constants.CONNECT_IDENTIFER)){
if(stinfo.hasMoreTokens()){
//关键字后的第二段数据是客户名信息
clientName= stinfo.nextToken();
}
if(stinfo.hasMoreTokens()){
//关键字后的第三段数据是客户ip信息
clientIP= stinfo.nextToken();
}
System.out.println(head);//在控制台打印头信息
}
} catch(IOException e){
System.out.println("Error:"+ e);
}
}
/**
*向客户端发送消息
*@param msg
*/
public void send(StringBuffer msg){
ps.println(msg);
ps.flush();
}
//线程运行方法
public void run(){
while(running){
String line= null;
try{
//读取客户端发来的数据流
line= br.readLine();
} catch(IOException e){
System.out.println("Error"+ e);
ChatServer.disconnect(this);
ChatServer.notifyRoomPeople();
return;
}
//客户已离开
if(line== null){
ChatServer.disconnect(this);
ChatServer.notifyRoomPeople();
return;
}
StringTokenizer st= new StringTokenizer(line, Constants.SEPERATOR);
String keyword= st.nextToken();
//如果关键字是MSG则是客户端发来的聊天信息
if(keyword.equals(Constants.MSG_IDENTIFER)){
StringBuffer msg= new StringBuffer(Constants.MSG_IDENTIFER).append(Constants.SEPERATOR);
msg.append(clientName);
msg.append(st.nextToken("\0"));
//再将某个客户发来的聊天信息发送到每个连接客户的聊天栏中
ChatServer.sendMsgToClients(msg);
} else if(keyword.equals(Constants.QUIT_IDENTIFER)){
//如果关键字是QUIT则是客户端发来断开连接的信息
//服务器断开与这个客户的连接
ChatServer.disconnect(this);
//继续监听聊天室并刷新其他客户的聊天人名list
ChatServer.notifyRoomPeople();
running= false;
}
}
}
public void toStop(){
running= false;
}
//覆盖Object类的equals方法
public boolean equals(Object obj){
if(obj instanceof ClientProcessor){
ClientProcessor obj1=(ClientProcessor)obj;
if(obj1.clientIP.equals(this.clientIP)&&
(obj1.clientName.equals(this.clientName))){
return true;
}
}
return false;
}
//覆盖Object类的hashCode方法
public int hashCode(){
return(this.clientIP+ Constants.SEPERATOR+ this.clientName).hashCode();
}
}
package Chat;
/**
*定义聊天室程序中用到的常量
*/
public class Constants{
//服务器的端口号
public static final int SERVER_PORT= 2525;
public static final int MAX_CLIENT= 10;
//消息标识符与消息体之间的分隔符
public static final String SEPERATOR=":";
//消息信息的标识符
public static final String MSG_IDENTIFER="MSG";
//用户列表信息的标识符
public static final String PEOPLE_IDENTIFER="PEOPLE";
//连接服务器信息的标识符
public static final String CONNECT_IDENTIFER="INFO";
//退出信息标识符
public static final String QUIT_IDENTIFER="QUIT";
}
好了,本文到此结束,如果可以帮助到大家,还望关注本站哦!