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、  完成后启动程序,鼠标在地图上滑动,大家会看到底下状态栏信息随之鼠标滑动而改变

 



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