如何根据Windows DPI计算SWT小部件大小

5
我面临的问题是,当我在个性化设置->显示->自定义DPI中将DPI值更改为大于或等于110%时,我的标签不再完全可见。我通过.setLayoutData()设置标签的高度和宽度。当dpi值恢复正常时,这个问题就不会出现了。 我的操作系统:Windows 7 x64,SWT库:swt-4.3-win32-win32-x86.zip。 Eclipse IDE版本:Eclipse RCP Kepler,Java:1.6
这是我如何设置标签的布局数据
public GridData buildENodeBTopLabelGridData() {
   eNBTopLabelGridData = new GridData(SWT.FILL, SWT.FILL, true, true);
   eNBTopLabelGridData.heightHint = 17;
   eNBTopLabelGridData.widthHint = 200;
   return eNBTopLabelGridData;

}

这是我更改DPI之前我的小部件的外观(默认值 -> 100%) http://img194.imageshack.us/img194/3134/e26e.png 这是在更高的DPI值下我的小部件的外观(在这种情况下为110%) http://imageshack.us/photo/my-images/89/1o2t.png/ 如果我在提问的地方或问题的格式上犯了错误,请谅解。 提前感谢您!

为什么您还要手动设置大小呢?这是“布局”的工作。如果您还没有阅读,请参阅:了解SWT中的布局 - Baz
因为我需要控制布局中小部件的排列方式...还有其他方法可以实现吗? - Bogdan
1
取决于你想要做什么。设置固定的宽度/高度限制是不好的实践。 - Baz
我只想在更改操作系统的 DPI 时拥有正常的行为。如果小部件增大,这不是问题,问题是它们变得不够清晰,它们会“吞噬”彼此。我尝试使用 SWT 默认值,但这对我没有解决办法...谢谢回复。 - Bogdan
如果您只是删除宽度和高度限制,会发生什么? - Baz
1
如果我移除宽度和高度的限制,表格会变得更不可见,甚至比之前还要不可见。从我所看到的情况来看...标签内的文本增长速度比小部件本身更快... - Bogdan
1个回答

9
尽管这是一个老问题,但这是我在寻找解决方案时遇到的首个问题之一,因此我想分享我的结果。我为绝对(null)布局开发了这个解决方案,而不是GridLayout,因此必须为其他布局进行调整。然而,总体思路可能会有所帮助。
SWT有一种简单的方法来获取操作系统的当前DPI,即Display.getDefault().getDPI()。在Windows中,100%情况下默认DPI为96。因此,我将此作为比较当前DPI与默认DPI的起点,并根据结果缩放每个小部件。
//I used x here since x and y are always* the same.

public static final int DPI_CURRENT = Display.getDefault().getDPI().x;
public static final float DPI_DEFAULT = 96.0f;
public static final float DPI_SCALE = DPI_CURRENT / DPI_DEFAULT;

如果设置为100%,则此函数将返回值为1.0的DPI_SCALE;如果设置为150%等,则该函数将返回值为1.5。

通过循环运行此函数来缩放应用程序窗口中的每个组件(以及窗口本身),可以得到所需的结果。

public static void scaleToDpi(Composite composite) {
    for(Control control : composite.getChildren()) {
        if(control instanceof Composite) {
            scaleToDpi((Composite) control);
        }
        scaleControl(control);
    }
}

private static void scaleControl(Control control) {
    int x = (int) (control.getLocation().x * DPI_SCALE);
    int y = (int) (control.getLocation().y * DPI_SCALE);
    int w = (int) (control.getSize().x * DPI_SCALE);
    int h = (int) (control.getSize().y * DPI_SCALE);

    control.setBounds(x, y, w, h);
}

假设应用程序使用绝对定位并在通过 scaleToDpi(shell); 进行缩放之前设置了每个小部件的大小,以便为100% DPI设计。希望这些信息对某人有用,即使与 GridLayout 没有直接关系。感谢您阅读我的第一个答案!* 在罕见情况下,DPI 的 xy 可能不总是相同的(我听说过)。

谢谢!您的回答为我节省了相当多的时间 :-) - Stefan Winkler

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接