2016-08-15 114 views
0

我一直在使用GUI,但发现了一个问题。大约10%的时间启动该程序,我得到一个ClassCastException,但代码不会挂起并且不会执行奇怪。它只是正常运行。什么是weirder是堆栈跟踪从不参考我写的任何代码。我试图通过将所有内容都包含在try-catch中来证实这一点,并且确信,错误仍然被抛出并且从未被捕获。由于它从来没有真正影响代码,我想这不会造成任何伤害,但我仍然宁愿不发布有我不了解的错误的代码。为什么会抛出ClassCastException?

这里是简化的,因为我可以得到它仍重复错误代码:

import java.awt.GridBagLayout; 

import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 

public class ErrorTracker extends JFrame{ 

    private JButton addRow; 
    private JScrollPane pane; 
    private JPanel scrollPanel, panel; 
    private JFrame frame; 

    public static void main (String[] args) { 
     /** 
     * The error only occurs sometimes, so I'm running it 20 times to 
     * make the odds of repeating the error pretty good. 
     */ 
     for(int i = 0; i < 20; i++) 
      new ErrorTracker(); 
    } 

    public ErrorTracker() { 
     /** 
     * Proof that the error somehow occurs outside of all the code... 
     * The line "An error took place" is never outputted. 
     **/ 
     try { 
      initialize(); 
     } catch (Exception e) { 
      System.out.println("An error took place"); 
     } 
    } 

    public void initialize() { 
     frame = new JFrame("Apparently this is defective"); 

     JPanel bigPanel = new JPanel(new GridBagLayout()); 

     frame.add(bigPanel); 

     addRow = new JButton("..."); 

     scrollPanel = new JPanel(); 
     scrollPanel.add(addRow); 

     pane = new JScrollPane(scrollPanel); 
     bigPanel.add(pane); 

     frame.setVisible(true); 

     panel = new JPanel(); 
     panel.add(addRow); 
    } 
} 

我知道有99%的把握,加入addRow两次至少一些这样做的原因,因为服用输出add(addRow)行中的任一行都可以解决问题。在任何人建议改变之前,别担心。我会。但是,这个问题主要是为了解这个错误发生的原因。摆脱frame.setVisible(true);也消除了这个问题,所以我想象当GUI被绘制时,它在自己的Thread中完成,它真的很生气,因为它将相同的元素添加到两个JPanel s(这可以解释为什么我的代码不是在堆栈跟踪中,我认为...),但我不明白这个过程足够好,不能确定地知道。

这里的堆栈跟踪:

Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException 
    at javax.swing.LayoutComparator.compare(Unknown Source) 
    at javax.swing.LayoutComparator.compare(Unknown Source) 
    at java.util.TimSort.countRunAndMakeAscending(Unknown Source) 
    at java.util.TimSort.sort(Unknown Source) 
    at java.util.Arrays.sort(Unknown Source) 
    at java.util.ArrayList.sort(Unknown Source) 
    at java.util.Collections.sort(Unknown Source) 
    at javax.swing.SortingFocusTraversalPolicy.enumerateAndSortCycle(Unknown Source) 
    at javax.swing.SortingFocusTraversalPolicy.getFocusTraversalCycle(Unknown Source) 
    at javax.swing.SortingFocusTraversalPolicy.getFirstComponent(Unknown Source) 
    at javax.swing.LayoutFocusTraversalPolicy.getFirstComponent(Unknown Source) 
    at javax.swing.SortingFocusTraversalPolicy.getDefaultComponent(Unknown Source) 
    at java.awt.FocusTraversalPolicy.getInitialComponent(Unknown Source) 
    at java.awt.Window.getMostRecentFocusOwner(Unknown Source) 
    at java.awt.DefaultKeyboardFocusManager.dispatchEvent(Unknown Source) 
    at java.awt.Component.dispatchEventImpl(Unknown Source) 
    at java.awt.Container.dispatchEventImpl(Unknown Source) 
    at java.awt.Window.dispatchEventImpl(Unknown Source) 
    at java.awt.Component.dispatchEvent(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$500(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.SequencedEvent.dispatch(Unknown Source) 
    at java.awt.EventQueue.dispatchEventImpl(Unknown Source) 
    at java.awt.EventQueue.access$500(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.awt.EventQueue$3.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.awt.EventQueue$4.run(Unknown Source) 
    at java.security.AccessController.doPrivileged(Native Method) 
    at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source) 
    at java.awt.EventQueue.dispatchEvent(Unknown Source) 
    at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.pumpEvents(Unknown Source) 
    at java.awt.EventDispatchThread.run(Unknown Source) 

有谁知道为什么被抛出这个错误?我在另一个线程中是否正确,如果没有,为什么堆栈跟踪不会引用我的代码?另外,它为什么只在某些时候抛出错误?

+0

您的类扩展了'JFrame'。不需要私人成员“框架”。 – pzaenger

+1

这是错误吗? http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8013775 – khelwood

+0

@ khelwood我认为这是错误!这是否意味着发生这种情况,因为在我的主线程中使用Swing线程正在使用的组件的'addRow'可见的混乱之后,向'JPanel'添加'addRow'?我会继续点击“解决了我的问题”这个副本,但我很乐意确保我完全掌握了第一个 –

回答

0

首先你猜对了,问题是因为你添加了两次addRow。偶然地,第二次添加的面板不会显示在框架中。 Swing中的组件必须只有一个父对象,它不能在同一时间给予两个父对象。如果您想更改组件的父项,则必须先将其从其父项中删除,然后将其添加到其他项中,然后使双亲无效以查看结果。

类抛出的异常发生是因为父内部是混淆的

相关问题