Меню SWT приводит к обрезке макета

#swt

#swt

Вопрос:

Я впервые пробую SWT, и я не могу понять, как использовать строку меню вместе с любым макетом, заполняющим пространство. Компоновка композита рассчитывается без учета меню, так что после добавления меню нижняя часть макета обрезается.

Удивительно, но когда пользователь изменяет размер, меню учитывается, и макет в порядке. Но я не могу понять, как это исправить программно; shell.layout(true,true) , shell.setSize(250,250) , shell.pack() не устраняйте проблему.

Меню приводит к обрезке макета.После изменения размера все в порядке.

 package com.appspot.htmldoodads.pdfstuffs;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.Shell;

public class MenuLayout {
    public static void main(String[] argv) {
        final Display display = new Display();
        final Shell shell = new Shell(display);

        GridLayout shellLayout = new GridLayout();
        shell.setLayout(shellLayout);

        // Add a menu bar with File -> Open...
        Menu bar = new Menu(shell, SWT.BAR);
        shell.setMenuBar(bar);
        MenuItem fileItem = new MenuItem(bar, SWT.CASCADE);
        fileItem.setText("amp;File");
        Menu subMenu = new Menu(shell, SWT.DROP_DOWN);
        fileItem.setMenu(subMenu);
        MenuItem openItem = new MenuItem(subMenu, SWT.CASCADE);
        openItem.setText("amp;Open...");

        // Add a button that fills the space.
        Button big = new Button(shell, SWT.PUSH);
        big.setText("Fill.");
        GridData bigLayoutData = new GridData(GridData.FILL, GridData.FILL, true, true);
        big.setLayoutData(bigLayoutData);

        // Add a button that doesn't fill space.
        new Button(shell, SWT.PUSH).setText("Regular");

        shell.layout(true, true);
        shell.setSize(250,250);
        shell.open();
        while ( ! shell.isDisposed ()) {
            if (!display.readAndDispatch())
                display.sleep();
        }
        display.dispose();
    }
}
  

Ответ №1:

Я нашел решение, как только заканчивал вопрос. Мне нужно было вызвать shell.layout() after shell.open() , чтобы GTK мог отображать меню до того, как SWT вычислит доступное пространство для макета.

Ответ №2:

Добавление к ответу йонрана:

При использовании JFace и подкласса ApplicationWindow в качестве основной точки входа shell.open() выполняется для вас. Поэтому вместо использования applicationWindow.open() вызова метода блокировки JFace вы должны использовать типичный цикл SWT.

JFace раньше (не работал и имел проблему с обрезкой, описанную в вопросе):

 public static void main(String[] args) {
    ApplicationWindow window = new MyApplicationWindow("My Window Title");
    window.setBlockOnOpen(true);
    window.open();
    Display.getCurrent().dispose()
}
  

JFace После (корректно отображается без каких-либо обрезок):

 public static void main(String[] args) {
    ApplicationWindow window = new MyApplicationWindow("My Window Title");
    window.open();

    Shell shell = window.getShell();
    shell.layout(true, true);
    while (!shell.isDisposed())
        if (!Display.getCurrent().readAndDispatch())
            Display.getCurrent().sleep();
    Display.getCurrent().dispose();
}