您的位置:首页 > 编程语言

自己写代码 - HelloHi开发流水账 四 不止是String

2010-02-03 17:05 429 查看
最起码消息要包含发言人的信息吧,现在这样子连我说的还是对方说的话都区分不出来。String是不能胜任了,新加HiMessage类。
HiMessage放在客户端还是服务端呢?这取决于HiMessage是否要用于异步调用的返回类型。客户端的代码都要编译成Javascript,虽
说我不懂这玩意,但是我感觉它效率肯定快不了,高举云计算的口号,客户端尽量不留逻辑,得,updateMessages还就返回字符串数组吧,告诉我怎
么显示就行。将来哪怕要更具说话人改颜色,大不了改成用HTML,那也还是字符串。

添加HiMessage类

public
class HiMessage {

private int clientId;

private String
content;

public HiMessage(int clientId, String content) {

this.setClientId(clientId);

this.setContent(content);

}

public void setClientId(int clientId) {

this.clientId = clientId;

}

public int getClientId() {

return clientId;

}

public void setContent(String
content) {

this.content = content;

}

public
String getContent() {

return content;

}

}


改异步接口的实现

@Override

public void sendMessage(int clientId,
String message) {

ArrayList<HiMessage> messageList =
clientMgr.getClient(clientId).getRoom().getMessageList();

messageList.add(new HiMessage(clientId, message));

}

@Override

public String[] updateMessage(int clientId, int
lastIndex) {

ArrayList<HiMessage> messageList =
clientMgr.getClient(clientId).getRoom().getMessageList();

if
(lastIndex >= messageList.size()) {

return null;

}

String[] messageArray = new String[messageList.size()
- lastIndex];

for (int i = lastIndex; i <
messageList.size(); i++) {

HiMessage message =
messageList.get(i);

String messageStr = "";

if (clientId == message.getClientId()) {

messageStr
+= "You:";

} else {

messageStr +=
"Stranger:";

}

messageStr +=
message.getContent();

messageArray[i - lastIndex] =
messageStr;

}

return messageArray;

}


在已经能区分消息是谁发的了。不过还是有点丑,很明显客户端需要对消息数据做一些处理,现在我突然强烈怀疑返回纯字符串的接口设计。原本想即使要更改显示
的方式,也可以以HTML的方式返回纯字符串。啊,这让我想起了jsp,我不怎么喜欢这个。也许CS之间通信就应该只有数据本身,单纯的数据。改,让
updateMessage返回HiMessage[]类型。然后在客户端就可以得到消息的发布者的clientId,和自己的一对比就知道是自己发的,
还是别人发的。现在,客户端已经有能力自己规定如何显示消息了。也许是时候包装一下了。

创建了一个HiMessageUi类,继承
Composite,负责显示得到的消息,呃,前面的发信人最好换个颜色和字体,然后换一行再空出几个像素开始显示消息正文应该比较好。尝试了很久,利用
Chrome看了看Omegle和web
qq的实现,发现GWT的接口不太够用了,什么padding之类的都没有,虽然也可以在Java代码里取得DOM对象进行操作,不过貌似GWT2.0有
了一种叫UiBinder的东西。趁机看了下,感觉还不错,决定用这个来做UI了。

创建UiBinder HiMessageUi

<!DOCTYPE
ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">

<ui:UiBinder
xmlns:ui="urn:ui:com.google.gwt.uibinder"

xmlns:g="urn:import:com.google.gwt.user.client.ui">

<ui:style>

/* Add CSS here. See the GWT docs on UI
Binder for more details */

.message {

padding:
5px;

}

.sender {

color: blue;

}

.content {

padding-left: 12px;

word-break: break-all;

word-wrap: break-word;

}

</ui:style>

<g:HTMLPanel
styleName="{style.message}">

<g:HTML
styleName="{style.sender}" ui:field="sender"/>

<g:HTML
styleName="{style.content}" ui:field="content"/>

</g:HTMLPanel>

</ui:UiBinder>

