TWaver3D機(jī)房不但可以單獨(dú)作為工具使用,而且還提供了獨(dú)立的組件,為開發(fā)者提供二次開發(fā)的能力。
開發(fā)環(huán)境
使用TWaver機(jī)房組件進(jìn)行二次開發(fā),需要以下開發(fā)環(huán)境:
- JDK 6+;
- Java IDE(Netbeans或Eclipse);
- TWaver Java 3.5+;
類結(jié)構(gòu)
TWaver機(jī)房二次開發(fā)涉及到的主要類及其關(guān)系:

其中,各個(gè)類的主要用途如下:
類 |
用途 |
Network2D |
是TWaver Java中TNetwork的一個(gè)擴(kuò)展。作為3D視圖的2D呈現(xiàn)、編輯和數(shù)據(jù)驅(qū)動(dòng)。 |
Floor2D |
和Network2D配合,用于繪制2D視圖中的地板平面。 |
Network3D |
3D視圖,以3D的方式呈現(xiàn)2D視圖中的數(shù)據(jù),并提供縮放、旋轉(zhuǎn)等交互。Network3D必須依賴于Network2D而存在。 |
Floor3D |
和Network3D配合,用于在3D視圖中繪制地板平面的3D視圖。它依賴于Floor2D存在。 |
SittingPane |
一個(gè)封裝好的3D機(jī)房屬性編輯面板。包括3D視圖中的各種參數(shù)設(shè)置,可以用于需要數(shù)據(jù)編輯的場合中。對(duì)于只需要3D數(shù)據(jù)呈現(xiàn)的情況,可以不使用該類。 |
PropertySheet3D |
一個(gè)封裝好的3D數(shù)據(jù)屬性表。當(dāng)一個(gè)或多個(gè)3D數(shù)據(jù)被選中后,所有3D相關(guān)的屬性會(huì)自動(dòng)羅列在這個(gè)屬性表中,方便查看和修改。該類可以用于需要數(shù)據(jù)編輯的場合中。對(duì)于只需要3D數(shù)據(jù)呈現(xiàn)的情況,可以不使用該類。 |
簡單例子
下面的代碼可以創(chuàng)建一個(gè)簡單的3D機(jī)房視圖。該程序只顯示了一個(gè)3D視圖,并顯示了一個(gè)3D立方體物體。3D視圖可以通過鼠標(biāo)的滾輪、拖拽等方式進(jìn)行縮放、平移等操作。
代碼如下:
1
import java.awt.Color;
2
import javax.swing.JFrame;
3
import javax.swing.SwingUtilities;
4
import twaver.TDataBox;
5
import twaver.TWaverConst;
6
import twaver.TWaverUtil;
7
8
public class SimpleTest extends JFrame
{
9
10
private TDataBox box = new TDataBox();
11
private Network2D network2d = new Network2D(box);
12
private Floor2D roomFloor2D = new Floor2D(network2d);
13
private Network3D view3d = new Network3D(network2d, roomFloor2D, 300, 100);
14
15
public SimpleTest()
{
16
this.setTitle("TWaver 3D");
17
this.setSize(900, 600);
18
TWaverUtil.centerWindow(this);
19
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
20
view3d.setScale(1.5);
21
22
this.add(view3d);
23
24
//add a 3d object
25
Element3D element = new Element3D();
26
element.setLocation(100, 100);
27
element.setSize(200, 50);
28
element.setDeep(100);
29
element.setFillColor(Color.orange.darker());
30
network2d.getDataBox().addElement(element);
31
}
32
33
public static void main(String[] args)
{
34
SwingUtilities.invokeLater(new Runnable()
{
35
36
public void run()
{
37
TWaverUtil.setLocale(TWaverConst.EN_US);
38
SimpleTest test = new SimpleTest();
39
test.setVisible(true);
40
}
41
});
42
}
43
運(yùn)行該代碼,效果如下圖:

在3D視圖中顯示Link
和TWaver Java中類似,要在3D視圖中顯示Link,直接在2D Network的DataBox中添加Link對(duì)象即可。以下代碼在2D視圖中創(chuàng)建了幾個(gè)節(jié)點(diǎn)和連線:
1
private void testLink()
{
2
Element3D node1 = new Element3D();
3
node1.setLocation(50, 50);
4
node1.getAlarmState().addNewAlarm(AlarmSeverity.CRITICAL);
5
node1.setDeep(50);
6
node1.setFillColor(Color.green.darker());
7
network2d.getDataBox().addElement(node1);
8
9
Element3D node2 = new Element3D();
10
node2.setLocation(200, 100);
11
node2.setDeep(50);
12
node2.setFillColor(Color.green.darker());
13
network2d.getDataBox().addElement(node2);
14
15
Element3D node3 = new Element3D();
16
node3.setLocation(300, 200);
17
node3.setDeep(50);
18
node3.setFillColor(Color.green.darker());
19
network2d.getDataBox().addElement(node3);
20
21
Link link = new Link(node1, node2);
22
link.putLinkColor(Color.cyan.darker());
23
link.putLinkWidth(8);
24
link.setLinkType(TWaverConst.LINK_TYPE_ORTHOGONAL);
25
link.putLinkOutlineColor(Color.red);
26
link.putLinkOutlineWidth(1);
27
link.putLinkOrthogonalDirection(OrthogonalLinkDirectionType.Y_TO_X);
28
network2d.getDataBox().addElement(link);
29
30
link = new Link(node2, node3);
31
link.putLinkColor(Color.green.darker());
32
link.putLinkWidth(8);
33
link.setLinkType(TWaverConst.LINK_TYPE_FLEXIONAL);
34
link.putLinkOutlineColor(Color.red);
35
link.putLinkOutlineWidth(2);
36
network2d.getDataBox().addElement(link);
37
}
在2D和3D視圖中會(huì)同時(shí)顯示Link,顯示效果如下:

3D視圖會(huì)將Link繪制在地板上,并保持和2D的顏色、邊框、線寬、選擇狀態(tài)等屬性一致。以下是將3D視圖進(jìn)行各角度旋轉(zhuǎn)后Link的顯示效果:

創(chuàng)建3D視圖右鍵菜單
在TWaver 2D的Network組件中已經(jīng)提供了右鍵菜單支持。TWaver通過一個(gè)菜單生成器來動(dòng)態(tài)生成Network的右鍵菜單。下面代碼展示了這種用法:
1
network2d.setPopupMenuGenerator(new PopupMenuGenerator()
{
2
public JPopupMenu generate(TView tview, MouseEvent me)
{
3
JPopupMenu menu = new JPopupMenu();
4
…
5
return menu;
6
}
7
}
8
});
同樣,在3D視圖中,TWaver也提供了類似機(jī)制,并使用了相同的方法名稱和接口。我們可以new一個(gè)PopupMenuGenerator實(shí)例然后同時(shí)應(yīng)用在2D和3D視圖中,如下面代碼:
1
PopupMenuGenerator generator= new PopupMenuGenerator()
{
2
public JPopupMenu generate(TView tview, MouseEvent me)
{
3
JPopupMenu menu = new JPopupMenu();
4
JMenuItem item = new JMenuItem("Create Object Icon");
5
menu.add(item);
6
return menu;
7
}
8
}
9
});
10
network2d. setPopupMenuGenerator(generator);
11
network3d. setPopupMenuGenerator(generator);
運(yùn)行以上代碼可以看到,在2D和3D視圖上右鍵點(diǎn)擊同一個(gè)節(jié)點(diǎn),可以看到同樣的右鍵菜單:

創(chuàng)建簡單的編輯器
上述例子顯示了一個(gè)非常簡單的、只讀的3D視圖。本節(jié)將介紹如何創(chuàng)建一個(gè)簡單的編輯器程序,可以對(duì)數(shù)據(jù)進(jìn)行動(dòng)態(tài)的添加、編輯等操作。其實(shí)在上述例子中已經(jīng)創(chuàng)建了Network2D視圖,只是沒有顯示出來而已。下面的例子將Network2D視圖顯示出來,并增加了SettingPane參數(shù)編輯視圖、PropertySheet3D屬性表等組件,共同構(gòu)成了簡單的編輯器程序。
代碼如下:
1
import java.awt.Color;
2
import java.awt.Insets;
3
import java.awt.event.ActionEvent;
4
import java.awt.event.ActionListener;
5
import javax.swing.JButton;
6
import javax.swing.JComponent;
7
import javax.swing.JFrame;
8
import javax.swing.JSplitPane;
9
import javax.swing.SwingUtilities;
10
import twaver.TDataBox;
11
import twaver.TWaverConst;
12
import twaver.TWaverUtil;
13
import twaver.table.TPropertySheetPane;
14
15
public class Test extends JFrame
{
16
17
private TDataBox box = new TDataBox();
18
private Network2D network2d = new Network2D(box);
19
private Floor2D roomFloor2D = new Floor2D(network2d);
20
private Network3D view3d = new Network3D(network2d, roomFloor2D, 300, 50);
21
private SettingPane settingPane = new SettingPane(roomFloor2D, view3d, 2);
22
private PropertySheet3D sheet = new PropertySheet3D(box);
23
private TPropertySheetPane sheetPane = new TPropertySheetPane(sheet);
24
25
public Test()
{
26
init();
27
}
28
29
private void init()
{
30
this.setTitle("TWaver 3D Room");
31
this.setSize(1000, 700);
32
TWaverUtil.centerWindow(this);
33
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
34
35
JSplitPane split1 = createSplit(sheetPane, network2d, JSplitPane.HORIZONTAL_SPLIT, 300);
36
JSplitPane split2 = createSplit(settingPane, view3d, JSplitPane.HORIZONTAL_SPLIT, 350);
37
JSplitPane split = createSplit(split1, split2, JSplitPane.VERTICAL_SPLIT, 350);
38
39
this.add(split);
40
41
JButton createNodeButton = new JButton("New");
42
createNodeButton.setMargin(new Insets(0, 0, 0, 0));
43
createNodeButton.addActionListener(new ActionListener()
{
44
45
public void actionPerformed(ActionEvent e)
{
46
Element3D element = new Element3D();
47
element.setLocation(100, 100);
48
element.setDeep(50);
49
element.setFillColor(Color.green.darker());
50
network2d.getDataBox().addElement(element);
51
}
52
});
53
network2d.getToolbar().add(createNodeButton);
54
}
55
56
private JSplitPane createSplit(JComponent one, JComponent two, int direction, int dividerLocation)
{
57
JSplitPane split = new JSplitPane(direction);
58
59
split.setLeftComponent(one);
60
split.setTopComponent(one);
61
62
split.setRightComponent(two);
63
split.setBottomComponent(two);
64
65
split.setContinuousLayout(true);
66
split.setDividerLocation(dividerLocation);
67
68
return split;
69
}
70
71
public static void main(String[] args)
{
72
SwingUtilities.invokeLater(new Runnable()
{
73
74
public void run()
{
75
TWaverUtil.setLocale(TWaverConst.EN_US);
76
Test test = new Test();
77
test.setVisible(true);
78
}
79
});
80
}
81
}
上述代碼在Network2D的工具條上添加了一個(gè)按鈕,點(diǎn)擊按鈕后,創(chuàng)建一個(gè)Element3D對(duì)象,并將其設(shè)置在面板上。程序運(yùn)行效果如下圖:

