rpv_swing 0.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +19 -0
- data/lib/rpv/generators/swing/templates/view/view.rb.erb +11 -0
- data/lib/rpv/generators/swing/templates/view/view_spec.rb.erb +11 -0
- data/lib/rpv/generators/swing/view_generator.rb +29 -0
- data/lib/rpv/java/java_getters_and_setters.rb +37 -0
- data/lib/rpv/swing.rb +8 -0
- data/lib/rpv/swing/dialog_view.rb +23 -0
- data/lib/rpv/swing/event_handler_mixin.rb +138 -0
- data/lib/rpv/swing/events.rb +78 -0
- data/lib/rpv/swing/frame_view.rb +23 -0
- data/lib/rpv/swing/panel_view.rb +23 -0
- data/lib/rpv/swing/swingset.rb +252 -0
- data/lib/rpv/wiring/java_array.rb +15 -0
- data/spec/java/java_getters_and_setters_spec.rb +53 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/swing/frame_view_spec.rb +14 -0
- data/spec/swing/generators/view_spec.rb +37 -0
- data/spec/swing/panel_view_spec.rb +14 -0
- data/spec/wiring/java_array_spec.rb +17 -0
- metadata +98 -0
data/Rakefile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'rake'
|
2
|
+
require 'spec/rake/spectask'
|
3
|
+
require 'rdoc/task'
|
4
|
+
|
5
|
+
desc "Run all specs"
|
6
|
+
Spec::Rake::SpecTask.new('spec') do |t|
|
7
|
+
t.spec_opts = ["--colour", "--format progress", "--loadby mtime"]
|
8
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
9
|
+
t.libs = [File.dirname(__FILE__) + '/lib']
|
10
|
+
end
|
11
|
+
|
12
|
+
RDoc::Task.new do |rdoc|
|
13
|
+
rdoc.main = "Readme.rdoc"
|
14
|
+
rdoc.rdoc_dir = "doc"
|
15
|
+
rdoc.title = "RPV: Swing"
|
16
|
+
rdoc.rdoc_files.include("Readme.rdoc")
|
17
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
18
|
+
rdoc.options << '--line-numbers' << '--inline-source'
|
19
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../spec_helper.rb"
|
2
|
+
#require 'views/<%= class_name.underscore %>' #uncomment if you do not use the autoloader
|
3
|
+
|
4
|
+
describe <%= class_name %> do
|
5
|
+
before(:all) do
|
6
|
+
@instance = <%= class_name %>.new
|
7
|
+
end
|
8
|
+
|
9
|
+
#should_fire :some_event
|
10
|
+
#should_have_attr_readers :some_control
|
11
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rpv/generators/base'
|
2
|
+
|
3
|
+
module RPV
|
4
|
+
module Generators
|
5
|
+
module Swing
|
6
|
+
class ViewGenerator < RPV::Generators::Base
|
7
|
+
argument :name
|
8
|
+
argument :base_class
|
9
|
+
parse 'view.rb.erb', 'app/views/#{name}.rb'
|
10
|
+
parse 'view_spec.rb.erb', 'spec/views/#{name}_spec.rb'
|
11
|
+
|
12
|
+
def initialize
|
13
|
+
@template_path = File.dirname(__FILE__) + '/templates/view'
|
14
|
+
end
|
15
|
+
|
16
|
+
def parse_args
|
17
|
+
@arguments[:base_class] ||= "frame"
|
18
|
+
@arguments[:base_class] = "RPV::Swing::" + (@arguments[:base_class].underscore + "_view").camelize
|
19
|
+
@arguments[:name] = @arguments[:name].underscore + "_view"
|
20
|
+
@arguments[:class_name] = @arguments[:name].camelize
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.describe
|
24
|
+
"creates a swing view"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require 'rpv/inflector'
|
2
|
+
|
3
|
+
# Adds Java style getters and setters to your class. Maps (getFooBar, setFooBar, isFooBar) to
|
4
|
+
# (foo_bar, foo_bar=, foo_bar?).
|
5
|
+
# If a class implements method_missing, it should be included afterwards
|
6
|
+
# in order to preserve it by chaining the methods.
|
7
|
+
module JavaGettersAndSetters
|
8
|
+
GetterRegex = /get([A-Z]+.*)/
|
9
|
+
SetterRegex = /set([A-Z]+.*)/
|
10
|
+
PredicateRegex = /is([A-Z]+.*)/
|
11
|
+
|
12
|
+
def method_missing_with_java_getters_and_setters(method, *args)
|
13
|
+
if method.to_s =~ GetterRegex
|
14
|
+
property = method.to_s.match(GetterRegex)[1].underscore
|
15
|
+
self.send(property, *args)
|
16
|
+
elsif method.to_s =~ SetterRegex
|
17
|
+
property = method.to_s.match(SetterRegex)[1].underscore
|
18
|
+
self.send("#{property}=", *args)
|
19
|
+
elsif method.to_s =~ PredicateRegex
|
20
|
+
property = method.to_s.match(PredicateRegex)[1].underscore
|
21
|
+
self.send("#{property}?", *args)
|
22
|
+
else
|
23
|
+
if self.respond_to?(:method_missing_without_java_getters_and_setters)
|
24
|
+
method_missing_without_java_getters_and_setters(method, *args)
|
25
|
+
else
|
26
|
+
raise NoMethodError.new("undefined method `#{method.to_s}' for #{self.to_s}", method, *args)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def self.included(base)
|
32
|
+
base.class_eval do
|
33
|
+
alias_method :method_missing_without_java_getters_and_setters, :method_missing if self.instance_methods.include?("method_missing")
|
34
|
+
alias_method :method_missing, :method_missing_with_java_getters_and_setters
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
data/lib/rpv/swing.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rpv/option_extractor'
|
2
|
+
|
3
|
+
module RPV
|
4
|
+
module Swing
|
5
|
+
class DialogView < Java::javax.swing.JDialog
|
6
|
+
include RPV::EventPublisher
|
7
|
+
include RPV::Swing::EventHandlerMixin
|
8
|
+
include RPV::OptionExtractor
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
@parent, @modal = extract_options(args, :parent, :modal)
|
12
|
+
super() unless @parent
|
13
|
+
super(@parent, (@modal || false)) if @parent
|
14
|
+
setup_components(*args)
|
15
|
+
wire_events
|
16
|
+
end
|
17
|
+
|
18
|
+
def setup_components(*args)
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module RPV
|
2
|
+
module Swing
|
3
|
+
module EventHandlerMixin
|
4
|
+
#TODO write specs for this, urgh...
|
5
|
+
def self.included(base)
|
6
|
+
base.extend ClassMethods
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def publish_defaults
|
11
|
+
@publish_defaults = { :events => :action_performed } if @publish_defaults.nil?
|
12
|
+
@publish_defaults
|
13
|
+
end
|
14
|
+
|
15
|
+
def publish_events(options = nil)
|
16
|
+
@publish_events ||= []
|
17
|
+
unless options.nil?
|
18
|
+
unless options[:events].is_a? Hash
|
19
|
+
events = [options[:events]].flatten
|
20
|
+
options[:events] = {}
|
21
|
+
events.each do |event|
|
22
|
+
options[:events][event] = event
|
23
|
+
end
|
24
|
+
end
|
25
|
+
@publish_events << { :options => options }
|
26
|
+
options[:events].each do |event, as|
|
27
|
+
fires "#{as}".to_sym
|
28
|
+
end
|
29
|
+
end
|
30
|
+
@publish_events
|
31
|
+
end
|
32
|
+
|
33
|
+
def publish_events_for(components = nil, options = {})
|
34
|
+
@publish_events_for ||= []
|
35
|
+
unless components.nil?
|
36
|
+
components = [components].flatten
|
37
|
+
options = options || {}
|
38
|
+
options = publish_defaults.merge(options)
|
39
|
+
unless options[:events].is_a? Hash
|
40
|
+
events = [options[:events]].flatten
|
41
|
+
options[:events] = {}
|
42
|
+
events.each do |event|
|
43
|
+
options[:events][event] = event
|
44
|
+
end
|
45
|
+
end
|
46
|
+
@publish_events_for << { :components => components, :options => options }
|
47
|
+
components.each do |component|
|
48
|
+
options[:events].each do |event, as|
|
49
|
+
fires "#{component}_#{as}".to_sym
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
@publish_events_for
|
54
|
+
end
|
55
|
+
end
|
56
|
+
private
|
57
|
+
def wire_events
|
58
|
+
self.class.publish_events_for.each do |publish_event|
|
59
|
+
publish_event[:components].each do |component|
|
60
|
+
publish_event[:options][:events].each do |event, as|
|
61
|
+
add_fire_handler_for(component, event, as)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
self.class.publish_events.each do |publish_event|
|
66
|
+
publish_event[:options][:events].each do |event, as|
|
67
|
+
add_fire_handler_for("#self", event, as)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def add_fire_handler_for(component_name, event_name, event_alias)
|
73
|
+
@__registered_handlers ||= Hash.new{|h,k| h[k] = []}
|
74
|
+
@__event_handler_procs ||= Hash.new{|h,k| h[k] = []}
|
75
|
+
|
76
|
+
component_name = component_name.to_s
|
77
|
+
event_name = event_name.to_s
|
78
|
+
begin
|
79
|
+
if component_name != "#self"
|
80
|
+
component = self.instance_eval(component_name, __FILE__, __LINE__)
|
81
|
+
else
|
82
|
+
component = self
|
83
|
+
end
|
84
|
+
rescue NameError => e
|
85
|
+
#rescue RPV::UndefinedComponentError => e
|
86
|
+
# swallow, handler style methods for controls that don't exist is allowed
|
87
|
+
else
|
88
|
+
component.methods.each do |method|
|
89
|
+
listener_match = /add(.*)Listener$/.match(method)
|
90
|
+
next if listener_match.nil?
|
91
|
+
handler_type = listener_match[1]
|
92
|
+
if RPV::Swing::Handlers::EVENT_NAMES_BY_TYPE[handler_type].member? event_name
|
93
|
+
unless (@__registered_handlers[component].map { |h| h.type }).member?(handler_type)
|
94
|
+
handler = "RPV::Swing::#{handler_type.camelize}Handler".constantize.new(component_name.to_s, event_name.to_s, event_alias.to_s) do |component, event, arg|
|
95
|
+
if component != "#self"
|
96
|
+
name = "#{component}_#{event}"
|
97
|
+
else
|
98
|
+
name = event
|
99
|
+
end
|
100
|
+
fire name.to_sym, arg
|
101
|
+
end
|
102
|
+
add_handler(handler, component_name)
|
103
|
+
@__registered_handlers[component] << handler
|
104
|
+
else
|
105
|
+
@__registered_handlers[component].find { |h| h.type == handler_type }.add_event_name(event_name.to_s, event_alias.to_s)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def add_handler(handler, component)
|
113
|
+
component = component.to_s
|
114
|
+
if "global" == component
|
115
|
+
raise "Global handler declarations are not yet supported"
|
116
|
+
elsif "#self" == component
|
117
|
+
begin
|
118
|
+
send("add#{handler.type.camelize}Listener", handler)
|
119
|
+
rescue NameError
|
120
|
+
raise InvalidHandlerError, "There is no listener of type #{handler.type} on #{@main_view_component}"
|
121
|
+
end
|
122
|
+
else
|
123
|
+
begin
|
124
|
+
object = instance_eval(component, __FILE__, __LINE__)
|
125
|
+
rescue NameError
|
126
|
+
raise UndefinedComponentError, "Cannot add #{handler.type} handler to #{component} on #{self}, the component could not be found"
|
127
|
+
end
|
128
|
+
|
129
|
+
begin
|
130
|
+
object.send("add#{handler.type.camelize}Listener", handler)
|
131
|
+
rescue NameError
|
132
|
+
raise InvalidHandlerError, "There is no listener of type #{handler.type} on #{component}"
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'rpv/inflector'
|
2
|
+
|
3
|
+
include_class 'javax.swing.SwingUtilities'
|
4
|
+
|
5
|
+
module RPV
|
6
|
+
module Swing
|
7
|
+
|
8
|
+
|
9
|
+
# This module is used internally by the various XYZHandler classes as the
|
10
|
+
# recipent of events. It dispatches the event handling to the controller's
|
11
|
+
# handle_event method.
|
12
|
+
module BaseHandler
|
13
|
+
def method_missing(method, *args, &block)
|
14
|
+
if @event_names.keys.member?(method.underscore)
|
15
|
+
event_alias = @event_names[method.underscore]
|
16
|
+
unless @callback.nil?
|
17
|
+
@callback.handle_event(@component_name, event_alias, args[0])
|
18
|
+
else
|
19
|
+
@block.call @component_name, event_alias, args[0]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
module Handlers
|
26
|
+
# TODO: add bean types like vetoable change, property change, etc.
|
27
|
+
BEAN_TYPES = ["PropertyChange"]
|
28
|
+
AWT_TYPES = ["Action","Adjustment","AWTEvent","Component","Container","Focus",
|
29
|
+
"HierarchyBounds","Hierarchy","InputMethod","Item","Key","Mouse",
|
30
|
+
"MouseMotion","MouseWheel","Text", "WindowFocus","Window","WindowState"]
|
31
|
+
SWING_TYPES = ["Ancestor", "Caret", "CellEditor", "Change", "Document",
|
32
|
+
"Hyperlink", "InternalFrame", "ListData", "ListSelection",
|
33
|
+
"MenuDragMouse", "MenuKey", "Menu", "MouseInput", "PopupMenu",
|
34
|
+
"TableColumnModel", "TableModel", "TreeExpansion", "TreeModel",
|
35
|
+
"TreeSelection", "TreeWillExpand", "UndoableEdit"]
|
36
|
+
ALL_EVENT_NAMES = []
|
37
|
+
EVENT_NAMES_BY_TYPE = Hash.new{|h,k| h[k] = []}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
{"java.awt.event" => RPV::Swing::Handlers::AWT_TYPES, "javax.swing.event" => RPV::Swing::Handlers::SWING_TYPES, "java.beans" => RPV::Swing::Handlers::BEAN_TYPES}.each do |java_package, types|
|
43
|
+
types.each do |type|
|
44
|
+
str = <<-ENDL
|
45
|
+
module RPV
|
46
|
+
module Swing
|
47
|
+
class #{type}Handler
|
48
|
+
def initialize(component_name, event_name, event_alias, callback = nil, &block)
|
49
|
+
@callback = callback
|
50
|
+
@block = block if block_given?
|
51
|
+
@component_name = component_name
|
52
|
+
@event_names = {event_name => event_alias}
|
53
|
+
end
|
54
|
+
|
55
|
+
def add_event_name(event_name, event_alias)
|
56
|
+
@event_names[event_name] = event_alias
|
57
|
+
end
|
58
|
+
|
59
|
+
def type
|
60
|
+
"#{type}"
|
61
|
+
end
|
62
|
+
|
63
|
+
include RPV::Swing::BaseHandler
|
64
|
+
include #{java_package}.#{type}Listener
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
ENDL
|
69
|
+
eval(str, nil, __FILE__, __LINE__)
|
70
|
+
|
71
|
+
interface = eval "#{java_package}.#{type}Listener"
|
72
|
+
interface.java_class.java_instance_methods.each do |method|
|
73
|
+
RPV::Swing::Handlers::ALL_EVENT_NAMES << method.name.underscore
|
74
|
+
RPV::Swing::Handlers::EVENT_NAMES_BY_TYPE[type] << method.name.underscore
|
75
|
+
end
|
76
|
+
RPV::Swing::Handlers::ALL_EVENT_NAMES.uniq!
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rpv/option_extractor'
|
2
|
+
|
3
|
+
module RPV
|
4
|
+
module Swing
|
5
|
+
class FrameView < Frame
|
6
|
+
include RPV::EventPublisher
|
7
|
+
include RPV::Swing::EventHandlerMixin
|
8
|
+
include RPV::OptionExtractor
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
super()
|
12
|
+
setup_components(*args)
|
13
|
+
wire_events
|
14
|
+
end
|
15
|
+
|
16
|
+
# Override this method and setup your components.
|
17
|
+
# It gets passed the constructor's *args.
|
18
|
+
def setup_components(*args)
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'rpv/option_extractor'
|
2
|
+
|
3
|
+
module RPV
|
4
|
+
module Swing
|
5
|
+
class PanelView < Panel
|
6
|
+
include RPV::EventPublisher
|
7
|
+
include RPV::Swing::EventHandlerMixin
|
8
|
+
include RPV::OptionExtractor
|
9
|
+
|
10
|
+
def initialize(*args)
|
11
|
+
super()
|
12
|
+
setup_components(*args)
|
13
|
+
wire_events
|
14
|
+
end
|
15
|
+
|
16
|
+
# Override this method and setup your components.
|
17
|
+
# It gets passed the constructor's *args.
|
18
|
+
def setup_components(*args)
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,252 @@
|
|
1
|
+
module RPV
|
2
|
+
module Swing
|
3
|
+
module SwingSet
|
4
|
+
module DefaultFont
|
5
|
+
def self.included(base)
|
6
|
+
base.extend(ClassMethods)
|
7
|
+
end
|
8
|
+
|
9
|
+
module ClassMethods
|
10
|
+
def default_font(font = nil)
|
11
|
+
@default_font = font unless font.nil?
|
12
|
+
@default_font
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
|
18
|
+
module SwingConstants
|
19
|
+
%w{
|
20
|
+
BOTTOM
|
21
|
+
CENTER
|
22
|
+
EAST
|
23
|
+
HORIZONTAL
|
24
|
+
LEADING
|
25
|
+
LEFT
|
26
|
+
NEXT
|
27
|
+
NORTH
|
28
|
+
NORTH_EAST
|
29
|
+
NORTH_WEST
|
30
|
+
PREVIOUS
|
31
|
+
RIGHT
|
32
|
+
SOUTH
|
33
|
+
SOUTH_EAST
|
34
|
+
SOUTH_WEST
|
35
|
+
TOP
|
36
|
+
TRAILING
|
37
|
+
VERTICAL
|
38
|
+
WEST}.each do |konst|
|
39
|
+
class_eval "#{konst} = Java::javax.swing.SwingConstants.#{konst}"
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
module LookAndFeels
|
45
|
+
Java::javax.swing.UIManager.getInstalledLookAndFeels().each do |laf|
|
46
|
+
class_eval "#{laf.get_class_name.split('.').last.gsub('LookAndFeel', '')} = '#{laf.get_class_name}'"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
|
51
|
+
module LineBorder
|
52
|
+
def self.new(color = Color.black, t = 1)
|
53
|
+
Java::javax.swing.BorderFactory.createLineBorder(color, t)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
|
58
|
+
class Font < Java::java.awt.Font
|
59
|
+
def self.available_fonts
|
60
|
+
Java::java.awt.GraphicsEnvironment.local_graphics_environment.available_font_family_names.to_ary
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
class Dimension
|
66
|
+
def self.[](width, height)
|
67
|
+
Java::java.awt.Dimension.new width, height
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# Proxies missing methods to java.awt.Color
|
73
|
+
# Color.white #=> java.awt.Color.white
|
74
|
+
# And constructs colors from hex values
|
75
|
+
# Color.00ff00 #=> Color[0, 255, 0]
|
76
|
+
# Color.11f #=> Color[16, 16, 240]
|
77
|
+
class Color
|
78
|
+
# Constructs a new java.awt.Color object from the given RGB values
|
79
|
+
def self.[](red, green, blue)
|
80
|
+
Java::java.awt.Color.new red.to_i, green.to_i, blue.to_i
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.method_missing(name) #:no_doc:
|
84
|
+
if Java::java.awt.Color.respond_to? name
|
85
|
+
Java::java.awt.Color.send(name)
|
86
|
+
else
|
87
|
+
name = name.to_s
|
88
|
+
if name.size == 6
|
89
|
+
r, g, b = name[0..1].hex, name[2..3].hex, name[4..5].hex
|
90
|
+
elsif name.size == 3
|
91
|
+
r, g, b = name[0..0].hex * 16, name[1..1].hex * 16, name[2..2].hex * 16
|
92
|
+
else
|
93
|
+
raise NoMethodError, "no method #{name} on Color"
|
94
|
+
end
|
95
|
+
Color[r, g, b]
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
|
101
|
+
class Button < Java::javax.swing.JButton
|
102
|
+
def initialize(text = nil)
|
103
|
+
super()
|
104
|
+
self.text = text unless text.nil?
|
105
|
+
yield self if block_given?
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
class MenuBar < Java::javax.swing.JMenuBar
|
111
|
+
def initialize(*args)
|
112
|
+
super(*args)
|
113
|
+
yield self if block_given?
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
|
118
|
+
class MenuItem < Java::javax.swing.JMenuItem
|
119
|
+
def initialize(*args)
|
120
|
+
super(*args)
|
121
|
+
yield self if block_given?
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
|
126
|
+
class Menu < Java::javax.swing.JMenu
|
127
|
+
def initialize(*args)
|
128
|
+
super(*args)
|
129
|
+
yield self if block_given?
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
|
134
|
+
class Label < Java::javax.swing.JLabel
|
135
|
+
include DefaultFont
|
136
|
+
|
137
|
+
default_font Font.new("Sans", 0, 12)
|
138
|
+
|
139
|
+
def initialize(text = nil)
|
140
|
+
super
|
141
|
+
self.text = text.to_s
|
142
|
+
self.font = Label.default_font
|
143
|
+
yield self if block_given?
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
|
148
|
+
class TextField < Java::javax.swing.JTextField
|
149
|
+
include DefaultFont
|
150
|
+
|
151
|
+
default_font Font.new("Sans", 0, 14)
|
152
|
+
|
153
|
+
def initialize(text = nil)
|
154
|
+
super
|
155
|
+
self.text = text.to_s
|
156
|
+
self.font = TextField.default_font
|
157
|
+
yield self if block_given?
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
#TODO wtf?
|
162
|
+
#irb(main):001:0> a = RPV::Swing::SwingSet::FormattedTextField.new(TimeFormatter.new)
|
163
|
+
#=> #<RPV::Swing::SwingSet::FormattedTextField:0x565902ca>
|
164
|
+
#irb(main):002:0> a.formatter
|
165
|
+
#=> #<TimeFormatter:0x6c533246 @document_filter=#<TimeDocumentFilter:0x15e193f2>, @navigation_filter=#<TimeNavigationFilter:0xcb80017>>
|
166
|
+
#irb(main):003:0> a.set_value(20)
|
167
|
+
#=> nil
|
168
|
+
#irb(main):004:0> a.formatter
|
169
|
+
#=> #<Java::JavaxSwingText::NumberFormatter:0xf4f7a86>
|
170
|
+
class FormattedTextField < Java::javax.swing.JFormattedTextField
|
171
|
+
include DefaultFont
|
172
|
+
|
173
|
+
default_font Font.new("Sans", 0, 12)
|
174
|
+
|
175
|
+
def initialize(formatter)
|
176
|
+
super()
|
177
|
+
self.formatter = formatter
|
178
|
+
self.font = FormattedTextField.default_font
|
179
|
+
yield self if block_given?
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
class LayeredPane < Java::javax.swing.JLayeredPane
|
185
|
+
def preferred_dimensions(width, height)
|
186
|
+
self.preferred_size = Dimension[width, height]
|
187
|
+
end
|
188
|
+
|
189
|
+
def add_ordered_components(*components)
|
190
|
+
components.each do |c|
|
191
|
+
self.add c
|
192
|
+
end
|
193
|
+
|
194
|
+
components.each do |c|
|
195
|
+
self.moveToFront c
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
199
|
+
|
200
|
+
|
201
|
+
class ScrollPane < Java::javax.swing.JScrollPane
|
202
|
+
def initialize(*args)
|
203
|
+
super(*args)
|
204
|
+
yield self if block_given?
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
|
209
|
+
class SplitPane < Java::javax.swing.JSplitPane
|
210
|
+
def initialize(*args)
|
211
|
+
super(*args)
|
212
|
+
yield self if block_given?
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
|
217
|
+
class TabbedPane < Java::javax.swing.JTabbedPane
|
218
|
+
def initialize(*args)
|
219
|
+
super(*args)
|
220
|
+
yield self if block_given?
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
class Panel < Java::javax.swing.JPanel
|
226
|
+
def initialize(*args)
|
227
|
+
super(*args)
|
228
|
+
yield self if block_given?
|
229
|
+
end
|
230
|
+
|
231
|
+
def preferred_dimensions(width, height)
|
232
|
+
self.preferred_size = Dimension[width, height]
|
233
|
+
end
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
class Frame < Java::javax.swing.JFrame
|
238
|
+
def initialize(*args)
|
239
|
+
super(*args)
|
240
|
+
end
|
241
|
+
|
242
|
+
def minimum_dimensions(width, height)
|
243
|
+
self.minimum_size = Dimension[width.to_i, height.to_i]
|
244
|
+
end
|
245
|
+
|
246
|
+
def preferred_dimensions(width, height)
|
247
|
+
self.preferred_size = Dimension[width, height]
|
248
|
+
end
|
249
|
+
end
|
250
|
+
end
|
251
|
+
end
|
252
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rpv/wiring/base"
|
2
|
+
|
3
|
+
module RPV
|
4
|
+
module Wiring
|
5
|
+
class JavaArrayWiring < Base
|
6
|
+
def update_view(model, view, presenter)
|
7
|
+
unless @model.nil?
|
8
|
+
send_nested(view, "#{@view}=", send_nested(model, @model).to_java)
|
9
|
+
else
|
10
|
+
send_nested(view, "#{@view}=", send_nested(presenter, @presenter).to_java)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'rpv/java/java_getters_and_setters'
|
3
|
+
|
4
|
+
describe "JavaGettersAndSetters" do
|
5
|
+
before(:all) do
|
6
|
+
@class = Class.new do
|
7
|
+
def method_missing(method, *args)
|
8
|
+
if method == :bar
|
9
|
+
self.some_internal_method
|
10
|
+
else
|
11
|
+
raise NoMethodError
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
include JavaGettersAndSetters
|
16
|
+
end
|
17
|
+
@instance = @class.new
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should alias method_missing" do
|
21
|
+
@instance.should respond_to(:method_missing_without_java_getters_and_setters)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "should call the aliased mm" do
|
25
|
+
@instance.should_receive(:some_internal_method)
|
26
|
+
@instance.bar
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should call a setter" do
|
30
|
+
@instance.should_receive(:foo_bar=).with(123)
|
31
|
+
@instance.setFooBar(123)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should call a getter" do
|
35
|
+
@instance.should_receive(:foo_bar).and_return(123)
|
36
|
+
@instance.getFooBar.should == 123
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should call a predicate" do
|
40
|
+
@instance.should_receive(:foo_bar?).and_return(true)
|
41
|
+
@instance.isFooBar.should be_true
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should raise an exception if a getter or setter is missing" do
|
45
|
+
class_without_mm = Class.new do
|
46
|
+
include JavaGettersAndSetters
|
47
|
+
end
|
48
|
+
instance = class_without_mm.new
|
49
|
+
lambda {instance.getFoo}.should raise_error(NoMethodError)
|
50
|
+
lambda {instance.setFoo}.should raise_error(NoMethodError)
|
51
|
+
lambda {instance.isFoo}.should raise_error(NoMethodError)
|
52
|
+
end
|
53
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'rpv/swing/frame_view'
|
3
|
+
|
4
|
+
describe "FrameView" do
|
5
|
+
it "should call setup_components from the constructor and pass all arguments" do
|
6
|
+
class FooFrame < RPV::Swing::FrameView
|
7
|
+
def initialize(*args)
|
8
|
+
self.should_receive(:setup_components).with(1, "bar", { :a => "b"})
|
9
|
+
super(*args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
FooFrame.new 1, "bar", :a => "b"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
require File.dirname(__FILE__) + "/../../spec_helper.rb"
|
2
|
+
require 'fileutils'
|
3
|
+
|
4
|
+
require "rpv/generators/swing/view"
|
5
|
+
|
6
|
+
describe "view generator" do
|
7
|
+
before(:all) do
|
8
|
+
FileUtils.mkdir_p 'spec/tmp'
|
9
|
+
end
|
10
|
+
|
11
|
+
after(:all) do
|
12
|
+
FileUtils.rm_r 'spec/tmp'
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should create a view and a spec" do
|
16
|
+
g = RPV::Generators::Swing::ViewGenerator.new
|
17
|
+
FileUtils.cd 'spec/tmp' do
|
18
|
+
FileUtils.rm_r 'app' if File.exists? 'app'
|
19
|
+
FileUtils.rm_r 'spec' if File.exists? 'spec'
|
20
|
+
g.execute(:to_path => '.', :name => "foo")
|
21
|
+
end
|
22
|
+
File.exists?('spec/tmp/app/views/foo_view.rb').should be_true
|
23
|
+
File.exists?('spec/tmp/spec/views/foo_view_spec.rb').should be_true
|
24
|
+
File.read('spec/tmp/app/views/foo_view.rb').should =~ /class FooView < RPV::Swing::FrameView/
|
25
|
+
File.read('spec/tmp/spec/views/foo_view_spec.rb').should =~ /describe FooView/
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should create a dialog view" do
|
29
|
+
g = RPV::Generators::Swing::ViewGenerator.new
|
30
|
+
FileUtils.cd 'spec/tmp' do
|
31
|
+
FileUtils.rm_r 'app' if File.exists? 'app'
|
32
|
+
FileUtils.rm_r 'spec' if File.exists? 'spec'
|
33
|
+
g.execute(:to_path => '.', :name => "foo", :base_class => "dialog")
|
34
|
+
end
|
35
|
+
File.read('spec/tmp/app/views/foo_view.rb').should =~ /class FooView < RPV::Swing::DialogView/
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'rpv/swing/panel_view'
|
3
|
+
|
4
|
+
describe "PanelView" do
|
5
|
+
it "should call setup_components from the constructor and pass all arguments" do
|
6
|
+
class FooPanel < RPV::Swing::PanelView
|
7
|
+
def initialize(*args)
|
8
|
+
self.should_receive(:setup_components).with(1, "bar", { :a => "b"})
|
9
|
+
super(*args)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
FooPanel.new 1, "bar", :a => "b"
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../spec_helper.rb'
|
2
|
+
require 'rpv/wiring/java_array'
|
3
|
+
|
4
|
+
describe "JavaArrayWiring" do
|
5
|
+
it "should " do
|
6
|
+
m = mock_block("model") do |m|
|
7
|
+
m.should_receive(:bar).and_return(mock_block("bar") { |b|
|
8
|
+
b.should_receive(:to_java).and_return("JavaArray")
|
9
|
+
})
|
10
|
+
end
|
11
|
+
v = mock_block("view") do |v|
|
12
|
+
v.should_receive(:foo=).with("JavaArray")
|
13
|
+
end
|
14
|
+
w = RPV::Wiring::JavaArrayWiring.new :view => "foo", :model => "bar"
|
15
|
+
w.update_view m, v, nil
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rpv_swing
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 15
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 2
|
9
|
+
version: "0.2"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Martin Vielsmaier
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-07-07 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: rpv_core
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 15
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
- 2
|
32
|
+
version: "0.2"
|
33
|
+
type: :runtime
|
34
|
+
version_requirements: *id001
|
35
|
+
description:
|
36
|
+
email: martin.vielsmaier@gmail.com
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- Rakefile
|
45
|
+
- spec/wiring/java_array_spec.rb
|
46
|
+
- spec/spec_helper.rb
|
47
|
+
- spec/java/java_getters_and_setters_spec.rb
|
48
|
+
- spec/swing/panel_view_spec.rb
|
49
|
+
- spec/swing/frame_view_spec.rb
|
50
|
+
- spec/swing/generators/view_spec.rb
|
51
|
+
- lib/rpv/wiring/java_array.rb
|
52
|
+
- lib/rpv/swing.rb
|
53
|
+
- lib/rpv/java/java_getters_and_setters.rb
|
54
|
+
- lib/rpv/swing/dialog_view.rb
|
55
|
+
- lib/rpv/swing/frame_view.rb
|
56
|
+
- lib/rpv/swing/event_handler_mixin.rb
|
57
|
+
- lib/rpv/swing/swingset.rb
|
58
|
+
- lib/rpv/swing/panel_view.rb
|
59
|
+
- lib/rpv/swing/events.rb
|
60
|
+
- lib/rpv/generators/swing/templates/view/view_spec.rb.erb
|
61
|
+
- lib/rpv/generators/swing/templates/view/view.rb.erb
|
62
|
+
- lib/rpv/generators/swing/view_generator.rb
|
63
|
+
has_rdoc: true
|
64
|
+
homepage: http://moserei.de
|
65
|
+
licenses: []
|
66
|
+
|
67
|
+
post_install_message:
|
68
|
+
rdoc_options: []
|
69
|
+
|
70
|
+
require_paths:
|
71
|
+
- lib
|
72
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
hash: 3
|
78
|
+
segments:
|
79
|
+
- 0
|
80
|
+
version: "0"
|
81
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
82
|
+
none: false
|
83
|
+
requirements:
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
hash: 3
|
87
|
+
segments:
|
88
|
+
- 0
|
89
|
+
version: "0"
|
90
|
+
requirements:
|
91
|
+
- JRUBY
|
92
|
+
rubyforge_project:
|
93
|
+
rubygems_version: 1.3.7
|
94
|
+
signing_key:
|
95
|
+
specification_version: 3
|
96
|
+
summary: A GUI framework for Swing & RPV
|
97
|
+
test_files: []
|
98
|
+
|