New: Plugin for NetBeans

173 views
Skip to first unread message

ScraM Team

unread,
Nov 29, 2020, 12:02:28 AM11/29/20
to TeaVM
I have published a NetBeans plugin for TeaVM.

Currently it follows the "do one thing and do it well" mantra.  It has one feature: hyperlinking to HTML files from @BindTemplate annotations.

Read more or download here:

vic-cw

unread,
Dec 1, 2020, 5:29:31 AM12/1/20
to TeaVM
That is great, congratulations and thanks!

Is Netbeans your IDE of choice?

ScraM Team

unread,
Dec 2, 2020, 10:27:35 PM12/2/20
to TeaVM
Thanks!  I'd be interested in what features people are looking for in a TeaVM / Flavour IDE plugin.  Please post here if you have ideas.

A few things I'm already planning to add over time:
* Template recognition of Flavour built-in components (e.g. no more red warning under 'std:foreach')
* Browser debugging integration [I'm not sure how difficult this will be]
* Flavour EL parsing in templates, with hyperlinking to methods (click on a method in an EL expression, go to the corresponding Java implementation) [Could be challenging]
* Extend refactoring to update references in EL expressions

I'm hoping that having a plugin for another IDE will further increase TeaVM's lead in the market.  I have always been impressed with Codename One's "we support every IDE" strategy, I think that must help win evaluations in enterprise shops and make it worth the substantial effort required. 

And yes, NetBeans is my IDE of choice, though I've used all of the "big 3" and find them all quite powerful.

vic-cw

unread,
Dec 3, 2020, 4:04:21 AM12/3/20
to TeaVM
I'll try to think about it. The link from a Java Component to the template is already a good feature.

I remember thinking that one thing that would be good to add to an IDE would be a shortcut and a wizard to create a component. As of now, creating a component requires several steps:
- creating a Java class
- creating a template file
- adding the Java class to META-INF/...
- and making sure that the path in the Java class is the path of the template file

I was thinking that a wizard to create a component would be good in 2 ways:
1) obviously save time
2) but also just avoiding having to think hard to what all the steps needed are. Unless I am working on Flavour a lot at a given time, I find myself having to think hard to remember all the things I need to do, and that consumes cognitive energy.

The wizard would take a Java component class name, a package path, a template file name, and do all the steps from there.

Your ideas are really good. The one that I find most valuable is the refactoring one, because it is in line with statically typed languages, where you expect everything to be easily refactorable.

Not sure whether this is what you meant by "flavour el parsing in templates", but it would be really good, even better than the refactoring, to have checks in the templates, with red underlining if a method doesn't exist or if there is a syntax error. It would be very much in line with the general idea of statically typed languages, and thus of TeaVM, of having checks as you type.

Not sure about this, but I thought that usually IDE plugins use the compiler libraries to parse things and report errors. If there is a way to do that I would tend to think that it would make any feature much more trivial. I guess having feedback from someone who wrote plugins for another language would be really helpful.

mauro...@gmail.com

unread,
Dec 4, 2020, 2:35:49 AM12/4/20
to TeaVM
Great job for a start! I'm a Netbeans user (used all 3 IDE's and really like Netbeans no-nonsense feeling) and welcome any plugin that will help me write Teavm/Flavour code.
Your planned features would be very welcome, but some will be quite hard to implement I suppose. But don't let that stop you ;)

Also the proposed feature of adding a component would be a nice one.

Of course, starting the Devserver with a dedicated button would be nice as well!
Anyway, keep up the good work and if you need help, let us know.

Op donderdag 3 december 2020 om 10:04:21 UTC+1 schreef vic-cw:

ScraM Team

unread,
Dec 4, 2020, 12:48:54 PM12/4/20
to TeaVM
Thanks to all for the positive feedback from everyone.  I'm investigating the NetBeans plugin APIs.  They are astoundingly rich, but finding which of the hundreds of APIs to use for a particular use case requires some research.