點(diǎn)擊“new”按鈕創(chuàng)建一個(gè)3D物體,并在左側(cè)屬性表中設(shè)置其上、左、右三面的圖片貼圖。效果如下:

保存至文件
要將編輯器中的數(shù)據(jù)保存至文件,可以在工具條上添加一個(gè)按鈕,點(diǎn)擊后將DataBox中的數(shù)據(jù)輸出到XML字符串,然后將字符串保存至文件。
1
String xml = network3d.toXML(true);
2
JFileChooser chooser = new JFileChooser();
3
chooser.setFileFilter(filter);
4
int answer = chooser.showSaveDialog(EditorDemo.this);
5
if (answer == JFileChooser.APPROVE_OPTION)
{
6
String fileName = chooser.getSelectedFile().getAbsolutePath();
7
if (fileName != null)
{
8
if (!fileName.toUpperCase().endsWith(".XML"))
{
9
fileName += ".xml";
10
}
11
OutputStream out = new FileOutputStream(fileName);
12
out.write(xml.getBytes());
13
out.close();
14
}
15
}
從文件打開
對(duì)于保存的數(shù)據(jù),可以寫一個(gè)按鈕,選擇對(duì)應(yīng)的文件,通過DataBox的parse方法進(jìn)行解析,打開數(shù)據(jù)文件。
1
JFileChooser chooser = new JFileChooser();
2
chooser.setFileFilter(filter);
3
int answer = chooser.showOpenDialog(EditorDemo.this);
4
if (answer == JFileChooser.APPROVE_OPTION)
{
5
File file = chooser.getSelectedFile();
6
if (file.exists())
{
7
network2d.getDataBox().clear();
8
network3d.clearObject3D();
9
InputStream input = new FileInputStream(file);
10
network2d.getDataBox().parse(input);
11
}
12
}
Element3D主要屬性
通過以上例子可以發(fā)現(xiàn),創(chuàng)建一個(gè)3D視圖非常簡單。在3D視圖中創(chuàng)建一個(gè)3D數(shù)據(jù)的主要代碼只有如下幾行:
1
Element3D element = new Element3D();
2
element.setLocation(100, 100);
3
element.setDeep(50);
4
element.setFillColor(Color.green.darker());
5
network2d.getDataBox().addElement(element);
Element3D實(shí)際上是一個(gè)普通的TWaver Element對(duì)象,它從TWaver預(yù)定義的Element——ResizableNode繼承而來,并封裝了3D物體的基本屬性,例如左側(cè)圖片、右側(cè)圖片、頂部圖片等等。通過設(shè)置和修改這些屬性,即可實(shí)現(xiàn)對(duì)3D物體的外觀定制。
Element3D類的主要屬性羅列如下。注意:所有setLeft***均作用域左側(cè)里面,而右側(cè)立面均有對(duì)應(yīng)的setRight***方法,其功能是對(duì)右側(cè)立面進(jìn)行相應(yīng)的功能設(shè)置。
- setFillColor:設(shè)置填充顏色;
- setDeep:設(shè)置3D物體的厚度(也就是三維中的高度);
- setPaintLeft:是否左側(cè)立面可見。當(dāng)設(shè)置false,整個(gè)左側(cè)立面將消失;
- setLeftImageUrl:設(shè)置左側(cè)立面的貼圖。和TWaver Java中的慣例一樣,給定圖片的URL字符串即可。注意:默認(rèn)的貼圖方法,是將圖片拉伸并鋪滿整個(gè)左側(cè)立面。如需要邊距或自定義邊界,可以使用setLeftImageBounds方法進(jìn)行設(shè)置;
- setLeftImageBounds:設(shè)置左側(cè)立面的固定邊界。該函數(shù)可以強(qiáng)制指定左側(cè)立面圖片的起始坐標(biāo)位置和圖片的寬高;
- setLeftImageTexture:指定左側(cè)立面貼圖是否使用紋理模式。如果設(shè)置true,則貼圖會(huì)被作為紋理進(jìn)行全立面貼圖。注意:一旦啟用紋理,ImageBounds參數(shù)將不再起作用;
- setLeftImageTextureScale:設(shè)置左側(cè)立面紋理貼圖的放大比例。默認(rèn)值為3。當(dāng)該值越大,紋理的單位貼圖尺寸也更大;
- isPaintTop:是否頂面可見。當(dāng)設(shè)置false,物體的頂面將會(huì)消失;
- setTopImageUrl:物體的頂面貼圖。注意:一旦設(shè)置頂面貼圖,則Network2D中物體的圖片將使用該頂面貼圖進(jìn)行顯示。
Network3D主要屬性
Network3D類是用來呈現(xiàn)3D場景的組件。注意它并非從TWaver Java的TNetwork或上面提到的TNetwork2D繼承而來,而是直接從Swing的JPanel擴(kuò)展而來。Network3D必須依賴于Network2D而存在,從而從Network2D獲得數(shù)據(jù)。此外,Network3D還必須設(shè)置一個(gè)Floor2D的類,用來繪制3D的場景地平面。Network3D還提供了構(gòu)造函數(shù)可以直接設(shè)置其3D坐標(biāo)原點(diǎn)的屏幕坐標(biāo)位置。
Network3D的構(gòu)造函數(shù):
1
//給定Network2D和Floor2D進(jìn)行構(gòu)造
2
public Network3D(Network2D network2d, Floor2D floor2d)
3
//給定Network2D和Floor2D進(jìn)行構(gòu)造,同時(shí)指定3D場景的坐標(biāo)原點(diǎn)的位置。
4
public Network3D(Network2D network2d, Floor2D floor2d, int originX, int originY)
Network3D的主要函數(shù)和用法如下:
- getNetwork2D:獲得與Network3D綁定的Network2D對(duì)象。
- setScale:設(shè)置3D場景的放大系數(shù)。設(shè)置1為原始比例。也可以通過調(diào)用zoomIn或zoomOut函數(shù)進(jìn)行單次的縮放。
- zoomIn/zoomOut:放大或縮小。每次縮放會(huì)用當(dāng)前縮放因數(shù)乘以(放大)或除以(縮小)scale step數(shù)值(可以通過getScaleStep函數(shù)獲得,其默認(rèn)值是1.2)。
- setScaleStep:設(shè)置單次縮放變化因數(shù)。
- setOrigin:設(shè)置3D坐標(biāo)原點(diǎn)的x和y數(shù)值。
- setHorizontalAngle:設(shè)置3D場景水平旋轉(zhuǎn)角度。必須為0-90度。
- setVerticalAngle:設(shè)置3D場景垂直旋轉(zhuǎn)角度。必須為0-90度。
- getObjectAt:獲得給定坐標(biāo)的3D物體。如果多個(gè)物體存在該點(diǎn),則返回所有物體。
- toXML:將3D場景所有數(shù)據(jù)輸出到XML中。
告警呈現(xiàn)
在TWaver Java中,Network以及其他各組件都有完整的告警呈現(xiàn)能力,例如告警渲染、告警冒泡等。在TWaver 3D機(jī)房中,我們也同樣也提供了該功能。
告警冒泡
當(dāng)一個(gè)物體在發(fā)生新發(fā)告警后,在2D的Network組件一樣,3D視圖也會(huì)繪制完全相同的告警冒泡。告警冒泡的位置在物體的頂面中央位置(如下圖)。同時(shí),3D物體的三個(gè)面的圖片也會(huì)被動(dòng)態(tài)的渲染為告警顏色:

