eclipse 狀態欄



WorldWind嵌入EclipseRCP框架(四)-爲地圖添加狀態欄信息

一、    添加完成後的最終效果

如圖劃紅線並用紅線圈住的地方,就是狀態欄顯示的踢球信息

二、    讓Eclipse顯示狀態欄

1、  顯示狀態欄

Eclipse的狀態欄默認是不顯示的,所以需要修改ApplicationWorkbenchWindowAdvisor類的preWindowOpen()方法在其中添加。configurer.setShowStatusLine(true);代碼,這樣就可以顯示狀態欄了。

2、  Eclipse狀態欄分類

Elicpse的狀態欄分爲五種:

  • Fast Views—Fast Views區域顯示從窗口中刪除的視圖,但可以單擊這一欄停靠的圖標迅速進行訪問
  • Icon/Message—-狀態欄共享,任何部分有焦點都可以進行工具
  • Progress—-第一個Progress區域用於顯示模型進度。它通常是看不見的,直到IWorkbenchWindow.run()操作被調用。只有在該操作運行時,進度指示器和Cancel按鈕纔可見。
  • Contributions—-Contributions區域保留給Workbench顧問和激活部分共享。
  • Job Progress—-Job Progress區域默認情況下是隱藏的,但可以通過調用IWorkbenchWindowConfigurator.setShowProgressIndicator(boolean)來被啓動。

各個狀態欄信息在狀態欄中的位置如下圖:

3、  讓狀態欄顯示地球信息

顯示地球信息我們在這裏只關心Contributions狀態欄。爲了是Contributions顯示不是緊貼右邊的邊我們需要讓JobProgress狀態欄也顯示出來,我們需要設置ApplicationWorkbenchWindowAdvisor類的preWindowOpen()方法中設置configurer.setShowProgressIndicator(true),這樣JobProgress就會佔用右邊的一塊位置。

三、    設置地理信息狀態欄

1、  創建ContributionPool類

創建cn.v5cn.swt_wwj.util包,並在其中創建ContributionPool類,源碼如下:

1 package cn.v5cn.swt_wwj.util;
2  
3 import java.util.HashMap;
4 import java.util.Map;
5  
6 import org.eclipse.jface.action.StatusLineContributionItem;
7  
8 public class ContributionPool {
9     private final Map<String,StatusLineContributionItem> cmap = new HashMap<String,StatusLineContributionItem>();
10  
11     private static final ContributionPool cpool = new ContributionPool();
12  
13     private ContributionPool(){}
14  
15     public static ContributionPool getInstance(){
16         return cpool;
17     }
18  
19     public void setContrbution(String key,StatusLineContributionItem item){
20         if(!cmap.containsKey(key)){
21             cmap.put(key, item);
22         }
23     }
24  
25     public StatusLineContributionItem getContrbution(String key){
26         if(cmap.containsKey(key)){
27             return cmap.get(key);
28         }
29         return null;
30     }
31  
32 }

這個類就是一個Contribution池,也就是可以包含多個StatusLineContributionItem對象,該類是一個單例類。

2、  修改ApplicationActionBarAdvisor類

修改完成後的代碼如下:

