2011-06-29 59 views
1

我试图让内部框架包含选项卡式窗格。但是,我的代码似乎并未将窗格加载到内部框架中。我有我的代码在java文件中,称为InternalFrame.java和TabbedPaneSample.java。两个文件的代码都包含在下面。任何人都可以告诉我如何修复下面的代码,以便在运行InternalFrame.java时加载选项卡式窗格?内部框架内的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(); 
} 
} 
+1

是否有任何理由为什么你在使用'javax.swing.JPanel'的地方使用'java.awt.Panel'?如果你没有很好的理由这样做,你应该避免混合AWT和Swing组件。 – jfpoilpret

+0

非常感谢您的帮助。我将在明天详细回顾这些代码,并在那个时候专门回复。 – CodeMed

回答

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

我没有看到任何理由来扩展'JTabbedPane'。当然,也没有理由扩展'JFrame'。 :-) – trashgod

+0

@trashgod good +1 – mKorbel

+0

再次感谢您。我尝试了这一点,它主要工作,但每个内部框架的大小太小。我试着添加this.setMinimumSize(new Dimension(300,300));和this.setSize(300,300);紧随你的this.setPreferredSize(new Dimension(400,400)); 。但是,内部框架的大小没有改变。对于如何解决这个问题,你有任何建议,以便内部框架的大小默认为某些定义的最小值,例如(300,300)?我应该注意到我正在使用Windows 7,当然这需要跨平台。 – CodeMed

2

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

然后,以下this problemJInternalFrame曾经,我劝你打电话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 trashgod意见和简化返修他已经在你的代码段完成同意。

+0

伟大的国家(博客)+1 for Java – mKorbel

+0

+1感谢您对此进行扩展; 'add()'后跟'pack()'是有经验的,但我不知道为什么。 – trashgod

+0

@mKorbel:您的+1似乎已丢失。 :-) – trashgod

1

我优选在我的主框架类(其延伸的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)。