一、 添加完成后的最终效果
如图划红线并用红线圈住的地方,就是状态栏显示的踢球信息
二、 让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; |
3 | import java.util.HashMap; |
6 | import org.eclipse.jface.action.StatusLineContributionItem; |
8 | public class ContributionPool { |
9 | private final Map<String,StatusLineContributionItem> cmap = new HashMap<String,StatusLineContributionItem>(); |
11 | private static final ContributionPool cpool = new ContributionPool(); |
13 | private ContributionPool(){} |
15 | public static ContributionPool getInstance(){ |
19 | public void setContrbution(String key,StatusLineContributionItem item){ |
20 | if(!cmap.containsKey(key)){ |
25 | public StatusLineContributionItem getContrbution(String key){ |
26 | if(cmap.containsKey(key)){ |
这个类就是一个Contribution池,也就是可以包含多个StatusLineContributionItem对象,该类是一个单例类。
2、 修改ApplicationActionBarAdvisor类
修改完成后的代码如下:
1 | package cn.v5cn.swt_wwj; |
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; |
10 | import cn.v5cn.swt_wwj.util.ContributionPool; |
12 | public class ApplicationActionBarAdvisor extends ActionBarAdvisor { |
14 | StatusLineContributionItem longitude; |
15 | StatusLineContributionItem latitude; |
16 | StatusLineContributionItem altitude; |
17 | StatusLineContributionItem elevation; |
19 | public ApplicationActionBarAdvisor(IActionBarConfigurer configurer) { |
23 | protected void makeActions(IWorkbenchWindow window) { |
27 | protected void fillMenuBar(IMenuManager menuBar) { |
29 | longitude = new StatusLineContributionItem("longitude", 20); |
30 | longitude.setText("经度:0"); |
31 | longitude.setVisible(true); |
32 | ContributionPool.getInstance().setContrbution("longitude", longitude); |
34 | latitude = new StatusLineContributionItem("latitude", 20); |
35 | latitude.setText("纬度:0"); |
36 | latitude.setVisible(true); |
37 | ContributionPool.getInstance().setContrbution("latitude", latitude); |
39 | altitude = new StatusLineContributionItem("altitude", 20); |
40 | altitude.setText("高度:0千米"); |
41 | altitude.setVisible(true); |
42 | ContributionPool.getInstance().setContrbution("altitude", altitude); |
44 | elevation = new StatusLineContributionItem("elevation", 20); |
45 | elevation.setText("海拔:0米"); |
46 | elevation.setVisible(true); |
47 | ContributionPool.getInstance().setContrbution("elevation", elevation); |
51 | protected void fillStatusLine(IStatusLineManager statusLine) { |
54 | statusLine.add(longitude); |
55 | statusLine.add(latitude); |
56 | statusLine.add(altitude); |
57 | statusLine.add(elevation); |
每一个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; |
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; |
12 | import java.awt.EventQueue; |
14 | import org.eclipse.jface.action.StatusLineContributionItem; |
15 | import org.eclipse.swt.widgets.Display; |
17 | import cn.v5cn.swt_wwj.util.ContributionPool; |
19 | public class StatusBarData implements PositionListener,RenderingListener { |
21 | private WorldWindow dataSource; |
23 | public final static String UNIT_METRIC = "gov.nasa.worldwind.StatusBar.Metric"; |
24 | public final static String UNIT_IMPERIAL = "gov.nasa.worldwind.StatusBar.Imperial"; |
26 | private String elevationUnit = UNIT_METRIC; |
27 | private String angleFormat = Angle.ANGLE_FORMAT_DD; |
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; |
35 | public StatusBarData(){ |
36 | longitude = cpool.getContrbution("longitude"); |
37 | latitude = cpool.getContrbution("latitude"); |
38 | altitude = cpool.getContrbution("altitude"); |
39 | elevation = cpool.getContrbution("elevation"); |
43 | public void stageChanged(RenderingEvent event) { |
44 | if (!event.getStage().equals(RenderingEvent.BEFORE_BUFFER_SWAP)) |
47 | EventQueue.invokeLater(new Runnable() { |
49 | if (dataSource.getView() != null && dataSource.getView().getEyePosition() != null){ |
50 | Display.getDefault().asyncExec(new Runnable() { |
53 | altitude.setText(makeEyeAltitudeDescription(dataSource.getView().getEyePosition().getElevation())); |
63 | public void moved(PositionEvent event) { |
65 | handleCursorPositionChange(event); |
69 | public void setDataSource(WorldWindow dataSource){ |
70 | if(dataSource != null){ |
71 | dataSource.removePositionListener(this); |
72 | dataSource.removeRenderingListener(this); |
74 | dataSource.addPositionListener(this); |
75 | dataSource.addRenderingListener(this); |
77 | this.dataSource = dataSource; |
80 | protected String makeCursorElevationDescription(double metersElevation) { |
83 | if (UNIT_IMPERIAL.equals(elevationUnit)) |
84 | s = String.format(elev + " %,7d 英尺",(int) (WWMath.convertMetersToFeet(metersElevation))); |
87 | s = String.format(elev + " %,7d 米", (int) metersElevation); |
91 | protected String makeEyeAltitudeDescription(double metersAltitude) { |
93 | String altitude = "高度:"; |
94 | if (UNIT_IMPERIAL.equals(elevationUnit)) |
95 | s = String.format(altitude + " %,7d mi", (int) Math.round(WWMath.convertMetersToMiles(metersAltitude))); |
98 | s = String.format(altitude + " %,7d 千米",(int) Math.round(metersAltitude / 1e3)); |
102 | protected String makeAngleDescription(String label, Angle angle) { |
104 | if (Angle.ANGLE_FORMAT_DMS.equals(angleFormat)) |
105 | s = String.format("%s %s", label, angle.toDMSString()); |
107 | s = String.format("%s %7.4f\u00B0", label, angle.degrees); |
111 | protected void handleCursorPositionChange(final PositionEvent event){ |
112 | Display.getDefault().asyncExec(new Runnable() { |
115 | Position newPos = event.getPosition(); |
117 | String las = makeAngleDescription("纬度", newPos.getLatitude()); |
118 | String los = makeAngleDescription("经度", newPos.getLongitude()); |
119 | String els = makeCursorElevationDescription(dataSource.getModel() |
121 | .getElevation(newPos.getLatitude(), newPos.getLongitude())); |
122 | latitude.setText(las); |
123 | longitude.setText(los); |
124 | elevation.setText(els); |
126 | latitude.setText(""); |
127 | longitude.setText(""); |
128 | elevation.setText(""); |
该类包含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、 完成后启动程序,鼠标在地图上滑动,大家会看到底下状态栏信息随之鼠标滑动而改变
