JDOR (Java drawing for ooRexx) is a Rexx command handler (implemented in Java taking advantage of BSF4ooRexx850 and later) that makes Java's 2D functionality available to Rexx programmers via commands that simplify the interaction, yet allow for creating the most challenging graphics (images) from Rexx.
Example "jdor_doc_sample.rex":
jdor=.bsf~new("org.oorexx.handlers.jdor.JavaDrawingHandler") -- create a JDOR handler call BsfCommandHandler "add", "JDOR", jdor -- add the JDOR handler to ooRexx address JDOR -- set default environment to the JDOR command handler -- now we may use JDOR commands, executed by default by the JDOR command handler width =220 -- define width of image in pixels (there are 72 px to an inch) height=250 -- define height of image in pixels (there are 72 px to an inch) newImage width height -- create new bitmap with currX=0, currY=0, width=220, height=250 winShow -- show frame on screen -- draw two lines forming a big X drawLine (width-1) (height-1) -- from currX=0, currY=0 color red -- set the color to red (preregistered with nickname "RED") moveTo (width-1) 0 -- currX=219, currY=0 position -- query current position say "--> rc="pp(rc) -- RC refers to the previous command's result: "219 0" (currX=219, currY=0) drawLine 0 (height-1) -- from currX=219, currY=0 -- draw a rectangle at the center of the bitmap len = 50 -- drawing a rectangle with each side being 50 px (a square) moveTo (width-len)/2 (height-len)/2 -- go to the center minus half of the square's side lengths color green -- set color to green (preregistered with nickname "GREEN") fillRect len len -- fill the square with the green color stroke str3 3 -- set line stroke to 3 points width, store it with nickname "STR3" color blue -- set color to blue (preregistered with nickname "BLUE") drawRect len len -- draw the frame with the blue color -- draw a string (text) at the lower half of the bitmap color somePurple 127 46 111 -- define a custom RGB color, store it with nickname "SOMEPURPLE" color -- query current color say "--> rc="pp(rc) -- show result from command (a Java color object) say " rc~toString:" pp(rc~toString) -- shows the RGB intensities of the current color -- draw three lines of centered strings at the bottom lineHeight = 15 -- default font size is 12px, add 3 px lead newY=height-40 -- draw the three strings at the bottom clrs=("somePurple", "blue", "gray") -- define three different colors text=("Hello, Rexx world ...", "... from JDOR ...", "(a Rexx command handler)") -- array of 3 strings do counter c i=0 to 30 by lineHeight -- iterate over array of strings s=text[c] -- fetch the string to draw from array stringBounds s -- get the bounding box dimensions for this string parse var rc . . w . -- parse the width of the string's bounding box moveTo (width-w)/2 (newY+i) -- calc x position to center this string, set y position color clrs[c] -- fetch and use the color from the array drawString s -- draw the string end -- save the current image saveImage "jdor_doc_sample.png" -- save image to file "jdor_doc_sample.png" sleep 3.123 -- sleep for 3.123 seconds ::requires "BSF.CLS" -- get ooRexx-Java bridge, contains JDOR Rexx command handler
--> rc=[219 0] --> rc=[java.awt.Color@5fa7e7ff] rc~toString: [java.awt.Color[r=127,g=46,b=111]]and create and save the following image (bitmap) using as filename "jdor_doc_sample.png":
The JDOR Rexx command handler makes Java2D functionality available to Rexx programmers. The commands are formed after the methods in the java.awt.Graphics and java.awt.Graphics2D Java classes. The only difference is that the x and y co-ordinates used by many methods as their first two arguments are handled differently. The Rexx programmer defines these co-ordinates with the moveTo x y command preceding command and they are therefore omitted from the Rexx commands matching the Java method names.
Many methods in the classes Graphis[2D] expect arguments to be integers. To ease programming argument values that may be calculated (e.g. x or y positions, width, height, ...) and yield decimal numbers will get rounded to integer values by JDOR.
Hint: using the redirection option of the Rexx ADDRESS keyword instruction (i.e., its WITH subkeyword with the redirection definitions) has the following effects:
ADDRESS JDOR WITH using input (.input) /* activate input redirection */Note: you need to supply at least one command (e.g. a comment command like
"-- some comment"
) to the command handler
such that it gets invoked and becomes able to note that input is redirected, such
that it takes the commands from the redirected input.
ADDRESS JDOR WITH using output (.output) /* activate output redirection */
ADDRESS JDOR WITH using error (.error) /* activate error redirection */In addition ooRexx will communicate the result of executing a command by setting the environment symbol .RS (value 0 indicates successful completion, -1 indicates a failure and 1 indicates an error).
ADDRESS JDOR /* all unqualified commands should go to this handler */
The ADDRESS keyword instruction is documented in the ooRexx reference book (rexxref.pdf) in "Chapter 2. Keyword Instructions", section "2.1 ADDRESS").
To Rexx programmers the following JDOR related materials may be helpful:
For the newcomer the following Java 2D related tutorial may be helpful (as of 2022-09-29):
-
(dash),
;
(semi colon),
/
(slash),
"
(double quote),
'
(single quote),
.
(dot),
:
(colon),
!
(exclamation mark),
?
(question mark),
_
(underscore). Therefore it is sufficient to prefix a command with one
of these characters in order to turn it into "comment command".
In general the arguments to a command are blank delimited. If supplying a Rexx variable, its referred to value will be supplied, if using a Rexx expression it will be evaluated and the resulting value will be supplied to the Rexx command handler.
If you wish to supply the name of a Rexx variable to a command (e.g. for the commands drawPolygon, drawPolyline, fillPolygon or getState) then make sure to enquote that variable name as otherwise its value gets supplied instead.
Commands need not be enquoted, unless their names collide with Rexx keyword names (which at the time of writing does not happen) or are used as Rexx variable names in your program.
Unquoted literals will be uppercased according to the Rexx rules and then supplied to the command handler. If commands or arguments are unquoted then they get uppercased as well and blanks between them will be reduced to a single blank according to the Rexx rules before supplying the resulting command with arguments to the Rexx command handler.
Hint: in general any command that allows for querying and setting a value will return the current value and in the case of setting it to a new value will return the old (previously current) value.
Command | Argument(s) | Description | ||
---|---|---|---|---|
"areaAdd"
"areaUnion" | The constructive area geometry (CAG) "add" operation, cf. Constructing Complex Shapes from Geometry Primitives. The shapeNickName argument gets uppercased and used to look it up in the shape registry or if not found from a Rexx variable of the same name and uses that shape instead. | |||
areaNickName shapeNickName | areaNickName the registered area shape that will be changed by adding the area of the shapeNickName as the argument. If shapeNickName is not yet of type java.awt.geom.Area then an Area gets created from it and used as the argument. | |||
"areaExclusiveOr"
"areaXor" | The constructive area geometry (CAG) "exclusiveOr" operation, cf. Constructing Complex Shapes from Geometry Primitives. The shapeNickName argument gets uppercased and used to look it up in the shape registry or if not found from a Rexx variable of the same name and uses that shape instead. | |||
areaNickName shapeNickName | areaNickName the registered area shape that will be changed by applying the exclusiveOr operation using the area of the shapeNickName as the argument. If shapeNickName is not yet of type java.awt.geom.Area then an Area gets created from it and used as the argument. | |||
"areaIntersect" | The constructive area geometry (CAG) "intersect" operation, cf. Constructing Complex Shapes from Geometry Primitives. The shapeNickName argument gets uppercased and used to look it up in the shape registry or if not found from a Rexx variable of the same name and uses that shape instead. | |||
areaNickName shapeNickName | areaNickName the registered area shape that will be changed by applying the intersect operation using the area of the shapeNickName as argument. If shapeNickName is not yet of type java.awt.geom.Area then an Area gets created from it and used as the argument. | |||
"areaSubtract" | The constructive area geometry (CAG) "subtract" operation, cf. Constructing Complex Shapes from Geometry Primitives. The shapeNickName argument gets uppercased and used to look it up in the shape registry or if not found from a Rexx variable of the same name and uses that shape instead. | |||
areaNickName shapeNickName | areaNickName the registered area shape that will be changed by applying the subtract operation using the area of the shapeNickName as argument. If shapeNickName is not yet of type java.awt.geom.Area then an Area gets created from it and used as the argument. | |||
"areaTransform" | Transforms the area shape. The transformNickName argument gets uppercased and used to look it up in the transform registry or if not found from a Rexx variable of the same name and uses that transform (an AffinityTransform) instead. | |||
areaNickName transformNickName | Transforms the area shape stored under the areaNickName and applies the transform stored under the transformNickName to it. | |||
"assignRC" | Allows to assign the current value of the Rexx variable RC
(set when a command returns a value) to a Rexx variable with the supplied name.
This allows for creating self contained macros (redirecting the output will protocol the commands which can later be used for replaying those commands) that need to refer to returned values later. Note: supplying Rexx variable names to commands will supply the value the Rexx variable points to. Therefore it is advised to enquote such commands, at least the Rexx variable name argument. | |||
rexxVariableName | The name of a Rexx variable which gets the current value of the Rexx variable RC assigned to for later use. | |||
"background" | Queries and optionally sets the background color to a registered color.
Querying the current value (no argument supplied) will return it, setting (changing) the value to a new color value will return the old (previously set) value via the Rexx variable RC. Cf. the Java documentation for the Java class Graphics[2D] and the methods: getBackground(), setBackground(...). | |||
colorNickName | The name of a registered color (cf. color command) or the name of a Rexx variable referring to a color to which the background color should be set to. | |||
"clearRect" | Clears a rectangle of the supplied width and height
at the current x and y position (cf. goto command),
using the background (cf. background command) color.
Cf. the Java documentation for the Java class Graphics[2D] and the method clearRect(...). | |||
width height | width and height in pixels of the rectangle. | |||
"clip" | Queries and optionally sets a clipping area of an image. Returns a
blank delimited string with the x, y,
width and height values of the previously defined clipping rectangle (area)
or .nil if no such area was defined
via the Rexx variable RC. If a clipping area exists already,
then the intersection with it will be the new clipping area.
Cf. the Java documentation for the Java class Graphics[2D] and the methods getClipBounds(), clipRect(...). | |||
x y width height | x position on the x-axis, the y position on the y-axis, the width and the height in pixels of the rectangle. | |||
"clipRemove" | Removes clip from image, if any defined.
Cf. the Java documentation for the Java class Graphics[2D] and the method setClip(null). | |||
"color" "colour" | Query, get and set, define and set the color.
Querying the current value (no argument supplied) will return it, setting (changing) the value to a new value will return the old (previously set) value via the Rexx variable RC. Supplying only the colorNickName argument will load the color from the internal register or from a Rexx variable by that name referring to a color and assign it to the GC to be used for drawing from now on. Supplying in addition intensity (cf. RGB color or RGBA color) for the colors red, green, blue, and optionally alpha, a java.awt.Color of that type gets created, registered with the supplied colorNickName and then used for setting the new color. The command name colour is an alias, a synonym for this command. Cf. the Java documentation for the Java class Graphics[2D] and the methods getColor(), setColor(...), as well as the Java class java.awt.Color. | |||
colorNickName | colorNickName gets uppercased and is used to look up the internal
color registry for the denoted color
or the name of a Rexx variable referring to a color
which should be used from now on. The
previously defined color gets gets returned via the Rexx variable RC.
The following color names get predefined and can be directly used (cf. the constants
defined for javafx.scene.paint.Color
which show the color they represent, in addition cf. W3schools HTML color names):
AliceBlue, AntiqueWhite, Aqua, Aquamarine, Azure,
Beige, Bisque, Black, BlanchedAlmond, Blue,
BlueViolet, Brown, BurlyWood, CadetBlue, Chartreuse,
Chocolate, Coral, CornflowerBlue, Cornsilk, Crimson,
Cyan, DarkBlue, DarkCyan, DarkGoldenRod, Dark_Gray,
DarkGray, DarkGrey, DarkGreen, DarkKhaki, DarkMagenta,
DarkOliveGreen, DarkOrange, DarkOrchid, DarkRed, DarkSalmon,
DarkSeaGreen, DarkSlateBlue, DarkSlateGray, DarkSlateGrey,
DarkTurquoise, DarkViolet, DeepPink, DeepSkyBlue, DimGray,
DimGrey, DodgerBlue, FireBrick, FloralWhite, ForestGreen,
Fuchsia, Gainsboro, GhostWhite, Gold, GoldenRod,
Gray, Grey, Green, GreenYellow, HoneyDew, HotPink,
IndianRed, Indigo, Ivory, Khaki, Lavender,
LavenderBlush, LawnGreen, LemonChiffon, LightBlue,
LightCoral, LightCyan, LightGoldenRodYellow, Light_Gray,
LightGray, LightGrey, LightGreen, LightPink, LightSalmon,
LightSeaGreen, LightSkyBlue, LightSlateGray, LightSlateGrey,
LightSteelBlue, LightYellow, Lime, LimeGreen, Linen,
Magenta, Maroon, MediumAquaMarine, MediumBlue, MediumOrchid,
MediumPurple, MediumSeaGreen, MediumSlateBlue, MediumSpringGreen,
MediumTurquoise, MediumVioletRed, MidnightBlue, MintCream,
MistyRose, Moccasin, NavajoWhite, Navy, OldLace,
Olive, OliveDrab, Orange, OrangeRed, Orchid,
PaleGoldenRod, PaleGreen, PaleTurquoise, PaleVioletRed,
PapayaWhip, PeachPuff, Peru, Pink, Plum, PowderBlue,
Purple, RebeccaPurple, Red, RosyBrown, RoyalBlue,
SaddleBrown |