问题描述
我正在尝试以JTabbedPane作为主要组件(这是JFrame的唯一组件)实现JFrame。 首先,选项卡式面板不应包含任何选项卡。 事件发生时添加后期。 每个选项卡都包含带有BorderLayout的JPanel。 这是我遇到一些问题的代码。 有效地,当添加选项卡时,我得到了ArrayIndexOutOfBoundException。 我已经确定了产生错误的代码行,当我将第二个元素添加到面板时就会发生。 有人知道如何解决此错误吗? 我试图捕获该错误,但是它不起作用。 我现在有这个实现:
这是主机的代码
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
public class MyFrame extends JFrame {
static JTabbedPane main;
public MyFrame() {
main = new JTabbedPane();
this.add(main);
this.setMinimumSize(new Dimension(600, 800));
this.setVisible(true);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
this.pack();
}
public static JPanel addTab(String title) {
MyPanel panel = new MyPanel();
main.addTab(title, panel);
return panel;
}
}
这是选项卡式面板中面板的类别:
import java.awt.BorderLayout;
import java.awt.Color;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.ScrollPaneLayout;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
public class MyPanel extends JPanel {
private JPanel scrollPanel;
private JTextArea textArea;
private JButton button;
public MessageTo panel;
public MyPanel() {
JScrollPane scrollPane = new JScrollPane(
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setLayout(new ScrollPaneLayout());
scrollPanel = new JPanel();
scrollPane.setViewportView(scrollPanel);
scrollPanel.setLayout(new BoxLayout(scrollPanel, BoxLayout.Y_AXIS));
textArea = new JTextArea();
Border roundedBorder = new LineBorder(Color.black, 1, true);
textArea.setBorder(roundedBorder);
button = new JButton("Send");
JPanel panel1 = new JPanel();
panel1.setBorder(new EmptyBorder(0, 10, 0, 0));
panel1.add(button);
JPanel inner_panel = new JPanel();
inner_panel.setLayout(new BorderLayout());
inner_panel.add(panel1, BorderLayout.EAST);
inner_panel.add(textArea, BorderLayout.CENTER);
inner_panel.setBorder(new EmptyBorder(10, 10, 10, 10));
this.setLayout(new BorderLayout());
this.add(scrollPane, BorderLayout.CENTER);
this.add(inner_panel, BorderLayout.SOUTH); // This line produces the error
}
}
这是我的错误:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 0
at javax.swing.plaf.basic.BasicTabbedPaneUI.tabForCoordinate(BasicTabbedPaneUI.java:1506)
at javax.swing.plaf.basic.BasicTabbedPaneUI.setRolloverTab(BasicTabbedPaneUI.java:575)
at javax.swing.plaf.basic.BasicTabbedPaneUI.access$2000(BasicTabbedPaneUI.java:54)
at javax.swing.plaf.basic.BasicTabbedPaneUI$Handler.mouseEntered(BasicTabbedPaneUI.java:3626)
at java.awt.Component.processMouseEvent(Component.java:6525)
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321)
at java.awt.Component.processEvent(Component.java:6281)
at java.awt.Container.processEvent(Container.java:2229)
at java.awt.Component.dispatchEventImpl(Component.java:4872)
at java.awt.Container.dispatchEventImpl(Container.java:2287)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4832)
at java.awt.LightweightDispatcher.trackMouseEnterExit(Container.java:4620)
at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4474)
at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4422)
at java.awt.Container.dispatchEventImpl(Container.java:2273)
at java.awt.Window.dispatchEventImpl(Window.java:2719)
at java.awt.Component.dispatchEvent(Component.java:4698)
at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:747)
at java.awt.EventQueue.access$300(EventQueue.java:103)
at java.awt.EventQueue$3.run(EventQueue.java:706)
at java.awt.EventQueue$3.run(EventQueue.java:704)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:87)
at java.awt.EventQueue$4.run(EventQueue.java:720)
at java.awt.EventQueue$4.run(EventQueue.java:718)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(ProtectionDomain.java:76)
at java.awt.EventQueue.dispatchEvent(EventQueue.java:717)
at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:242)
at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:161)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:150)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:146)
at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:138)
at java.awt.EventDispatchThread.run(EventDispatchThread.java:91)
谢谢 !
编辑:
这是您可以用来测试我的代码的代码:
public class Main {
public static MyFrame frame;
public static void main(String[] args) {
frame = new MyFrame();
new Thread() {
public void run() {
frame.addTab("Test");
}
}.start();
}
}
1楼
更换
new Thread() {
public void run() {
frame.addTab("Test");
}
}.start();
与
frame.addTab("Test");
目前,您正在尝试从另一个线程(而不是JFrame
所在的线程)修改GUI元素。
在程序完成构建窗口之前,可能已到达添加选项卡的代码,因此会出现错误。
可能是一本好书。
2楼
正如Kiheru所建议的,必须以这种方式通过修改来自另一个线程的框架来完成:
public class Main {
public static MyFrame frame;
public static void main(String[] args) throws InterruptedException,
ExecutionException, UnknownHostException, IOException {
frame = new MyFrame();
new Thread() {
public void run() {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.addTab("Test");
}
});
try {
this.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
frame.addTab("Test2");
}
});
}
}.start();
}
}
3楼
import javax.swing.SwingWorker;
请在此处阅读有关此内容的信息...
new SwingWorker() {
@Override protected Void doInBackground() throws Exception {
return null;
}
@Override protected void done() {
//PUT HERE THE CODE
frame.addTab("Test");
frame.addTab("Test2");
}
}.execute();