3D物體顏色自定義
TWaver Java的Network本身具有自定義數(shù)據(jù)顏色的接口。通過一個(gè)插入的Generator接口,開發(fā)者可以攔截所有數(shù)據(jù)并返回任意顏色用于繪制數(shù)據(jù)。例如,一個(gè)node的fillColor為綠色,則默認(rèn)會(huì)使用綠色來填充該node;但通過Generator攔截后,可以返回紅色;此時(shí),TWaver Network會(huì)使用紅色來填充物體,而不再是綠色。
同樣,TWaver 3D視圖也提供了同樣的能力。而且,3D視圖直接使用了2D視圖的該Generator,以便3D和2D保持同樣的外觀特性。也就是說,我們不需要在3D視圖上設(shè)置Generator,而是只在3D視圖對(duì)應(yīng)的2D視圖上設(shè)置Generator即可讓2D、3D視圖同時(shí)生效。以下例子強(qiáng)行將2D、3D視圖中所有物體繪制顏色設(shè)置為MAGENTA顏色:
1
network2d.setElementBodyColorGenerator(new Generator()
{
2
public Object generate(Object o)
{
3
return Color.MAGENTA;
4
}
5
});

數(shù)據(jù)的輸入與輸出
默認(rèn)輸出方法
在3D視圖程序中,3D機(jī)房數(shù)據(jù)使用和TWaver Java提供的同樣的對(duì)象XML序列化方法進(jìn)行數(shù)據(jù)的序列化和反序列化,從而實(shí)現(xiàn)數(shù)據(jù)的輸入與輸出。通過TDataBox.output()方法和TDataBox.parse()方法完成數(shù)據(jù)的導(dǎo)出和輸入。不過,為了方便開發(fā)者使用,Network3D類提供了toXML函數(shù)可以直接輸出XML字符串:
1
String xml = this.network3d.toXML(true);
其中的boolean值是用來控制是否對(duì)各立面貼圖進(jìn)行BASE64編碼輸出。
自定義格式輸出
如果要進(jìn)行進(jìn)一步細(xì)致的輸出參數(shù)控制,也可以不適用toXML函數(shù),而直接使用TDataBox的output方法進(jìn)行。以下代碼顯示了如何將內(nèi)存中的3D數(shù)據(jù)導(dǎo)出到XML格式的字符串中并進(jìn)行輸出,同時(shí)對(duì)輸出的各種參數(shù)進(jìn)行控制,例如是否輸出ID、是否輸出告警信息等:
1
ByteArrayOutputStream out = new ByteArrayOutputStream();
2
setting.setWithElementId(false);
3
setting.setWithUserProperty(true);
4
setting.setOutputStream(out);
5
box.output(setting);
6
String xml = out.toString("utf8");
以上代碼可以對(duì)數(shù)據(jù)進(jìn)行XML序列化輸出。
為何使用BASE64圖片編碼輸出
3D物體中的各個(gè)立面貼圖將以URL字符串的方式輸出到XML中。當(dāng)XML被傳輸?shù)狡渌麢C(jī)器或應(yīng)用環(huán)境中,如果圖片的URL資源位置發(fā)生變化,則無法讀到這些圖片。解決這一問題的一個(gè)方法是:在數(shù)據(jù)輸出過程中,使用BASE64編碼對(duì)所有圖片資源進(jìn)行編碼并序列化輸出。這樣,XML中就包含了所有的圖片資源,無論XML被傳輸?shù)侥睦铮伎梢詿o外部依賴的打開。
使用Network3D的toXML函數(shù)可以直接進(jìn)行圖片的BASE64編碼輸出。實(shí)際上,該函數(shù)也是使用了TDataBox的輸出參數(shù)控制機(jī)制,對(duì)用到的圖片進(jìn)行遍歷和編碼設(shè)置。以下代碼展示了其具體實(shí)現(xiàn)方法:
1
//use base64 image encoding output setting.
2
DataBoxOutputSetting setting = new DataBoxOutputSetting();
3
Map images = new HashMap();
4
Iterator it = this.view2d.getDataBox().iterator();
5
while (it.hasNext())
{
6
Element element = (Element) it.next();
7
if (element instanceof RoomNode)
{
8
RoomNode roomNode = (RoomNode) element;
9
this.addImage(images, roomNode.getLeftImageUrl());
10
this.addImage(images, roomNode.getRightImageUrl());
11
this.addImage(images, roomNode.getTopImageUrl());
12
}
13
}
14
setting.setImages(images);
經(jīng)過以上代碼的預(yù)處理之后,再使用這個(gè)setting對(duì)象對(duì)box進(jìn)行序列化,即可實(shí)現(xiàn)BASE64的圖片編碼存儲(chǔ)。
3D物體圖片導(dǎo)出
TWaver 3D視圖提供了對(duì)單個(gè)3D物體進(jìn)行圖片導(dǎo)出的功能。通過下面的方法可以直接將指定的3D物體繪制在一個(gè)Image圖片上:
1
public Image createObjectImage(Object objectID)
以上代碼會(huì)將3D視圖中指定的3D物體繪制在一個(gè)單獨(dú)的Image對(duì)象中返回。該物體在圖片上的大小、角度、材質(zhì)等,均與3D視圖保持一致;Image圖片的大小也會(huì)自動(dòng)裁剪到物體邊緣位置,保持圖片尺寸最小。
請(qǐng)注意該方法并不需要提供導(dǎo)出圖片的大小尺寸。要使用更大或更小的尺寸,或使用不同的旋轉(zhuǎn)角度,可以先通過API或鼠標(biāo)調(diào)整3D視圖的縮放系數(shù)、旋轉(zhuǎn)角度,再使用該方法進(jìn)行圖片導(dǎo)出。
通過這一功能,可以將一些3D物體導(dǎo)出為小圖片或Icon,為其他軟件使用。為了演示這一功能,以下代碼通過右鍵菜單來為某個(gè)3D物體創(chuàng)建導(dǎo)出圖片,并顯示在一個(gè)彈出對(duì)話框中:
1
PopupMenuGenerator generator=new PopupMenuGenerator()
{
2
3
public JPopupMenu generate(TView tview, MouseEvent me)
{
4
TDataBox box = tview.getDataBox();
5
if (box.getSelectionModel().size() == 1)
{
6
Element element = box.getSelectionModel().lastElement();
7
final Object id = element.getID();
8
9
JPopupMenu menu = new JPopupMenu();
10
JMenuItem item = new JMenuItem("Create Object Icon");
11
item.addActionListener(new ActionListener()
{
12
13
public void actionPerformed(ActionEvent e)
{
14
Image image = network3d.createObjectImage(id);
15
if (image != null)
{
16
JDialog dialog = new JDialog(EditorDemo.this);
17
dialog.setModal(true);
18
dialog.add(new JLabel(new ImageIcon(image)));
19
dialog.pack();
20
dialog.setTitle("Object Icon");
21
dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
22
TWaverUtil.centerWindow(dialog);
23
dialog.setVisible(true);
24
}
25
}
26
});
27
menu.add(item);
28
return menu;
29
} else
{
30
return null;
31
}
32
}
33
};
34
network3d.setPopupMenuGenerator(generator);
運(yùn)行以上代碼:

