Simple Sprite Editor in J

Lobsters Hottest Tools

Summary

This article introduces how to build a simple sprite editor in the J language, covering window management, grid drawing, keyboard shortcuts, mouse drawing, and palette customization, demonstrating the core techniques of interactive graphics programs.

<p><a href="https://lobste.rs/s/eitko7/simple_sprite_editor_j">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 05/31/26, 02:15 AM

TL;DR: This article walks through building a simple sprite editor in J, covering window management, grid drawing, keyboard shortcuts, mouse painting, and a customizable palette. ## Setup: Window & Close Handler Every J GUI program starts with a window close handler. Name the window `gpw` (short for grid pad window). When the close button is clicked, J automatically looks for the `gpw_close` function. The handler does not close the window automatically, allowing confirmation, save, etc. Here, we simply use window driver commands to select and close the window: ``j wd 'parent select gpw parent close' wd 'timer 0' `` Below, the `power` conjunction controls the number of runs; `wd 'parent'` returns 0 or 1 indicating whether the window exists. If it does, the old window is closed. ## Window Layout & Rendering Use `wd` with window driver commands to set up the interface. Use the `bin` command to group controls horizontally or vertically, creating a left palette, right canvas, and an invisible bottom status bar. After the layout, define the `render` function: ``j render =: 3 : 0 bm img;image wd 'psel ', gpw ) `` Here we import `viewmat`, call `bm` to draw the image matrix into the child control, and pass the parent name `gpw` to ensure the drawing target is correct. After that, call `render` every 100 milliseconds (via a timer); in the palette, redraw only explicitly after changes. ## Drawing the Grid Add grid drawing logic inside `render`. Get height and width from the image shape, query the canvas control's viewport dimensions, compute the cell size, then generate line positions row by row and column by column: ``j grid =: 3 : 0 shape =. $image 'w h' =. >3{ wd 'qchildxywhx ', img cellsize =. (w,h) % |. shape ... ) `` Both horizontal and vertical lines are drawn using `glqchild` to get viewport dimensions; `+0.5 <.` rounds to exact coordinates. When placing window height as the last item of a list, use the tilde `~` to swap argument order, making it a verb. Grid display is controlled by keyboard shortcuts (see next section). ## Keyboard Shortcuts Each control has its own keyboard event handler. Naming convention: `gpw_pal_char` and `gpw_image_char` both bind to the same verb, so the keyboard responds no matter which control has focus. The event data `sysdata` contains the ASCII character of the key pressed. Define shortcuts: - **G**: Toggle grid display (`grid =: -. grid`) - **R**: Generate a random 32×32 24‑bit color grid (8 bits each for red, green, blue) - **N**: Reset all pixels to 0 (black, new image) Because the canvas redraws 10 times per second, holding R creates an animation effect. ## Mouse Interaction: Coordinate Mapping & Drawing ### Getting Mouse Coordinates Define the `mmove` event handler (canvas‑specific). The `sysdata` string contains mouse event information; parse it — the first two numbers are x and y coordinates relative to the control's top‑left corner. ### Mapping to Array Indices Define `cellsize` by querying the canvas's width and height divided by the image shape (remember the array shape is “height then width”, so reverse). `whichbox` takes the first two coordinates from `sysdata`, divides by `cellsize`, floors, and reverses the coordinate order (screen coordinates → array indices). ``j whichbox =: (|.@:<.@:(%~ |.))~ `` Effect: as the mouse moves up/down, the first coordinate (array row index) changes; the second is the column. ### Click to Draw In the left‑button up event `mblup`, call the `mousedraw` verb. `mousedraw` uses the `amend` adverb (curly braces `{`) to modify the image: insert the current pen color (hex value) at the specified coordinates. Important: a single coordinate must be boxed (`<`) because J would otherwise treat a 2D array index as a 1D index (processed row‑wise). For example, `4 2 8` would modify entire rows 4 and 28. Correct approach: ``j mousedraw =: 3 : 0 image =: pen (< y) } image ) `` ## Continuous Drawing & Bounds Checking To support continuous drawing while holding down the mouse button, check in the `mousemove` handler whether the left button is pressed (the fourth element of `sysdata`). If pressed, pass the coordinates to `mousedraw`. When dragging outside the canvas, mouse events still report out‑of‑range coordinates, causing array index errors. Add bounds checking: ``j inbounds =: 4 : ' *./ (0<:x) *. (x < y)' `` Wrap the `mousedraw` call with `inbounds image` to ensure the coordinate is ≥0 and < the corresponding size in each dimension. ## Palette & Color Selection The palette is a one‑dimensional array of colors, defaulting to the 16‑color ZZT art standard from the 1990s. For vertical rendering, use `,.` to turn each element into a separate row (2D array). Define a palette drawing event handler, but do not attach it to the timer — it only takes effect when the window redraws. The pen color is stored in the variable `pen` (a palette index). Update `mousedraw` to use `pen` instead of a fixed value, enabling drawing with different colors. ## Summary This article demonstrates building a basic sprite editor in J with full functionality. From window management, rendering, mouse and keyboard event handling, to a custom palette, it covers the core techniques for creating interactive graphical programs. The code can be run directly in the J environment and serves as a foundation for further development. Source: [YouTube video link (https://www.youtube.com/watch?v=CzK2SazvCxM)](https://www.youtube.com/watch?v=CzK2SazvCxM)

Similar Articles

@0xQiYan: Still drawing architecture diagrams manually? Dragging and tweaking for half a day? Bookmark this! Today I have to recommend this skill—I recently installed `drawio-skill`, and with just one sentence it can generate professional diagrams, no more drawing by hand. The logic is very simple: just speak naturally (e.g., "draw a trading system architecture diagram"), and it generates the diagram directly...

X AI KOLs Timeline

Introducing the drawio-skill tool, which generates professional diagrams such as architecture diagrams, flowcharts, ER diagrams, etc., based on natural language descriptions. It supports multi-round iteration and export to various formats, significantly improving diagramming efficiency.

@VincentLogic: Discovered an amazing tool for scientific visualization! nature-skills lets you create Nature-level figures using matplotlib. It handles multi-panel layouts, color schemes, fonts, and typography seamlessly, directly exporting editable SVGs. Comes with 5 built-in Nature-style template examples, supporting bar…

X AI KOLs Timeline

nature-skills is a scientific visualization tool based on matplotlib. It features built-in Nature-style templates, supports various chart types, and outputs editable SVG format, aiming to streamline the figure creation process for scientific papers.

@VincentLogic: A widely recognized animation tool in the frontend community, 68K stars are no exaggeration! anime.js – a lightweight but incredibly powerful JavaScript animation engine. Frontend devs, you're in for a treat; it's like the Swiss Army knife for animators: all-rounder, whether it's CSS…

X AI KOLs Timeline

Anime.js is a lightweight yet powerful JavaScript animation engine that supports CSS, SVG, DOM attributes, and JavaScript object animation. It features an intuitive API, timeline system, scroll observer, drag-and-drop, and responsive animations. With 68K stars on GitHub, it's a go-to tool for frontend developers and interaction designers.

@VincentLogic: Found an incredible open-source desktop AI tool from ByteDance! UI-TARS Desktop, with 31k stars, truly lives up to the hype. It can actually understand your screen and automate computer operations for you. Just tell it "Enable auto-save in VS Code and set the delay to 500ms", and it will automatically: -…

X AI KOLs Timeline

ByteDance's open-source desktop AI automation tool, UI-TARS Desktop, supports local execution and screen visual understanding. It can autonomously control your computer to handle daily tasks through natural language commands.