You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@pivot.apache.org by Edvin Syse <ed...@sysedata.no> on 2011/06/15 14:54:29 UTC

Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

I have implemented "double click edits" in a TreeViewer. If I expand and 
collapse a branch in rapid succession, this will also trigger my double 
click handler:

     private class DoubleClickEditsAdapter extends 
ComponentMouseButtonListener.Adapter {
         public boolean mouseClick(Component component, Mouse.Button 
button, int x, int y, int count) {
             if (count == 2 && button == Mouse.Button.LEFT)
                 editSelectedNode(component);
             return true;
         }
     }

I somehow have to avoid that the clicks used to expand and collapse the 
node counts as double click candidates. Any idea how I can do that?

-- Edvin



Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Chris Bartlett <cb...@gmail.com>.
I think the TreeView skin will probably be looking at the indent size,
checkbox widths etc to determine how to process mouseClick, mouseDown and
mouseUp events.

Not sure if you will be able to access enough of that data to perform
similar calculations.

Chris


On 15 June 2011 20:45, Edvin Syse <ed...@sysedata.no> wrote:

>
> Den 15.06.2011 15:41, skrev Chris Bartlett:
>
>> I just took a *very* quick look at the Kitchen Sink demo, and it seems to
>> handle this scenario OK.
>> http://pivot.apache.org/demos/kitchen-sink.html
>>
>> Are you using a TreeView.NodeEditor, or have you rolled your own solution?
>>
>> http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.NodeEditor.html
>>
>> http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.html#setNodeEditor(org.apache.pivot.wtk.TreeView.NodeEditor)<
>> http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.html#setNodeEditor%28org.apache.pivot.wtk.TreeView.NodeEditor%29
>> >
>>
>> Chris
>>
> I realize I wasn't completly clear. Double click doesn't open a node
> editor, it opens a BoxPane in a neighbouring TabPane, it doesn't change
> anything in the TreeView. I'll have a look at the kitchen sink demo code, as
> you say it seems to handle it somehow :)
>

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Edvin Syse <ed...@sysedata.no>.
Den 15.06.2011 15:41, skrev Chris Bartlett:
> I just took a *very* quick look at the Kitchen Sink demo, and it seems 
> to handle this scenario OK.
> http://pivot.apache.org/demos/kitchen-sink.html
>
> Are you using a TreeView.NodeEditor, or have you rolled your own 
> solution?
> http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.NodeEditor.html
> http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.html#setNodeEditor(org.apache.pivot.wtk.TreeView.NodeEditor) 
> <http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.html#setNodeEditor%28org.apache.pivot.wtk.TreeView.NodeEditor%29>
>
> Chris
I realize I wasn't completly clear. Double click doesn't open a node 
editor, it opens a BoxPane in a neighbouring TabPane, it doesn't change 
anything in the TreeView. I'll have a look at the kitchen sink demo 
code, as you say it seems to handle it somehow :)

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Chris Bartlett <cb...@gmail.com>.
On 15 June 2011 20:41, Chris Bartlett <cb...@gmail.com> wrote:

> I just took a *very* quick look at the Kitchen Sink demo, and it seems to
> handle this scenario OK.
> http://pivot.apache.org/demos/kitchen-sink.html
>

Just to clarify - I was looking at the first TreeView in the 'Trees' rollup.

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Greg Brown <gk...@verizon.net>.
No problem.  :-)

On Jun 15, 2011, at 1:11 PM, Edvin Syse wrote:

> Den 15.06.2011 19:00, skrev Greg Brown:
>> Could you possibly use TreeView#getNodeAt() and getNodeIndent() instead of looking at the style values?
> 
> Hehe.. yes, that was a lot easier (and skin independent):
> 
> Sequence.Tree.Path path = treeView.getNodeAt(y);
> if (path != null) {
>    TreeNode node = (TreeNode) Sequence.Tree.get(treeView.getTreeData(), path);
>    if (node instanceof TreeBranch) {
>        if (x > treeView.getNodeIndent(path.getLength()))
>            doubleClicked(node);
>    } else {
>        doubleClicked(node);
>    }
> }
> 
> Thank you so much :)
> 
> -- Edvin


Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Edvin Syse <ed...@sysedata.no>.
Den 15.06.2011 19:00, skrev Greg Brown:
> Could you possibly use TreeView#getNodeAt() and getNodeIndent() instead of looking at the style values?

