Mercurial Hosting > luan
changeset 1872:29a1e9bde185
swing
author | Franklin Schmidt <fschmidt@gmail.com> |
---|---|
date | Thu, 03 Apr 2025 14:33:37 -0600 |
parents | 299331f3fcba |
children | cf38353d77bd |
files | src/luan/modules/swing/Component.luan src/luan/modules/swing/List.luan src/luan/modules/swing/Menu.luan src/luan/modules/swing/TextAreaLineNumbers.java src/luan/modules/swing/Utils.luan src/luan/modules/swing/WeakDocumentListener.java |
diffstat | 6 files changed, 122 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/src/luan/modules/swing/Component.luan Thu Apr 03 08:46:30 2025 -0600 +++ b/src/luan/modules/swing/Component.luan Thu Apr 03 14:33:37 2025 -0600 @@ -17,6 +17,10 @@ end jcomponent.setFont(font) end + component._dont_gc = {} + function component.dont_gc(obj) + component._dont_gc[obj] = true + end return component end
--- a/src/luan/modules/swing/List.luan Thu Apr 03 08:46:30 2025 -0600 +++ b/src/luan/modules/swing/List.luan Thu Apr 03 14:33:37 2025 -0600 @@ -1,37 +1,55 @@ local Luan = require "luan:Luan.luan" local error = Luan.error local set_metatable = Luan.set_metatable 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 = Component.new or error() require "java" local JList = require "java:javax.swing.JList" local DefaultListModel = require "java:javax.swing.DefaultListModel" +local TextAreaLineNumbers = require "java:luan.modules.swing.TextAreaLineNumbers" local List = {} -local mt = {} - -function mt.__index(list,key) +function List.__index(list,key) if key == "size" then return list.model.getSize() end - error("'"..key.."' not defined") + return fail end -function mt.__new_index(list,key,value) - if key == "size" then - list.model.setSize(value) - return +function List.__new_index(list,key,value) + local model = list.model + if model.instanceof(DefaultListModel) then + if key == "size" then + list.model.setSize(value) + return + end end - error("'"..key.."' not defined") + return fail end -function List.new() - local model = DefaultListModel.new() +local mt = make_metatable(List) + +local function new(model) local jlist = JList.new(model) - local list = { java=jlist, model=model } - list.add_element = model.addElement + local list = { java = jlist, model = model } + if model.instanceof(DefaultListModel) then + list.add_element = model.addElement + end set_metatable(list,mt) return list end +function List.new_default_list() + return new(DefaultListModel.new()) +end + +function List.new_text_area_line_numbers(text_area) + return new(TextAreaLineNumbers.new(text_area.java)) +end + return List
--- a/src/luan/modules/swing/Menu.luan Thu Apr 03 08:46:30 2025 -0600 +++ b/src/luan/modules/swing/Menu.luan Thu Apr 03 14:33:37 2025 -0600 @@ -20,11 +20,11 @@ function Menu.new() local jmenu = JMenu.new() local menu = { java = jmenu } - super(menu) menu.add_separator = jmenu.addSeparator function menu.add(menu_item) jmenu.add(menu_item.java) end + super(menu) set_metatable(menu,mt) return menu end
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/swing/TextAreaLineNumbers.java Thu Apr 03 14:33:37 2025 -0600 @@ -0,0 +1,46 @@ +package luan.modules.swing; + +import javax.swing.AbstractListModel; +import javax.swing.JTextArea; +import javax.swing.event.DocumentListener; +import javax.swing.event.DocumentEvent; + + +public final class TextAreaLineNumbers extends AbstractListModel<Integer> implements DocumentListener { + private final JTextArea textArea; + private int lines; + + public TextAreaLineNumbers(JTextArea textArea) { + this.textArea = textArea; + this.lines = textArea.getLineCount(); + textArea.getDocument().addDocumentListener(new WeakDocumentListener(this)); + } + + @Override public Integer getElementAt(int index) { + return index + 1; + } + + @Override public int getSize() { + return lines; + } + + @Override public void changedUpdate(DocumentEvent e) { + int n = textArea.getLineCount(); + if( lines < n ) { + fireIntervalAdded(e.getDocument(),lines,n-1); + lines = n; + } else if( lines > n ) { + fireIntervalRemoved(e.getDocument(),n,lines-1); + lines = n; + } + } + + @Override public void removeUpdate(DocumentEvent e) { + changedUpdate(e); + } + + @Override public void insertUpdate(DocumentEvent e) { + changedUpdate(e); + } + +}
--- a/src/luan/modules/swing/Utils.luan Thu Apr 03 08:46:30 2025 -0600 +++ b/src/luan/modules/swing/Utils.luan Thu Apr 03 14:33:37 2025 -0600 @@ -22,10 +22,7 @@ function mt.__new_index(t,key,value) local rtn = __new_index(t,key,value) - -- rtn ~= fail or error("'"..key.."' not defined") - if rtn == fail then - raw_set(t,key,value) - end + rtn ~= fail or error("'"..key.."' not defined") end return mt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/luan/modules/swing/WeakDocumentListener.java Thu Apr 03 14:33:37 2025 -0600 @@ -0,0 +1,39 @@ +package luan.modules.swing; + +import java.lang.ref.WeakReference; +import javax.swing.event.DocumentListener; +import javax.swing.event.DocumentEvent; + + +public final class WeakDocumentListener implements DocumentListener { + private final WeakReference<DocumentListener> ref; + + public WeakDocumentListener(DocumentListener dl) { + ref = new WeakReference<DocumentListener>(dl); + } + + private DocumentListener get(DocumentEvent e) { + DocumentListener dl = ref.get(); + if( dl==null ) + e.getDocument().removeDocumentListener(this); + return dl; + } + + @Override public void changedUpdate(DocumentEvent e) { + DocumentListener dl = get(e); + if( dl != null ) + dl.changedUpdate(e); + } + + @Override public void removeUpdate(DocumentEvent e) { + DocumentListener dl = get(e); + if( dl != null ) + dl.removeUpdate(e); + } + + @Override public void insertUpdate(DocumentEvent e) { + DocumentListener dl = get(e); + if( dl != null ) + dl.insertUpdate(e); + } +}