内部框架内的Java选项卡式窗格

时间:2011-06-29 00:32:13

标签: java swing user-interface awt

我正在尝试获取包含选项卡式窗格的内部框架。但是,我的代码似乎没有将窗格加载到内部框架中。我的代码在java文件中,名为InternalFrame.java和TabbedPaneSample.java。这两个文件的代码包含在下面。谁能告诉我如何修复下面的代码,以便在运行InternalFrame.java时加载选项卡式窗格?

这是我的代码:

InternalFrame.java的代码是:

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 个答案:

答案 0 :(得分:3)

这是一种方法,如下所示。使用Action的更灵活的方法被引用here

附录:检查代码,您应该让各种布局管理器和组件首选大小完成更多工作,如图所示。特别是,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);
            }
        });
    }
}

答案 1 :(得分:2)

首先,我认为最后,我认为您不应该使用desktop.add(internalFrame, new Integer(1))而是使用desktop.add(internalFrame),原因是JDesktopPane使用其图层(它是JLayeredPane 1}}子类)内部,我不认为你应该自己玩图层。

然后,在我使用JInternalFrame后的this problem后,我建议您在将内部框架添加到桌面窗格后致电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);
        }
    }
}

此外,我同意当前对Action的垃圾视频评论以及他对你的片段进行的简化返工。

答案 2 :(得分:1)

我更喜欢在我的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的一个实例,以前被设置为我的主JFrame的ContentPane。

因为我的程序通常包含许多不同的类,继承自JInternalFrame,所以从事件处理程序调用此函数以显示JInternalFrame的新子类更容易。

我的程序中JInternalFrame的每个子类都有一个带有一个参数的构造函数 - MainFrame(main JFrame)。