Java Tips Weblog

  • Blog Stats

    • 2,571,736 hits
  • Categories

  • Archives

Drag Layout

Posted by Rob Camick on October 23, 2011

We have been taught that you should always use a layout manager to layout components on a container. But what about the times when you want the ability to randomly position components on a panel by dragging them with a mouse? Should we use a null layout or can we still use a layout manager?

To answer this question it is important to remember that a layout manager performs 3 different functions:

  • set the location of the components in the container
  • set the size of the components in the container
  • calculate the preferred size of the container. The preferred size is important so you can pack() your frame or dialog. It is also important for any container that is added to a scroll pane. In order for the scrollbars to function properly, the preferred size must be calculated correctly.

When dragging components, it should be apparent that a layout manager should not override the location of the component. However, there is no reason that a layout manager could not set the size of the component and calculate the preferred size of the container.

DragLayout was designed to replace a null layout. It will respect the location of a component. By default it will use the preferred size of the component to determines its size. Finally, it will automatically calculate the preferred size of the Container.

An added feature of the DragLayout is that it will ensure that components cannot have a negative location. When a component is dragged outside the top/left edge of a container, its location will be adjusted such that it is placed within the border of the container. In addition all other components in the container will be adjusted to retain the same relative location to the moved component

DragLayout only has a single property:

  • setUsePreferredSize – when true (default), the preferred size of the component is always used as the size of the component. When false, the preferred size is used as the size of the component only when the size is 0. Therefore you can manually set the initial size or change the size dynamically. This would be useful when you require the ability to manually resize components.

The DragLayout class is not responsible for doing the dragging of any component. The code you use to drag a component is responsible for invoking revalidate() on the component when the drag is finished. This will cause the layout manager to be invoked so the containers preferred size can be recalculated.

Usage of a DragLayout is straight forward:

JPanel dragPanel = new JPanel( new DragLayout() );
...
frame.add( new JScrollPane(dragPanel) );

The Webstart demo uses the ComponentMover class (see link below) to handle dragging of the components. The code allows you to move a component up to 100 pixels outside the bounds of the container at one time:

ComponentMover cm = new ComponentMover();
cm.setEdgeInsets( new Insets(-100, -100, -100, -100) );
cm.setAutoLayout(true);

The labels where then created with code something like:

JLabel north = new JLabel("North");
north.setLocation(150, 0);
dragPanel.add(north);
cm.registerComponent(north);

JLabel south = new JLabel(“South”);
south.setLocation(150, 200);
dragPanel.add(south);
cm.registerComponent(south);

The DragLayout class should be used any time you consider using a null layout. Even if you manually set the location and size of a component, you will still benefit from the calculation of the containers preferred size.

Get The Code

DragLayout.java
DragLayoutDemo.java

See Also

Moving Windows (ComponentMover)

Related Reading

Java Tutorials:
Java API: ?

5 Responses to “Drag Layout”

  1. Google said

    It works excellent, in my Fedora 15. But when i make the screen maximize, the layout does not put all icons auto resize back.

    • Rob Camick said

      If you maximize the frame and move a component to an edge and then restore the frame the component is not supposed to move. Only the preferred size changes which means the scrollbar will now be larger because you will need to scroll more to see the component at the edge of the frame. If this doesn’t help then you need to use the “Contact Us” page to send mea a SSCCE that demonstrates your problem.

  2. Anonymous said

    This is super useful

  3. Anonymous said

    how do I set the size of the dragPanel? is it possible to add a background image too?

    • Rob Camick said

      The panel is just a regular panel. The DragLayout is a layout manager you add to any panel. You can search the web for information/examples on adding an image to a panel. One solution you might find the Background Panel from this website, but there are many other examples.

Leave a comment