Created
April 22, 2009 05:48
-
-
Save adamsanderson/99612 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /usr/bin/env jruby | |
include Java | |
import java.lang.System | |
import javax.swing.JFrame | |
import javax.swing.JLabel | |
import javax.swing.JTextField | |
import javax.swing.event.DocumentListener | |
import java.awt.GridLayout | |
class Calculator < JFrame | |
def initialize(name='Calculator', &block) | |
super(name) | |
self.layout = GridLayout.new(0, 2) | |
@fields = {} | |
configue(&block) | |
pack | |
show | |
end | |
def configue(&block) | |
data = CalculatorDSL.new(&block) | |
data.inputs.each do |input| | |
add JLabel.new(input.to_s) | |
add @fields[input] = JTextField.new | |
end | |
data.outputs.each do |output, spec| | |
add JLabel.new(output.to_s) | |
add field = JTextField.new | |
field.enabled = false | |
@fields[output] = field # can cause loops | |
calculation = spec.pop | |
compute = lambda{ | |
values = spec.map{|key| @fields[key].get_text.to_i } | |
result = calculation.call(*values) | |
field.set_text(result.to_s) | |
} | |
spec.each{|key| @fields[key].get_document.add_document_listener(FieldListener.new(compute))} | |
end | |
end | |
end | |
class CalculatorDSL | |
attr_reader :inputs, :outputs | |
def initialize(&block) | |
@inputs = [] | |
@outputs = {} | |
instance_eval &block | |
end | |
def input *names | |
names.each{|name| @inputs << name } | |
end | |
def output specs | |
specs.each{|name, spec| @outputs[name] = spec} | |
end | |
end | |
class FieldListener | |
include DocumentListener | |
def initialize(block) | |
@block = block | |
end | |
def insertUpdate(e); update; end | |
def removeUpdate(e); update; end | |
def changedUpdate(e); update; end | |
def update; @block.call; end | |
end | |
# This is the equivelant DSL | |
Calculator.new do | |
input :width | |
input :height | |
output :area => [:width, :height, lambda{|w,h| w * h}] | |
output :price => [:area, lambda{|area| "$#{area * 25}" }] | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment