Is it possible to use Java Lambdas to implement something like Groovy's SwingBuilder? -
it occurred me lambdas might possible build swingbuilder in native java--but seems if possible have been done now.
is there reason couldn't done, or has been done?
i realize similar swingbuilder gui syntax java?, hoping add lambdas mix. swingbuilder built on lambdas absolutely wasn't possible before java 8. uses bit of dynamic programming , can't used won't ever clean, think it's possible...
first, have identify issues want solve. biggest issue creation of simple event bindings needed use of inner classes in previous java versions. can replaced lambda expression single-method listener interfaces in cases, multi-method interfaces, you’d need adapters, discussed in this or that q&a, has done once.
the other issue structure of initialization code. in principle, imperative code works fine, if want modify properties of component you’re going add container, have change container.add(new componenttype());
introduce new local variable used subsequent statements. also, adding container requires keep in variable. while java allows limit scope of local variables curly braces, result still clumsy.
this best starting point. if use, e.g.
public class swingbuilder { public static <t> t build(t instance, consumer<t> prepare) { prepare.accept(instance); return instance; } public static <t extends container> t build( t instance, consumer<t> prepare, component... ch) { return build(build(instance, prepare), ch); } public static <t extends container> t build(t instance, component... ch) { for(component c: ch) instance.add(c); return instance; } }
these simple generic methods quiet powerful due fact can combined. using import static
, use site can like
jframe frame = build(new jframe("example"), f -> { f.getcontentpane().setlayout( new boxlayout(f.getcontentpane(), boxlayout.line_axis)); f.setresizable(false); f.setdefaultcloseoperation(jframe.exit_on_close); }, build(new jlabel("\u263a"), l -> l.setfont(l.getfont().derivefont(36f))), box.createhorizontalstrut(16), build(new jpanel(new gridlayout(0, 1, 0, 5)), new jlabel("hello world"), build(new jbutton("close"), b -> { b.addactionlistener(ev -> system.exit(0)); }) ) ); frame.pack(); frame.setvisible(true);
compared groovy, still have use variable express target of method invocations change properties, these variable can declared simple name ->
using type inference when implementing consumer
via lambda expression. also, variable’s scope automatically limited duration of initialization.
using starting point, may add specialized method used components and/or used properties, mentioned factory methods multi-method listeners. e.g.
public static jframe frame(string title, consumer<windowevent> closingaction, consumer<? super jframe> prepare, component... contents) { jframe f = new jframe(title); if(closingaction!=null) f.addwindowlistener(new windowadapter() { @override public void windowclosing(windowevent e) { closingaction.accept(e); } }); if(prepare!=null) prepare.accept(f); final container target = f.getcontentpane(); if(contents.length==1) target.add(contents[0], borderlayout.center); else { target.setlayout(new boxlayout(target, boxlayout.page_axis)); for(component c: contents) target.add(c); } return f; }
but think, picture clear.
Comments
Post a Comment