也可以用ImageIO等機(jī)制進(jìn)一步改造以上代碼,把圖片保存到文件中或數(shù)據(jù)庫中。
I18N國際化
切換語言
TWaver Java本身已經(jīng)提供了完整的國際化功能。通過Java的I18N機(jī)制以及TWaver Java包內(nèi)置的多語言資源文件,可以動(dòng)態(tài)的支持不同語言。TWaver 3D直接使用并擴(kuò)展了TWaver Java的國際化機(jī)制,對(duì)TWaver 3D中的組件、對(duì)象屬性名稱等內(nèi)容進(jìn)行了國際化。
要在TWaver 3D機(jī)房中切換國際化,在程序的啟動(dòng)初期,直接調(diào)用TWaver Java提供的API進(jìn)行設(shè)置即可:
1
//set Chinese language for TWaver 3D
2
TWaverUtil.setLocale(TWaverConst.ZH_CN);
3
//set English language for TWaver 3D
4
TWaverUtil.setLocale(TWaverConst.EN_US);
TWaver Java本身提供了中文、英文、西班牙語、日語等多種語言。而TWaver 3D目前僅支持英文、中文兩種語言。
擴(kuò)展資源字符串
TWaver 3D中所有的字符串都通過I18N機(jī)制存放在以下資源文件中:
- \twaver\network\d3\d3_en_US.properties(英文資源文件)
- \twaver\network\d3\d3_zh_CN.properties(中文資源文件)
以上資源文件都被直接打包在twaver3d.jar運(yùn)行文件中。以下是資源文件中的幾個(gè)例子:
d3_zh_CN.properties |
d3_en_US.properties |
image_texture=紋理圖片pick_color=選擇顏色room_name=機(jī)房名稱:
floor_grid_span_count=地板各單位數(shù)量:
network_grid_unit_size=最小單元格大小:
|
image_texture=Image Texturepick_color=Pick Colorroom_name=Room Name:
floor_grid_span_count=Floor Grid Span Count:
network_grid_unit_size=Network Grid Unit Size:
|
其中,等號(hào)左側(cè)是資源鍵值,右側(cè)是對(duì)應(yīng)的語言翻譯。我們可以直接對(duì)翻譯進(jìn)行修改,并更新到包中,來修改TWaver 3D的默認(rèn)翻譯。另外,還可以在資源文件中增加自定義的資源,并在程序中使用。
例如,增加一個(gè)新的國際化字符串:
d3_zh_CN.properties |
d3_en_US.properties |
test_key =測試字符串 |
test_key =Test String |
然后,通過twaver.network.d3.Util.getString(String key)方法來獲取字符串資源:
1
TWaverUtil.setLocale(TWaverConst.ZH_CN);
2
String resource = Util.getString(“test_key”);
3
System.out.println(resource);
4
TWaverUtil.setLocale(TWaverConst.EN_US);
5
String resource = Util.getString(“test_key”);
6
System.out.println(resource);
運(yùn)行結(jié)果:
總結(jié)
通過這個(gè)簡單的介紹,你一定對(duì)TWaver 3D機(jī)房充滿了好奇。要想獲得TWaver 3D機(jī)房產(chǎn)品包,可與我們聯(lián)系。進(jìn)一步深入的探索,會(huì)給你帶來更多的驚喜。