Skip to main content



      Home
Home » Eclipse Projects » Standard Widget Toolkit (SWT) » [SOLVED] Setting limit to Sash position doesn't work on Mac OS X(Setting minimum width to SashForm children)
icon5.gif  [SOLVED] Setting limit to Sash position doesn't work on Mac OS X [message #633984] Wed, 20 October 2010 03:36 Go to next message
Eclipse UserFriend
Hi, everybody,

I have encountered a strange behavior when setting minimum composite width when moving sash. I have two composites inside a SWT.HORIZONTAL style SashForm. When I want to set a limit how far to the right Sash can be moved, I'm using a code, which works on Windows and GTK, but when running this code on Mac OS X (10.6), once the sash is moved to this limit, "West-East" cursor won't appear anymore when hovering with a mouse over it, and Sash cannot be no longer moved. If I resize the shell, cursor reappears and Sash can be moved again.

Here is the snippet that can be used to reproduce this behavior:


import java.lang.reflect.Field;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.SashForm;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Sash;
import org.eclipse.swt.widgets.Shell;

public class SashFormTest
{
    // Minimum width of right composite
    final static int MIN_WIDTH = 200;
    
    public static void main (String [] args)
    {
        Display display = new Display ();
        
        final Shell shell = new Shell(display);        
        shell.setLayout(new FormLayout());        
        shell.setText("SashFormTest");
        
        final SashForm sashForm = new SashForm(shell, SWT.HORIZONTAL);
        
        sashForm.setLayout(new FormLayout());
        {
            FormData formData = new FormData();
            formData.top = new FormAttachment(0, 0);            
            formData.bottom = new FormAttachment(100, 0);
            formData.left = new FormAttachment(0, 0);            
            formData.right = new FormAttachment(100, 0);
            sashForm.setLayoutData(formData);
        }
        
        Composite leftComposite = new Composite(sashForm, SWT.NONE);
        leftComposite.setLayout(new FormLayout());
        {
            FormData formData = new FormData();
            formData.top = new FormAttachment(0, 0);            
            formData.bottom = new FormAttachment(100, 0);
            formData.left = new FormAttachment(0, 0);            
            formData.right = new FormAttachment(100, 0);
            leftComposite.setLayoutData(formData);
        }
        leftComposite.setBackground(new Color(shell.getDisplay(), 255, 0, 0));
                
        Composite rightComposite = new Composite(sashForm, SWT.NONE);        
        rightComposite.setLayout(new FormLayout());
        {
            FormData formData = new FormData();
            formData.top = new FormAttachment(0, 0);            
            formData.bottom = new FormAttachment(100, 0);
            formData.left = new FormAttachment(0, 0);            
            formData.right = new FormAttachment(100, 0);
            rightComposite.setLayoutData(formData);
        }
        rightComposite.setBackground(new Color(shell.getDisplay(), 0, 255, 0));
        
        sashForm.setWeights(new int[] {30, 70});
        
        shell.setSize(500, 200);
        
        // Get sashes using reflection
        Sash[] sashes = getSashes(sashForm);
        
        Sash sash = sashes[0];
        
        // Composite on the right side of the sash
        // is always at least 200 px wide, when sash is moved
        sash.addSelectionListener(new SelectionAdapter ()
        {                     
            public void widgetSelected(SelectionEvent event)
            {   
                if (event.x >= shell.getBounds().width - MIN_WIDTH)
                {   
                    int shellWidth = shell.getBounds().width;
                    
                    // Calculate new ratio for sashes weights                    
                    double ratio = (double)shellWidth / Math.abs(shell.getBounds().width - MIN_WIDTH);                                            
                    double percent = 100 / ratio;                  
                    
                    int percentRounded = (int) Math.floor(percent);
                    
                    sashForm.setWeights(new int[]{percentRounded, 100 - percentRounded});                                      
                    sashForm.layout();                      
                }
            }
        });
        
        shell.open ();
        
        while (!shell.isDisposed ())
        {
            if (!display.readAndDispatch())
            {
                display.sleep ();
            }   
        }
        display.dispose ();
    }
    
    private static Sash[] getSashes(SashForm sf)
    {
        Field fields[] = sf.getClass().getDeclaredFields();
        for (int i = 0; i < fields.length; ++i)
        {            
            if (fields[i].getName().equals("sashes"))
            {   
                try
                {   
                    fields[i].setAccessible(true);
                    return (Sash[]) fields[i].get(sf);
                }
                catch (IllegalAccessException e)
                {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}



I'm not sure if there is any better way to achieve this, but I couldn't find any other means to limit how far a Sash can be moved. Nevertheless, I can't see a reason why this wouldn't work. Am I missing something obvious here? Any suggestion would be helpful,


best regards,

Albert




[Updated on: Fri, 22 October 2010 08:24] by Moderator

Re: Setting limit to Sash position doesn't work on Mac OS X [message #634563 is a reply to message #633984] Fri, 22 October 2010 04:54 Go to previous messageGo to next message
Eclipse UserFriend
Hi,

Moving the sashForm.layout() inside display.asyncExec() seems to fix the problem.

Since this doesn't work only on Mac as it is, it may be a bug.
I suggest you to open a bug under SWT --> https://bugs.eclipse.org/bugs/enter_bug.cgi?product=Platform &component=SWT

Another way to do this is to use a controlListener to the composite and do the weight computation when control is resized.
rightComposite.addControlListener(new ControlListener() {
public void controlResized(ControlEvent e) {
if (rightComposite.getSize().x <= MIN_WIDTH) {
// weight computation code here
}
}}
note: SashForm is a composite, so you can use sashForm.getChildren() to get the sash (instead of using reflection).

Re: Setting limit to Sash position doesn't work on Mac OS X [message #634602 is a reply to message #634563] Fri, 22 October 2010 08:22 Go to previous messageGo to next message
Eclipse UserFriend
Hi, Lakshmi,

thank you for your quick answer, putting sashForm.layout(); inside an asyncExec() really fixed the problem. I'll report a bug on Eclipse Bugzilla.

I didn't look at the SashForm hierarchy, so I was completely unaware that SashForm is a Composite and I was using reflection instead of simple call to SashForm.getChildren() in order to get the sash.


Thanks again, best regards,

Albert

[Updated on: Fri, 22 October 2010 10:09] by Moderator

Re: [SOLVED] Setting limit to Sash position doesn't work on Mac OS X [message #639945 is a reply to message #633984] Thu, 18 November 2010 08:52 Go to previous message
Eclipse UserFriend
Hi,Lakshmi,

I'm sorry for the late reply, I totally forgot to report a bug on Eclipse Bugzilla. I reported it today, please see:

https://bugs.eclipse.org/bugs/show_bug.cgi?id=330566

I searched Bugzilla before reporting and didn't find any similar entry.


Best regards,

Albert
Previous Topic:Menu with Unity Desktop
Next Topic:label length within form toolkit
Goto Forum:
  


Current Time: Fri Jul 04 19:25:46 EDT 2025

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

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

Back to the top