在利用中,有時候需要顯示大段的文字。如游戲中的幫助信息,以及RPG游戲的人物對白。對於這種大批文字的顯示,我們會很自然地想到應用高級界面的Form來顯示,利益就是簡略方便,我們不用往費心文字的斷行排版,Form會為你搞定一切。
但是,有時候我們無法應用高級界面,如游戲規定必需應用低級界面,再有就是RPG類的游戲也是必需要應用低級界面來顯示對白的。
應用低級界面顯示大段文字,要害在於你要把它給排好版。最直接的標題就是:一行可以顯示幾個字?
許多人這樣做:通過真機(必需用真機,模仿器不行的,會有差別)丈量好一行能顯示幾個字,比如說7個。然後把大段的文字分成7個一行,變成了一個字符串數組,如:
final String[] strGameHelp = {
"年份不詳的一個",
"時代中,妖與人",
"類都存在於世界",
"上,並基礎為對",
"立狀態,但是不",
"消除有相處一起",
"的可能,由於人",
"類基礎已經接收",
"世界上有妖的事",
"實了。"
};
有了這麼一個字符串數組,我們就可以循環把它畫出來:
for(int i=0;i<strGameHelp.length;i++){
g.drawString(strGameHelp[i],5,5+20*i,Graphics.TOP|Graphics.LEFT);
}
上NOKIA、SE、MOTO幾個模仿器一看,恩,不錯,很管用,後果很好。當下把幾個版本呼啦呼啦就全給搞定了。
當你正要端起杯子喝口水的時候,策劃跑了過來,K700的文字怎麼出框了,不可能啊,我量好了的,模仿器上看的好好的,不信你看……,策劃取出了K700,你一看,果然出了框,看起來一行只能顯示6個字。無奈,你開端挪字,改成:
final String[] strGameHelp = {
"年份不詳的一",
"個時代中,妖",
"與人類都存在",
"於世界上,並",
"基礎為對峙狀",
"態,但是不排",
"除有相處一起",
"的可能,由於",
"人類基礎已經",
"接收世界上有",
"妖的事實了。"
};
保留,編譯,打包發給策劃。
但策劃拒盡了文件傳送。
干嗎不收啊,你問。
還要改個東西,加一個字,改成“在年份不詳的……”,策劃告訴你。
你想了想,問策劃:能不能不改?
不能。策劃答復的很快,我也不想加的,某某領導請求的。
你無語。准備再開端挪字……
忽然想:我不能總是改文字呀,萬一下次他跑過來說再加個什麼東西怎麼辦?
得想個方法搞定它。
於是寫了個函數:
final int CharacterNumber = 6;public Vector getSubsection(String str) { Vector vector = new Vector(); int i = 0; while (!str.equals("") { if (str.length > 6) { vector.addElement(str.substring(0, CharacterNumber)); str = str.substring(CharacterNumber); } else { vector.addElement(str); str = ""; } } { return vector; }}
再把幫助信息改一改:
final String strGamehelp =
"在年份不詳的一"+
"個時代中,妖"+
"與人類都存在"+
"於世界上,並"+
"基礎為對峙狀"+
"態,但是不排"+
"除有相處一起"+
"的可能,由於"+
"人類基礎已經"+
"接收世界上有"+
"妖的事實了。";
最後是畫出來:
Vector vector = getSubsection(strGamehelp);for(int i=0;i<vector.size();i++){ g.drawString((String)vector.elementAt(i),5,5+20*i,Graphics.TOP|Graphics.LEFT);}vector = null;
這下好了,隨便加,怎麼加我都不怕,嘿嘿,主動換行。
到這是不是結束了?還沒。
一個月後,你開端做英文版,幫助信息改成了英文。你發明幫助界面是慘不忍睹。
本來,英文字母和中文不一樣,它是不等寬字體,有肥有瘦,發育不太均衡。
更重要的是,,英文中一個單詞是不能拆開分成兩行顯示。
怎麼辦。回過往用高級界面?想都不要想。
你打開API手冊查閱,希看能找出點什麼來。
有了,你眼前一亮,印進眼簾的正是Font類供給的stringWidth函數,該函數能夠返回字符串在屏幕上顯示時的長度。
有了這個函數,就可以改良getSubsection函數了
其中,strSource是待斷行的文字,font是畫文字時應用的字體,width是每行的最大寬度,而最後的strSplit是用於分詞的,即英文單詞中的間隔符號,函數依附這個參數來分辨單詞
public Vector getSubsection(String strSource, Font font, int width,
{ i = temp.indexOf("\n"); if (i > 0) { if (font.stringWidth(temp.substring(0, i - 1)) >= width) { i = -1; } } if (i == -1) { if (LastLength > temp.length()) { i = temp.length(); } else { i = LastLength; step = font.stringWidth(temp.substring(0, i)) > width ? -1 : 1; if (i < temp.length()) { while (!(font.stringWidth(temp.substring(0, i)) <= width && font.stringWidth(temp.substring(0, i + 1)) > width)) { i = i + step;
if (i == temp.length()) { break; } } } } if (!strSplit.equals("")) { j = i; if (i < temp.length()) { while (strSplit.indexOf(temp.substring(i - 1, i)) == -1) { i--; if (i == 0) { i = j; break; } } } } } LastLength = i; vector.addElement(temp.substring(0, i)); if (i == temp.length()) { temp = ""; } else { temp = temp.substring(i); if (temp.substring(0, 1).equals(
"\n")) { temp = temp.substring(1); } } } } catch (Exception e) { System.out.println("getSubsection:" + e); } return vector;}再改一下調用的處所:Font font = Font.getFont(Font.FACE_SYSTEM,Font.STYLE_PLAIN, Font.SIZE_SMALL);g.setFont(font);Vector vector = getSubsection(strGamehelp,font,getWidth()-10," ,.?!");
這樣,對於英文我們也可以准確的主動斷行顯示了。
終於,你可以坐下來,喝杯水(咖啡被搶光了),聽點music,享受一下:
1、通用性好,主動適應不同的屏幕大小,各種語言文字通吃。
2、工作量小,你不用往辛苦手工分行,更不用為了加一個字而全部重新來過。想調劑寬度?改一個參數就好。
然而,最最後不得不和你說,千萬要留心的是,必定要留心調用函數時應用的字體和實際應用的字體要一致,不然我會錯(我常犯這樣的錯誤:))