I do see APIs that talk about supporting "embedded" languages within others, like how JSP allows embedding Java in HTML.  That should allow extending the HTML support to allow embedded Flavour EL (Expression Langauge).  I will have to create a grammar for Flavour EL, or reuse the one already defined in the Flavour project, depending on technical and licensing compatibility.

I will start posting a list of future features on the plugin page.  Maybe I'll write some articles about creating NetBeans plugins too as I work through it.

ScraM Team

unread,
Dec 4, 2020, 1:05:10 PM12/4/20
to TeaVM
Future features page:


Let me know if I missed anything.

negora

unread,
Dec 5, 2020, 2:39:28 AM12/5/20
to TeaVM
Thank you for contributing to the NetBeans plug-in ecosystem. It's my favourite IDE since many years ago. I use it on a daily basis.

Nowadays, I'm a back-end only developer, but in my spare time I'm trying to work, again, in the front-end. And I'm trying to do it with TeaVM, of course. I don't use Flavour yet, because when I programmed in JavaScript, I always preferred to use vanilla JavaScript and build my own framework. But I'll try to take a look to your plug-in when my family duties let me some more time.

On Sunday, 29 November 2020 at 06:02:28 UTC+1 ScraM Team wrote:

vic-cw

unread,
Dec 7, 2020, 5:01:54 AM12/7/20
to TeaVM
Great to see so much movement.

I think it would be good to create a Github repo for this project if there isn't one already, and use the Issues feature to track feature requests. That would enable commenting on each feature, providing suggestions and feedback etc.

Thank you again very much for pushing this forward!

ScraM Team

unread,
Dec 10, 2020, 11:05:18 PM12/10/20
to TeaVM
I like the idea of a public feature/issue tracking site.  Give me a bit to get that set up.

Update on the plugin:
* I've been discussing with the NetBeans team how to add support for the HTML tags.  I found a plugin that does something very similar (for Angular), but it uses non-public API features.  But the NetBeans team seems ready to open those APIs, so that may be feasible soon.
* I've started looking at debugging.  There is support to debug JS apps in NetBeans, including a Chrome plugin, so this may also be possible.
* A component wizard actually seems the most feasible, since it uses existing APIs and there are examples.  I may work on that next.

vic-cw

unread,
Dec 11, 2020, 4:22:30 AM12/11/20
to TeaVM
Great to hear that this is moving forward. Thank you very much!!

mauro...@gmail.com

unread,
Dec 11, 2020, 4:44:49 AM12/11/20
to TeaVM
I just installed your current version and while being extremely simple, it is already useful!
Having teavm tags in the HTML editor would be great. Hope to see some progress there soon!
Op vrijdag 11 december 2020 om 10:22:30 UTC+1 schreef vic-cw:

ScraM Team

unread,
Dec 12, 2020, 11:28:21 AM12/12/20
to TeaVM
Thank you!  Very glad to hear that it is useful, even with just one feature.  :-)

I too am excited about a feature supporting tags in the HTML editor.  I will continue to work with the NetBeans team on that, since I need a little help from them to expose a private API. 

Currently I'm working on the Component Wizard, since the other features are bigger or temporarily blocked.  I'm currently planning how it should work.  Here is the current write-up: https://frequal.com/TeaVM/TeaVMForNetBeans/ComponentWizard.html

There are a couple of important questions.  Most importantly, where should it be invoked?  Please read it over and provide feedback, I'm about to start working on it.

ScraM Team

unread,
Dec 12, 2020, 6:07:20 PM12/12/20
to TeaVM
Some progress, new screen shots here.  The UI parts are coming along, but the file creation/manipulation is not started.

mauro...@gmail.com

unread,
Dec 13, 2020, 9:48:35 AM12/13/20
to TeaVM
Great to see some progress! Keep up the pace :)
Regarding your question from the previous message; invoking from a specific package is surely nice. But a user should be able to invoke it from the project node as well, just as the default wizard for creating a Java class. That would be most consistent.