public
class HiMessageUi extends Composite {

private static
HiMessageUiUiBinder uiBinder = GWT

.create(HiMessageUiUiBinder.class);

interface
HiMessageUiUiBinder extends UiBinder<Widget, HiMessageUi> {

}

@UiField

HTML sender;

@UiField

HTML content;

public HiMessageUi(String sender, String
content) {

initWidget(uiBinder.createAndBindUi(this));

// Can access @UiField after calling createAndBindUi

this.sender.setText(sender);

this.content.setText(content);

}

}
然后修改updateMessage

@Override

public void onSuccess(HiMessage[] result) {

if (result != null && result.length != 0) {

for (HiMessage message : result) {

if (message.getClientId() == clientId) {

contentPanel.add(new HiMessageUi("You:",
message.getContent()));

} else {

contentPanel.add(new
HiMessageUi("Stanger:", message.getContent()));

}

lastIndex++;

}

scrollPanel.scrollToBottom();

}

}
感觉还不错。索性彻底把Ui都改成UiBinder的方
式。

新建UiBinder HiChatUi

<!DOCTYPE ui:UiBinder SYSTEM
"http://dl.google.com/gwt/DTD/xhtml.ent">

<ui:UiBinder
xmlns:ui="urn:ui:com.google.gwt.uibinder"

xmlns:g="urn:import:com.google.gwt.user.client.ui">

<ui:style>

.important {

font-weight:
bold;

}

</ui:style>

<g:HTMLPanel>

<g:DecoratorPanel>

<g:VerticalPanel>

<g:ScrollPanel width="500px" height="400px"
ui:field="scrollPanel">

<g:VerticalPanel
ui:field="contentPanel"/>

</g:ScrollPanel>

<g:TextArea width="500px" height="120px"
ui:field="inputText"/>

</g:VerticalPanel>

</g:DecoratorPanel>

</g:HTMLPanel>

</ui:UiBinder>

再把原来的HelloUi里面相关的内容移到HiChatUi里面

public class HiChatUi
extends Composite {

private static HelloHiUiUiBinder uiBinder
= GWT

.create(HelloHiUiUiBinder.class);

interface HelloHiUiUiBinder extends UiBinder<Widget, HiChatUi> {

}

@UiField

VerticalPanel contentPanel;

@UiField

TextArea inputText;

@UiField

ScrollPanel
scrollPanel;

private int clientId = -1;

private
HelloServiceAsync service = GWT.create(HelloService.class);

private int lastIndex = 0;

private Timer timer = new
Timer() {

@Override

public void run() {

update();

}

};

public HiChatUi() {

initWidget(uiBinder.createAndBindUi(this));

timer.scheduleRepeating(2000);//ms

}

@UiHandler("inputText")

void onKeyPress(KeyPressEvent event) {

if (event.getCharCode() == KeyCodes.KEY_ENTER) {

sendMessage();

}

}

private void initClientId()
{

service.getClientId(new AsyncCallback<Integer>() {

@Override

public void onFailure(Throwable
caught) {

// TODO Auto-generated method stub

}

@Override

public void onSuccess(Integer result) {

clientId
= result;

}

});

}

private void update() {

if (clientId == -1) {

initClientId();

} else {

service.updateMessage(clientId, lastIndex, new
AsyncCallback<HiMessage[]>() {

@Override

public void onFailure(Throwable caught) {

// TODO Auto-generated method stub

}

@Override

public void onSuccess(HiMessage[] result) {

if
(result != null && result.length != 0) {

for (HiMessage message : result) {

if (message.getClientId() == clientId) {

contentPanel.add(new HiMessageUi("You:", message.getContent()));

} else {

contentPanel.add(new HiMessageUi("Stanger:", message.getContent()));

}

lastIndex++;

}

scrollPanel.scrollToBottom();

}

}

});

}

}

private void sendMessage() {

String input =
inputText.getText();

if (!input.isEmpty()) {

service.sendMessage(clientId, input, new AsyncCallback<Void>() {

@Override

public void
onFailure(Throwable caught) {

// TODO
Auto-generated method stub

}

@Override

public void onSuccess(Void
result) {

inputText.setText("");

update();

}

});

}

}

}

实际上两个类区别并不大,不过一个是在构造函数里写代码画
Ui,另一个是在xml里面定义Ui,稍微直观一点罢了。原来的HelloUi可以删掉了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