File APIs for Java Developers
Manipulate DOC, XLS, PPT, PDF and many others from your application.
http://aspose.com/file-tools
The moose likes Swing / AWT / SWT and the fly likes How could I drag and drop a component within a layout manager? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Swing / AWT / SWT
Bookmark "How could I drag and drop a component within a layout manager?" Watch "How could I drag and drop a component within a layout manager?" New topic
Author

How could I drag and drop a component within a layout manager?

Tom Josephits
Ranch Hand

Joined: Mar 11, 2012
Posts: 31
For example, say I have I BoxLayout with a few JButtons in it. How could I make it such that I could drag a JButton such that it could be in front or behind the others?

I've thought about using ComponentMover and just switching to a null layout right before moving it and switch it back right after like bellow, but I'm not sure how to make it keep the change in order.





ComponentMover.java: http://www.camick.com/java/source/ComponentMover.java
Brett Spell
Ranch Hand

Joined: Feb 24, 2001
Posts: 96
I'm not sure I understand what it is you're trying to accomplish. Which of the following are you trying to implement:

  • Be able to drop a component and have it stay where you dropped it
  • Be able to manipulate the Z-order of what you dragged and dropped


  • If you want to have a component stay at an arbitrary position then yes, you'd need to consider using a null layout manager, though without knowing more about what you're trying to accomplish I suspect doing that will open up an even bigger can of worms for you.

    To manipulate the Z-order of the components (i.e., which component is in front of / behind other components in the same container), take a look at Container.setZOrder.

    I'll have to defer to Rob concerning the use of his ComponentMover, but it appears to be intended to be used to move windows, not just a specific component within a window.
    Tom Josephits
    Ranch Hand

    Joined: Mar 11, 2012
    Posts: 31
    Brett Spell wrote:I'm not sure I understand what it is you're trying to accomplish. Which of the following are you trying to implement:

  • Be able to drop a component and have it stay where you dropped it
  • Be able to manipulate the Z-order of what you dragged and dropped


  • If you want to have a component stay at an arbitrary position then yes, you'd need to consider using a null layout manager, though without knowing more about what you're trying to accomplish I suspect doing that will open up an even bigger can of worms for you.

    To manipulate the Z-order of the components (i.e., which component is in front of / behind other components in the same container), take a look at Container.setZOrder.

    I'll have to defer to Rob concerning the use of his ComponentMover, but it appears to be intended to be used to move windows, not just a specific component within a window.


    Both in a way. When I drop it, I want it's Z-order to change such that the component would go approximately to the spot I dropped it.

    So normally with drag & drop, you use a null layout and set position. I want to do something like that, but instead use a layout manager and change the z-order instead of changing the actual position directly.

    As for the ComponentMover, it's sort of a tri-purpose class. I look at the source code and it seems to do three completely different things depending on how you initialize it. Moreover, I've used it plenty of times for rearranging components in a null layout, and even extended it before. Now I'm just trying to make it rearange the Z-order in a layout rather than just changing the location.
    Brett Spell
    Ranch Hand

    Joined: Feb 24, 2001
    Posts: 96
    I think I now understand better what you're trying to do: it's not that you want one component to be in front of or behind another visually, but rather you're using the Z-order as a proxy for the component's position within the BoxLayout-managed container. Is that correct?
    Tom Josephits
    Ranch Hand

    Joined: Mar 11, 2012
    Posts: 31
    Brett Spell wrote:I think I now understand better what you're trying to do: it's not that you want one component to be in front of or behind another visually, but rather you're using the Z-order as a proxy for the component's position within the BoxLayout-managed container. Is that correct?


    Exactly. (From my experimentation, I found that changing the Z-order in a box layout rearranged the items. Sorry if that wasn't clear.)
    Brett Spell
    Ranch Hand

    Joined: Feb 24, 2001
    Posts: 96
    In that case the actual insertion on drop is pretty simple and the only complexity is in determining which existing component the dropped one needs to be inserted before. For example, let's say that you're dragging component X and want to insert it prior to Y by dropping it.

    For the insertion you just need to do something like this, where componentX and componentY are initialized appropriately:



    This code assumes (based on your earlier comments) that componentX and componentY are both already contained in the same parent container and that your drag and drop is just meant to change the Z position of the component (X) being dropped.

    The trickier part is probably going to be how to identify componentY, but that should pretty much be standard drag-and-drop processing.
    Rob Camick
    Ranch Hand

    Joined: Jun 13, 2009
    Posts: 2153
        
        7
    The ComponentMover class wasn't really designed for this.

    As mentioned by Brent, the problem is in identifying the component you are dragging the component over so you know where in the Container to insert the dragged component.

    Normally, you would use the Container.getComponentAt(...) method to determine what component is visible at a current mouse point. But when dragging components from the top of the box towards the bottom this method will always return the "dragged" component, not the component under the dragged component. So you need to do one of two things:

    1. write your own getComponentAt(...) method that ignores the dragged component when doing the search
    2. remove the dragged component from the Container before invoking the Container.getComponentAt(...) method.

    I created a little demo that uses the second approach:



    However this code still have many limitations:

    1. you need to handle the case where you drag the component to an empty space in the container because in this case the getComponentAt() method will return the panel.
    2. you need to handle dragging the component left or up outside of the container. In this case the getComponentAt(...) method returns null
    3. you need to handle the case when you just click on a component and then don't drag it anywhere

    Anyway, maybe the code will get you started on a more complete solution. Good luck (I won't be around for several days).
     
    Consider Paul's rocket mass heater.
     
    subject: How could I drag and drop a component within a layout manager?
     
    Similar Threads
    AWT FlowLayout to BorderLayout
    dynamically adding components
    Weird flashy Buffer thing in Swing..I think. Maybe
    How to draw straight line instead of curved line??
    How does one delete a button?