Панели Java с вкладками во внутреннем фрейме - PullRequest
1 голос
/ 29 июня 2011

Я пытаюсь получить внутреннюю рамку для вкладок.Однако мой код, похоже, не загружает панели во внутреннюю рамку.У меня есть мой код в файлах Java, называемых InternalFrame.java и TabbedPaneSample.java.Код для обоих файлов приведен ниже.Может кто-нибудь показать мне, как исправить код ниже, чтобы он загружал панели с вкладками при запуске InternalFrame.java?

Вот мой код:

Код для InternalFrame.java:1005 *

package test;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Panel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLayeredPane;

public class InternalFrame extends JFrame {
    JButton openButton;
JLayeredPane desktop;
JInternalFrame internalFrame;
TabbedPaneSample myTabbedPaneSample = new TabbedPaneSample();

public InternalFrame() {
    super("Click button to open internal frame with two panels.");
    setSize(500, 400);
    openButton = new JButton("Open");
    Panel p = new Panel();
    p.add(openButton);
    add(p, BorderLayout.SOUTH);
    addWindowListener(new WindowAdapter() {
        public void windowClosing(WindowEvent e) {
            System.exit(0);
        }
    });
    openButton.addActionListener(new OpenListener());
    desktop = new JDesktopPane();
    desktop.setOpaque(true);
    add(desktop, BorderLayout.CENTER);
}
class OpenListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        if ((internalFrame == null) || (internalFrame.isClosed())) {
            internalFrame = new JInternalFrame("Internal Frame", true, true, true, true);
            internalFrame.setBounds(50, 50, 200, 100);
            internalFrame.add(myTabbedPaneSample, BorderLayout.CENTER);
            internalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            internalFrame.pack();
            internalFrame.setMinimumSize(new Dimension(300, 300));
            desktop.add(internalFrame, new Integer(1));
            internalFrame.setVisible(true);
        }
    }
}
public static void main(String args[]) {
    InternalFrame myInternalFrame = new InternalFrame();
    myInternalFrame.setVisible(true);
}
}

И код для TabbedPaneSample.java:

package test;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

public class TabbedPaneSample extends JTabbedPane {
private JTabbedPane tabbedPane = new JTabbedPane();
private ImageIcon closeImage = new ImageIcon("C:/test/shipIcon.gif");
private Dimension closeButtonSize;
private int tabCounter = 0;

public TabbedPaneSample() {
    closeButtonSize = new Dimension(closeImage.getIconWidth() + 2, closeImage.getIconHeight() + 2);
    }
public void add() {
    final JPanel content = new JPanel();
    JPanel tab = new JPanel();
    tab.setOpaque(false);
    JLabel tabLabel = new JLabel("Tab " + (++tabCounter));
    JButton tabCloseButton = new JButton(closeImage);
    tabCloseButton.setPreferredSize(closeButtonSize);
    tabCloseButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            int closeTabNumber = tabbedPane.indexOfComponent(content);
            tabbedPane.removeTabAt(closeTabNumber);
        }
    });
    tab.add(tabLabel, BorderLayout.WEST);
    tab.add(tabCloseButton, BorderLayout.EAST);
    this.addTab(null, content);
    this.setTabComponentAt(this.getTabCount() - 1, tab);
}
public static void main(String[] args) {
    TabbedPaneSample main = new TabbedPaneSample();
    main.add();
    main.add();
}
}

Ответы [ 3 ]

3 голосов
/ 29 июня 2011

Вот один из подходов, показанный ниже.На более гибкий подход, использующий Action, ссылается здесь .

Приложение: просматривая код, вы должны позволить различным менеджерам компоновки и предпочтительным размерам компонентов выполнять больше работы, как показано.В частности, this.setPreferredSize() сделано для демонстрационных целей.В реальном приложении вы бы восстановили настройки размера и местоположения пользователя.

Desktop pane with internal frames

package overflow;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;

/** @see https://stackoverflow.com/posts/6514889 */
public class InternalFrame extends JFrame {

    JButton openButton;
    JLayeredPane desktop;
    JInternalFrame internalFrame;

    public InternalFrame() {
        super("Click button to open internal frame with two tabs.");
        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        this.setPreferredSize(new Dimension(400, 400));
        openButton = new JButton("Open");
        JPanel p = new JPanel();
        p.add(openButton);
        this.add(p, BorderLayout.SOUTH);
        openButton.addActionListener(new OpenListener());
        desktop = new JDesktopPane();
        this.add(desktop, BorderLayout.CENTER);
        this.pack();
        this.setLocationRelativeTo(null);
    }