I've read your specs page and it seems you've given the basics enough thought, so I have no comments.
Op zondag 13 december 2020 om 00:07:20 UTC+1 schreef ScraM Team:

ScraM Team

unread,
Dec 14, 2020, 10:10:29 PM12/14/20
to TeaVM
It's alive!  :-)  The component wizard is very close to release.

New screen shot here showing a 'Button' component generated by the wizard:

All 3 parts are working: generated Java class, generated HTML template, and entry in the component 'registry'.

Not shown, but worth mentioning, is the error handling: It detects and prevents execution if the Java, HTML, or registry entry is already present.

I need to display the error message on failure and then I'll post the new version.

vic-cw

unread,
Dec 15, 2020, 5:30:16 AM12/15/20
to TeaVM
This is awesome, thank you VERY MUCH!!!

About where to create this from: I don't know exactly how NetBeans works, but I'll tell you how I would like it to exist if NetBeans were like Eclipse, which is what I use. When I work in Eclipse, whenever I want to create a new Java Class, I just hit Cmd + N, and it shows me a dialog with a list of many things I can create: java class, package, empty file, html file, etc. I then type "class" and it filters out everything else. I then hit "Return", and it brings me to the wizard to create a Java class. The ideal scenario for me, if that plugin was an Eclipse plugin, would be that this flavour component be in the list, so that I can quickly create one with "Cmd + N" - "flav" - "Return". I don't know if things are similar in Netbeans.

Apart from that, I only have very minor comments on this version of the feature:
  • Path of HTML template: In your screenshot, it seems that the "button.html" file was added in "resources/component". I don't know what the best practices are, but personally I store my Flavour templates in "resources/templates/package/full/path". In the example that would be "resources/templates/com/frequal/button". Is there a Flavour best practice for this? If not I think we should look at the conventions for other similar Java stuff, or Angular stuff. I think it is important that the NetBeans plugin do this right, as this will definitely serve as a reference to all users going through it.
  • Naming conventions: I think it is good to append "Component" to the class name. Regarding the HTML file, I don't know what is the convention for HTML files, whether it's camel case, dashes, etc. If, like me, you don't know too, I would suggest looking at Google code style guides to see what is their convention, and adopting it
  • Naming conventions again: maybe it would be good to enable user to choose the HTML tag (used in @BindElement) from the wizard as well.
  • component Java template: I feel like it would be slightly nicer if there are empty lines around the constructor method in the generated Java code
  • also component Java template: I feel like it would be more newbie-user friendly, and thus ultimately more user friendly, if the constructor was more explicit, by naming the "slot" variable with something more explanatory. I actually don't know what this represents, whether this represents the parent where to insert the component, or something else. In any case I would make it more explicit, just so that a user creating a component this way can understand what this means without going through the docs or Flavour's source code.
  • "Phase 2. Maybe there should be a checkbox in the wizard to control this": I don't think it's necessary to add a checkbox. When you create a component, the next thing you do is fill it I guess.
Your limitations and priorizations look fine to me.

It is really cool that all three documents get opened in the window on top of one another, I had never thought of doing that, it is great!

Huge congratulations on this, it is great to see this come to life so fast!

ScraM Team

unread,
Dec 16, 2020, 12:42:59 AM12/16/20
to TeaVM
The TeaVM for NetBeans plugin has been updated.  This release includes a Flavour component wizard.



Note: I'm not sure how to version the plugin yet, so you may have to uninstall the old to install the new.

mauro...@gmail.com

unread,
Dec 19, 2020, 6:16:57 PM12/19/20
to TeaVM
I've just installed and tested this version and ran into a problem.
Creating the new component works as it should, but I'm having trouble editing the newly created html template file. Shortcuts using the control or alt key are not working in this file.

From the log I got this stacktrace:

