Java SWT - 侦听是否有新的子项被添加到复合中



我有一个Composite .在SWT中,孩子是由孩子添加的,不是由父母添加的:

Composite parent = new Composite(shell, SWT.none);
Composite child = new Composite(parent, SWT.none);

这意味着,我不知道父母的内部,以何种方式以及何时将孩子添加到父母中。

问题:

在父项

内部,我需要知道何时将新子项添加到父项中。有没有办法注册onChildAddListener或任何add()方法来覆盖?

添加自定义MyComposite和创建自定义ChildEvent以及ChildEventListener界面的唯一方法。 MyComposite能够注册ChildEvent侦听器,并在创建子Composite时触发此事件。

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.TypedEvent;
import org.eclipse.swt.internal.SWTEventListener;
import org.eclipse.swt.widgets.*;
/*
 * This example demonstrates the minimum amount of code required
 * to open an SWT Shell and process the events.
 */
public class HelloWorld1 {
public static void main (String [] args) {
    Display display = new Display ();
    Shell shell = new HelloWorld1 ().open (display);
    while (!shell.isDisposed ()) {
        if (!display.readAndDispatch ()) display.sleep ();
    }
    display.dispose ();
}
public Shell open (Display display) {
    Shell shell = new Shell (display);
    MyComposite parent = new MyComposite(shell, SWT.NONE);
    parent.addChildEventListener(new ChildEventListener() {
        @Override
        public void add(ChildEvent e) {
            System.out.println("Child added.");
        }
    });
    MyComposite child = new MyComposite(parent, SWT.NONE);
//  shell.open ();
    return shell;
}
}
class MyComposite extends Composite {
    ChildEventListener[] childEventListeners = new ChildEventListener[0];
    public MyComposite(Composite parent, int style) {
        super(parent, style);
        if (parent instanceof MyComposite){
            ((MyComposite)parent).fireChildEvent(new ChildEvent(this));
        }
    }
    public void addChildEventListener (ChildEventListener listener) {
        checkWidget();
        if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
        ChildEventListener[] newChildEventListeners = new ChildEventListener[childEventListeners.length + 1];
        System.arraycopy(childEventListeners, 0, newChildEventListeners, 0, childEventListeners.length);
        childEventListeners = newChildEventListeners;
        childEventListeners[childEventListeners.length - 1] = listener;
    }
    public void removeChildEventListener (ChildEventListener listener) {
        if (childEventListeners.length == 0) return;
        int index = -1;
        for (int i = 0; i < childEventListeners.length; i++) {
            if (listener == childEventListeners[i]){
                index = i;
                break;
            }
        }
        if (index == -1) return;
        if (childEventListeners.length == 1) {
            childEventListeners = new ChildEventListener[0];
            return;
        }
        ChildEventListener[] newChildEventListeners = new ChildEventListener[childEventListeners.length - 1];
        System.arraycopy (childEventListeners, 0, newChildEventListeners, 0, index);
        System.arraycopy (childEventListeners, index + 1, newChildEventListeners, index, childEventListeners.length - index - 1);
        childEventListeners = newChildEventListeners;
    }
    public void fireChildEvent(ChildEvent event){
        for (int i = 0; i < childEventListeners.length; i++) {
            childEventListeners[i].add (event);
        }
    }
}
interface ChildEventListener extends SWTEventListener {
    public void add(ChildEvent e);
}
class ChildEvent extends TypedEvent {
    public ChildEvent(Widget widget) {
        super(widget);
        // TODO Auto-generated constructor stub
    }
}

我想知道的关于儿童添加的目的 - 是为了布置孩子(添加LayoutData例如 GridData (当子项被添加到子项时,子项以特定的布局进行布局(例如 GridLayout(。

由于无法在添加时布局子项 - 在每次调整小部件大小时检查其布局:

    /*
     * To make the forms fill the group - laying out the children is necessary.
     * Unfortunately it is not possible to listen for children addition, in order to layout the children addition automatically.
     * This means that the user will have to remember  to layout the children, which is a nogo.
     * 
     * Solution: 
     * istead of adding right layout on child addition -  check if there are new children every time the widget is resized.
     * if a widget without layoutData is found (new child not layed out) - add a layout
     */
    this.addControlListener(new ControlAdapter() {
        @Override
        public void controlResized(ControlEvent e) {
            layoutChildren();
        }
    });
}
private void layoutChildren(){
    for(Control child:getChildren()){
        if(child.getLayoutData() == null){
            child.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1)); 
        }
    }
}
public void addToGroup(Composite child){
    child.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
}

最新更新