Eclipse中的特定于平台的代码

时间:2015-10-14 07:21:33

标签: java linux eclipse swt eclipse-rcp

我们正在开发一个带有图形布局组件的Java桌面/ Eclipse RCP应用程序。我们在Windows上遇到了更新(8,8.1,10)版本的GUI缩放问题,似乎只能通过win32 api调用检索缩放因子,所以我们添加了一个小DLL来执行此操作并通过JNI调用它。在windows上工作正常,在linux / osx上的maven中工作正常,因为类从未在那里实例化。

问题在于,要获得缩放因子,我们需要窗口句柄,我们可以像这样检索:

public float getScale(GC gc) {
  return getScale(gc.getGCData().hwnd);
}

其中GCorg.eclipse.swt.graphics.GC,以下调用是dll。但是,在linux上调试时,这些行给了我一个编译错误,因为该对象没有hwnd变量。如何在没有编译错误的情况下以更干净的方式解决这个问题?

1 个答案:

答案 0 :(得分:3)

您可以使用插件片段,因为Greg已消化。片段可以有一个platform filter,当当前平台与过滤器表达式不匹配时,它会阻止它被加载。

Windws 32bit的平台过滤器如下所示:

d3.select(window).on("resize", throttle);

var zoom = d3.behavior.zoom()
    .scaleExtent([1, 8])
    .on("zoom", move);

var width = document.getElementById('container').offsetWidth-60;
var height = width / 2;
var dataset = [{W: -5.0, N: 50.0, E: 10.0, S: 40.0 }, {W: -95.0, N: 50.0, E: -40.0, S: 40.0 }];
var topo,projection,path,svg,g;

var tooltip = d3.select("#container").append("div").attr("class", "tooltip hidden");

setup(width,height);

function setup(width,height){
  projection = d3.geo.mercator()
    .translate([0, 0])
    .scale(width / 2 / Math.PI);

  path = d3.geo.path()
      .projection(projection);

  svg = d3.select("#container").append("svg")
      .attr("width", width)
      .attr("height", height)
      .append("g")
      .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
      .call(zoom);
  g = svg.append("g");


}

d3.json("http://techslides.com/demos/d3/data/world-topo.json", function(error, world) {

  var countries = topojson.feature(world, world.objects.countries).features;

  topo = countries;
  draw(topo);
  dataset.forEach(function(bb){
    var arc = d3.geo.graticule()
      .majorExtent([[bb.W, bb.S], [bb.E, bb.N]])

    g.append("path")
        .attr("class", "arc")
        .attr("d", path(arc.outline()));

  });  
});

function draw(topo) {

  var country = g.selectAll(".country").data(topo);

  country.enter().insert("path")
      .attr("class", "country")
      .attr("d", path)
      .attr("id", function(d,i) { return d.id; })
      .attr("title", function(d,i) { return d.properties.name; })
      .style("fill", function(d, i) { return d.properties.color; });

  //ofsets plus width/height of transform, plsu 20 px of padding, plus 20 extra for tooltip offset off mouse
  var offsetL = document.getElementById('container').offsetLeft+(width/2)+40;
  var offsetT =document.getElementById('container').offsetTop+(height/2)+20;

  //tooltips
  country
    .on("mousemove", function(d,i) {
      var mouse = d3.mouse(svg.node()).map( function(d) { return parseInt(d); } );
        tooltip
          .classed("hidden", false)
          .attr("style", "left:"+(mouse[0]+offsetL)+"px;top:"+(mouse[1]+offsetT)+"px")
          .html(d.properties.name)
      })
      .on("mouseout",  function(d,i) {
        tooltip.classed("hidden", true)
      }); 

}

function redraw() {
  width = document.getElementById('container').offsetWidth-60;
  height = width / 2;
  d3.select('svg').remove();
  setup(width,height);
  draw(topo);
}

function move() {

  var t = d3.event.translate;
  var s = d3.event.scale;  
  var h = height / 3;

  t[0] = Math.min(width / 2 * (s - 1), Math.max(width / 2 * (1 - s), t[0]));
  t[1] = Math.min(height / 2 * (s - 1) + h * s, Math.max(height / 2 * (1 - s) - h * s, t[1]));

  zoom.translate(t);
  g.style("stroke-width", 1 / s).attr("transform", "translate(" + t + ")scale(" + s + ")");

}

var throttleTimer;
function throttle() {
  window.clearTimeout(throttleTimer);
    throttleTimer = window.setTimeout(function() {
      redraw();
    }, 200);
}

片段还必须指定主机包。在运行时,片段资源合并到主机包的类空间

Eclipse-PlatformFilter: (& (osgi.ws=win32) (osgi.os=win32) (osgi.arch=x86))

为避免编译错误,您的主机包中将有一个接口或抽象类,以及两个具有不同Windows和Linux实现的片段。

Windows实现可以安全地访问Fragment-Host: the.parent.bundle 字段,Linux实现可以返回一个值,表明缩放不可用/已修复。

例如,主机包将具有hwnd

ScaleProvider

为简洁起见,实现加载程序接口描述属于一种类型。 class abstract ScaleProvider { ScaleProvider getInstance() { String className = ScaleProvider.class.getName() + "Impl"; try { Class<?> implClass = ScaleProvider.class.getClassLoader().loadClass( className ); return ( ScaleProvider )implClass.newInstance(); } catch( ClassNotFoundException | InstantiationException | IllegalAccessException e ) { throw new RuntimeException( e ); } } abstract float getScale( Gc gc ); } 代码要求名为getInstance()的类存在于同一个包中。

ScaleProviderImpl类由与当前平台匹配的片段提供,并且具有类

ScaleProviderImpl

此示例假定始终存在匹配的平台特定片段。但是,如果找不到class ScaleProviderImpl extends ScaleProvider { float getScale( Gc gc ) { // platform-specific implementation } } ,您当然可以更改getInstance()代码以返回默认实现。