用定制的GUI開發(fā)Java聊天軟件
發(fā)表時間:2024-02-02 來源:明輝站整理相關(guān)軟件相關(guān)文章人氣:
[摘要]摘要:本文詳細介紹一個AWT版本的java聊天軟件的開發(fā)過程,并著重分析如何用AWT組件實現(xiàn)軟件的個性化界面。簡介本Java聊天軟件,純粹基于AWT組件,沒有使用任何Swing組件。在本程序中,我開發(fā)了自己的Tab控件和圖像畫布并給出完整的源碼分析。軟件實現(xiàn)界面見下圖:軟件特點1)用本文傳遞笑臉圖...
摘要:本文詳細介紹一個AWT版本的java聊天軟件的開發(fā)過程,并著重分析如何用AWT組件實現(xiàn)軟件的個性化界面。
簡介
本Java聊天軟件,純粹基于AWT組件,沒有使用任何Swing組件。在本程序中,我開發(fā)了自己的Tab控件和圖像畫布并給出完整的源碼分析。軟件實現(xiàn)界面見下圖:
軟件特點
1)用本文傳遞笑臉圖片
2)私人聊天功能
3)基于定制顏色的良好界面
4)音頻功能
描述
在軟件中,實現(xiàn)了服務(wù)器端模塊與客戶端模塊。在服務(wù)器端,我定義了自己的RFC命令。在該應(yīng)用程序中用到的命令有:
HELO - 初始化到服務(wù)器的連接
QUIT - 用戶退出聊天室
KICK - 禁止參預(yù)聊天
CHRO - 更換聊天室
MESS - 發(fā)送普通信息
PRIV - 發(fā)送私人信息
ROCO - 取得指定聊天室的聊天人數(shù)
CALL - 邀請語音聊天(本文示例中沒有包括)
服務(wù)器端模塊設(shè)計
在本模塊中,我想解釋以下幾點:
·建立一個定制的UserObject類,該類包含了如用戶名,用戶套接字,聊天室名稱等等詳細的客戶端信息。
·當服務(wù)器端運行時,它在端口1436(當然我們也可以修改)開通服務(wù)器端套接字,聽候客戶端的連接。如果客戶連接上服務(wù)器,它將開通一個獨立的服務(wù)線程。這樣,當客戶發(fā)送"QUIT"命令時,它就會關(guān)掉該線程。詳見源文件ChatCommunication.java中的細節(jié)編程。
下面的示例代碼實現(xiàn)了從聊天室客戶端獲取連接并創(chuàng)建一個新的ChatCommunication對象的功能。在類ChatCommunication中,我們將創(chuàng)建一個專門線程來負責(zé)監(jiān)守來自客戶端的所有命令并作出相應(yīng)的回答。
//ChatServer.java
…………
while(true)
{
Socket socket = serversocket.accept();
ChatCommunication chat = new ChatCommunication(socket);
}
.........
//ChatCommunication.java
..........
ChatCommuncation(Socket socket)
{
personalsocket = sokcet;
dout = new Dataoutputstream(personalsocket.getoutoutstream());
.....
}
客戶端模塊設(shè)計
在本模塊中,我想解釋以下幾點:
·當客戶端運行時,它開通一個套接字并通過發(fā)送 HELO RFC給服務(wù)器與ChatServer 建立連接。一旦連接上,客戶端將一直保持該套接字的連接和與服務(wù)器的通信,無論用戶在什么時候發(fā)送命令。
·關(guān)于用戶接口的設(shè)計。我建立了定制的Tab組件和Image支持的消息畫布。
·創(chuàng)建消息畫布的基本邏輯較簡單些:無論用戶什么時候輸入消息,我都把該消息存儲到一個數(shù)組列表中。而且,在這個列表中,我保留了每條消息的X和Y的偏移位置。詳見下面的源碼解釋:
//Ex:
...........
for(int i =0; i < messagearraylist.size();i++)
{
PaintMessageToMessageCanvas((MessageObject)messagearraylist.get(i);
}.........
/**************************************************************
下面函數(shù)用來繪制圖像和文本消息
**************************************************************/
private void PaintMessageIntoCanvas(MessageObject messageObject)
{
int m_YPos = messageobject.StartY - YOffset;
int m_XPos = 5 - XOffset;
int CustomWidth = 0;
String Message = messageobject.Message;
/*************以用戶名字體打印出用戶名 **************/
if(Message.indexOf(":") >= 0)
{
graphics.setFont(UserNameFont);
chatclient.getGraphics().setFont(UserNameFont);
fontmetrics = chatclient.getGraphics().getFontMetrics();
String m_UserName = Message.substring(0,Message.indexOf(":")+1);
graphics.drawString(m_UserName,m_XPos+CustomWidth,m_YPos);
CustomWidth+=fontmetrics.stringWidth(m_UserName)+HorizantalSpace;
Message = Message.substring(Message.indexOf(":")+1);
}
/*********設(shè)置文本的字體**********/
chatclient.getGraphics().setFont(TextFont);
graphics.setFont(TextFont);
fontmetrics = chatclient.getGraphics().getFontMetrics();
/**********打印圖像區(qū)域********/
if(messageobject.IsImage == true)
{
tokenizer = new StringTokenizer(Message," ");
while(tokenizer.hasMoreTokens())
{
TokenString = tokenizer.nextToken();
if(TokenString.indexOf("~~") >= 0)
{
/********如果是正確的圖像*************/
try {
int m_ImageIndex = Integer.parseInt(TokenString.substring(2));
if((m_ImageIndex >= 0) && (m_ImageIndex < chatclient.IconCount))
{
graphics.drawImage(chatclient.IconArray[m_ImageIndex]
,m_XPos+CustomWidth,m_YPos - 15,messageobject.Width,messageobject.Height,this);
CustomWidth+=messageobject.Width+HorizantalSpace;
}
}
catch(Exception _Exc) { }
}
else
{
graphics.drawString(TokenString,m_XPos+CustomWidth,m_YPos);
CustomWidth+=fontmetrics.stringWidth(TokenString)+HorizantalSpace;
}
if(TotalWidth < m_XPos+CustomWidth)
{
TotalWidth = m_XPos+CustomWidth;
scrollview.setValues(TotalWidth,TotalHeight);
}
.................
}