2016-08-15 3 views
0

Я работаю над графическим интерфейсом, но нашел проблему. Примерно в 10% случаев я запускаю программу, я получаю ClassCastException, но код не зависает и не выполняется странно. Он просто работает, как обычно. Что более странно, так это трассировка стека никогда не ссылается на какой-либо код, который я написал. Я попытался подтвердить это, завернув все в 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); также устраняет проблему, поэтому я представляю, когда рисуется графический интерфейс, это делается в собственной теме, которая действительно сердится на добавление одного и того же элемента к двум JPanel (это объясняет, почему мой код не является в трассировке стека, я думаю ...), но я не понимаю этот процесс достаточно хорошо, чтобы точно знать.

Вот трассировки стека:

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'. Нет необходимости в частном члене 'frame'. – pzaenger

+1

Это ошибка? http://bugs.java.com/bugdatabase/view_bug.do?bug_id=8013775 – khelwood

+0

@khelwood Я думаю, что это ошибка! Означает ли это, что это происходит потому, что добавление 'addRow' в' JPanel' после того, как я создаю 'addRow' видимые помехи с компонентами в моем основном потоке, которые использует поток Swing? Я пойду вперед и нажмем «что решил мою проблему» для этого дубликата, но я бы хотел убедиться, что полностью понял это первое. –

ответ

0

Сначала вы догадались, проблема в том, что вы добавляете addRow два раза. Случайно панель, в которую вы добавляете второй раз, не отображается в кадре. Компонент в Swing ДОЛЖЕН иметь только одного родителя, он не может быть предоставлен двум родителям в одно и то же время. Если вы хотите изменить родительский компонент компонента, вы должны сначала удалить его из родителя, добавить его в другое и сделать недействительным оба родителя, чтобы их можно было увидеть.

Класс исключений исключений случается, потому что внутренне родитель путается

Смежные вопросы