Hehe.. yes, that was a lot easier (and skin independent):

Sequence.Tree.Path path = treeView.getNodeAt(y);
if (path != null) {
     TreeNode node = (TreeNode) 
Sequence.Tree.get(treeView.getTreeData(), path);
     if (node instanceof TreeBranch) {
         if (x > treeView.getNodeIndent(path.getLength()))
             doubleClicked(node);
     } else {
         doubleClicked(node);
     }
}

Thank you so much :)

-- Edvin

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Greg Brown <gk...@verizon.net>.
Could you possibly use TreeView#getNodeAt() and getNodeIndent() instead of looking at the style values?

On Jun 15, 2011, at 12:52 PM, Edvin Syse wrote:

> Den 15.06.2011 18:35, skrev Greg Brown:
>> Why might you need to know what type of skin is installed on a component? Maybe there is another alternative that might address your use case?
> 
> My use case is to avoid the problem described in the subject. I don't want to edit when I double click the branch controls (double clicking happens when you collapse and expand in rapid succession). I wrote a utility class that I install on the TreeView like this:
> 
> getComponentMouseButtonListeners().add(new DoubleClickTreeAdapter(this) {
>    public void doubleClicked(TreeNode node) {
>        editNode(node);
>    }
> });
> 
> The doubleClicked() callback is invoked when an actual double click occured. editNode() opens my editor for the current node, this is _not_ an inline editor, it opens a BoxPane with a Form and some other stuff inside a TabPane to the right of the TreeView.
> 
> The DoubleClickTreeAdapter.java looks like this:
> 
> public abstract class DoubleClickTreeAdapter implements ComponentMouseButtonListener {
>    private TreeView treeView;
> 
>    public DoubleClickTreeAdapter(TreeView treeView) {
>        this.treeView = treeView;
>    }
> 
>    public boolean mouseClick(Component component, Mouse.Button button, int x, int y, int count) {
>        if (count == 2 && button == Mouse.Button.LEFT) {
>            Sequence.Tree.Path path = treeView.getNodeAt(y);
>            if (path != null) {
>                TreeNode node = (TreeNode) Sequence.Tree.get(treeView.getTreeData(), path);
>                if (node instanceof TreeBranch) {
>                    if (Theme.getTheme().getSkinClass(TreeView.class).isAssignableFrom(TerraTreeViewSkin.class)) {
>                        Integer indent = (Integer) treeView.getStyles().get("indent");
>                        Integer spacing = (Integer) treeView.getStyles().get("spacing");
>                        int baseNodeX = path.getLength() * (indent + spacing);
>                        if (x > baseNodeX)
>                            doubleClicked(node);
>                    } else {
>                        // Add support for other skins here, default to allow double click anywhere for unknown skins
>                        doubleClicked(node);
>                    }
>                } else {
>                    doubleClicked(node);
>                }
>            }
>        } else if (count == 1 && treeView.getNodeAt(y) == null)
>            treeView.clearSelection();
>        return true;
>    }
> 
>    public abstract void doubleClicked(TreeNode node);
> }
> 
> As you can see, I check that the TreeViewSkin is infact TerraTreeViewSkin, so that I know I can relay on the indent and spacing to determine if I clicked on or to the left of a branch control, or on the actual node icon/text.
> 
> I will default to call doubleClicked() if there is a non-standard skin installed, but I can easily add more checks for different skins.
> 
> (I removed the empty mouseDown/mouseUp calls from the code above).
> 
> -- Edvin


Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Edvin Syse <ed...@sysedata.no>.
Den 15.06.2011 18:35, skrev Greg Brown:
> Why might you need to know what type of skin is installed on a component? Maybe there is another alternative that might address your use case?

My use case is to avoid the problem described in the subject. I don't 
want to edit when I double click the branch controls (double clicking 
happens when you collapse and expand in rapid succession). I wrote a 
utility class that I install on the TreeView like this:

getComponentMouseButtonListeners().add(new DoubleClickTreeAdapter(this) {
     public void doubleClicked(TreeNode node) {
         editNode(node);
     }
});

The doubleClicked() callback is invoked when an actual double click 
occured. editNode() opens my editor for the current node, this is _not_ 
an inline editor, it opens a BoxPane with a Form and some other stuff 
inside a TabPane to the right of the TreeView.

