代码之家  ›  专栏  ›  技术社区  ›  David Young

SWT ExpandListener在Linux上发生崩溃之前执行

  •  2
  • David Young  · 技术社区  · 14 年前

    这是一个显示问题的简单可执行代码段。

    使用ExpandBar时,所需的结果是在出现折叠或展开时调整窗口大小。它在Mac上正常工作,但在Linux上不正常。

    看起来像是 扩展侦听器 在折叠/展开实际发生之前调用,因此 打包() 大小调整不正确。

    异步执行只是让它在Mac上工作的绷带,但在Linux上不起作用。

    import org.eclipse.swt.*;
    import org.eclipse.swt.layout.*;
    import org.eclipse.swt.widgets.*;
    import org.eclipse.swt.events.ExpandEvent;
    import org.eclipse.swt.events.ExpandListener;
    
    public class ExpandBarExample {
        public static void main(String[] args) {
            Shell shell = new Shell(SWT.DIALOG_TRIM | SWT.MIN
                    | SWT.APPLICATION_MODAL);
            shell.setLayout(new FormLayout());
            shell.setText("Expand Bar");
            final ExpandBar bar = new ExpandBar(shell, SWT.NONE);
            FormData fd = new FormData();
            fd.top = new FormAttachment(0);
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            fd.bottom = new FormAttachment(100);
            bar.setLayoutData(fd);
    
            bar.addExpandListener(new ExpandListener() {
    
                public void itemCollapsed(ExpandEvent arg0) {
                    Display.getCurrent().asyncExec(new Runnable() {
                        public void run() {
                            bar.getShell().pack();
                        }
                    });
                }
    
                public void itemExpanded(ExpandEvent arg0) {
                    bar.getShell().pack();
    
                    Display.getCurrent().asyncExec(new Runnable() {
                        public void run() {
                            bar.getShell().pack();
                        }
                    });
                }
    
            });
    
            Composite composite = new Composite(bar, SWT.NONE);
            fd = new FormData();
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            composite.setLayoutData(fd);
    
            FormLayout layout = new FormLayout();
            layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
    
            composite.setLayout(layout);
            Label label = new Label(composite, SWT.NONE);
            label.setText("This is Bar 1");
            ExpandItem item1 = new ExpandItem(bar, SWT.NONE, 0);
            item1.setText("Bar 1");
            item1.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
            item1.setControl(composite);
            item1.setExpanded(true);
    
            composite = new Composite(bar, SWT.NONE);
            fd = new FormData();
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            composite.setLayoutData(fd);
    
            layout = new FormLayout();
            layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
            composite.setLayout(layout);
            label = new Label(composite, SWT.NONE);
            label.setText("This is Bar2");
            ExpandItem item2 = new ExpandItem(bar, SWT.NONE, 1);
            item2.setText("Bar 2");
            item2.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
            item2.setControl(composite);
            item2.setExpanded(true);
    
            composite = new Composite(bar, SWT.NONE);
            fd = new FormData();
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            composite.setLayoutData(fd);
    
            layout = new FormLayout();
            layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
            composite.setLayout(layout);
            label = new Label(composite, SWT.NONE);
            label.setText("This is Bar3");
            ExpandItem item3 = new ExpandItem(bar, SWT.NONE, 2);
            item3.setText("Bar 3");
            item3.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
            item3.setControl(composite);
            item3.setExpanded(true);
    
            bar.setSpacing(6);
            shell.pack();
            shell.open();
            Display display = shell.getDisplay();
    
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
            display.dispose();
        }
    
    }
    
    2 回复  |  直到 14 年前
        1
  •  2
  •   David Young    14 年前

    我对这个解决方案不满意,但它是有效的。

    绝对是 XXX 解决方案

    使用 在评论中标记一些虚假但有效的东西。使用FIXME标记伪造和损坏的东西。 -java.sun.com网站

    import org.eclipse.swt.*;
    import org.eclipse.swt.layout.*;
    import org.eclipse.swt.widgets.*;
    import org.eclipse.swt.events.ExpandEvent;
    import org.eclipse.swt.events.ExpandListener;
    
    public class ExpandBarExample {
        public static void main(String[] args) {
            Shell shell = new Shell(SWT.DIALOG_TRIM | SWT.MIN
                    | SWT.APPLICATION_MODAL);
            shell.setLayout(new FormLayout());
            shell.setText("Expand Bar");
            final ExpandBar bar = new ExpandBar(shell, SWT.NONE);
            FormData fd = new FormData();
            fd.top = new FormAttachment(0);
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            fd.bottom = new FormAttachment(100);
            bar.setLayoutData(fd);
    
            bar.addExpandListener(new ExpandListener() {
    
                private void resize(final ExpandEvent event, final boolean expand){
    
                    final Display display = Display.getCurrent();
    
                    new Thread(new Runnable() {
                        public void run() {
    
                            final int[] orgSize = new int[1];
                            final int[] currentSize = new int[1];
    
                            final Object lock = new Object();
    
                            if (display.isDisposed() || bar.isDisposed()){
                                return;
                            }
    
                            display.syncExec(new Runnable() {
                                public void run() {
                                    if (bar.isDisposed() || bar.getShell().isDisposed()){
                                        return;
                                    }
    
                                    synchronized(lock){
                                        bar.getShell().pack(true);
                                        orgSize[0] = bar.getShell().getSize().y;
                                        currentSize[0] = orgSize[0];
                                    }
                                }
                            });     
    
                            while (currentSize[0] == orgSize[0]){
                                if (display.isDisposed() || bar.isDisposed()){
                                    return;
                                }
    
                                display.syncExec(new Runnable() {
                                    public void run() {
    
                                        synchronized(lock){
                                            if (bar.isDisposed() || bar.getShell().isDisposed()){
                                                return;
                                            }
    
                                            currentSize[0] = bar.getShell().getSize().y;
    
                                            if (currentSize[0] != orgSize[0]){
                                                return;
                                            }
                                            else{
                                                bar.getShell().layout(true);
                                                bar.getShell().pack(true);
                                            }
                                        }
                                    }
                                });                             
                            }
                        }
                    }).start();
            }
    
            public void itemCollapsed(ExpandEvent event) {
                resize(event, false);
            }
    
            public void itemExpanded(ExpandEvent event) {        
                resize(event, true);
            }
    
            });
    
            Composite composite = new Composite(bar, SWT.NONE);
            fd = new FormData();
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            composite.setLayoutData(fd);
    
            FormLayout layout = new FormLayout();
            layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
    
            composite.setLayout(layout);
            Label label = new Label(composite, SWT.NONE);
            label.setText("This is Bar 1");
            ExpandItem item1 = new ExpandItem(bar, SWT.NONE, 0);
            item1.setText("Bar 1");
            item1.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
            item1.setControl(composite);
            item1.setExpanded(true);
    
            composite = new Composite(bar, SWT.NONE);
            fd = new FormData();
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            composite.setLayoutData(fd);
    
            layout = new FormLayout();
            layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
            composite.setLayout(layout);
            label = new Label(composite, SWT.NONE);
            label.setText("This is Bar2");
            ExpandItem item2 = new ExpandItem(bar, SWT.NONE, 1);
            item2.setText("Bar 2");
            item2.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
            item2.setControl(composite);
            item2.setExpanded(true);
    
            composite = new Composite(bar, SWT.NONE);
            fd = new FormData();
            fd.left = new FormAttachment(0);
            fd.right = new FormAttachment(100);
            composite.setLayoutData(fd);
    
            layout = new FormLayout();
            layout.marginLeft = layout.marginTop = layout.marginRight = layout.marginBottom = 8;
            composite.setLayout(layout);
            label = new Label(composite, SWT.NONE);
            label.setText("This is Bar3");
            ExpandItem item3 = new ExpandItem(bar, SWT.NONE, 2);
            item3.setText("Bar 3");
            item3.setHeight(composite.computeSize(SWT.DEFAULT, SWT.DEFAULT).y);
            item3.setControl(composite);
            item3.setExpanded(true);
    
            bar.setSpacing(6);
            shell.pack();
            shell.open();
            Display display = shell.getDisplay();
    
            while (!shell.isDisposed()) {
                if (!display.readAndDispatch()) {
                    display.sleep();
                }
            }
            display.dispose();
        }
    
    }
    

    如果有人想知道这是做什么,不想看代码。

    基本上 扩展侦听器 打包() 直到壳实际改变大小。非常繁忙的等待方式。

        2
  •  2
  •   OwainD    13 年前

    这是一个旧的职位,但我最近有这个问题,并发现这个解决方案的帮助。

    但是,我发现只需要从另一个线程调用shell.pack()(当然是通过syncExec)。我从来不用绕圈子。所以我创建了这个小子程序:

    private void async_shell_pack(final Display display, final ExpandBar bar) {
        new Thread(new Runnable(){
             public void run(){
                display.syncExec(new Runnable() {
                    public void run() {
                                bar.getShell().pack(true);
                            }
                        });
                }}).start();
            }
    

    这似乎很管用。出于我的目的,更好的是,使用下面的侦听器简单地通过扩展项的高度来增加shell的高度。

    public void itemExpanded(ExpandEvent e) {
            if (e.item instanceof ExpandItem){
                    ExpandItem item = (ExpandItem)e.item;
                    shell.setSize(shell.getSize().x, shell.getSize().y+item.getHeight());
                } else {
                    System.out.println("Boom");
                }
            }
    

    这意味着不要乱搞线程。