1 package cn.v5cn.swt_wwj;
2  
3 import org.eclipse.jface.action.IMenuManager;
4 import org.eclipse.jface.action.IStatusLineManager;
5 import org.eclipse.jface.action.StatusLineContributionItem;
6 import org.eclipse.ui.IWorkbenchWindow;
7 import org.eclipse.ui.application.ActionBarAdvisor;
8 import org.eclipse.ui.application.IActionBarConfigurer;
9  
10 import cn.v5cn.swt_wwj.util.ContributionPool;
11  
12 public class ApplicationActionBarAdvisor extends ActionBarAdvisor {
13  
14     StatusLineContributionItem  longitude;      //經度
15     StatusLineContributionItem  latitude;       //緯度
16     StatusLineContributionItem  altitude;       //高度
17     StatusLineContributionItem  elevation;      //海拔
18  
19     public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) {
20         super(configurer);
21     }
22  
23     protected void makeActions(IWorkbenchWindow window) {
24  
25     }
26  
27     protected void fillMenuBar(IMenuManager menuBar) {
28  
29         longitude = new StatusLineContributionItem("longitude", 20);
30         longitude.setText("經度:0");
31         longitude.setVisible(true);
32         ContributionPool.getInstance().setContrbution("longitude", longitude);
33  
34         latitude = new StatusLineContributionItem("latitude", 20);
35         latitude.setText("緯度:0");
36         latitude.setVisible(true);
37         ContributionPool.getInstance().setContrbution("latitude", latitude);
38  
39         altitude = new StatusLineContributionItem("altitude", 20);
40         altitude.setText("高度:0千米");
41         altitude.setVisible(true);
42         ContributionPool.getInstance().setContrbution("altitude", altitude);
43  
44         elevation = new StatusLineContributionItem("elevation", 20);
45         elevation.setText("海拔:0米");
46         elevation.setVisible(true);
47         ContributionPool.getInstance().setContrbution("elevation", elevation);
48     }
49  
50     @Override
51     protected void fillStatusLine(IStatusLineManager statusLine) {
52         //在狀態欄創建之前這個方法就被調用了,所以不能在這個裏面設置參數
53 //      contribution.setVisible(true);
54         statusLine.add(longitude);
55         statusLine.add(latitude);
56         statusLine.add(altitude);
57         statusLine.add(elevation);
58     }
59 }

每一個Contribution就是一個StatusLineContributionItem類的對象,所以在這個類裏面創建了四個StatusLineContributionItem類的對象分別表示經度、緯度、高度和海拔。

makeAction()方法是創建菜單和狀態欄信息的方法,創建是個StatusLineContributionItem對象,傳入ID和字符寬度,並設置他的表示是否顯示。把對象添加的上面創建的池中。fillMenuBar()方法填充菜單和工具欄方法。fillStatusLine()是填充狀態欄使用的方法,所以在這裏添加上面創建的StatusLineContributionItem對象。

3、  運行應用

這個時候大家運行應用程序就會看到顯示到狀態欄中的四個狀態,只是現在還沒有交互

四、    爲狀態欄添加交互

1、  創建StatusBarData類

創建cn.v5cn.swt_wwj.status包,並在其中創建StatusBarData類該類實現PositionListener,RenderingListener兩個接口。代碼如下:

