2010-04-13 20 views
7

मैं एक ग्रोवी विशेषज्ञ नहीं हूं, लेकिन मैंने पुस्तक "ग्रोवी इन एक्शन" पढ़ी है। ग्रोवी में, प्रत्येक बंद एक "संदर्भ" के साथ आता है, जहां बंद करने के अंदर की वस्तुओं को छद्म-चर जैसे "यह", "मालिक" और "प्रतिनिधि" तक पहुंच मिल सकती है, जिससे वस्तुओं को पता चल जाता है कि किसने बंद किया।स्कैला बंद संदर्भ

swing = new SwingBuilder() 
frame = swing.frame(title:'Demo') { 
    menuBar { 
    menu('File') { 
     menuItem 'New' 
     menuItem 'Open' 
    } 
    } 
    panel { 
    // ... 
    } 
} 

ध्यान दें कि 'मेनूबार' "जानता" इसे करने के लिए 'फ्रेम' अंतर्गत आता है कि क्योंकि यह मालिक और के प्रतिनिधि के बारे में संदर्भ जानकारी प्राप्त कर सकते हैं: यह एक (कार्रवाई में ग्रूवी से) इस तरह DSLs लिखने के लिए अनुमति देता है बंद।

क्या स्कैला में ऐसा करना संभव है? यदि हां, तो कैसे?

+0

मैं एक बार एचटीएमएल बिल्डर (नहीं मालिक/एक बंद करने की प्रतिनिधि) अनुकरण करने के लिए कुछ दृष्टिकोण के साथ tinkered SwingBuilder तरह लागू किया जा सकता। http://gist.github.com/260426 http://gist.github.com/260446 – retronym

+0

मैं स्विंग के साथ एक विशिष्ट अनुप्रयोग की तुलना में पैटर्न के लिए और अधिक देख रहा था। एक सीखने के अभ्यास के रूप में, मैं एसडब्ल्यूटी के साथ कोशिश करने पर विचार कर रहा हूं। – Ralph

उत्तर

16

एक तरीका संदर्भ ट्रैक करने के लिए scala.util.DynamicVariable का उपयोग करना है। के रूप में

import scala.util.DynamicVariable 
import javax.swing._ 

object SwingBuilder { 
    case class Context(frame: Option[JFrame], parent: Option[JComponent]) 
} 

class SwingBuilder { 
    import SwingBuilder._ 
    val context = new DynamicVariable[Context](Context(None,None)) 

    def frame(title: String)(f: =>Unit) = { 
    val res = new JFrame(title) 
    res.add(new JPanel()) 
    context.withValue(Context(Some(res),context.value.parent)){f;res} 
    } 

    def menuBar(f: =>Unit) = { 
    val mb = new JMenuBar() 
    context.value.frame.foreach(_.setJMenuBar(mb)) 
    context.withValue(Context(context.value.frame,Some(mb))){f;mb} 
    } 

    def menu(title: String)(f: =>Unit) = { 
    val m = new JMenu(title) 
    context.value.parent.foreach(_.asInstanceOf[JMenuBar].add(m)) 
    context.withValue(Context(context.value.frame,Some(m))){f;m} 
    } 

    def menuItem(title: String) = { 
    val mi = new JMenuItem(title) 
    context.value.parent.foreach(_.asInstanceOf[JMenu].add(mi)) 
    } 
} 

object Test { 
    def main(args: Array[String]) { 
    val builder = new SwingBuilder() 
    import builder._ 

    val f = frame("Demo") { 
     val mb = menuBar { 
     menu("File") { 
      menuItem("New") 
      menuItem("Open") 
     } 
     } 
    } 
    f.setVisible(true) 
    } 
} 
+3

स्कैला कभी मुझे आश्चर्यचकित नहीं करता:) ... धन्यवाद। – Ralph

संबंधित मुद्दे