changeset 1895:091b503f511c default tip

swing
author Franklin Schmidt <fschmidt@gmail.com>
date Sun, 13 Apr 2025 16:50:41 -0600
parents 801e1fe227f9
children
files src/luan/modules/swing/TextFieldLuan.java src/luan/modules/swing/Text_component.luan src/luan/modules/swing/Text_field.luan
diffstat 3 files changed, 58 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/modules/swing/TextFieldLuan.java	Sun Apr 13 16:50:41 2025 -0600
@@ -0,0 +1,49 @@
+package luan.modules.swing;
+
+import java.awt.Rectangle;
+import java.awt.Graphics;
+import java.awt.Color;
+import javax.swing.JTextField;
+import javax.swing.text.BadLocationException;
+import goodjava.logging.Logger;
+import goodjava.logging.LoggerFactory;
+
+
+public class TextFieldLuan extends JTextField {
+	private static final Logger logger = LoggerFactory.getLogger(TextFieldLuan.class);
+
+	private boolean showWhitespace = false;
+
+	public void showWhitespace(boolean showWhitespace) {
+		this.showWhitespace = showWhitespace;
+		repaint();
+	}
+
+	@Override protected void paintComponent(Graphics g) {
+		super.paintComponent(g);
+		if( !showWhitespace )
+			return;
+		g.setColor(Color.LIGHT_GRAY);
+		String text = getText();
+		int ascent = g.getFontMetrics().getAscent();
+		Rectangle visible = getVisibleRect();
+		for( int pos=0; pos<text.length(); pos++ ) {
+			char ch = text.charAt(pos);
+			String symbol;
+			switch(ch) {
+				case ' ': symbol = "·"; break;
+				case '\t': symbol = "→"; break;
+				case '\n': symbol = "¶"; break;
+				default: continue;
+			}
+			Rectangle r;
+			try {
+				r = modelToView(pos);
+			} catch(BadLocationException e) {
+				throw new RuntimeException(e);
+			}
+			if( visible.contains(r)	)
+				g.drawString( symbol, r.x, r.y + ascent );
+		}
+	}
+}
--- a/src/luan/modules/swing/Text_component.luan	Sun Apr 13 16:01:33 2025 -0600
+++ b/src/luan/modules/swing/Text_component.luan	Sun Apr 13 16:50:41 2025 -0600
@@ -4,6 +4,7 @@
 local stringify = Luan.stringify or error()
 local Utils = require "luan:swing/Utils.luan"
 local fail = Utils.fail or error()
+local make_metatable = Utils.make_metatable or error()
 local Component = require "luan:swing/Component.luan"
 local super__index = Component.__index or error()
 local super__new_index = Component.__new_index or error()
@@ -47,6 +48,8 @@
 	return fail
 end
 
+Text_component.mt = make_metatable(Text_component)
+
 function Text_component.construct(component,props)
 	super_construct(component,props)
 	local jcomponent = component.java
--- a/src/luan/modules/swing/Text_field.luan	Sun Apr 13 16:01:33 2025 -0600
+++ b/src/luan/modules/swing/Text_field.luan	Sun Apr 13 16:50:41 2025 -0600
@@ -2,23 +2,21 @@
 local error = Luan.error
 local set_metatable = Luan.set_metatable or error()
 local Utils = require "luan:swing/Utils.luan"
-local make_metatable = Utils.make_metatable or error()
 local delete = Utils.delete or error()
 local check_empty = Utils.check_empty or error()
 local Text_component = require("luan:swing/Text_component.luan")
 local super_construct = Text_component.construct or error()
+local super_mt = Text_component.mt or error()
 require "java"
-local JTextField = require "java:javax.swing.JTextField"
+local TextFieldLuan = require "java:luan.modules.swing.TextFieldLuan"
 local SwingLuan = require "java:luan.modules.swing.SwingLuan"
 local newActionListener = SwingLuan.newActionListener
 
 
 local Text_field = {}
 
-local mt = make_metatable(Text_component)
-
 function Text_field.new(props)
-	local jtext_field = JTextField.new()
+	local jtext_field = TextFieldLuan.new()
 	local text_field = { java = jtext_field }
 	super_construct(text_field,props)
 	local columns = delete(props,"columns")
@@ -27,8 +25,10 @@
 	if action~=nil then jtext_field.setActionCommand(action) end
 	local action_listener = delete(props,"action_listener")
 	if action_listener~=nil then jtext_field.addActionListener(newActionListener(action_listener)) end
+	local show_whitespace = delete(props,"show_whitespace")
+	if show_whitespace~=nil then jtext_field.showWhitespace(show_whitespace) end
 	check_empty(props)
-	set_metatable(text_field,mt)
+	set_metatable(text_field,super_mt)
 	return text_field
 end