Я новичок в разработке SWT и пытаюсь создать чрезвычайно простое окно графического интерфейса пользователя (переходя к онлайн-учебникам и примерам). Мой маленький графический интерфейс берет строку и анализирует ее (используя синтаксический анализ lib) и отображает проанализированные данные в полях группы.
Пока что это работает для ОДНОГО ПРОХОДА. Я ввожу строку, нажимаю «Parse It», и строка анализируется правильно, и соответствующие поля данных отображаются в группе под текстовым полем ввода и кнопками. У меня есть кнопка «Очистить все», которая очищает эти поля. Если я снова нажму «Parse It», логика синтаксического анализа выполнится (как видно из вывода консоли), но пользовательский интерфейс не отображает поля. (До сих пор я реализовал только опцию радио с фиксированной шириной, пока не обойду это).
Поведение озадачивает меня. Я пробовал несколько вещей, таких как помещение кода повторного создания группы в mouseUp на кнопку очистки, а не только удаление группы. Я попытался поместить воссоздание группы в код действия кнопки разбора. (Я также пытался создать подклассы MouseListener для каждого, передавая ссылки по мере необходимости, но для простоты просто поместил все обратно во внутренний класс anon).
Я использую group.layout (), а не перерисовывать. Чего не хватает новичку SWT? Конечно, это должно быть что-то супер простое. MTIA! (Извиняюсь, если код грязный - много играл с ним.)
Код:
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(btnParseIt, -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;
}
}
Я обобщил код, чтобы показать его ниже.