Although it's an old question, this was one of the first I stumbled upon while looking for a solution to this, so I want to share my results. I developed this for an absolute (null) layout however, not a GridLayout
, so it will have to be tweaked for other layouts. The general idea may help though.
SWT has an easy way of fetching the current DPI of the OS, being Display.getDefault().getDPI()
. In Windows, the default DPI (at 100%) is 96. I therefore used this as a starting point to compare the current DPI with the default DPI, and scale each widget based on the result.
//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;
This returns DPI_SCALE
with a value of 1.0 if set to 100%, 1.5 if set to 150% etc.
Running this through a loop to scale each component within the application window (and the window itself) provided me with the desired results.
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);
}
This assumes that the application is designed for 100% DPI using absolute positioning and has set up the size of each widget before running the scaling via scaleToDpi(shell);
I hope this information is useful to someone, even if it doesn't directly relate to GridLayout
. Thanks for reading my first answer here too!
*The x
and y
of the DPI may not always be the same in rare cases (I've heard).