Group.layout() not displaying newly added fields in modified group? (SWT Newbie!)
I am new to SWT development and am trying to build an extremely simple GUI window (going by the online tutorials and examples). My little GUI takes a string and parses it (using a parsing lib) and displays the parsed data in fields in a group.
Thus far, it works for ONE PASS. I enter a string, hit "Parse It", and the string is parsed correctly, and the corresponding data fields are shown in the grouping below the entry text box and buttons. I have a "Clear All" button which clears these fields. If I hit "Parse It" again, the parsing logic does execute (as is evident from console output) BUT the UI does not display the fields. (So far I have only implemented for the fixed width radio option until I get around this).
The behavior is perplexing to me. I have tried multiple things such as putting the group re-creation code in the mouseUp on the clear button, as opposed to only disposing the group. I have tried putting the group re-creation in the parse it button action code. (I also had tried creating subclasses of MouseListener for each, passing in references as necessary, but for simplicity's sake have just put everything back into an anon inner class).
I use group.layout() and not redraw. What is this SWT newbie missing? Surely it must be something super simple. MTIA! (Apologies if the code is messy - been playing with it a lot.)
Code:
package com.mycompany.common.utility.messageparser.ui;
import java.beans.PropertyDescriptor;
import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.commons.beanutils.PropertyUtils;
import org.eclipse.swt.widgets.*;
import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.*;
import org.eclipse.swt.events.*;
import com.mycompany.common.utility.MessageDefinitionFactory;
import com.mycompany.common.utility.FixedWidthMessageParserUtility;
import com.mycompany.messageutils.*;
public class MainWindow
{
private static Text messageInput;
public static Display display = null;
public static Shell windowShell = null;
public static Group group = null;
public static void main(String[] args)
{
Display display = Display.getDefault();
Shell shlMultiMessageParser= new Shell();
shlMultiMessageParser.setSize(460, 388);
shlMultiMessageParser.setText("Message Parser Utility");
shlMultiMessageParser.setLayout(new FormLayout());
final Composite composite = new Composite(shlMultiMessageParser, SWT.NONE);
FormData fd_composite = new FormData();
fd_composite.bottom = new FormAttachment(0, 351);
fd_composite.right = new FormAttachment(0, 442);
fd_composite.top = new FormAttachment(0, 10);
fd_composite.left = new FormAttachment(0, 10);
composite.setLayoutData(fd_composite);
composite.setLayout(new FormLayout());
group = new Group(composite, SWT.NONE);
FormData fd_group = new FormData();
fd_group.bottom = new FormAttachment(0, 331);
fd_group.right = new FormAttachment(0, 405);
fd_group.top = new FormAttachment(0, 79);
fd_group.left = new FormAttachment(0, 10);
group.setLayoutData(fd_group);
group.setLayout(new GridLayout(2, false));
Button btnFixedWidth= new Button(composite, SWT.RADIO);
FormData fd_btnFixedWidth= new FormData();
btnFixedWidth.setLayoutData(fd_btnFixedWidth);
btnFixedWidth.setText("FixedWidth");
Button btnDelimited = new Button(composite, SWT.RADIO);
fd_btnFixedWidth.top = new FormAttachment(btnDelimited, 0, SWT.TOP);
fd_btnFixedWidth.left = new FormAttachment(btnDelimited, 23);
FormData fd_btnDelimited = new FormData();
btnDelimited.setLayoutData(fd_btnDelimited);
btnDelimited.setText("DELIM");
Button btnGeneric = new Button(composite, SWT.RADIO);
fd_btnDelimited.left = new FormAttachment(btnGeneric, 17);
btnGeneric.setText("GENERIC");
btnGeneric.setLayoutData(new FormData());
messageInput = new Text(composite, SWT.BORDER);
messageInput.setSize(128, 12);
FormData fd_messageInput = new FormData();
fd_messageInput.top = new FormAttachment(0, 40);
fd_messageInput.left = new FormAttachment(0, 10);
messageInput.setLayoutData(fd_messageInput);
Button btnParseIt = new Button(composite, SWT.NONE);
fd_messageInput.right = new FormAttachment(btnPar开发者_Python百科seIt, -6);
FormData fd_btnParseIt = new FormData();
fd_btnParseIt.top = new FormAttachment(0, 38);
fd_btnParseIt.right = new FormAttachment(100, -29);
fd_btnParseIt.left = new FormAttachment(0, 335);
btnParseIt.setLayoutData(fd_btnParseIt);
btnParseIt.setText("Parse it");
// btnParseIt.addMouseListener (new ParseItButtonAction(messageInput,
// group, btnFixedWidth, btnDelimited, btnGeneric));
// PARSE IT BUTTON ACTION
btnParseIt.addMouseListener(new MouseListener()
{
public void mouseUp(MouseEvent arg0)
{
String messageString = messageInput.getText();
if (null == messageString || messageString.isEmpty())
return;
// PARSE THE MESSAGE AND BUILD THE FORM!
String messageId = messageString.substring(0, 3);
MessageDefinition messageDefinition = null;
try
{
// Will need to pull the type from the radio buttons
messageDefinition = (MessageDefinition) (MessageDefinitionFactory.getMessageDefinition("FixedWidth", messageId)).newInstance();
}
catch (Exception e2)
{
System.out.println("CAUGHT " + e2.getClass().getName() + ": " + e2.getMessage());
e2.printStackTrace();
}
ArrayList<FieldDefinition> fields = messageDefinition.getFields();
Object messageBean = null;
// List of ALL the name value pairs to be displayed.
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
try
{
messageBean = MessageHelper.getObjectFromDefinition(messageString, messageDefinition, ClientMessageType.FixedWidth);
/**
* Get the properties of the bean and display their names
* and values
*/
nameValuePairs = getNameValuePairs(messageBean, fields, nameValuePairs);
for (NameValuePair nameValuePair : nameValuePairs)
{
Label lblNewLabel = new Label(group, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblNewLabel.setText(nameValuePair.name);
Text textField = new Text(group, SWT.BORDER);
textField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
textField.setText(nameValuePair.value);
}
/**
* End iterate thru bean properties
*/
group.layout(true);
//windowShell.layout(true);
}
catch (MessageParsingException e1)
{
System.out.println("CAUGHT " + e1.getClass().getName() + ": " + e1.getMessage());
e1.printStackTrace();
}
}
@Override
public void mouseDown(MouseEvent arg0)
{
}
@Override
public void mouseDoubleClick(MouseEvent arg0)
{
}
public List getNameValuePairs(Object messageBean, List<FieldDefinition> fields, List<NameValuePair> list)
{
Object property = null;
if (fields == null)
{
Method[] objectMethods = messageBean.getClass().getDeclaredMethods();
String fieldName = "";
Object fieldValue = null;
for (Method thisMethod : objectMethods)
{
if (thisMethod.getName().contains("get"))
{
fieldName = thisMethod.getName().substring(3, thisMethod.getName().length());
System.out.println("ATTEMPTING TO INVOKE get" + fieldName + "() on " + messageBean.getClass().getName());
try
{
fieldValue = thisMethod.invoke(messageBean);
}
catch (Exception e)
{
System.out.println("CAUGHT TRYING TO GET " + fieldName + " From " + messageBean.getClass().getName() + "::" + e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
list.add(new NameValuePair(fieldName, String.valueOf(fieldValue)));
}
}
}
else
{
for (FieldDefinition f : fields)
{
try
{
property = PropertyUtils.getProperty(messageBean, f.getPropertyName());
}
catch (Exception e)
{
System.out.println("CAUGHT " + e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
if (property instanceof java.lang.String)
{
list.add(new NameValuePair(f.getPropertyName(), (String) property));
}
else if (property instanceof java.util.GregorianCalendar)
{
java.util.GregorianCalendar date = (java.util.GregorianCalendar) property;
Calendar cal = date;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
String value = dateFormat.format(cal.getTime());
list.add(new NameValuePair(f.getPropertyName(), value));
}
else if (property instanceof java.util.List)
{
for (Object thePropertyObject : (List) property)
{
System.out.println("Class type of property is " + thePropertyObject.getClass().getName());
list = getNameValuePairs(thePropertyObject, null, list);
}
}
else
// could be Integer or Long.
{
list.add(new NameValuePair(f.getPropertyName(), String.valueOf(property)));
}
}
} // END else fields not null
return list;
}
}); // END OF PARSE IT BUTTON MOUSE LISTENER
// CLEAR ALL BUTTON
Button btnClearAll = new Button(composite, SWT.NONE);
btnClearAll.addMouseListener(new MouseListener()
{
@Override
public void mouseUp(MouseEvent arg0)
{
System.out.println("CLEAR ALL MOUSE UP");
if ((group != null) && (! group.isDisposed()))
{
group.dispose();
}
// REFRESH THE GROUP
group = new Group(composite, SWT.NONE);
FormData fd_group = new FormData();
fd_group.bottom = new FormAttachment(0, 331);
fd_group.right = new FormAttachment(0, 405);
fd_group.top = new FormAttachment(0, 79);
fd_group.left = new FormAttachment(0, 10);
group.setLayoutData(fd_group);
group.setLayout(new GridLayout(2, false));
group.layout(true); }
@Override
public void mouseDown(MouseEvent arg0)
{
// TODO Auto-generated method stub
}
@Override
public void mouseDoubleClick(MouseEvent arg0)
{
// TODO Auto-generated method stub
}
});
Label lblNewLabel = new Label(composite, SWT.NONE);
FormData fd_lblNewLabel = new FormData();
fd_lblNewLabel.right = new FormAttachment(0, 167);
fd_lblNewLabel.top = new FormAttachment(0, 20);
fd_lblNewLabel.left = new FormAttachment(0, 10);
lblNewLabel.setLayoutData(fd_lblNewLabel);
lblNewLabel.setText("Paste message below:");
btnClearAll.setToolTipText("Click here to clear ALL fields.");
btnClearAll.setText("Clear All");
FormData fd_btnClearAll = new FormData();
fd_btnClearAll.right = new FormAttachment(btnParseIt, 68);
fd_btnClearAll.bottom = new FormAttachment(lblNewLabel, 0, SWT.BOTTOM);
fd_btnClearAll.left = new FormAttachment(btnParseIt, 0, SWT.LEFT);
btnClearAll.setLayoutData(fd_btnClearAll);
shlMultiMessageParser.open();
shlMultiMessageParser.layout();
while (!shlMultiMessageParser.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
}
}
class NameValuePair
{
public String name = "";
public String value = "";
public NameValuePair(String name, String value)
{
this.name = name;
this.value = value;
}
}
class ClearAllButtonAction extends MouseAdapter
{
Group group = null;
Composite composite = null;
public ClearAllButtonAction(Group group, Composite composite)
{
System.out.println("CLEAR ALL BUTTON CTOR");
this.group = group;
this.composite = composite;
}
public void mouseUp(MouseEvent e)
{
System.out.println("CLEAR ALL MOUSE UP");
group.dispose();
/*
* group = new Group(composite, SWT.NONE); FormData fd_group = new
* FormData(); fd_group.bottom = new FormAttachment(0, 331);
* fd_group.right = new FormAttachment(0, 405); fd_group.top = new
* FormAttachment(0, 79); fd_group.left = new FormAttachment(0, 10);
* group.setLayoutData(fd_group); group.setLayout(new GridLayout(2,
* false)); group.layout(true);
*/}
}
class ParseItButtonAction extends MouseAdapter
{
private Text messageInput = null;
private Group group = null;
private Button btnFixedWidth = null, btnDELIM = null;
public ParseItButtonAction(Text messageInput, Group group, Button btnFixedWidth, Button btnDELIM, Button btnGeneric)
{
this.messageInput = messageInput;
this.group = group;
this.btnFixedWidth = btnFixedWidth;
this.btnDELIM = btnDELIM;
}
public void mouseUp(MouseEvent e)
{
// PARSE THE MESSAGE AND BUILD THE FORM!
String messageString = messageInput.getText();
String messageId = messageString.substring(0, 3);
MessageDefinition messageDefinition = null;
try
{
// Will need to pull the type from the radio buttons
messageDefinition = (MessageDefinition) (MessageDefinitionFactory.getMessageDefinition("FixedWidth", messageId)).newInstance();
}
catch (Exception e2)
{
System.out.println("CAUGHT " + e2.getClass().getName() + ": " + e2.getMessage());
e2.printStackTrace();
}
ArrayList<FieldDefinition> fields = messageDefinition.getFields();
// If this were DELIM, it would be handling a BaseMessageBean type.
Object messageBean = null;
// List of ALL the name value pairs to be displayed.
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
try
{
messageBean = MessageHelper.getObjectFromDefinition(messageString, messageDefinition, ClientMessageType.FixedWidth);
/**
* Get the properties of the bean and display their names and values
*/
nameValuePairs = getNameValuePairs(messageBean, fields, nameValuePairs);
for (NameValuePair nameValuePair : nameValuePairs)
{
Label lblNewLabel = new Label(group, SWT.NONE);
lblNewLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
lblNewLabel.setText(nameValuePair.name);
Text textField = new Text(group, SWT.BORDER);
textField.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
textField.setText(nameValuePair.value);
}
/**
* End iterate thru bean properties
*/
group.layout();
}
catch (MessageParsingException e1)
{
System.out.println("CAUGHT " + e1.getClass().getName() + ": " + e1.getMessage());
e1.printStackTrace();
}
}
// The Object type should be converted into a type of messageBean superclass
public List getNameValuePairs(Object messageBean, List<FieldDefinition> fields, List<NameValuePair> list)
{
Object property = null;
// BECAUSE FixedWidth/GENERIC DO NOT SPECIFY TYPES FOR MESSAGE SUBSECTIONS
if (fields == null)
{
Method[] objectMethods = messageBean.getClass().getDeclaredMethods();
String fieldName = "";
Object fieldValue = null;
for (Method thisMethod : objectMethods)
{
if (thisMethod.getName().contains("get"))
{
fieldName = thisMethod.getName().substring(3, thisMethod.getName().length());
System.out.println("ATTEMPTING TO INVOKE get" + fieldName + "() on " + messageBean.getClass().getName());
try
{
fieldValue = thisMethod.invoke(messageBean);
}
catch (IllegalArgumentException e)
{
System.out.println("CAUGHT TRYING TO GET " + fieldName + " From " + messageBean.getClass().getName() + "::" + e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
catch (IllegalAccessException e)
{
System.out.println("CAUGHT TRYING TO GET " + fieldName + " From " + messageBean.getClass().getName() + "::" + e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
catch (InvocationTargetException e)
{
System.out.println("CAUGHT TRYING TO GET " + fieldName + " From " + messageBean.getClass().getName() + "::" + e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
list.add(new NameValuePair(fieldName, String.valueOf(fieldValue)));
}
}
}
else
{
for (FieldDefinition f : fields)
{
try
{
property = PropertyUtils.getProperty(messageBean, f.getPropertyName());
}
catch (Exception e)
{
System.out.println("CAUGHT " + e.getClass().getName() + ": " + e.getMessage());
e.printStackTrace();
}
if (property instanceof java.lang.String)
{
list.add(new NameValuePair(f.getPropertyName(), (String) property));
}
else if (property instanceof java.util.GregorianCalendar)
{
java.util.GregorianCalendar date = (java.util.GregorianCalendar) property;
Calendar cal = date;
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd hh:mm:ss");
String value = dateFormat.format(cal.getTime());
list.add(new NameValuePair(f.getPropertyName(), value));
}
else if (property instanceof java.util.List)
{
for (Object thePropertyObject : (List) property)
{
System.out.println("Class type of property is " + thePropertyObject.getClass().getName());
// Need to use the factory to get the message bean type
// for the subsections, but cannot
// DO THIS for SUBSECTIONS FOR FixedWidth/GENERIC, ONLY DELIM.
// ARGH.
// Add these types to the message factory, then do the
// lookup. for now just print the types.
list = getNameValuePairs(thePropertyObject, null, list);
}
}
else
// could be Integer or Long.
{
list.add(new NameValuePair(f.getPropertyName(), String.valueOf(property)));
}
}
} // END else fields not null
return list;
}
}
I genericized the code to show it below.
Found it. I need to dispose the children of the group, and not the group itself.
if ((group != null) && (! group.isDisposed()))
{
for (Control childWidget: group.getChildren())
{
childWidget.dispose();
}
}
messageInput.setText("");
精彩评论