The DoubleClickTreeAdapter.java looks like this:

public abstract class DoubleClickTreeAdapter implements 
ComponentMouseButtonListener {
     private TreeView treeView;

     public DoubleClickTreeAdapter(TreeView treeView) {
         this.treeView = treeView;
     }

     public boolean mouseClick(Component component, Mouse.Button button, 
int x, int y, int count) {
         if (count == 2 && button == Mouse.Button.LEFT) {
             Sequence.Tree.Path path = treeView.getNodeAt(y);
             if (path != null) {
                 TreeNode node = (TreeNode) 
Sequence.Tree.get(treeView.getTreeData(), path);
                 if (node instanceof TreeBranch) {
                     if 
(Theme.getTheme().getSkinClass(TreeView.class).isAssignableFrom(TerraTreeViewSkin.class)) 
{
                         Integer indent = (Integer) 
treeView.getStyles().get("indent");
                         Integer spacing = (Integer) 
treeView.getStyles().get("spacing");
                         int baseNodeX = path.getLength() * (indent + 
spacing);
                         if (x > baseNodeX)
                             doubleClicked(node);
                     } else {
                         // Add support for other skins here, default to 
allow double click anywhere for unknown skins
                         doubleClicked(node);
                     }
                 } else {
                     doubleClicked(node);
                 }
             }
         } else if (count == 1 && treeView.getNodeAt(y) == null)
             treeView.clearSelection();
         return true;
     }

     public abstract void doubleClicked(TreeNode node);
}

As you can see, I check that the TreeViewSkin is infact 
TerraTreeViewSkin, so that I know I can relay on the indent and spacing 
to determine if I clicked on or to the left of a branch control, or on 
the actual node icon/text.

I will default to call doubleClicked() if there is a non-standard skin 
installed, but I can easily add more checks for different skins.

(I removed the empty mouseDown/mouseUp calls from the code above).

-- Edvin

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Greg Brown <gk...@verizon.net>.
Why might you need to know what type of skin is installed on a component? Maybe there is another alternative that might address your use case?

On Jun 15, 2011, at 12:32 PM, Edvin Syse wrote:

> Den 15.06.2011 18:22, skrev Greg Brown:
>>> I see Component.getSkin() is protected - why is that? Would be nice to be able to check what kind of skin was installed on a component.
>> 
>> It is protected to prevent a caller from invoking methods directly on the skin. All interaction with a skin is done via styles or the component API (which fires events that the skin responds to). Anything else would create a hard association with a particular theme, which is undesirable.
>> 
>> If you want to find out what type of skin is installed on a component, you could always query the current theme.
> 
> That makes sense :) I'll use Theme#getSkinClass(component) to decide then :)
> 
> -- Edvin


Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Edvin Syse <ed...@sysedata.no>.
Den 15.06.2011 18:22, skrev Greg Brown:
>> I see Component.getSkin() is protected - why is that? Would be nice to be able to check what kind of skin was installed on a component.
>
> It is protected to prevent a caller from invoking methods directly on the skin. All interaction with a skin is done via styles or the component API (which fires events that the skin responds to). Anything else would create a hard association with a particular theme, which is undesirable.
>
> If you want to find out what type of skin is installed on a component, you could always query the current theme.

That makes sense :) I'll use Theme#getSkinClass(component) to decide then :)

-- Edvin

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Greg Brown <gk...@verizon.net>.
> I see Component.getSkin() is protected - why is that? Would be nice to be able to check what kind of skin was installed on a component.

It is protected to prevent a caller from invoking methods directly on the skin. All interaction with a skin is done via styles or the component API (which fires events that the skin responds to). Anything else would create a hard association with a particular theme, which is undesirable.

If you want to find out what type of skin is installed on a component, you could always query the current theme.


Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Chris Bartlett <cb...@gmail.com>.
Greg or Todd could give you the official answer, but I think it is meant to
ensure that access to the skin always occurs via the StyleDictionary.  That
way the code would be able to run with a different theme, or merely a
different skin for the component.

You could always extend   TerraTreeViewSkin and add your code into that
class.  Then you *know* that  'indent' and 'spacing will be there, and it
would be fine to access them directly.

CustomTerraTreeViewSkin extends TerraTreeViewSkin {
    public void myMethod() {
        int indent = getIndent();
        int spacing = getSpacing();
        ...
      }
}'