java.lang.ClassNotFoundException: org.netbeans.modules.html.editor.api.gsf.HtmlExtension
    at java.base/jdk.internal.loader.BuiltinClassLoader.loadClass(BuiltinClassLoader.java:581)
    at java.base/jdk.internal.loader.ClassLoaders$AppClassLoader.loadClass(ClassLoaders.java:178)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at org.netbeans.ProxyClassLoader.doFindClass(ProxyClassLoader.java:209)
Caused: java.lang.ClassNotFoundException: org.netbeans.modules.html.editor.api.gsf.HtmlExtension starting from ModuleCL@41a4a90[com.frequal.teavm4nb] with possible defining loaders [ModuleCL@5e785210[org.netbeans.modules.html.editor]] and declared parents [ModuleCL@40fe9c7[org.netbeans.modules.editor.mimelookup], ModuleCL@6a7d8f38[org.openide.dialogs], ModuleCL@6a399c65[org.netbeans.modules.editor], ModuleCL@31af0dde[org.netbeans.modules.html.lexer], ModuleCL@1e2556a1[org.netbeans.modules.html.editor.lib], org.netbeans.JarClassLoader@7e1ff239, ModuleCL@65b26ad7[org.openide.loaders], org.netbeans.MainImpl$BootClassLoader@4f3f5b24, ModuleCL@5e785210[org.netbeans.modules.html.editor], ModuleCL@1df25db2[org.openide.nodes], ...9 more]
    at org.netbeans.ProxyClassLoader.doFindClass(ProxyClassLoader.java:211)
    at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:125)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
Caused: java.lang.NoClassDefFoundError: org/netbeans/modules/html/editor/api/gsf/HtmlExtension
    at java.base/java.lang.ClassLoader.defineClass1(Native Method)
    at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1017)
    at org.netbeans.JarClassLoader.doLoadClass(JarClassLoader.java:287)
    at org.netbeans.ProxyClassLoader.selfLoadClass(ProxyClassLoader.java:246)
