views:

405

answers:

3

Hello,

I'm programming a short Paint program like and I'm trying to make an MDI architecture for it. To make that happen, I used JInternalFrame inside a JDesktopPane. Although I kind of obtain multiple frames, there are not really working properly. Basically, if I have 2 JInternalFrame I can draw only on the last one. The other one seems to be disabled.

Here is a short video illustrating the problem. http://bit.ly/9ydiwM

Here are some part of the code.

Panneau.java
public class Panneau extends JDesktopPane
{

    /** La liste de fenêtres ouvertes */
    private static ArrayList<Cadre> cadres;

    /** Le pannel comportant la liste des formes à dessiner*/
    private Pannel pannel;

    /** La barre d'outils */
    private ToolBox toolBox;

    public Panneau()
    {

        this.setLayout(new BorderLayout());

        // Initialisations des listes de cadres
        cadres = new ArrayList<Cadre>();

        // En haut ToolBox
        toolBox = new ToolBox();
        this.add(toolBox, BorderLayout.NORTH);

        **// Intialisation de la première internal frame
        Cadre cadre = new Cadre();
        this.add(cadre, BorderLayout.CENTER);**

        cadres.add(cadre);

        // Ajout du pannel à gauche
        pannel = new Pannel();

        this.add(pannel, BorderLayout.WEST);

    }

    /**
     * Crée une nouvelle fenêtre de dessin
     * 
     */
    **public void createNewInternalFrame()
    {
        Cadre cadre = new Cadre();
        this.add(cadre, BorderLayout.CENTER);

        cadres.add(cadre);
    }**
}

public class Cadre extends JInternalFrame
{
    /** Largeur par d'une fenêtre interne */
    private int width;

    /** Hauteur d'une fenêtre interne */
    private int height;

    /** Titre d'une fenêtre interne */
    private String title;

    /** Toile associée à la fenêtre interne */
    private Toile toile;

    public Cadre()
    {
        width = 400;
        height = 400;
        title = "Form";

        toile = new Toile();

        this.setTitle(title);

        this.setSize(width, height);

        this.setEnabled(true);

        this.setResizable(true);

        this.setAutoscrolls(true);

        this.setClosable(true);

        this.setIconifiable(true);

        this.setDoubleBuffered(true);

        this.setContentPane(toile);

        this.setVisible(true);

        this.pack();    
    }
}

Basically, Panneau is the main Window that contains all the differents parts of the GUI. I can create as much JInternalFrame that I want, using : Panneau.createNewInternalFrame(). Toile is basically where I draw my shapes.

Any idea ?

Thanks

+2  A: 

I think the problem is that you're overwriting the CENTER orientation in BorderLayout. The effect of this is that the two boxes are essentially the second added box, which plays havoc with the component which simply isn't designed for it. So, the hierarchy has two different elements, and the layout manager has the second element set the CENTER component, and the layout manager probably handles a fair bit of stuff.

Note the following code in BorderLayout (yes, it's deprecated, but it gets called by the non-deprecated method anyway):

/**
 * @deprecated  replaced by <code>addLayoutComponent(Component, Object)</code>.
 */
@Deprecated
public void addLayoutComponent(String name, Component comp) {
  synchronized (comp.getTreeLock()) {
    /* Special case:  treat null the same as "Center". */
    if (name == null) {
        name = "Center";
    }

    /* Assign the component to one of the known regions of the layout.
     */
    if ("Center".equals(name)) {
        center = comp;
    } else if ("North".equals(name)) {
        north = comp;
    } else if ("South".equals(name)) {
        south = comp;
    } else if ("East".equals(name)) {
        east = comp;
    } else if ("West".equals(name)) {
        west = comp;
    } else if (BEFORE_FIRST_LINE.equals(name)) {
        firstLine = comp;
    } else if (AFTER_LAST_LINE.equals(name)) {
        lastLine = comp;
    } else if (BEFORE_LINE_BEGINS.equals(name)) {
        firstItem = comp;
    } else if (AFTER_LINE_ENDS.equals(name)) {
        lastItem = comp;
    } else {
        throw new IllegalArgumentException("cannot add to layout: unknown constraint: " + name);
    }
  }
}

It would be cool to use a proper layout manager to do the job, but they aren't designed for mucking with MDI windows.

Chris Dennett
Adding two components to the CENTER region of the same BorderLayout container will just cause the first component to be replaced by the second. So, I think the use of BorderLayout.CENTER could definitely lead to the problem described here.
Joe Carnahan
+3  A: 

You are using the JDesktopPane incorrectly. The desktop pane "does not" use a layout manager on purpose. This allows you to add multiple internal frames and drag them around individually.

Your class should NOT be extending JDesktopPane since you are not adding any new functionality to it.

So in general all you logic should still deal with the JFrame. That is:

a) you create your toolbar and add it to the NORTH of the content pane.

b) you create your desktop pane and add it to the CENTER of the content pane

c) your create your internal frames and and them to the desktop pane

Read the Swing tutorial for examples of using internal frames.

camickr
You were right. I changed the way my GUI was built. Now I have a JFrame instead of a JPanel and it works just fine! There is just one little problem: I can't resize any of my JInternalFrame(s). When I try to, they just place themselves in the upper corner and they seem to be disabled.
Amokrane
Again, the Swing tutorial has working examples that use internal frames and they do not exhibit this behaviour. I have no idea what you might be doing differently. Compare you code with the tutorial code to see what is different.
camickr
A: 

See How to Use Internal Frames and InternalFrameDemo.

Arivu2020
Please do not strip copyright notices from example code.
trashgod