一、 添加完成后的最终效果
如图划红线并用红线圈住的地方,就是状态栏显示的踢球信息
二、 让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、 完成后启动程序,鼠标在地图上滑动,大家会看到底下状态栏信息随之鼠标滑动而改变