    class OpenListener implements ActionListener {

        private static final int DELTA = 40;
        private int offset = DELTA;

        public void actionPerformed(ActionEvent e) {
            internalFrame = new JInternalFrame(
                "Internal Frame", true, true, true, true);
            internalFrame.setLocation(offset, offset);
            offset += DELTA;
            internalFrame.add(createTabbedPane());
            desktop.add(internalFrame);
            internalFrame.pack();
            internalFrame.setVisible(true);
        }
    }

    private JTabbedPane createTabbedPane() {
        JTabbedPane jtp = new JTabbedPane();
        createTab(jtp, "One");
        createTab(jtp, "Two");
        return jtp;
    }

    private void createTab(JTabbedPane jtp, String s) {
        jtp.add(s, new JLabel("TabbedPane " + s, JLabel.CENTER));
    }

    public static void main(String args[]) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                InternalFrame myInternalFrame = new InternalFrame();
                myInternalFrame.setVisible(true);
            }
        });
    }
}
2 голосов
/ 29 июня 2011

Прежде всего, я думаю, наконец, я думаю, что вы не должны использовать desktop.add(internalFrame, new Integer(1)), а вместо этого desktop.add(internalFrame), причина в том, что JDesktopPane использует свои слои (это подкласс JLayeredPane) внутри, иЯ не думаю, что вы должны сами играть со слоями.

Затем, следуя этой задаче У меня был один раз с JInternalFrame, я бы посоветовал вам позвонить pack() после добавление внутреннего фрейма на панель рабочего стола.

Следовательно, вы должны попробовать, чтобы ваш класс OpenListener выглядел так:

class OpenListener implements ActionListener {
    public void actionPerformed(ActionEvent e) {
        if ((internalFrame == null) || (internalFrame.isClosed())) {
            internalFrame = new JInternalFrame("Internal Frame", true, true, true, true);
            internalFrame.setBounds(50, 50, 200, 100);
            internalFrame.add(myTabbedPaneSample, BorderLayout.CENTER);
            internalFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//          internalFrame.pack();
            internalFrame.setMinimumSize(new Dimension(300, 300));
//          desktop.add(internalFrame, new Integer(1));
            desktop.add(internalFrame);
            internalFrame.pack();
            internalFrame.setVisible(true);
        }
    }
}

Кроме того, я также согласен с комментариями trashgod по Action конечно же, и упрощающая переделка, которую он проделал для вашего фрагмента.

1 голос
/ 07 апреля 2012

Я предпочел создать в своем классе Main Frame (который расширяет JFrame) следующую функцию:

private void showIntFrame(Class intFrameClass) {
    JInternalFrame targetFrame = null;
    int xoff = 0, yoff = 0;
    for(JInternalFrame jif : jdp.getAllFrames()) {
        if(jif.getClass().equals(intFrameClass))
            targetFrame = jif;
        if(jif.getLocation().x > xoff)
            xoff = jif.getLocation().x;
        if(jif.getLocation().y > yoff)
            yoff = jif.getLocation().y;
        }
        if(targetFrame == null) {
            try {
                Constructor<JInternalFrame> c = intFrameClass.getConstructor(MainFrame.class);
                targetFrame = c.newInstance(MainFrame.this);
            } catch (Exception ex) {
                System.err.println("Exception in MainFrame.showIntFrame() while creating new JInternalFrame instance. " + ex.getLocalizedMessage());
                ex.printStackTrace();
                return;
            }
            jdp.add(targetFrame);
            targetFrame.setLocation(xoff + 30, yoff + 30);
        }
        targetFrame.setVisible(true);
        try {
            targetFrame.setSelected(true);
        } catch (PropertyVetoException ex) {
            System.err.println("PropertyVetoException in MainFrame.showIntFrame() while activating JInternalFrame instance. " + ex.getLocalizedMessage());
        }
}

Здесь jdp - это экземпляр JDesktopPane, который ранее был установлен как ContentPane моего основного JFrame.

Поскольку мои программы часто содержат номера разных классов, унаследованных от JInternalFrame, эту функцию проще вызывать из обработчиков событий, чтобы показать новый подкласс JInternalFrame.

Каждый подкласс JInternalFrame в моих программах имеет один конструктор с одним параметром - MainFrame (основной JFrame).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...