changeset 1869:e561174a8f69

swing
author Franklin Schmidt <fschmidt@gmail.com>
date Wed, 02 Apr 2025 17:41:21 -0600
parents 03209933fe4a
children e3a8568a11be
files src/luan/modules/swing/Document.luan src/luan/modules/swing/JUndo.java src/luan/modules/swing/SwingLuan.java src/luan/modules/swing/Text_component.luan src/luan/modules/swing/Utils.luan
diffstat 5 files changed, 109 insertions(+), 6 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/modules/swing/Document.luan	Wed Apr 02 17:41:21 2025 -0600
@@ -0,0 +1,24 @@
+local Luan = require "luan:Luan.luan"
+local error = Luan.error
+require "java"
+local JUndo = require "java:luan.modules.swing.JUndo"
+local Logging = require "luan:logging/Logging.luan"
+local logger = Logging.logger "swing/Document"
+
+
+local Document = {}
+
+function Document.new(jdocument)
+	local document = { java = jdocument }
+	local undo = JUndo.new()
+	jdocument.addUndoableEditListener(undo)
+	jdocument.putProperty("undo",undo.manager);
+	document.undo = undo.manager.undo
+	document.redo = undo.manager.redo
+	document.can_undo = undo.manager.canUndo
+	document.can_redo = undo.manager.canRedo
+	document.add_undoable_edit_listener = undo.addListener
+	return document
+end
+
+return Document
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/luan/modules/swing/JUndo.java	Wed Apr 02 17:41:21 2025 -0600
@@ -0,0 +1,36 @@
+package luan.modules.swing;
+
+import java.util.WeakHashMap;
+import javax.swing.event.UndoableEditListener;
+import javax.swing.event.UndoableEditEvent;
+import javax.swing.undo.UndoManager;
+import luan.Luan;
+import luan.LuanFunction;
+import luan.LuanException;
+import luan.LuanRuntimeException;
+
+
+public final class JUndo implements UndoableEditListener {
+	public final UndoManager manager = new UndoManager();
+	private final WeakHashMap<LuanFunction,Boolean> map = new WeakHashMap<LuanFunction,Boolean>();
+	private final Luan luan;
+
+	public JUndo(Luan luan) {
+		this.luan = luan;
+	}
+
+	@Override public void undoableEditHappened(UndoableEditEvent event) {
+		manager.addEdit(event.getEdit());
+		for( LuanFunction fn : map.keySet() ) {
+			try {
+				fn.call(luan);
+			} catch(LuanException e) {
+				throw new LuanRuntimeException(e);
+			}
+		}
+	}
+
+	public void addListener(LuanFunction fn) {
+		map.put(fn,Boolean.TRUE);
+	}
+}
--- a/src/luan/modules/swing/SwingLuan.java	Mon Mar 31 22:36:08 2025 -0600
+++ b/src/luan/modules/swing/SwingLuan.java	Wed Apr 02 17:41:21 2025 -0600
@@ -2,7 +2,13 @@
 
 import javax.swing.SwingUtilities;
 import javax.swing.UIManager;
+import javax.swing.KeyStroke;
+import javax.swing.Action;
+import javax.swing.AbstractAction;
 import javax.swing.UnsupportedLookAndFeelException;
+import javax.swing.text.JTextComponent;
+import javax.swing.text.Document;
+import javax.swing.undo.UndoManager;
 import java.awt.event.ActionListener;
 import java.awt.event.ActionEvent;
 import java.awt.event.WindowListener;
@@ -12,6 +18,7 @@
 import luan.LuanFunction;
 //import luan.LuanMutable;
 import luan.LuanException;
+import luan.LuanRuntimeException;
 
 
 public final class SwingLuan {
@@ -41,7 +48,7 @@
 				try {
 					fn.call(luan);
 				} catch(LuanException e) {
-					e.printStackTrace();
+					throw new LuanRuntimeException(e);
 				}
 			}
 		};