You could then create a CustomTreeView and associate it with your
CustomTerraTreeViewSkin in the Theme, so that any instance of
CustomTreeView would use   CustomTerraTreeViewSkin.

Chris

On 15 June 2011 23:14, Edvin Syse <ed...@sysedata.no> wrote:

> Den 15.06.2011 18:02, skrev Chris Bartlett:
>
>> On 15 June 2011 22:50, Edvin Syse <edvin@sysedata.no
>> <ma...@sysedata.no>> wrote:
>>
>>                        TerraTreeViewSkin skin = (TerraTreeViewSkin)
>>    getSkin();
>>                        int baseNodeX = path.getLength() *
>>    (skin.getIndent() + skin.getSpacing());
>>
>>
>> If all you need are the 'indent' and 'spacing', they are properties of
>> the skin, and therefore available as styles via the TreeView.  You can
>> avoid casting the skin to TerraTreeViewSkin and accessing its properies
>> directly.
>>
>> treeView.getStyles().get("indent");
>> treeView.getStyles().get("spacing");
>>
>> In reality that doesn't really help much though, as you are still
>> relying on those styles being there, and also relying on the fact that
>> they behave exactly as they do in TerraTreeViewSkin.
>>
>
> Absolutely :) I'll rewrite my utility class to use the indent and spacing
> styles anyway, since a new skin is more than likely to be based on Terra.
> Later on I could add special cases based on the skin maybe. I see
> Component.getSkin() is protected - why is that? Would be nice to be able to
> check what kind of skin was installed on a component.
>
>

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Edvin Syse <ed...@sysedata.no>.
Den 15.06.2011 18:02, skrev Chris Bartlett:
> On 15 June 2011 22:50, Edvin Syse <edvin@sysedata.no
> <ma...@sysedata.no>> wrote:
>
>                         TerraTreeViewSkin skin = (TerraTreeViewSkin)
>     getSkin();
>                         int baseNodeX = path.getLength() *
>     (skin.getIndent() + skin.getSpacing());
>
>
> If all you need are the 'indent' and 'spacing', they are properties of
> the skin, and therefore available as styles via the TreeView.  You can
> avoid casting the skin to TerraTreeViewSkin and accessing its properies
> directly.
>
> treeView.getStyles().get("indent");
> treeView.getStyles().get("spacing");
>
> In reality that doesn't really help much though, as you are still
> relying on those styles being there, and also relying on the fact that
> they behave exactly as they do in TerraTreeViewSkin.

Absolutely :) I'll rewrite my utility class to use the indent and 
spacing styles anyway, since a new skin is more than likely to be based 
on Terra. Later on I could add special cases based on the skin maybe. I 
see Component.getSkin() is protected - why is that? Would be nice to be 
able to check what kind of skin was installed on a component.


Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Chris Bartlett <cb...@gmail.com>.
On 15 June 2011 22:50, Edvin Syse <ed...@sysedata.no> wrote:

>                    TerraTreeViewSkin skin = (TerraTreeViewSkin) getSkin();
>                    int baseNodeX = path.getLength() * (skin.getIndent() +
> skin.getSpacing());
>


If all you need are the 'indent' and 'spacing', they are properties of the
skin, and therefore available as styles via the TreeView.  You can avoid
casting the skin to TerraTreeViewSkin and accessing its properies directly.

treeView.getStyles().get("indent");
treeView.getStyles().get("spacing");

In reality that doesn't really help much though, as you are still relying on
those styles being there, and also relying on the fact that they behave
exactly as they do in TerraTreeViewSkin.

Chris

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Edvin Syse <ed...@sysedata.no>.
Den 15.06.2011 16:05, skrev Chris Bartlett:
> Yep, in here it seems..
> http://svn.apache.org/repos/asf/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraTreeViewSkin.java
>
> See mouseUp, moiuseDown & mouseClick.

Cool, so my working solution is like this:

private class DoubleClickEditsAdapter extends 
ComponentMouseButtonListener.Adapter {
     public boolean mouseClick(Component component, Mouse.Button button, 
int x, int y, int count) {
         if (count == 2 && button == Mouse.Button.LEFT) {
             Sequence.Tree.Path path = getNodeAt(y);
             if (path != null) {
                 TreeNode node = (TreeNode) 
Sequence.Tree.get(getTreeData(), path);
                 if (node instanceof TreeBranch) {
                     TerraTreeViewSkin skin = (TerraTreeViewSkin) getSkin();
                     int baseNodeX = path.getLength() * 
(skin.getIndent() + skin.getSpacing());
                     if (x > baseNodeX)
                         editNode(node);
                 } else {
                     editNode(node);
                 }
             }
         }
         return true;
     }
}


