Java - Как сделать набор JInternalFrame независимым друг от друга?

Я программирую короткую программу Paint, например, и пытаюсь создать для нее архитектуру MDI. Чтобы это произошло, я использовал JInternalFrame внутри JDesktopPane. Хотя я как бы получаю несколько кадров, они не работают должным образом. В принципе, если у меня есть 2 JInternalFrame, я могу рисовать только на последнем. Другой, похоже, отключен.

Вот короткое видео, иллюстрирующее проблему. http://bit.ly/9ydiwM

Вот некоторая часть кода.

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();    
    }
}

По сути, Panneau — это основное окно, содержащее все различные части графического интерфейса. Я могу создать столько JInternalFrame, сколько захочу, используя: Panneau.createNewInternalFrame(). Туаль — это в основном место, где я рисую свои формы.

Есть идеи ?

Спасибо


person Amokrane Chentir    schedule 20.03.2010    source источник


Ответы (3)


Вы неправильно используете JDesktopPane. Панель рабочего стола «не» намеренно использует менеджер компоновки. Это позволяет вам добавлять несколько внутренних рамок и перетаскивать их по отдельности.

Ваш класс НЕ должен расширять JDesktopPane, поскольку вы не добавляете к нему никаких новых функций.

Так что в целом вся ваша логика должна по-прежнему иметь дело с JFrame. То есть:

а) вы создаете свою панель инструментов и добавляете ее к СЕВЕРУ панели содержимого.

б) вы создаете панель рабочего стола и добавляете ее в ЦЕНТР панели содержимого

c) вы создаете свои внутренние фреймы и выводите их на панель рабочего стола

Прочтите учебное пособие по Swing, где приведены примеры использования внутренних фреймов.

person camickr    schedule 20.03.2010
comment
Ты был прав. Я изменил способ построения моего графического интерфейса. Теперь у меня есть JFrame вместо JPanel, и он отлично работает! Есть только одна маленькая проблема: я не могу изменить размер ни одного из моих JInternalFrame(ов). Когда я пытаюсь это сделать, они просто помещаются в верхний угол и кажутся отключенными. - person Amokrane Chentir; 20.03.2010
comment
Опять же, в учебнике Swing есть рабочие примеры, в которых используются внутренние фреймы, но они не демонстрируют такого поведения. Я понятия не имею, что вы можете делать по-другому. Сравните свой код с кодом учебника, чтобы увидеть, что отличается. - person camickr; 20.03.2010

Я думаю, проблема в том, что вы перезаписываете ориентацию CENTER в BorderLayout. Результатом этого является то, что два блока, по сути, являются вторым добавленным блоком, который разрушает компонент, который просто не предназначен для него. Таким образом, иерархия имеет два разных элемента, а второй элемент менеджера компоновки устанавливает компонент CENTER, и менеджер компоновки, вероятно, обрабатывает немало вещей.

Обратите внимание на следующий код в BorderLayout (да, он устарел, но в любом случае вызывается не устаревшим методом):

/**
 * @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);
    }
  }
}

Было бы здорово использовать правильный менеджер компоновки для выполнения этой работы, но он не предназначен для работы с окнами MDI.

person Chris Dennett    schedule 20.03.2010
comment
Добавление двух компонентов в регион CENTER одного и того же контейнера BorderLayout просто приведет к замене первого компонента вторым. Итак, я думаю, что использование BorderLayout.CENTER определенно может привести к описанной здесь проблеме. - person Joe Carnahan; 20.03.2010