2013-04-16 2 views
1

Моя проблема сегодня связана с простым утверждением в JFace TreeViewerComposite. Я пытаюсь прикрепить ControlListener к столбцам моего дерева, чтобы обеспечить минимальную ширину. Для этого я смотрю каждый раз, когда размер столбца изменяется, и если новая ширина слишком мала, я накладываю на нее минимум.Предотвращение прослушивания от запуска самого себя

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

public static void getSizeControlListener(final TreeColumn column, final int minSize) { 
     column.addControlListener(new ControlListener() { 
      @Override 
      public void controlMoved(ControlEvent e) {} 

      @Override 
      public void controlResized(ControlEvent e) { 
       if(column.getWidth()<minSize) { 
        column.setWidth(minSize); 
       } 
      } 
    }); 

Одно решение, которое работает, чтобы добавить флаг, который получает установленный на входе, что все вложенные вызовы могут ссылаться и сразу же выход, если это необходимо. Он работает, но он грязный и уродливый.

public static void getSizeControlListener(final TreeColumn column, final int minSize) { 
     column.addControlListener(new ControlListener() { 

      private boolean isRunning; 

      @Override 
      public void controlMoved(ControlEvent e) {} 

      @Override 
      public void controlResized(ControlEvent e) { 
       if(isRunning) 
        return; 
       isRunning = true; 
       if(column.getWidth()<minSize) { 
        column.setWidth(minSize); 
       } 
       isRunning = false 
      } 
    }); 

ответ

1

Вашего решения с флагом абсолютно нормально, мы используем эту модель регулярно предотвратить уведомления каскадов.
Одним из примеров, когда возникают такие каскады, является синхронизация состояний модели в MVC. Использование такого флага позволяет реализовать однонаправленные обновления без каскадов с двунаправленной синхронизацией.

Единственное различие в вашей реализации является то, что мы используем try..finally, чтобы убедиться, что флаг всегда сбрасывается (также при возникновении исключения):

if (updating) { 
    return; 
} 
try { 
    updating=true; 

    // do stuff 

} finally { 
    updating=false; 
} 
0

Я думаю, вы должны поставить ниже кода в org.eclipse.swt.widgets.Display.asyncExec(Runnable)

column.setWidth(minSize); 
Смежные вопросы