居中对话框时,首先出现在左上角几毫秒

When centering dialog, first appears on topleft corner for some milliseconds

我正在生成一个包含很多内容的对话框。我想将对话框打包到孩子的高度,我想将它放在屏幕中央,所以我在添加所有孩子后这样做:

        shell.open();
        shell.layout();
        shell.pack(); //for wrap the dialog size to it's content width and height.

        //the dialog must be centered after doing shell.pack();
        Rectangle parentSize = getParent().getBounds();
        Rectangle shellSize = shell.getBounds();
        int x = parentSize.x + (parentSize.width - shellSize.width) / 2;
        int y = (int) (parentSize.y + (parentSize.height - shellSize.height) / 3.5);
        shell.setLocation(new Point(x, y));

问题是,在几毫秒内,对话框以很大的宽度显示在屏幕的左上角。我尝试对 shell 执行 setVisible(false) 和 (true) 来解决问题,但它不起作用。

如何避免在几毫秒内看到左上角的对话框并且宽度很大?

这是完整代码:

public class SelectTwoMatrixNumbersDialog extends Dialog {
    protected ArrayList<Integer> matrixNumbers1;
    protected ArrayList<Integer> matrixNumbers2;
    protected Shell shell;
    private JointBet jointBet;
    private boolean result; 
    NumbersMatrixWidget numbersMatrixWidget1;
    NumbersMatrixWidget numbersMatrixWidget2;

    /**
     * Create the dialog.
     * @param parent
     * @param style
     */
    public SelectTwoMatrixNumbersDialog(Shell parent, int style, JointBet jointBet) {
        super(parent, style);
        setText("Elegir Números");
        this.jointBet = jointBet;
    }

