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

内部框架内的Java选项卡式窗格,java,swing,user-interface,awt,Java,Swing,User Interface,Awt,我试图得到一个内部框架,以包含选项卡式窗格。但是,我的代码似乎没有将窗格加载到内部框架中。我的代码在java文件中,名为InternalFrame.java和TabbedPaneSample.java。下面包含这两个文件的代码。有人能告诉我如何修复下面的代码,以便在我运行InternalFrame.java时加载选项卡式窗格吗 这是我的密码: InternalFrame.java的代码是: package test; import java.awt.BorderLayout; import j

我试图得到一个内部框架,以包含选项卡式窗格。但是,我的代码似乎没有将窗格加载到内部框架中。我的代码在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);
}
}
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();
}
}
TabbedPaneSample.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);
}
}
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();
}
}

下面是一种方法,如下所示。参考了使用
操作
的更灵活方法

附录:回顾代码,您应该让各种布局管理器和组件首选尺寸完成更多工作,如图所示。特别是,
这个.setPreferredSize()
是为了演示而做的。在实际应用程序中,您将恢复用户大小和位置首选项

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


首先,我认为最后,我认为您不应该使用
desktop.add(internalFrame,newinteger(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);
        }
    }
}

此外,我还同意垃圾神对
操作的评论,当然也同意他对您的代码片段所做的简化返工。

我更喜欢在我的主框架类(扩展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());
        }
}
private void showIntFrame(类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){
试一试{
构造函数c=intFrameClass.getConstructor(MainFrame.class);
targetFrame=c.newInstance(MainFrame.this);
}捕获(例外情况除外){
System.err.println(“创建新JInternalFrame实例时MainFrame.showIntFrame()中出现异常。”+ex.getLocalizedMessage());
例如printStackTrace();
返回;
}
jdp.add(targetFrame);
目标帧设置位置(xoff+30,yoff+30);
}
targetFrame.setVisible(true);
试一试{
targetFrame.setSelected(true);
}捕获(PropertyVetoException-ex){
System.err.println(“当激活JInternalFrame实例时,MainFrame.showIntFrame()中的PropertyVetoException。”+ex.getLocalizedMessage());
}
}
这里jdp是JDesktopPane的实例,它以前被设置为我的主JFrame的ContentPane

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


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

我看不出有任何理由扩展
JTabbedPane
。当然,也没有理由扩展
JFrame
。:-)再次感谢你。我试过这个,它主要起作用,但是每个内部框架的大小太小了。我尝试添加这个.setMinimumSize(新维度(300300));这个.setSize(300300);紧跟在this.setPreferredSize(新维度(400400))之后。但是,内部框架的大小没有改变。对于如何修复此问题,使内部框架的大小默认为某个定义的最小值,例如(300300),您有什么建议吗?我应该注意到,我使用的是Windows 7,当然这需要跨平台。我认为最好让组件的首选大小来控制,但是你可以用
internalFrame.pack()
替换
internalFrame.setSize(320240)
,例如,我刚刚编写了
internalFrame.pack()内部框架设置尺寸(新尺寸(600300))之前的右侧。您认为这种排序会保留
internalFrame.pack()
的一些优点吗?当我不使用
setSize
时,我的屏幕输出的内容非常小,以至于会损坏屏幕上的预期内容。然而,
setMinimumSize
并不能改善这种情况;我的意思是建议“替换”作为一个实验。另请参见@jfpoilpret.when有什么理由使用
java.awt.Panel
在那里可以使用
javax.swing.JPanel
?如果你没有很好的理由这样做,你应该避免混合AWT和Swing组件。非常感谢你们的帮助。明天我将详细回顾这段代码,并在那一点上具体回复
add()
后跟
pack()
从经验上讲是有道理的,但我不知道为什么。@mKorbel:Your+1似乎丢失了。:-)@垃圾上帝是的,谢谢,在工作时间里我在***和代理和***后面,我看不到图标、图片、标签等,笑话是+1为你收到了所以服务器,也许我需要停止drinking@trashgod你什么时候睡的(美国时区)