SWT GUI Element Methods and Own Forms Widgets

SWT Designer allows you to create the views, editors, perspectives, pref pages, composites, etc. that comprise Eclipse SWT & RCP applications and plug-ins.

Moderators: Konstantin.Scheglov, gnebling, Alexander.Mitin, jwren, Eric Clayberg

SWT GUI Element Methods and Own Forms Widgets

Postby exelnet » Tue Dec 02, 2008 1:20 am

Hello!

1. I am not really happy with the generated code. Its hard to read and difficult to maintain. While i was browsing the prefs I found a nice option. "Put Code in own Methods" or something similar. But this option is only available for SWING and not for SWT. Is there a workaround to get this behaviour? It would be nice if I could setup the swt designer to create code similar to the gui code of the SplashHandler extension sample.

2. Defining own widgets is really nice. But the designer cant handle own forms widgets since their constructor is different and additionally needs a ToolKit. And its not possible to view own form widgets in the designer. In our case this would a Section derived from org.eclipse.forms SectionPart. Are there any tips and tricks concerning this problem?

thanks in advance
Jan Marc
exelnet
 
Posts: 2
Joined: Tue Dec 02, 2008 1:11 am

Re: SWT GUI Element Methods and Own Forms Widgets

Postby Eric Clayberg » Tue Dec 02, 2008 4:45 am

exelnet wrote:I am not really happy with the generated code. Its hard to read and difficult to maintain.

I find that to be an interesting statement as most users praise the tool for how nice the generated code is. It has been intentionally designed to create very readable and easy to maintain code and many code gen options are provided to allow you to change it. The tool can also reverse engineer most hand-written and refactored code.

exelnet wrote:While i was browsing the prefs I found a nice option. "Put Code in own Methods" or something similar. But this option is only available for SWING and not for SWT.

That pattern doesn't make sense for SWT due to the requirement to always pass the parent into the SWT constructor. You can't create a simple zero-arg accessor/creator for an SWT widget like that.

exelnet wrote:Is there a workaround to get this behavior? It would be nice if I could setup the swt designer to create code similar to the gui code of the SplashHandler extension sample.

I'm not familiar with that example.

exelnet wrote:Defining own widgets is really nice. But the designer cant handle own forms widgets since their constructor is different and additionally needs a ToolKit. And its not possible to view own form widgets in the designer. In our case this would a Section derived from org.eclipse.forms SectionPart. Are there any tips and tricks concerning this problem?

We are planning to add generic support for GUI factories (of which Forms widgets are just one example) in a near term release. You can read about them here...

http://download.instantiations.com/Desi ... ories.html
Eric Clayberg
Software Engineering Manager
Google
http://code.google.com/webtoolkit/download.html

Author: "Eclipse Plug-ins"
http://www.qualityeclipse.com
Eric Clayberg
Moderator
 
Posts: 4503
Joined: Tue Sep 30, 2003 6:39 am
Location: Boston, MA USA

Re: SWT GUI Element Methods and Own Forms Widgets

Postby exelnet » Tue Dec 02, 2008 8:03 am

Eric Clayberg wrote:
exelnet wrote:I am not really happy with the generated code. Its hard to read and difficult to maintain.

I find that to be an interesting statement as most users praise the tool for how nice the generated code is. It has been intentionally designed to create very readable and easy to maintain code and many code gen options are provided to allow you to change it. The tool can also reverse engineer most hand-written and refactored code.

exelnet wrote:While i was browsing the prefs I found a nice option. "Put Code in own Methods" or something similar. But this option is only available for SWING and not for SWT.

That pattern doesn't make sense for SWT due to the requirement to always pass the parent into the SWT constructor. You can't create a simple zero-arg accessor/creator for an SWT widget like that.

exelnet wrote:Is there a workaround to get this behavior? It would be nice if I could setup the swt designer to create code similar to the gui code of the SplashHandler extension sample.

I'm not familiar with that example.

exelnet wrote:Defining own widgets is really nice. But the designer cant handle own forms widgets since their constructor is different and additionally needs a ToolKit. And its not possible to view own form widgets in the designer. In our case this would a Section derived from org.eclipse.forms SectionPart. Are there any tips and tricks concerning this problem?

We are planning to add generic support for GUI factories (of which Forms widgets are just one example) in a near term release. You can read about them here...

http://download.instantiations.com/Desi ... ories.html


It does make sense if you are using fields. See the example below.

I posted the example. I like the way all components are put into their own methods and are invoked from one creareUI Method. This makes the code a lot more readable than using one big method. The same would apply to databinding. Each component one databinding method and one general databinding method which invokes the others. Since this would be possible to auto generate i am wondering why those options are missing.

I found what i was looking for. There is a new wizard for creating forms Sections. :=)


Code: Select all
package sacat.ui;

import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.layout.FillLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Button;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.splash.AbstractSplashHandler;

import sacat.client.ServerConnectionManager;

/**
* @since 3.3
*/
public class InteractiveSplashHandler extends AbstractSplashHandler {

   private final static int   F_LABEL_HORIZONTAL_INDENT   = 175;

   private final static int   F_BUTTON_WIDTH_HINT         = 80;

   private final static int   F_TEXT_WIDTH_HINT         = 175;

   private final static int   F_COLUMN_COUNT            = 3;

   private Composite         fCompositeLogin;

   private Text            fTextUsername;

   private Text            fTextPassword;

   private Button            fButtonOK;

   private Button            fButtonCancel;

   private boolean            fAuthenticated;

   /**
    *
    */
   public InteractiveSplashHandler() {
      this.fCompositeLogin = null;
      this.fTextUsername = null;
      this.fTextPassword = null;
      this.fButtonOK = null;
      this.fButtonCancel = null;
      this.fAuthenticated = false;
   }

   /**
    *
    */
   private void configureUISplash() {
      // Configure layout
      FillLayout layout = new FillLayout();
      this.getSplash().setLayout(layout);
      // Force shell to inherit the splash background
      this.getSplash().setBackgroundMode(SWT.INHERIT_DEFAULT);
   }

   /**
    *
    */
   private void createUI() {
      // Create the login panel
      this.createUICompositeLogin();
      // Create the blank spanner
      this.createUICompositeBlank();
      // Create the user name label
      this.createUILabelUserName();
      // Create the user name text widget
      this.createUITextUserName();
      // Create the password label
      this.createUILabelPassword();
      // Create the password text widget
      this.createUITextPassword();
      // Create the blank label
      this.createUILabelBlank();
      // Create the OK button
      this.createUIButtonOK();
      // Create the cancel button
      this.createUIButtonCancel();
   }

   /**
    *
    */
   private void createUIButtonCancel() {
      // Create the button
      this.fButtonCancel = new Button(this.fCompositeLogin, SWT.PUSH);
      this.fButtonCancel.setText("Cancel"); // NON-NLS-1
      // Configure layout data
      GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
      data.widthHint = InteractiveSplashHandler.F_BUTTON_WIDTH_HINT;
      data.verticalIndent = 10;
      this.fButtonCancel.setLayoutData(data);
   }

   /**
    *
    */
   private void createUIButtonOK() {
      // Create the button
      this.fButtonOK = new Button(this.fCompositeLogin, SWT.PUSH);
      this.fButtonOK.setText("OK"); // NON-NLS-1
      // Configure layout data
      GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
      data.widthHint = InteractiveSplashHandler.F_BUTTON_WIDTH_HINT;
      data.verticalIndent = 10;
      this.fButtonOK.setLayoutData(data);
   }

   /**
    *
    */
   private void createUICompositeBlank() {
      Composite spanner = new Composite(this.fCompositeLogin, SWT.NONE);
      GridData data = new GridData(SWT.FILL, SWT.FILL, true, true);
      data.horizontalSpan = InteractiveSplashHandler.F_COLUMN_COUNT;
      spanner.setLayoutData(data);
   }

   /**
    *
    */
   private void createUICompositeLogin() {
      // Create the composite
      this.fCompositeLogin = new Composite(this.getSplash(), SWT.BORDER);
      GridLayout layout = new GridLayout(InteractiveSplashHandler.F_COLUMN_COUNT, false);
      this.fCompositeLogin.setLayout(layout);
   }

   /**
    *
    */
   private void createUILabelBlank() {
      Label label = new Label(this.fCompositeLogin, SWT.NONE);
      label.setVisible(false);
   }

   /**
    *
    */
   private void createUILabelPassword() {
      // Create the label
      Label label = new Label(this.fCompositeLogin, SWT.NONE);
      label.setText("&Password:"); // NON-NLS-1
      // Configure layout data
      GridData data = new GridData();
      data.horizontalIndent = InteractiveSplashHandler.F_LABEL_HORIZONTAL_INDENT;
      label.setLayoutData(data);
   }

