我正在尝试获取包含选项卡式窗格的内部框架。但是,我的代码似乎没有将窗格加载到内部框架中。我的代码在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();
}
}
答案 0 :(得分:3)
这是一种方法,如下所示。使用Action
的更灵活的方法被引用here。
附录:检查代码,您应该让各种布局管理器和组件首选大小完成更多工作,如图所示。特别是,this.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);
}
});
}
}
答案 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)。