Friday, April 17, 2009

Another Bug Fix Part 2

This part describes my process for fixing the bug.

As I mentioned in part 1 I believed that the problem simply came down to refreshing the UI after the parts list was updated. So the questions I needed to answer were: where could I find the UI refresh method and where could I call it that would make the most sense?

Answering the first question was simple enough. After some light searching I came across the ExtensionDetailsViewer.java class. This class was responsible for generating the UI for the Extension Details section. In this class was a refresh() method. Perfect.

As for the answer to the second question, this was also easy enough. I simply needed to find out where the "Specify Parts" dialog was being initiated and include a call to refresh() after that.

After looking at the code for awhile trying to understand it, I came across a few lines that interested me located within a method called createButtonControl().


Button button = new Button(composite, SWT.NONE);
GridData gridData = new GridData();
gridData.heightHint = 17;
button.setLayoutData(gridData);
button.addSelectionListener(internalControlListener);
button.setData(ITEM_DATA, item);
button.setData(EDITOR_CONFIGURATION_DATA, configuration);


I thought this might be the button I was looking for (the one that opens up the Specify Parts dialog). I tested it by setting the button's text to something different and sure enough it changed, so I knew that this was the right button.

I took note of the addSelectionListener() call, as the listener that was passed was most likely what opens the dialog. The internalControlListener was an instance of the InternalControlListener class, the contents of which were actually defined inside ExtensionDetailsViewer.java. Looking at the class, I came across a method called widgetSelected()


public void widgetSelected(SelectionEvent e)
{
   // for button controls we handle selection events
   //
   Object item = e.widget.getData(EDITOR_CONFIGURATION_DATA);
   if (item == null)
      item = e.widget.getData(ITEM_DATA);
   if (item instanceof DialogNodeEditorConfiguration)
   {
      DialogNodeEditorConfiguration dialogNodeEditorConfiguration = (DialogNodeEditorConfiguration)item;
      dialogNodeEditorConfiguration.invokeDialog();
   }
   else if (item instanceof ExtensionItem)
   {
      applyEdit((ExtensionItem)item, e.widget);
   }
}


I took notice of the if statement that checks if the item is an instanceof DialogNodeEditorConfiguration. I suspected that it was here that the Specify Parts dialog was called. So I put a breakpoint on the invokeDialog() call and traced it. Sure enough, when I clicked on the "..." button I was stopped at this call. I stepped through it and ended up at a class called SOAPSelectPartsDialog.java which was responsible for creating the Specify Parts UI. So I knew then for sure that this line is what started the whole process. To test my original theory I inserted a call to refresh() right below the invokeDialog() call and ran the application. As I suspected, the UI was now fixed! After updating the parts and clicking OK in the Specify Parts dialog, the text in the parts field changed without me having to change focus.

You can find my patch on Bugzilla.

No comments: