Skip to main content



      Home
Home » Eclipse Projects » Rich Client Platform (RCP) » Custom preferences FieldEditor causes error(Using a custom FieldEditor causes an error dialog to appear)
Custom preferences FieldEditor causes error [message #524137] Tue, 30 March 2010 17:36 Go to next message
Eclipse UserFriend
Hi,

Within my simple RCP application, I've created a custom FieldEditor that I'm trying to use in a FieldEditorPreferencePage. I add my custom editor to the page via the standard addField(..) method within my override of the page createFieldEditors(..) . All very standard stuff.

During runtime, when I bring up the preferences dialog I get an error dialog titled "Could Not Accept Changes" with the message "The currently displayed page contains invalid values." Once I click past the error dialog, the preferences page displays correctly along with my custom FieldEditor, but all fields on the page are blank (not even defaults set by an implementation of AbstractPreferenceInitializer show).

If I comment out the addField() call for my custom FieldEditor everything runs fine (no error dialog) and shows the default values for the other field editors.

Clearly, something is amiss with my custom FieldEditor, but the problem evades me. What types of conditions cause this "Could Not Accept Changes" dialog to appear?

The custom editor code follows:

package com.objectnexus.rcp.preferences.page;

import org.eclipse.jface.preference.FieldEditor;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
import org.eclipse.swt.events.VerifyEvent;
import org.eclipse.swt.events.VerifyListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.GC;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.MessageBox;
import org.eclipse.swt.widgets.Scale;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class ImageScaleFieldEditor extends FieldEditor
{
    private static final int INIT_SCALE = 50;
    private static final int MIN_SCALE = 0;
    private static final int MAX_SCALE = 100;

    private static final int MIN_IMG_SIZE = 2;

    private Composite pageComposite = null;
    private Group grp = null;
    private Scale scale = null;
    private Text valueTxt = null;
    private Canvas canvas = null;
    private Label percentLbl = null;

    private CanvasPaintListener paintListener = null;

    public ImageScaleFieldEditor( String name, String labelText, Composite parent )
    {
        super( name, labelText, parent );
    }

    @Override
    protected void adjustForNumColumns( int numColumns )
    {
        ( (GridData) pageComposite.getLayoutData() ).horizontalSpan = numColumns;
    }

    @Override
    protected void doFillIntoGrid( Composite parent, int numColumns )
    {
        pageComposite = parent;

        grp = new Group( pageComposite, SWT.SHADOW_ETCHED_OUT );
        grp.setText( getLabelText() );

        FormLayout lout = new FormLayout();
        lout.marginWidth = 5;
        lout.marginHeight = 5;

        grp.setLayout( lout );

        canvas = new Canvas( grp, SWT.NONE );
        paintListener = new CanvasPaintListener( canvas, INIT_SCALE );
        canvas.addPaintListener( paintListener );

        scale = new Scale( grp, SWT.HORIZONTAL );
        scale.setMaximum( MAX_SCALE );
        scale.setMinimum( 0 );

        valueTxt = new Text( grp, SWT.SINGLE | SWT.CENTER );
        PercentVerifyListener pctVerifyListener = new PercentVerifyListener();
        valueTxt.addVerifyListener( pctVerifyListener );
        PercentModifyListener pctModifyListener = new PercentModifyListener( scale, paintListener );
        valueTxt.addModifyListener( pctModifyListener );

        percentLbl = new Label( grp, SWT.LEFT );
        percentLbl.setText( "%" );

        ScaleSelectionListener scaleListener = new ScaleSelectionListener( valueTxt, paintListener );
        scale.addSelectionListener( scaleListener );
        scale.setSelection( INIT_SCALE );

        valueTxt.setText( String.valueOf( INIT_SCALE ) );

        // do layout
        FormData fdata = new FormData();
        fdata.left = new FormAttachment( 0, 5 );
        fdata.top = new FormAttachment( 0, 5 );
        fdata.right = new FormAttachment( 55, -5 );
        scale.setLayoutData( fdata );

        // define the preferred width of the valueTxt field
        GC gc = new GC( valueTxt );
        Point p = gc.textExtent( String.valueOf( MAX_SCALE ) );
        gc.dispose();

        fdata = new FormData();
        fdata.width = p.x;
        fdata.left = new FormAttachment( scale, 5 );
        fdata.top = new FormAttachment( scale, 0, SWT.CENTER );
        valueTxt.setLayoutData( fdata );

        fdata = new FormData();
        fdata.left = new FormAttachment( valueTxt, 0 );
        fdata.top = new FormAttachment( valueTxt, 0, SWT.CENTER );
        percentLbl.setLayoutData( fdata );

        fdata = new FormData();
        fdata.left = new FormAttachment( percentLbl, 10 );
        fdata.top = new FormAttachment( percentLbl, 0, SWT.CENTER );
        canvas.setLayoutData( fdata );

        // page layout
        GridData gd = new GridData( GridData.FILL_HORIZONTAL );
        gd.horizontalSpan = numColumns;
        grp.setLayoutData( gd );

    }

    @Override
    protected void doLoad()
    {
        int scaleValue = getPreferenceStore().getInt( getPreferenceName() );
        scale.setSelection( scaleValue );
    }

    @Override
    protected void doLoadDefault()
    {
        int scaleValue = getPreferenceStore().getDefaultInt( getPreferenceName() );
        scale.setSelection( scaleValue );
    }

    @Override
    protected void doStore()
    {
        int scaleValue = scale.getSelection();
        getPreferenceStore().setValue( getPreferenceName(), scaleValue );
    }

    @Override
    public int getNumberOfControls()
    {
        return 5;
    }

    private class CanvasPaintListener implements PaintListener
    {
        private int scaleFactor = 0;
        private Canvas canvas = null;

        public CanvasPaintListener( Canvas canvas, int scaleFactor )
        {
            this.canvas = canvas;
            setScaleFactor( scaleFactor );
        }

        public void setScaleFactor( int scaleFactor )
        {
            this.scaleFactor = scaleFactor;
        }

        public int getScaleFactor()
        {
            return scaleFactor;
        }

        public Canvas getCanvas()
        {
            return canvas;
        }

        @Override
        public void paintControl( PaintEvent e )
        {
            GC gc = e.gc;
            Color borderColor = e.display.getSystemColor( SWT.COLOR_BLACK );
            gc.setBackground( borderColor );

            int maxWidth = e.width - 1;
            int maxHeight = e.height - 1;
            gc.drawRectangle( e.x, e.y, maxWidth, maxHeight );

            Color sqColor = e.display.getSystemColor( SWT.COLOR_DARK_GREEN );
            int centerX = e.x + e.width / 2;
            int centerY = e.y + e.height / 2;

            // if ( getScaleFactor() < 20 )
            // setScaleFactor( 20 );

            int scaledWidth = (int) maxWidth * getScaleFactor() / MAX_SCALE;
            int scaledHeight = (int) maxHeight * getScaleFactor() / MAX_SCALE;

            if ( scaledWidth > e.width )
                scaledWidth = e.width - 1;

            if ( scaledHeight > e.height )
                scaledHeight = e.height - 1;

            if ( scaledWidth < MIN_IMG_SIZE || scaledHeight < MIN_IMG_SIZE )
                scaledWidth = scaledHeight = MIN_IMG_SIZE;

            int sqX = centerX - scaledWidth / 2;
            int sqY = centerY - scaledHeight / 2;

            gc.setBackground( sqColor );
            gc.fillRectangle( sqX, sqY, scaledWidth, scaledHeight );

        }

    }

    private class ScaleSelectionListener implements SelectionListener
    {
        private Text valueTxt;
        private CanvasPaintListener paintListener;

        public ScaleSelectionListener( Text txt, CanvasPaintListener listener )
        {
            valueTxt = txt;
            paintListener = listener;
        }

        @Override
        public void widgetSelected( SelectionEvent e )
        {
            Scale scale = (Scale) e.widget;
            int value = scale.getSelection();

            if ( value < MIN_SCALE )
            {
                scale.setSelection( MIN_SCALE );
                value = MIN_SCALE;
            }

            valueTxt.setText( String.valueOf( value ) );

            paintListener.setScaleFactor( value );
            paintListener.getCanvas().redraw();
        }

        @Override
        public void widgetDefaultSelected( SelectionEvent e )
        {
        }

    }

    private class PercentVerifyListener implements VerifyListener
    {

        @Override
        public void verifyText( VerifyEvent e )
        {
            String value = e.text;
            try
            {
                Integer.parseInt( value );
            }
            catch ( Exception ex )
            {
                e.doit = false;
            }
        }

    }

    private class PercentModifyListener implements ModifyListener
    {
        private Scale scale;
        private CanvasPaintListener paintListener;

        public PercentModifyListener( Scale sc, CanvasPaintListener listener )
        {
            scale = sc;
            paintListener = listener;
        }

        @Override
        public void modifyText( ModifyEvent e )
        {
            Text txtWidget = (Text) e.widget;
            String txt = txtWidget.getText();

            int newValue = Integer.parseInt( txt );
            if ( newValue < MIN_SCALE || newValue > MAX_SCALE )
            {
                Shell shell = e.display.getActiveShell();
                MessageBox msgBox = new MessageBox( shell, SWT.ERROR | SWT.OK );
                msgBox.setMessage( "Value out of Range" );
                msgBox.open();

                // reset view to initial default
                txtWidget.setText( String.valueOf( INIT_SCALE ) );
                txtWidget.selectAll();
                scale.setSelection( INIT_SCALE );
                paintListener.setScaleFactor( INIT_SCALE );
                paintListener.getCanvas().redraw();
            }
            else
            {
                scale.setSelection( newValue );
                paintListener.setScaleFactor( newValue );
                paintListener.getCanvas().redraw();
            }

        }

    }

}



Thanks in advance for the help.

Re: Custom preferences FieldEditor causes error [message #524384 is a reply to message #524137] Wed, 31 March 2010 14:14 Go to previous messageGo to next message
Eclipse UserFriend
After spending lots of time in the eclipse debugger, I fixed a number of issues with my code and finally got things to work.

The main question: What types of conditions cause this "Could Not Accept Changes" dialog to appear?

Answer: Any exception thrown in the code propagates up the stack, and ultimately results in the "Could Not Accept Changes" dialog to appear.

In my case, there were NullPointerExceptions being thrown in places within the doLoad() method that caused the dialog to appear.

Hopefully this tidbit will help others.
Re: Custom preferences FieldEditor causes error [message #524411 is a reply to message #524384] Wed, 31 March 2010 16:07 Go to previous message
Eclipse UserFriend
Hi,

> In my case, there were NullPointerExceptions being thrown in places
> within the doLoad() method that caused the dialog to appear.

was an exception logged to the log of your application (launch with -consolelog)? If not,
you probably should file a bug about this, because the preference dialog or page should
catch the exception in the page initialization and at least log it so it's easy to spot.

Greetings,

Ralf


--
http://www.ralfebert.de/blog/
http://twitter.com/ralfebert/
Previous Topic:Refresh CommenNavigator
Next Topic:Cut/Copy/Paste for CustomControls
Goto Forum:
  


Current Time: Sat Jun 14 14:18:27 EDT 2025

Powered by FUDForum. Page generated in 0.04672 seconds
.:: Contact :: Home ::.

Powered by: FUDforum 3.0.2.
Copyright ©2001-2010 FUDforum Bulletin Board Software

Back to the top