rpv_swing 0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|