Caused: java.lang.NoClassDefFoundError: org/netbeans/modules/html/editor/api/gsf/HtmlExtension while loading com.frequal.teavm4nb.TemplateHtmlExtension; see http://wiki.netbeans.org/DevFaqTroubleshootClassNotFound
    at org.netbeans.ProxyClassLoader.selfLoadClass(ProxyClassLoader.java:250)
    at org.netbeans.ProxyClassLoader.doFindClass(ProxyClassLoader.java:174)
    at org.netbeans.ProxyClassLoader.loadClass(ProxyClassLoader.java:125)
    at org.netbeans.ModuleManager$SystemClassLoader.loadClass(ModuleManager.java:769)
    at java.base/java.lang.ClassLoader.loadClass(ClassLoader.java:522)
    at java.base/java.lang.Class.forName0(Native Method)
    at java.base/java.lang.Class.forName(Class.java:398)
    at org.netbeans.modules.editor.mimelookup.impl.FolderPathLookup$InstanceItem.findTypeFor(FolderPathLookup.java:402)
    at org.netbeans.modules.editor.mimelookup.impl.FolderPathLookup$InstanceItem.createInstanceFor(FolderPathLookup.java:384)
    at org.netbeans.modules.editor.mimelookup.impl.FolderPathLookup$InstanceItem.getInstance(FolderPathLookup.java:324)
    at org.netbeans.modules.editor.mimelookup.impl.FolderPathLookup$PairItem.getInstance(FolderPathLookup.java:179)
    at org.openide.util.lookup.AbstractLookup$R.allInstances(AbstractLookup.java:1030)
    at org.openide.util.lookup.AbstractLookup$R.allInstances(AbstractLookup.java:1010)
    at org.openide.util.lookup.ProxyLookup$LazyCollection.computeSingleResult(ProxyLookup.java:1348)
    at org.openide.util.lookup.ProxyLookup$LazyCollection.computeDelegate(ProxyLookup.java:1186)
    at org.openide.util.lookup.ProxyLookup$LazyCollection.access$900(ProxyLookup.java:1114)
    at org.openide.util.lookup.ProxyLookup$LazyCollection$1.hasNext(ProxyLookup.java:1314)
    at org.netbeans.modules.html.editor.gsf.HtmlGSFParser.parse(HtmlGSFParser.java:99)
    at org.netbeans.modules.html.editor.gsf.HtmlGSFParser.parse(HtmlGSFParser.java:55)
    at org.netbeans.modules.parsing.impl.TaskProcessor.callParse(TaskProcessor.java:598)
    at org.netbeans.modules.parsing.impl.SourceCache.getResult(SourceCache.java:228)
    at org.netbeans.modules.parsing.api.ResultIterator.getParserResult(ResultIterator.java:115)
    at org.netbeans.modules.html.editor.gsf.HtmlDeclarationFinder$DocumentMimeTypeCacheUpdateTask$1.run(HtmlDeclarationFinder.java:106)
    at org.netbeans.modules.parsing.impl.TaskProcessor.callUserTask(TaskProcessor.java:586)
    at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:130)
    at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:114)
    at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:181)
    at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:178)
    at org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager.priorityIO(FileChangedManager.java:153)
    at org.netbeans.modules.masterfs.providers.ProvidedExtensions.priorityIO(ProvidedExtensions.java:335)
    at org.netbeans.modules.parsing.nb.DataObjectEnvFactory.runPriorityIO(DataObjectEnvFactory.java:118)
    at org.netbeans.modules.parsing.impl.Utilities.runPriorityIO(Utilities.java:67)
    at org.netbeans.modules.parsing.impl.TaskProcessor.runUserTask(TaskProcessor.java:178)
    at org.netbeans.modules.parsing.api.ParserManager.parse(ParserManager.java:81)
    at org.netbeans.modules.html.editor.gsf.HtmlDeclarationFinder$DocumentMimeTypeCacheUpdateTask.run(HtmlDeclarationFinder.java:101)
    at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1418)
    at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
    at org.openide.util.lookup.Lookups.executeWith(Lookups.java:278)
[catch] at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2033)


Op woensdag 16 december 2020 om 06:42:59 UTC+1 schreef ScraM Team:

mauro...@gmail.com

unread,
Dec 19, 2020, 6:57:48 PM12/19/20
to TeaVM
Found another issue: there seems to be a problem with finding the custom component when the name is camel cased. This seems to be the default for this plugin.
I went out to create a component named WeekDayComponent, resulting in a generated element name of 'weekDay', like this:
@BindElement(name = "weekDay")

On compilation an error was thrown stating that the component called 'weekday' (all lower case) could not be found.
When I changed this to 'week-day' , the custom component could be used.

Therefore I think the correct default would be to not use camel casing, but dash separated words. This would be more fitting for HTML tags anyway I think.





Op zondag 20 december 2020 om 00:16:57 UTC+1 schreef mauro...@gmail.com:

ScraM Team

unread,
Dec 30, 2020, 3:52:35 PM12/30/20
to TeaVM
I have started looking at these issues.  Thanks for the feedback!

ScraM Team

unread,
Jan 4, 2021, 2:23:00 AM1/4/21
to TeaVM
I am getting close to fixing these.  I think BindElement and component lookup only work with all-lowercase names, so I'm lowercasing the name for now.  In the future I can make an option that adds hyphens.

Hopefully I'll have the next version ready shortly.

ScraM Team

unread,
Feb 14, 2021, 10:52:06 AM2/14/21
to TeaVM
Versioni 3 is ready now on the TeaVM for NetBeans download page here:

It is a bugfix release, addressing the issues identified earlier in this thread with component name handling and extra pop-up warning messages.

I've added links to the older versions in case they are of interest.

For anyone new to the plugin, the homepage is here:

  -Andy
Reply all
Reply to author
Forward
0 new messages