Как управлять слушателями scala swing - PullRequest
0 голосов
/ 28 июня 2011

Это продолжение моего последнего вопроса.Я использовал шаблон MVC с компонентами Swing, и код выглядит так:

import scala.swing
import scala.swing.event._

case object MyBusinessEvent extends Event

class MyController extends Publisher {
    val form = new MyForm
    listenTo(form)
    reactions += {
      case MyBusinessEvent => //handle event code here
    }
}

class MyForm extends Publisher {
  val ui = new GridBagPanel {
    val c = new Constraints
    .... more code here
  }

  val button1 = new Button("Button 1") 
  //add button to panel


  listenTo(button1) 
  reactions += {
    case ButtonClicked(_) => publish(MyBusinessEvent)
  }  
}

Однако с несколькими кнопками программа зависает и, похоже, перестает публиковать события.Есть ли способ это исправить?Спасибо

Ответы [ 2 ]

1 голос
/ 28 июня 2011

Хотя из усеченного примера не ясно, в чем проблема, я предполагаю, что вы создаете цикл, который, к сожалению, может произойти довольно просто с Swing и MVC. то есть одна модель обновляется как часть прослушивания другой модели, и это снова вызывает обновление в другой модели. В Java-свинге у вас есть два варианта,

a) временно удалить слушателя, который обновляет модель (например, выполните removeActionListener перед вызовом setSelectedItem на JComboBox, а затем повторно зарегистрируйтесь с addActionListener)

b) проверить источник события (getSource на java.util.EventObject) и игнорировать события в модели, которые произошли от той же самой модели.

Теперь качели в Scala упрощены, поэтому у вас нет объектов и источников событий. Вы можете добавить источник в свой класс событий. Возможно, удастся удалить реакцию и добавить ее снова после установки состояния модели.

0 голосов
/ 25 февраля 2012

Чтобы избежать циклов, упомянутых в ответе 0 __, у меня есть такая черта:

trait Editable extends Publisher {  
    private var _editing = false

    def editing = _editing

    def editing_=(b: Boolean) = _editing = b

    override def publish(e: Event) {
        if(!editing) super.publish(e)
    }
}

, который я добавляю в компоненты, которые я хочу иметь больше контроля над событиями. Поэтому, когда я хочу что-то изменить без какого-либо события, я просто помещаю код между editing = true и editing = false.

...