我们正在开发一个带有图形布局组件的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);
}
其中GC
是org.eclipse.swt.graphics.GC
,以下调用是dll。但是,在linux上调试时,这些行给了我一个编译错误,因为该对象没有hwnd
变量。如何在没有编译错误的情况下以更干净的方式解决这个问题?
答案 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()
代码以返回默认实现。