2014-11-09 2 views
0

Прежде всего я не носитель английского языка, поэтому я приношу свои извинения за любые возможные «странные» письма.Невозможная ошибка согласования памяти Java

Я разрабатываю приложение Swing Java на Eclipse, которое обновляет Jpanel. Эта панель содержит несколько подпанелей, и я постоянно переключаю «режимы» панелей, что происходит с изменением MouseListener, поэтому они реагируют несколько иначе на пользовательские входы мыши.

Независимо от того, что делает приложение, это происходит с ошибкой, которая, как представляется, не имеет логического объяснения для меня. В какой-то момент в моем коде я пытаюсь обновить панели до того, что я назвал neutralMode. Это происходит по следующей методике:

//Guarded block (see http://docs.oracle.com/javase/tutorial/essential/concurrency/guardmeth.html) 
private synchronized boolean waitsForUserSatisfactionAnswer() 
{ 

    while(!userIndicatedSatisfaction) 
    {   
     try { 
      wait(); 
     } catch (InterruptedException e) {} 
    } 

    userIndicatedSatisfaction = false; //reset for future new query 

    getObjectSetVisualizationPanel().neutralMode(); 
    //getObjectSetVisualizationPanel().queryPatternMode(); 


    return userSatisfied; 
} 

Это обновление не работает (вызов neutralMode() не делают то, что, как ожидается). Однако вызов функции queryPatternMode() (прокомментированный в строке справа) работает отлично. Поэтому я решил копировать тело запросаPatternMode() и PASTE на тело neutralMode() ECXATLY SAME! И ЭТО ПРОДОЛЖАЕТ РАБОТУ!

Код метода выглядит так:

public void queryPatternMode() 
    { 
     System.out.println("Inside queryPatternMode!!!"); 
     System.out.println("panels.size(): " + panels.size()); 

     for (DigitalObjectPanel panel : panels) 
     { 
      System.out.println("Inside the loop!!!"); 
      panel.resetBehavior(); 
      panel.setQuerySelectionBehavior(gui); 

      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        panel.validate(); 
       } 
      }); 

     } 
    } 

    public void neutralMode() 
    { 
     System.out.println("Inside neutralMode!!!"); 
     System.out.println("panels.size(): " + panels.size()); 

     for (DigitalObjectPanel panel : panels) 
     { 
      System.out.println("Inside the loop!!!"); 
      panel.resetBehavior(); 
      panel.setQuerySelectionBehavior(gui); 

      SwingUtilities.invokeLater(new Runnable() { 
       public void run() { 
        panel.validate(); 
       } 
      }); 
     } 

    } 

Что происходит, что, когда я называю neutralMode(), то «панели» коллекция оказывается пустым (panels.size() равна нулю). Однако, когда я вызываю queryPatternMode(), коллекция имеет ожидаемый размер (20 панелей). Но оба метода равны, и оба вызываются из одного и того же места !!!

Что это может быть ??? Есть ли возможное объяснение этому?

+1

Вы выполняете все обновления объектов Swing в [Событие Dispatch Thread?] (Https://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html) – markspace

+0

Какова область действия ' panels'? Может быть, вы скрываете это одним способом, но не другим? Что говорит ваша IDE? заменяет 'panel', с' this.panels' что-то меняет? У вас есть полный пример работы, который мы можем попробовать? –

+1

Ваш код выглядит, возможно, игнорируя принципы программирования, управляемого событиями. Обычно вам не следует постоянно опроса переменной, например 'userIndicatedSatisfaction', а вместо этого использовать шаблон слушателя или наблюдателя и, таким образом, получать уведомления об изменениях. Как рекомендовано другими, рассмотрите возможность создания и публикации [Минимальной, полной и проверяемой примерной программы] (http://stackoverflow.com/help/mcve). –

ответ

1

Это определенно похоже на проблему синхронизации. Вы должны проверить, сколько потоков обращается к панелям коллекции.

Это просто удача, что он работает для вас с запросомPatternMode() все время, а не с нейтральнымMode(). В другой прекрасный день это может быть наоборот.

+0

Спасибо за ответ.Сначала я думал, был вопросом синхронизации, поэтому я попытался несколько исправлений: -declared списка панелей летучего -synchronized оба метода -Изменена панель доступа только к оберточным синхронизируются методам -tried коллекции коммутационных панелей из arralist вектора -tried получение панелей через Collections.synchronizedList() ничего из этого не сработало. Кроме того, даже учитывая проблемы с потоками, это действительно не имеет смысла, поскольку я вызываю методы из одной и той же точки, и оба выполняют один и тот же код. –

+0

Также есть некоторые странные странные вещи: я попытался просто делегировать neutralMode() на queryPatternMode(), поэтому я печатаю размер панелей на нейтральномMode(), а затем снова вызываю queryPatternMode() и размер панелей печати. И размер коллекций по-прежнему отличается! первый ноль, а затем 20! Объем метода - это единственное, что определяет размер видимых коллекций! –

+0

Одно можно сказать наверняка - не будет иметь никакого значения то, что вы называете этими методами, поэтому вы можете полностью это исключить. Забудьте об этом и продолжайте думать об альтернативах. Снова сосредоточьтесь на том, где «панели» меняются. Возможно ли, чтобы вы предоставили полный файл здесь или, по крайней мере, методы, в которых панели коллекций меняются каким-либо образом? Cheers –

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