I allow double clicking anywhere on a TreeNode to edit it, but only to 
the right of the branch controls on a TreeBranch. Will refactor it to 
create a utility method though :)

-- Edvin

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Chris Bartlett <cb...@gmail.com>.
Yep, in here it seems..
http://svn.apache.org/repos/asf/pivot/trunk/wtk-terra/src/org/apache/pivot/wtk/skin/terra/TerraTreeViewSkin.java

See mouseUp, moiuseDown & mouseClick.

On 15 June 2011 20:56, Chris Bartlett <cb...@gmail.com> wrote:

> Sorry, I should have been more clear, myself!
>
> The KitchenSink demo uses a standard TreeView as far as I know.
> So the code that is handling the mouse clicks will be in
> org.apache.pivot.wtk.skin.terra.TerraTreeViewSkin.
>
> Chris
>
> On 15 June 2011 20:52, Edvin Syse <ed...@sysedata.no> wrote:
>
>>
>> Den 15.06.2011 15:41, skrev Chris Bartlett:
>>
>>> I just took a *very* quick look at the Kitchen Sink demo, and it seems to
>>> handle this scenario OK.
>>>
>>> http://pivot.apache.org/demos/kitchen-sink.html
>>>
>>
>> Can you point me in the right direction? I looked around line 600 and
>> down, but can't find anything useful (even though I see that it handles it
>> :)
>>
>
>

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Chris Bartlett <cb...@gmail.com>.
Sorry, I should have been more clear, myself!

The KitchenSink demo uses a standard TreeView as far as I know.
So the code that is handling the mouse clicks will be in
org.apache.pivot.wtk.skin.terra.TerraTreeViewSkin.

Chris

On 15 June 2011 20:52, Edvin Syse <ed...@sysedata.no> wrote:

>
> Den 15.06.2011 15:41, skrev Chris Bartlett:
>
>> I just took a *very* quick look at the Kitchen Sink demo, and it seems to
>> handle this scenario OK.
>>
>> http://pivot.apache.org/demos/kitchen-sink.html
>>
>
> Can you point me in the right direction? I looked around line 600 and down,
> but can't find anything useful (even though I see that it handles it :)
>

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Edvin Syse <ed...@sysedata.no>.
Den 15.06.2011 15:41, skrev Chris Bartlett:
> I just took a *very* quick look at the Kitchen Sink demo, and it seems 
> to handle this scenario OK.
> http://pivot.apache.org/demos/kitchen-sink.html

Can you point me in the right direction? I looked around line 600 and 
down, but can't find anything useful (even though I see that it handles 
it :)

Re: Avoid "double click signal" when expanding and collapsing a branch in a TreeViewer

Posted by Chris Bartlett <cb...@gmail.com>.
I just took a *very* quick look at the Kitchen Sink demo, and it seems to
handle this scenario OK.
http://pivot.apache.org/demos/kitchen-sink.html

Are you using a TreeView.NodeEditor, or have you rolled your own solution?
http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.NodeEditor.html
http://pivot.apache.org/2.0/docs/api/org/apache/pivot/wtk/TreeView.html#setNodeEditor(org.apache.pivot.wtk.TreeView.NodeEditor)

Chris

On 15 June 2011 19:54, Edvin Syse <ed...@sysedata.no> wrote:

> I have implemented "double click edits" in a TreeViewer. If I expand and
> collapse a branch in rapid succession, this will also trigger my double
> click handler:
>
>    private class DoubleClickEditsAdapter extends
> ComponentMouseButtonListener.Adapter {
>        public boolean mouseClick(Component component, Mouse.Button button,
> int x, int y, int count) {
>            if (count == 2 && button == Mouse.Button.LEFT)
>                editSelectedNode(component);
>            return true;
>        }
>    }
>
> I somehow have to avoid that the clicks used to expand and collapse the
> node counts as double click candidates. Any idea how I can do that?
>
> -- Edvin
>
>
>