2014-02-12 1 views
2

Я пытаюсь понять, как следующие работы класса, взятые из ответа из этой темы: Scala Popup MenuКак создать классы оболочки Swa Swa с помощью SuperMixin?

Поскольку нить довольно старые, я решил просто начать новый вопрос. Я новичок в Scala с фоном Java, и мне интересно, как работает этот класс. Я читал, что объект с тем же именем, что и класс, похож на класс с одноэлементным объектом? Я не уверен, как это подходит для достижения обертки, хотя .. (зачем нам нужен объект?)

И что именно делает черта SuperMixin? API говорит: «Эта черта используется для перенаправления определенных вызовов от однорангового узла к обертке и обратно. Полезно для раскрытия методов, которые можно настроить с помощью переопределения». который не очень хорошо объясняет новичкам.

Я бы очень признателен, если кто-то может помочь объяснить новичкам, как этот класс и объект (как мне кажется, волшебным образом) получают мне класс-оболочку для JPopupMenu и позволяют мне вызвать метод show, из-за которого появляется popupMenu на экране ... и кажется, что я могу установить его содержимое (содержимое + = некоторый scala.swing.menuItem), если он не определен в классе ниже?

import javax.swing.JPopupMenu 
import scala.swing.{ Component, MenuItem } 
import scala.swing.SequentialContainer.Wrapper 

object PopupMenu { 
    private[PopupMenu] trait JPopupMenuMixin { def popupMenuWrapper: PopupMenu } 
} 

class PopupMenu extends Component with Wrapper { 

    override lazy val peer: JPopupMenu = new JPopupMenu with PopupMenu.JPopupMenuMixin with SuperMixin { 
    def popupMenuWrapper = PopupMenu.this 
    } 

    def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y) 

    /* Create any other peer methods here */ 
} 

ответ

2

компаньона объект для PopupMenu не служит какой-либо конкретной цели здесь, кроме функционирования в качестве пространства имен для вспомогательного признака JPopupMenuMixin. Затем этот признак можно «спрятать», сделав его private[PopupMenu], поэтому он известен только классом PopupMenu и его сопутствующим объектом.

Честно говоря, я не вижу цели этой черты. Он определяет метод popupMenuWrapper, указывающий на внешний компонент Scala Swing, но этот метод вообще не используется. Таким образом, менее запутанная версия будет просто:

import scala.swing._ 
import javax.swing.JPopupMenu 

class PopupMenu extends Component with SequentialContainer.Wrapper { 
    override lazy val peer: JPopupMenu = new JPopupMenu with SuperMixin 

    def show(invoker: Component, x: Int, y: Int): Unit = peer.show(invoker.peer, x, y) 
} 

Тест:

val pop = new PopupMenu { 
    contents += new MenuItem("Foo") 
} 
lazy val but: Button = Button("Test") { 
    pop.show(but, 0, 0) 
} 
val f = new Frame { 
    contents = but 
    pack().centerOnScreen() 
    open() 
} 

Единственное, что необходимо для обертки, чтобы расширить scala.swing.Component и переопределить значение peer с подстилающей javax.swing компонента. Смеситель with SuperMixinoverrides a few methods этого компонента, такой как paintComponent, для пересылки их на внешний компонент оболочки. Это все.

Обертка смешивается в SequentialContainer.Wrapper, которая позволяет выполнить операцию contents += для добавления пунктов меню.

+0

Спасибо, что имеет смысл – user3301485

+0

Примечание: PopupMenu, кажется, является частью [stock scala.swing в 2.11] (http://www.scala-lang.org/api/2.11.1/scala-swing/ index.html # scala.swing.PopupMenu). – Suma

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