1 package cn.v5cn.swt_wwj.status;
2  
3 import gov.nasa.worldwind.WorldWindow;
4 import gov.nasa.worldwind.event.PositionEvent;
5 import gov.nasa.worldwind.event.PositionListener;
6 import gov.nasa.worldwind.event.RenderingEvent;
7 import gov.nasa.worldwind.event.RenderingListener;
8 import gov.nasa.worldwind.geom.Angle;
9 import gov.nasa.worldwind.geom.Position;
10 import gov.nasa.worldwind.util.WWMath;
11  
12 import java.awt.EventQueue;
13  
14 import org.eclipse.jface.action.StatusLineContributionItem;
15 import org.eclipse.swt.widgets.Display;
16  
17 import cn.v5cn.swt_wwj.util.ContributionPool;
18  
19 public class StatusBarData implements PositionListener,RenderingListener {
20  
21     private WorldWindow dataSource;
22  
23     public final static String UNIT_METRIC = "gov.nasa.worldwind.StatusBar.Metric";
24     public final static String UNIT_IMPERIAL = "gov.nasa.worldwind.StatusBar.Imperial";
25  
26     private String elevationUnit = UNIT_METRIC;
27     private String angleFormat = Angle.ANGLE_FORMAT_DD;
28  
29     private ContributionPool cpool = ContributionPool.getInstance();
30     private StatusLineContributionItem  longitude = null;       //經度
31     private StatusLineContributionItem  latitude = null;        //緯度
32     private StatusLineContributionItem  altitude = null;        //高度
33     private StatusLineContributionItem  elevation = null;       //海拔
34  
35     public StatusBarData(){
36         longitude = cpool.getContrbution("longitude");      //經度
37         latitude = cpool.getContrbution("latitude");        //緯度
38         altitude = cpool.getContrbution("altitude");        //高度
39         elevation = cpool.getContrbution("elevation");
40     }
41  
42     @Override
43     public void stageChanged(RenderingEvent event) {
44         if (!event.getStage().equals(RenderingEvent.BEFORE_BUFFER_SWAP))
45             return;
46  
47         EventQueue.invokeLater(new Runnable() {
48             public void run() {
49                 if (dataSource.getView() != null && dataSource.getView().getEyePosition() != null){
50                     Display.getDefault().asyncExec(new Runnable() {
51                         @Override
52                         public void run() {
53                             altitude.setText(makeEyeAltitudeDescription(dataSource.getView().getEyePosition().getElevation()));
54                         }
55                     });
56                 }else
57                     altitude.setText("");
58             }
59         });
60     }
61  
62     @Override
63     public void moved(PositionEvent event) {
64  
65         handleCursorPositionChange(event);
66  
67     }
68  
69     public void setDataSource(WorldWindow dataSource){
70         if(dataSource != null){
71             dataSource.removePositionListener(this);
72             dataSource.removeRenderingListener(this);
73         }
74         dataSource.addPositionListener(this);
75         dataSource.addRenderingListener(this);
76  
77         this.dataSource = dataSource;
78     }
79  
80     protected String makeCursorElevationDescription(double metersElevation) {
81         String s;
82         String elev = "海拔:";
83         if (UNIT_IMPERIAL.equals(elevationUnit))
84             s = String.format(elev + " %,7d 英尺",(int) (WWMath.convertMetersToFeet(metersElevation)));
85         else
86             // Default to metric units.
87             s = String.format(elev + " %,7d 米", (int) metersElevation);
88         return s;
89     }
90  
91     protected String makeEyeAltitudeDescription(double metersAltitude) {
92         String s;
93         String altitude = "高度:";
94         if (UNIT_IMPERIAL.equals(elevationUnit))
95             s = String.format(altitude + " %,7d mi", (int) Math.round(WWMath.convertMetersToMiles(metersAltitude)));
96         else
97             // Default to metric units.
98             s = String.format(altitude + " %,7d 千米",(int) Math.round(metersAltitude / 1e3));
99         return s;
100     }
101  
102     protected String makeAngleDescription(String label, Angle angle) {
103         String s;
104         if (Angle.ANGLE_FORMAT_DMS.equals(angleFormat))
105             s = String.format("%s %s", label, angle.toDMSString());
106         else
107             s = String.format("%s %7.4f\u00B0", label, angle.degrees);
108         return s;
109     }
110  
111     protected void handleCursorPositionChange(final PositionEvent event){
112         Display.getDefault().asyncExec(new Runnable() {
113             @Override
114             public void run() {
115                 Position newPos = event.getPosition();
116                 if(newPos != null){
117                     String las = makeAngleDescription("緯度", newPos.getLatitude());
118                     String los = makeAngleDescription("經度", newPos.getLongitude());
119                     String els = makeCursorElevationDescription(dataSource.getModel()
120                             .getGlobe()
121                             .getElevation(newPos.getLatitude(), newPos.getLongitude()));
122                     latitude.setText(las);
123                     longitude.setText(los);
124                     elevation.setText(els);
125                 }else{
126                     latitude.setText("");
127                     longitude.setText("");
128                     elevation.setText("");
129                 }
130             }
131         });
132     }
133  
134 }

該類包含WorldWindow對象,通過ContributionPool獲得是個StatusLineContributionItem對象,類中最主要的方法是stageChanged()獲得高度值handleCursorPositionChange()獲得海拔、經度和緯度值,值得注意的是兩個方法都有Display.getDefault().asyncExec(new Runnable() {線程包裹這是因爲SWT的UI線程是不允許其他線程信息訪問的。解決這個錯誤就通過添加Display.getDefault.asyncExce(new Runnable(){ run(){}})加一解決。代碼的其他部分大家可以參考WorldWind源碼中gov.nasa.worldwind.util. StatusBar類。

2、  修改WWJView類

修改WWJView類的createPartControl()方法在方法最後添加new StatusBarData().setDataSource(wwd)這樣就完成了,狀態欄動態顯示地圖狀態信息。

3、  完成後啓動程序,鼠標在地圖上滑動,大家會看到底下狀態欄信息隨之鼠標滑動而改變

 



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章