    /**
     * Open the dialog.
     * @return the result
     */
    public boolean open() {
        createContents();

        matrixNumbers1 = new ArrayList<Integer>();
        matrixNumbers2 = new ArrayList<Integer>();

        GridLayout gl_shell = new GridLayout(1, false);
        gl_shell.marginWidth = 20;
        gl_shell.marginHeight = 20;
        shell.setLayout(gl_shell);

        Composite contentComposite = new Composite(shell, SWT.NONE);
        contentComposite.setLayout(new GridLayout(1, false));
        contentComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, true, true, 1, 1));

        Label lblNumbers = new Label(contentComposite, SWT.NONE);
        lblNumbers.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
        lblNumbers.setText("Números:");

        Composite numbersContainerComposite = new Composite(contentComposite, SWT.NONE);
        numbersContainerComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));

        //variable values depending of type of game
        boolean firstCellEmpty = jointBet.getGameType().getNumbersMatrixArray()[0].isFirstCellEmpty();      
        int matrix1Rows = jointBet.getGameType().getNumbersMatrixArray()[0].getRows();
        int matrix1Columns = jointBet.getGameType().getNumbersMatrixArray()[0].getColumns();
        int matrix1MinNumber = jointBet.getGameType().getNumbersMatrixArray()[0].getMinNumber();
        int matrix1MaxNumber = jointBet.getGameType().getNumbersMatrixArray()[0].getMaxNumber();        
        GridLayout gl_numbersContainerComposite = new GridLayout(2, false);
        gl_numbersContainerComposite.horizontalSpacing = 15;
        numbersContainerComposite.setLayout(gl_numbersContainerComposite);
        numbersMatrixWidget1 = new NumbersMatrixWidget(numbersContainerComposite, SWT.BORDER, false, jointBet.getGameType().getNumbersMatrixArray()[0].getNumbers(), matrix1Rows, matrix1Columns, matrix1MinNumber, matrix1MaxNumber, firstCellEmpty);

        //variable values depending of type of game
        firstCellEmpty = jointBet.getGameType().getNumbersMatrixArray()[1].isFirstCellEmpty();      
        int matrix2Rows = jointBet.getGameType().getNumbersMatrixArray()[1].getRows();
        int matrix2Columns = jointBet.getGameType().getNumbersMatrixArray()[1].getColumns();
        int matrix2MinNumber = jointBet.getGameType().getNumbersMatrixArray()[1].getMinNumber();
        int matrix2MaxNumber = jointBet.getGameType().getNumbersMatrixArray()[1].getMaxNumber();
        numbersMatrixWidget2 = new NumbersMatrixWidget(numbersContainerComposite, SWT.BORDER, false, jointBet.getGameType().getNumbersMatrixArray()[1].getNumbers(), matrix2Rows, matrix2Columns, matrix2MinNumber, matrix2MaxNumber, firstCellEmpty);
        numbersMatrixWidget2.setLayoutData(new GridData(SWT.LEFT, SWT.BOTTOM, false, false, 1, 1));

        Composite fillNumbersComposite = new Composite(shell, SWT.NONE);
        fillNumbersComposite.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1));
        fillNumbersComposite.setLayout(new GridLayout(1, false));

        Composite compositeFillMatrix1 = new Composite(fillNumbersComposite, SWT.NONE);
        compositeFillMatrix1.setLayout(new GridLayout(4, false));

        Label lblFillMatrix1WithMostCommonNumbers1 = new Label(compositeFillMatrix1, SWT.NONE);
        lblFillMatrix1WithMostCommonNumbers1.setText("Rellenar Matriz 1 con los");

        Spinner matrix1NumbersSpinner = new Spinner(compositeFillMatrix1, SWT.BORDER);
        matrix1NumbersSpinner.setMaximum(jointBet.getGameType().getNumbersMatrixArray()[0].getPossibleNumbersCount());
        matrix1NumbersSpinner.setMinimum(1);

        Label lblFillMatrix1WithMostCommonNumbers2 = new Label(compositeFillMatrix1, SWT.NONE);
        lblFillMatrix1WithMostCommonNumbers2.setText("números mas repetidos:");

        Button btnFillMatrix1 = new Button(compositeFillMatrix1, SWT.NONE);
        btnFillMatrix1.setText("Rellenar");
        btnFillMatrix1.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                String gameType = jointBet.getGameType().getType();
                int matrix = 1;
                int amount = Integer.parseInt(matrix1NumbersSpinner.getText());
                numbersMatrixWidget1.setNumbers(StatisticsManager.getInstance().getMostUsedNumberKeys(gameType, matrix, amount));
            }
        });

        Composite compositeFillMatrix2 = new Composite(fillNumbersComposite, SWT.NONE);
        compositeFillMatrix2.setLayout(new GridLayout(4, false));

        Label lblFillMatrix2WithMostCommonNumbers1 = new Label(compositeFillMatrix2, SWT.NONE);
        lblFillMatrix2WithMostCommonNumbers1.setText("Rellenar Matriz 2 con los");

        Spinner matrix2NumbersSpinner = new Spinner(compositeFillMatrix2, SWT.BORDER);
        matrix2NumbersSpinner.setMaximum(jointBet.getGameType().getNumbersMatrixArray()[1].getPossibleNumbersCount());
        matrix2NumbersSpinner.setMinimum(1);

        Label lblFillMatrix2WithMostCommonNumbers2 = new Label(compositeFillMatrix2, SWT.NONE);
        lblFillMatrix2WithMostCommonNumbers2.setText("números mas repetidos:");

        Button btnFillMatrix2 = new Button(compositeFillMatrix2, SWT.NONE);
        btnFillMatrix2.setText("Rellenar");
        btnFillMatrix2.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                String gameType = jointBet.getGameType().getType();
                int matrix = 2;
                int amount = Integer.parseInt(matrix2NumbersSpinner.getText());
                numbersMatrixWidget2.setNumbers(StatisticsManager.getInstance().getMostUsedNumberKeys(gameType, matrix, amount));
            }
        });

        Composite buttonsComposite = new Composite(shell, SWT.NONE);
        FillLayout fl_buttonsComposite = new FillLayout(SWT.HORIZONTAL);
        fl_buttonsComposite.marginHeight = 10;
        fl_buttonsComposite.spacing = 40;
        buttonsComposite.setLayout(fl_buttonsComposite);
        GridData gd_buttonsComposite = new GridData(SWT.CENTER, SWT.CENTER, false, false, 1, 1);
        gd_buttonsComposite.heightHint = 45;
        buttonsComposite.setLayoutData(gd_buttonsComposite);

        Button acceptButton = new Button(buttonsComposite, SWT.NONE);
        acceptButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {  
                //matrix 1
                matrixNumbers1.clear();
                for (Button b : numbersMatrixWidget1.getButtons()) {
                    if (b.getSelection()) {
                        matrixNumbers1.add(Integer.parseInt(b.getText()));
                    }
                }

                //matrix 2
                matrixNumbers2.clear();
                for (Button b : numbersMatrixWidget2.getButtons()) {
                    if (b.getSelection()) {
                        matrixNumbers2.add(Integer.parseInt(b.getText()));
                    }
                }

                if (matrixNumbers1.size()<jointBet.getGameType().getNumbersMatrixArray()[0].getNumbersPerBet() || matrixNumbers2.size()<jointBet.getGameType().getNumbersMatrixArray()[1].getNumbersPerBet()) {
                    ErrorDialog dialog = new ErrorDialog(shell, SWT.DIALOG_TRIM | SWT.PRIMARY_MODAL, "El mínimo de números es "+jointBet.getGameType().getNumbersMatrixArray()[0].getNumbersPerBet()+" + "+jointBet.getGameType().getNumbersMatrixArray()[1].getNumbersPerBet());
                    dialog.open();
                }else {                 
                    Collections.sort(matrixNumbers1);
                    Collections.sort(matrixNumbers2);

                    jointBet.setNumbers(0, matrixNumbers1);
                    jointBet.setNumbers(1, matrixNumbers2);
                    DataManager.getInstance().saveData();

                    result = true;
                    shell.close();
                }
            }
        });
        acceptButton.setBounds(0, 0, 75, 25);
        acceptButton.setText("Aceptar");

        Button cancelButton = new Button(buttonsComposite, SWT.NONE);
        cancelButton.addSelectionListener(new SelectionAdapter() {
            @Override
            public void widgetSelected(SelectionEvent e) {
                result = false;
                shell.close();
            }
        });
        cancelButton.setBounds(0, 0, 75, 25);
        cancelButton.setText("Cancelar");

        shell.setDefaultButton(acceptButton);

        shell.open();
        shell.layout();
        shell.pack(); //for wrap the dialog size to it's content width and height.

        //the dialog must be centered after doing shell.pack();
        Rectangle parentSize = getParent().getBounds();
        Rectangle shellSize = shell.getBounds();
        int x = parentSize.x + (parentSize.width - shellSize.width) / 2;
        int y = (int) (parentSize.y + (parentSize.height - shellSize.height) / 3.5);
        shell.setLocation(new Point(x, y));

        Display display = getParent().getDisplay();
        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }

        return result;
    }

    /**
     * Create contents of the dialog.
     */
    private void createContents() {
        shell = new Shell(getParent(), getStyle());
        shell.setText(getText());
    }
}

只需将 shell.open() 移动到尺寸计算的末尾 - 在 shell.setLocation 之后。