1

I've been trying to create a Draw2D Figure that consists of two parts - a central resizeable shape, such as a circle or rectangle, and an editable label for the bottom part. An example of this type of figure is the icon/label you see on a computer's Desktop.

The first attempt was to create a parent container figure with two child sub-figures - a shape figure placed centrally and a label placed at the bottom. It also implemented HandleBounds so that selection and resizing occurs only on the upper shape sub-figure. This turned out not to be a working solution because as the label gets wider with more text so does the main parent figure and consequently the central shape figure. In other words the overall parent figure is as wide as the child label figure.

What I'm seeking is a Figure that maintains the size of the shape figure but allows the width of the label figure to grow independently. Exactly the same behaviour as a desktop icon.

Phillipus
  • 455
  • 1
  • 5
  • 14

2 Answers2

2

Ok I get your question right now. It's impossible to do what you want:

The parent figure can't be smaller than one of its children or this child will not be visible !!!

Manuel Selva
  • 18,554
  • 22
  • 89
  • 134
  • Yes, I agree. I wonder then if I need two separate figures that are somehow linked together. – Phillipus Mar 15 '11 at 17:00
  • The idea is to be able to only resize the shape figure and the label stays centred at the bottom showing all its text. – Phillipus Mar 15 '11 at 17:11
  • Yes you'll have to have 2 separated figures with the label listening for the move of the shape in order to move it each time its associated shape is moved. Good luck ;-) – Manuel Selva Mar 16 '11 at 07:15
0

You have to create a container figure as you mentioned with an XYLayout and "manually" place and "size" the 2 (the shape and the label) children figure inside this layout using the IFigure.add(IFigure child, Object constraint) method with a Constraint of type Rectangle (Draw2d)

Edit with code sample

Here is an example of what your figure class could look like:

package draw2dtest.views;

import org.eclipse.draw2d.ColorConstants;
import org.eclipse.draw2d.Ellipse;
import org.eclipse.draw2d.Figure;
import org.eclipse.draw2d.FigureListener;
import org.eclipse.draw2d.IFigure;
import org.eclipse.draw2d.Label;
import org.eclipse.draw2d.MouseEvent;
import org.eclipse.draw2d.MouseListener;
import org.eclipse.draw2d.XYLayout;
import org.eclipse.draw2d.geometry.Rectangle;

public class LabeledFigure extends Figure {

    private final Figure shapeFigure;
    private final Label labelFigure;
    private Rectangle customShapeConstraint;

    public LabeledFigure(String label) {
        setLayoutManager(new XYLayout());
        setBackgroundColor(ColorConstants.lightGray);
        setOpaque(true);

        shapeFigure = new Ellipse();
        this.add(shapeFigure);
        shapeFigure.setBackgroundColor(ColorConstants.yellow);

        shapeFigure.addMouseListener(new MouseListener.Stub() {
            @Override
            public void mousePressed(MouseEvent me) {
                customShapeConstraint = new Rectangle(
                        (Rectangle) LabeledFigure.this.getLayoutManager()
                                .getConstraint(shapeFigure));
                customShapeConstraint.width -= 6;
                customShapeConstraint.x += 3;
                LabeledFigure.this.getLayoutManager().setConstraint(
                        shapeFigure, customShapeConstraint);
                LabeledFigure.this.revalidate();
            }
        });

        labelFigure = new Label(label);
        labelFigure.setOpaque(true);
        labelFigure.setBackgroundColor(ColorConstants.green);
        labelFigure.addMouseListener(new MouseListener.Stub() {
            @Override
            public void mousePressed(MouseEvent me) {
                Rectangle shapeFigureConstraint = new Rectangle(0, 0,
                        bounds.width, bounds.height - 15);
                LabeledFigure.this.getLayoutManager().setConstraint(
                        shapeFigure, shapeFigureConstraint);
                LabeledFigure.this.revalidate();
            }
        });
        this.add(labelFigure);

        this.addFigureListener(new FigureListener() {

            @Override
            public void figureMoved(IFigure source) {

                Rectangle bounds = LabeledFigure.this.getBounds();
                Rectangle shapeFigureConstraint = new Rectangle(0, 0,
                        bounds.width, bounds.height - 15);
                LabeledFigure.this.getLayoutManager().setConstraint(
                        shapeFigure, shapeFigureConstraint);

                Rectangle labelFigureConstraint = new Rectangle(0,
                        bounds.height - 15, bounds.width, 15);
                if (customShapeConstraint != null) {
                    labelFigureConstraint = customShapeConstraint;
                }
                LabeledFigure.this.getLayoutManager().setConstraint(
                        labelFigure, labelFigureConstraint);
            }
        });
    }
}

This is not a clean class but it should be a good entry to show you how to achieve your goal. This is an example based on pure Draw2d without any Gef code, thus the resizing of the shape is done by clicking in the yellow Ellipse (the size is decreased) and on the green label (the initial size is restored)

To test this class I created a simple Eclipse view as following:

@Override
public void createPartControl(Composite parent) {

    FigureCanvas fc = new FigureCanvas(parent, SWT.DOUBLE_BUFFERED);
    fc.setBackground(ColorConstants.red);

    Panel panel = new Panel();
    panel.setLayoutManager(new XYLayout());

    LabeledFigure labeledFigure = new LabeledFigure("This is the label");
    fc.setContents(panel);

    panel.add(labeledFigure, new Rectangle(10,10, 200,100));
}

Hope this can help, Manu

Manuel Selva
  • 18,554
  • 22
  • 89
  • 134
  • Thanks for your answer, however I'm not sure if an XYLayout will work any better than the layouts I've already tried (DelegatingLayout and BorderLayout). The desired behaviour is that the user can resize the child shape figure without affecting the size of the label figure. – Phillipus Mar 15 '11 at 14:43
  • Thanks for taking the time to create a code sample. Unfortunately it doesn't solve the problem. I'm looking for a solutionso that the resizing of the figure resizes the shape figure, but the size of the label remains the same (as wide as the text in the label). – Phillipus Mar 15 '11 at 16:40
  • This is exactly what my code does! Have you tried it ? Heuuuu after reading your comment: you can't do that! See my new answer – Manuel Selva Mar 15 '11 at 16:54