   /**
    *
    */
   private void createUILabelUserName() {
      // Create the label
      Label label = new Label(this.fCompositeLogin, SWT.NONE);
      label.setText("&User Name:"); // NON-NLS-1
      // Configure layout data
      GridData data = new GridData();
      data.horizontalIndent = InteractiveSplashHandler.F_LABEL_HORIZONTAL_INDENT;
      label.setLayoutData(data);
   }

   /**
    *
    */
   private void createUIListeners() {
      // Create the OK button listeners
      this.createUIListenersButtonOK();
      // Create the cancel button listeners
      this.createUIListenersButtonCancel();
   }

   /**
    *
    */
   private void createUIListenersButtonCancel() {
      this.fButtonCancel.addSelectionListener(new SelectionAdapter() {
         @Override
         public void widgetSelected(SelectionEvent e) {
            InteractiveSplashHandler.this.handleButtonCancelWidgetSelected();
         }
      });
   }

   /**
    *
    */
   private void createUIListenersButtonOK() {
      this.fButtonOK.addSelectionListener(new SelectionAdapter() {
         @Override
         public void widgetSelected(SelectionEvent e) {
            InteractiveSplashHandler.this.handleButtonOKWidgetSelected();
         }
      });
   }

   /**
    *
    */
   private void createUITextPassword() {
      // Create the text widget
      int style = SWT.PASSWORD | SWT.BORDER;
      this.fTextPassword = new Text(this.fCompositeLogin, style);
      // Configure layout data
      GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
      data.widthHint = InteractiveSplashHandler.F_TEXT_WIDTH_HINT;
      data.horizontalSpan = 2;
      this.fTextPassword.setLayoutData(data);
   }

   /**
    *
    */
   private void createUITextUserName() {
      // Create the text widget
      this.fTextUsername = new Text(this.fCompositeLogin, SWT.BORDER);
      // Configure layout data
      GridData data = new GridData(SWT.NONE, SWT.NONE, false, false);
      data.widthHint = InteractiveSplashHandler.F_TEXT_WIDTH_HINT;
      data.horizontalSpan = 2;
      this.fTextUsername.setLayoutData(data);
   }

   /**
    *
    */
   private void doEventLoop() {
      Shell splash = this.getSplash();
      while (this.fAuthenticated == false) {
         if (splash.getDisplay().readAndDispatch() == false) {
            splash.getDisplay().sleep();
         }
      }
   }

   /**
    *
    */
   private void handleButtonCancelWidgetSelected() {
      // Abort the loading of the RCP application
      this.getSplash().getDisplay().close();
      System.exit(0);
   }

   /**
    *
    */
   private void handleButtonOKWidgetSelected() {
      String username = this.fTextUsername.getText();
      String password = this.fTextPassword.getText();
      // Aunthentication is successful if a user provides any username and
      // any password
      if ((username.length() > 0) && (password.length() > 0)) {
         this.fAuthenticated = true;
      }
      else {
         MessageDialog.openError(this.getSplash(), "Authentication Failed", // NON-NLS-1
                           "A username and password must be specified to login."); //NON-NLS
                                                                     // -1
      }
   }

   /*
    * (non-Javadoc)
    * @see org.eclipse.ui.splash.AbstractSplashHandler#init(org.eclipse.swt.widgets.Shell)
    */
   @Override
   public void init(final Shell splash) {
      // Store the shell
      super.init(splash);
      // Configure the shell layout
      this.configureUISplash();
      // Create UI
      this.createUI();
      // Create UI listeners
      this.createUIListeners();
      // Force the splash screen to layout
      splash.layout(true);
      // Keep the splash screen visible and prevent the RCP application from
      // loading until the close button is clicked.
      // TODO: No login atm. Would be annoying.
      // doEventLoop();
      this.initServerConnection();
   }

   private boolean initServerConnection() {
      return ServerConnectionManager.getInstance().isReachable();
   }
}
exelnet
 
Posts: 2
Joined: Tue Dec 02, 2008 1:11 am

Re: SWT GUI Element Methods and Own Forms Widgets

Postby Konstantin.Scheglov » Wed Dec 03, 2008 12:12 am

We can add support for something like this in future.

When I say "something like this", I mean that we will use same style as for "lazy creation" in Swing - each container method creates also children components (invokes
corresponding methods). In contrast, in your example hierarchy is build in single method, i.e. all single methods are invoked from single one. I think that Swing approach is better for structuring source.

This is not so easy to support however, so this will require some time.
Konstantin.Scheglov
Moderator
 
Posts: 186
Joined: Tue Oct 18, 2005 8:11 pm
Location: Russian Federation, Lipetsk


Return to SWT Designer

Who is online

Users browsing this forum: No registered users and 2 guests