我有Composite
。
在SWT中,孩子们不会由孩子添加孩子:
Composite parent = new Composite(shell, SWT.none);
Composite child = new Composite(parent, SWT.none);
这意味着,我不知道父母的内心,以及将孩子加入父母的方式。
问题:
在父母的内部我需要知道,当新的孩子被添加到父母。
有没有办法注册onChildAddListener
或任何add()
方法来覆盖?
答案 0 :(得分:3)
添加自定义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
}
}
答案 1 :(得分:1)
我想了解的有关加入儿童的目的 - 是为了让孩子们安排孩子
(当孩子被添加到孩子时添加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));
}