@@ -59,7 +66,7 @@
 				try {
 					fn.call(luan);
 				} catch(LuanException e) {
-					e.printStackTrace();
+					throw new LuanRuntimeException(e);
 				}
 			}
 			@Override public void actionPerformed(ActionEvent e) {
@@ -74,7 +81,7 @@
 				try {
 					fn.call(luan);
 				} catch(LuanException e) {
-					e.printStackTrace();
+					throw new LuanRuntimeException(e);
 				}
 			}
 			@Override public void windowClosed(WindowEvent e) {
@@ -82,4 +89,26 @@
 			}
 		};
 	}
+
+	public static void fixTextComponent(final JTextComponent tc) {
+		tc.getInputMap().put(KeyStroke.getKeyStroke("meta Z"),"undo");
+		Action undoAction = new AbstractAction() {
+			@Override public void actionPerformed(ActionEvent e) {
+				UndoManager undoManager = (UndoManager)tc.getDocument().getProperty("undo");
+				if( undoManager.canUndo() )
+					undoManager.undo();
+			}
+		};
+		tc.getActionMap().put("undo",undoAction);
+
+		tc.getInputMap().put(KeyStroke.getKeyStroke("shift meta Z"),"redo");
+		Action redoAction = new AbstractAction() {
+			@Override public void actionPerformed(ActionEvent e) {
+				UndoManager undoManager = (UndoManager)tc.getDocument().getProperty("undo");
+				if( undoManager.canRedo() )
+					undoManager.redo();
+			}
+		};
+		tc.getActionMap().put("redo",redoAction);
+	}
 }
--- a/src/luan/modules/swing/Text_component.luan	Mon Mar 31 22:36:08 2025 -0600
+++ b/src/luan/modules/swing/Text_component.luan	Wed Apr 02 17:41:21 2025 -0600
@@ -1,9 +1,15 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
+local raw_set = Luan.raw_set or error()
 local Utils = require "luan:swing/Utils.luan"
 local fail = Utils.fail or error()
 local new_component = require("luan:swing/Component.luan").new or error()
+local new_document = require("luan:swing/Document.luan").new or error()
 require "java"
+local SwingLuan = require "java:luan.modules.swing.SwingLuan"
+local fixTextComponent = SwingLuan.fixTextComponent
+local Logging = require "luan:logging/Logging.luan"
+local logger = Logging.logger "swing/Text_component"
 
 
 local Text_component = {}
@@ -13,7 +19,9 @@
 		return text_component.java.getText()
 	end
 	if key == "document" then
-		return text_component.java.getDocument()
+		local document = new_document(text_component.java.getDocument())
+		raw_set(text_component,"document",document)
+		return document
 	end
 	if key == "caret_position" then
 		return text_component.java.getCaretPosition()
@@ -27,7 +35,8 @@
 		return
 	end
 	if key == "document" then
-		text_component.java.setDocument(value)
+		text_component.java.setDocument(value.java)
+		raw_set(text_component,"document",value)
 		return
 	end
 	if key == "caret_position" then
@@ -40,6 +49,7 @@
 function Text_component.new(component)
 	new_component(component)
 	local jcomponent = component.java
+	fixTextComponent(jcomponent)
 	component.cut = jcomponent.cut
 	component.copy = jcomponent.copy
 	component.paste = jcomponent.paste
--- a/src/luan/modules/swing/Utils.luan	Mon Mar 31 22:36:08 2025 -0600
+++ b/src/luan/modules/swing/Utils.luan	Wed Apr 02 17:41:21 2025 -0600
@@ -1,5 +1,6 @@
 local Luan = require "luan:Luan.luan"
 local error = Luan.error
+local raw_set = Luan.raw_set or error()
 
 
 local Utils = {}
@@ -21,7 +22,10 @@
 
 	function mt.__new_index(t,key,value)
 		local rtn = __new_index(t,key,value)
-		rtn ~= fail or error("'"..key.."' not defined")
+		-- rtn ~= fail or error("'"..key.."' not defined")
+		if rtn == fail then
+			raw_set(t,key,value)
+		end
 	end
 
 	return mt