Git Product home page Git Product logo

coderad's Introduction

CodeRAD

Rapid Application Development toolkit and templates for Java developers using Codename One. It focuses on higher reusability, rich UI components and MVC (Model-View-Controller) principles.

CodeRAD GitHub

Watch the CodeRAD 2 Introduction Video for a short introduction to features and concepts.

Features

  1. Reusable Components - Facilitates the creation of View components that can be easily reused across projects without requiring any dependencies.

  2. Rich UI Components - Components built with CodeRAD are richer than the standard Codename One UI components. They are designed to be useful right out of the box, while still being customizable.

  3. Clean Separation of Code - Provides model, view, and controller classes which facilitate the clean separation of code following MVC (Model-View-Controller) principles.

  4. Loose Coupling - Views can be "loosely" coupled to their model, allowing them to be used with many different model classes. Learn more

  5. Declarative UI Syntax - Build your user interfaces declaratively using a light and expressive XML-based syntax.

Documentation

Code RAD 1.x Tutorials

The following tutorials were written for CodeRAD 1.0 and are in the process of being updated to CodeRAD 2. There have been substantial changes in the way you build apps using CodeRAD 2, so bear that in mind when going through them

  1. How to Build a Messenging App in Codename One - A good startng place for getting a feel for what it is like to develop an app using CodeRAD.

Sample Projects

  1. Tweetapp - A Twitter mobile app clone. (For demonstration only - is not a complete clone).

  2. RADChat Demo - RADChatApp is a full-featured chat room app UI component. UI only. For demonstration purposes. Developed using CodeRAD 1.0. Currently being updated to use 2.0.

  3. Grub - UberEats Clone. Developed using CodeRAD 1.0

  4. CodeRAD2 Samples - A collection of samples using CodeRAD components. This serves as a living testbed for CodeRAD components.

UI Kits (Libraries)

  1. Tweet App UI Kit - A CodeRAD 2 library with several Twitter-like UI components. Developed for CodeRAD 2.0.

  2. RADChat App - A library including full-featured components for building a Chat application. (Currently for CodeRAD 1.0, and being adapted to CodeRAD 2).

Building from Source

The following instructions are for Mac and Linux. May work on windows using Git Bash, but not sure.

  1. Open your terminal

  2. Make sure that JAVA_HOME is set to a valid JDK8

  3. Make sure mvn is in your PATH

git clone https://github.com/shannah/CodeRAD
mvn install

Support

CodeRAD is developed and supported by Codename One.

Credits

Developed by Steve Hannah, Codename One.

coderad's People

Contributors

shannah avatar yo-zubair avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

coderad's Issues

Entity setDate/getDate seems to be not working

I have a very simple Entity class and one of the fields is java.util.Date. When I use set/get methods I get a correct Date value, however, when I use setDate/getDate methods, the get always returns null.

Example code - this works correctly:

import com.codename1.rad.models.Entity
import com.codename1.rad.models.EntityType
import com.codename1.rad.schemas.ChatMessage
import java.util.Date


class Message(text: String?, creator: Contact, attachment: String? = null, date: Date = Date()) :
        Entity() {
    companion object TYPE: EntityType() {
        init {
            string(ChatMessage.text)
            entity(Contact::class.java, ChatMessage.creator)
            date(ChatMessage.dateCreated)
            string(ChatMessage.attachment)
            Boolean(ChatMessage.isFavorite)
        }
    }

    init {
        entityType = TYPE
        set(ChatMessage.text, text)
        set(ChatMessage.creator, creator)
        set(ChatMessage.attachment, attachment)
        set(ChatMessage.dateCreated, date) // <-- set method used
        set(ChatMessage.isFavorite, false)

        println("Original date: $date")
        println("Message Date: " + get(ChatMessage.dateCreated)?.toString()) // <-- get method used returns correct date, the same as original date above
    }
}

Example code - this does not work. In the last line I always get null:

import com.codename1.rad.models.Entity
import com.codename1.rad.models.EntityType
import com.codename1.rad.schemas.ChatMessage
import java.util.Date


class Message(text: String?, creator: Contact, attachment: String? = null, date: Date = Date()) :
        Entity() {
    companion object TYPE: EntityType() {
        init {
            string(ChatMessage.text)
            entity(Contact::class.java, ChatMessage.creator)
            date(ChatMessage.dateCreated)
            string(ChatMessage.attachment)
            Boolean(ChatMessage.isFavorite)
        }
    }

    init {
        entityType = TYPE
        set(ChatMessage.text, text)
        set(ChatMessage.creator, creator)
        set(ChatMessage.attachment, attachment)
        setDate(ChatMessage.dateCreated, date)   // <-- setDate method used
        set(ChatMessage.isFavorite, false)

        println("Original date: $date")
        println("Message Date: " + getDate(ChatMessage.dateCreated)?.toString())   // <-- getDate method used, always returns null
    }
}

I am not sure where is the problem, in the setDate or in the getDate method. I was not able to track it down.

enum EntityType?

I was wondering if there is a way to have enum field type in the Entity. I think it could be worked around with Integer field and takin ordinal value of the enum but this seems like a workaround rather than a solution.

Having enum field would be very useful for cases like handling states or status of a protocol flow or other things.

Any suggestions?

@RAD property with type Integer fails

With this code sample for an Entity, CodeRAD generates code that does not compile.

public interface MyEntity extends Entity {
    Tag myNumber= new Tag("myNumber");

    @RAD(tag = "myNumber")
    Integer getMyNumber();
    void setMyNumber(Integer myNumber);
}

CodeRAD generates the below wrapper class:

@Autogenerated
public final class MyEntityWrapper extends SimpleEntityWrapper implements MyEntity {
  public MyEntityWrapper(Entity entity) {
    super(entity);
  }

  public static MyEntity wrap(Entity entity) {
    if (entity == null) return null;if (entity instanceof MyEntity) return (MyEntity)entity;MyEntity wrapper = entity.getEntity().getWrapper(MyEntity.class);if (wrapper != null) return wrapper;wrapper = new MyEntityWrapper(entity); entity.getEntity().addWrapper(wrapper);return wrapper;
  }

  public Integer getMyNumber() {
    return (Integer)getEntity().getInteger(myNumber);
  }

  public void setMyNumber(Integer _value) {
    getEntity().setInteger(myNumber, _value);
  }
}

This fails to compile, because BaseEntity does not have a getInteger() method; it has getInt() instead.

RFE JSON encoding/decoding for models

Until now I used a lot PropertyBusinessObject to store the data. I'm used to create the app database using almost only PropertyBusinessObject objects. They are very convenient to exchange data with any external service, because they can seamlessly be converted to JSON and populated from JSON. Moreover, the RequestBuilder class offers method to send a PropertyBusinessObject object as body request and to fetch a PropertyBusinessObject object as the result of a request. At the moment, I consider the PropertyBusinessObject class as fundamental.

Your new CodeRAD model is very interesting, but it introduces a new way to store data in Entity objects. That makes sense, but do we lost all the advantages of the PropertyBusinessObject class? How can I use the CoreRAD concepts while maintaining all the advantages of the PropertyBusinessObject class in REST requests?

Thank you

Disable EntityEditor auto-scrolling

It seems that a default behavior for EntityEditor is to scroll the the added component to the list. This makes sense in many cases, like chat list where we want the view to automatically scroll to and show the last added message.

However, in some cases this is not desirable to automatically scroll the list when it is modified. Is there any option to disable auto-scrolling for EntityEditor when the list is modified?

Best way/component to display contact status

Hi,

I would like to indicate using colors or different icons contact's online status. That is a different icon or a color to be used when the contact is offline, online, busy, etc....

I could not find anything in the CodeRAD directly suitable for this purpose but maybe I am missing something. The closest thing, which I am going to base on my code would be TypingAnimation to have "pure" component or maybe better yet, something like LabelEntityView, so the view could react on entity changes.

Would you have any suggestions?

Problem with EntityEditor when it is not attached to a form

Ok, I do not know if this is related to EntityEditor or ListNode or NodeList. The thing is that I have AbstractEntityView implementation using EntityEditor and ListNode to render EntityList elements. Very similar thing to the ChatRoomView from RadChatRoom.
Now, I have several Views like this created. Think of it as several ChatRoomViews created. Each view corresponds to a different EntityList. Like you would have each ChatRoomView created for different person you talk with. Only one View is displayed on the screen though and a user can switch between these views to display a different one.

For performance reasons and to reduce resources usage, I do not want to create a View every time a user switched to this view. Once the View is created I keep it in a Map and when a user wants to see this View I just insert it into the form's Container. Everything works great, except adding Entity to EntityList when the View is not visible, that is when the View is not in the form's Container and it is stored in the Map.
When the View is visible on the screen, adding Entity shows it on the list. When it is not on the screen and stored in the Map then Entity is added to the EntityList but after I show the View on the form, this added Entity is not visible.

I guess, I should somehow refresh either EntityEditor or ListNode to render entities added when the View was in background. I cannot, however, find a suitable API.
Do you have any suggestions on how this could be accomplished?

Adding elements in bulk to `EntityList`

Hi,

I use EntityList for maintaining and displaying contact list. I may have 100 or more contacts. During app startup time, the app connects to the server and loads entire contact list.
Now, adding contacts to EntityList, one by one is very slow and inefficient. it would be much more efficient to add all contacts to the list and then redraw the contacts view.

I cannot find any method in EntityList for adding multiple elements in one call. But, maybe this is not the best approach any way. Maybe there is a way to somehow block the view from updating while the elements are being added to the EntityList?

What would be the best way to add many elements to EntityList in efficient way?

hasChanged() not updated on EntityList add/remove methods

EntityList extends Entity which extends Observable. My understanding is that the contract on Observable is that hasChanged() is updated every time the Entity is modified.

While this works for Entity as expected, it seems to be not working for EntityList add/remove methods. I looked in the code of EntityList and it seems that the field is not being updated for the list modifications.

It seems that EntityList took a different approach to rely on event handlers and fires an action event when the list is modified. This makes sense and is probably better than relying on hasChanged() but it is different from underlying Entity behavior and inconsistent.

I suggest to unify behavior for Entity and EntityList and make them behave the same way to monitor modifications. Either through hasChanged() or action events. I guess adding hasChanged() to EntityList would be simplest solution right now.

Displaying ordered collections

Currently EntityEditor displays entities from provided EntityList without any specific order. That is last added entity to the list is last displayed.
However, in some use cases it would be highly desirable to control order in which entities are displayed.

I am not sure what would be the best way to add/allow for ordering entities. Would it be EntityList with ordering API or EntityEditor with API for sorting entities.

Actually my current use case is even simpler than this. I just need to add new items to the top of the list. So, EntityList with a method to add a new element at position 0 would be good enough.

Disable EntityEditor auto-scrolling

It seems that a default behavior for EntityEditor is to scroll the the added component to the list. This makes sense in many cases, like chat list where we want the view to automatically scroll to and show the last added message.

However, in some cases this is not desirable to automatically scroll the list when it is modified. Is there any option to disable auto-scrolling for EntityEditor when the list is modified?

Rapidly adding and removing items from EntityListView results in duplications

Given a sequence of add, remove, add events on an EntityList, the EntityListView can end up showing incorrect items.
For example:

entityList.add(a);
entityList.remove(a);
entityList.add(a);

The root cause of this appears to be that after adding item a, the wrapper in EntityListView is not fully updated; the new component is added to the changeQueue, but is not yet returned when iterating through elements in EntityListView.handleEntityRemoved

To resolve this, I think that EntityListView.handleEntityRemoved should instead call wrapper.getChildrenAsList(true) to include the queued changes when removing items.

Missing piece of documentation and/or example

CodeRAD and RADChatRoom are great additions to CN1 environment and API. I appreciate the effort and try to use them in my code.

However, I am having hard time to fully grasp CodeRAD concept. RADChatRoom component and tutorial is a very good description how to use it in complex scenarios.

I am wondering what would be the best way to implement something as simple as user login form which shows when the user first opens the app and needs to enter account credentials. I guess this must be something rather simple like FormController with EntityEditor. I am sure I can create something based on the documentation, however, I am just not sure what is the best and most optimal way to do it using the library.

Actions not picked up from view-controller attribute on XML view.

From: https://www.reddit.com/r/cn1/comments/wjuarg/buttons_component_not_showing_in_rowtemplate_in/

Am trying to add buttons component to component in rowTemplate but this is not being displayed as would expect. I expect to see an overflow button icon especially since I have specified a limit of 1.

XML code

<?xml version="1.0"?>
    <border view-controller="MyGroupsPageViewController"
            rad-model="GroupModel"
            ...
        <define-category name = "MAIN_MENU"/>
      
         
        <entityList layout-constraint="center" name="groups" addAction="CREATE_GROUP_ACTION"
            provider="com.mgr.app.providers.MgrGroupsProvider.class">
            <row-template>
                <border uiid="groupContainer">
    
                    <border layout-constraint="north">
                        <radLabel tag = "GroupModel.groupName" layout-constraint="north" component.uiid="GroupNameLabel"/>
                        <radSpanLabel tag = "GroupModel.groupDescription" layout-constraint="center" component.uiid="GroupDescriptionLabel"/>
                    </border>
                    <buttons actionCategory="MAIN_MENU" layout-constraint="south" uiid="GroupsButton" limit="1" layout="BoxLayout.y()"/>
                </border>
            </row-template>
    
        </entityList>
    
    </border>

Controller

...
        protected void initControllerActions() {
            super.initControllerActions();
    
            ActionNode.
                    builder()
                    .label("Contribute")
                    .addToController(this, MyGroups.MAIN_MENU,this::contribute);
            ActionNode.
                    builder()
                    .label("Group Transactions")
                    .addToController(this, MyGroups.MAIN_MENU,this::groupTransactions);
            ActionNode.
                    builder()
                    .label("My Transactions")
                    .addToController(this, MyGroups.MAIN_MENU,this::myTransactionsInAGroup);
    
            ActionNode.
                    builder()
                    .label("Exit Group")
                    .addToController(this, MyGroups.MAIN_MENU,this::exitGroup);

Result

image

Sample project:

https://github.com/Ngosti2000/code-rad-test

Affected Versions: 2.0.1 (verified)

How to build the project

Hi,
I cloned the repo to my local machine. I would like to generate JavaDoc and maybe even build the whole project locally.
Simply running ant after cloning does not work. I guess I have to somehow initialize the repo with cn1 libs. How to do it?
I also opened the project under IntelliJ but it does not recognize it as cn1 project either.
Any suggestions would be very much appreciated.

I get an error when running mvn clean package

I get the below error when running mvn clean package and mvn clean install. I can't really figure out the cause.

This is my project: my-app

Stacktrace:

[ERROR] Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project vips-app-common: Fatal error compiling: java.lang.NullPointerException: Cannot read field "kind" because "sym" is null -> [Help 1]
    org.apache.maven.lifecycle.LifecycleExecutionException: Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:3.8.0:compile (default-compile) on project vips-app-common: Fatal error compiling
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:375)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
        at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
        at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
        at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
        at java.lang.reflect.Method.invoke (Method.java:577)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
    Caused by: org.apache.maven.plugin.MojoExecutionException: Fatal error compiling
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute (AbstractCompilerMojo.java:1140)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute (CompilerMojo.java:188)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
        at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
        at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
        at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
        at java.lang.reflect.Method.invoke (Method.java:577)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
    Caused by: org.codehaus.plexus.compiler.CompilerException: java.lang.NullPointerException: Cannot read field "kind" because "sym" is null
        at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess (JavaxToolsCompiler.java:173)
        at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile (JavacCompiler.java:174)
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute (AbstractCompilerMojo.java:1129)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute (CompilerMojo.java:188)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
        at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
        at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
        at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
        at java.lang.reflect.Method.invoke (Method.java:577)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
    Caused by: java.lang.RuntimeException: java.lang.NullPointerException: Cannot read field "kind" because "sym" is null
        at com.sun.tools.javac.api.JavacTaskImpl.invocationHelper (JavacTaskImpl.java:168)
        at com.sun.tools.javac.api.JavacTaskImpl.doCall (JavacTaskImpl.java:100)
        at com.sun.tools.javac.api.JavacTaskImpl.call (JavacTaskImpl.java:94)
        at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess (JavaxToolsCompiler.java:126)
        at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile (JavacCompiler.java:174)
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute (AbstractCompilerMojo.java:1129)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute (CompilerMojo.java:188)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
        at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
        at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
        at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
        at java.lang.reflect.Method.invoke (Method.java:577)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)
    Caused by: java.lang.NullPointerException: Cannot read field "kind" because "sym" is null
        at com.sun.tools.javac.model.JavacElements.getFileObjectOf (JavacElements.java:733)
        at java.util.stream.ReferencePipeline$3$1.accept (ReferencePipeline.java:197)
        at java.util.Spliterators$ArraySpliterator.forEachRemaining (Spliterators.java:992)
        at java.util.stream.AbstractPipeline.copyInto (AbstractPipeline.java:509)
        at java.util.stream.AbstractPipeline.wrapAndCopyInto (AbstractPipeline.java:499)
        at java.util.stream.AbstractPipeline.evaluate (AbstractPipeline.java:575)
        at java.util.stream.AbstractPipeline.evaluateToArrayNode (AbstractPipeline.java:260)
        at java.util.stream.ReferencePipeline.toArray (ReferencePipeline.java:616)
        at com.sun.tools.javac.processing.JavacFiler.originatingFiles (JavacFiler.java:534)
        at com.sun.tools.javac.processing.JavacFiler.createSourceOrClassFile (JavacFiler.java:512)
        at com.sun.tools.javac.processing.JavacFiler.createSourceFile (JavacFiler.java:438)
        at com.codename1.rad.annotations.processors.EntityProcessor.createEntityClass (EntityProcessor.java:839)
        at com.codename1.rad.annotations.processors.EntityProcessor.access$2200 (EntityProcessor.java:70)
        at com.codename1.rad.annotations.processors.EntityProcessor$EntityPlan.generateImplementationClass (EntityProcessor.java:682)
        at com.codename1.rad.annotations.processors.EntityProcessor$EntityPlan.executePlan (EntityProcessor.java:644)
        at com.codename1.rad.annotations.processors.EntityProcessor$ExecutionPlan.<init> (EntityProcessor.java:221)
        at com.codename1.rad.annotations.processors.EntityProcessor.processEntities (EntityProcessor.java:691)
        at com.codename1.rad.annotations.processors.EntityProcessor.process (EntityProcessor.java:155)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.callProcessor (JavacProcessingEnvironment.java:1023)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.discoverAndRunProcs (JavacProcessingEnvironment.java:939)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment$Round.run (JavacProcessingEnvironment.java:1267)
        at com.sun.tools.javac.processing.JavacProcessingEnvironment.doProcessing (JavacProcessingEnvironment.java:1382)
        at com.sun.tools.javac.main.JavaCompiler.processAnnotations (JavaCompiler.java:1234)
        at com.sun.tools.javac.main.JavaCompiler.compile (JavaCompiler.java:916)
        at com.sun.tools.javac.api.JavacTaskImpl.lambda$doCall$0 (JavacTaskImpl.java:104)
        at com.sun.tools.javac.api.JavacTaskImpl.invocationHelper (JavacTaskImpl.java:152)
        at com.sun.tools.javac.api.JavacTaskImpl.doCall (JavacTaskImpl.java:100)
        at com.sun.tools.javac.api.JavacTaskImpl.call (JavacTaskImpl.java:94)
        at org.codehaus.plexus.compiler.javac.JavaxToolsCompiler.compileInProcess (JavaxToolsCompiler.java:126)
        at org.codehaus.plexus.compiler.javac.JavacCompiler.performCompile (JavacCompiler.java:174)
        at org.apache.maven.plugin.compiler.AbstractCompilerMojo.execute (AbstractCompilerMojo.java:1129)
        at org.apache.maven.plugin.compiler.CompilerMojo.execute (CompilerMojo.java:188)
        at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo (DefaultBuildPluginManager.java:137)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute2 (MojoExecutor.java:370)
        at org.apache.maven.lifecycle.internal.MojoExecutor.doExecute (MojoExecutor.java:351)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:215)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:171)
        at org.apache.maven.lifecycle.internal.MojoExecutor.execute (MojoExecutor.java:163)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:117)
        at org.apache.maven.lifecycle.internal.LifecycleModuleBuilder.buildProject (LifecycleModuleBuilder.java:81)
        at org.apache.maven.lifecycle.internal.builder.singlethreaded.SingleThreadedBuilder.build (SingleThreadedBuilder.java:56)
        at org.apache.maven.lifecycle.internal.LifecycleStarter.execute (LifecycleStarter.java:128)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:294)
        at org.apache.maven.DefaultMaven.doExecute (DefaultMaven.java:192)
        at org.apache.maven.DefaultMaven.execute (DefaultMaven.java:105)
        at org.apache.maven.cli.MavenCli.execute (MavenCli.java:960)
        at org.apache.maven.cli.MavenCli.doMain (MavenCli.java:293)
        at org.apache.maven.cli.MavenCli.main (MavenCli.java:196)
        at jdk.internal.reflect.DirectMethodHandleAccessor.invoke (DirectMethodHandleAccessor.java:104)
        at java.lang.reflect.Method.invoke (Method.java:577)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launchEnhanced (Launcher.java:282)
        at org.codehaus.plexus.classworlds.launcher.Launcher.launch (Launcher.java:225)
        at org.codehaus.plexus.classworlds.launcher.Launcher.mainWithExitCode (Launcher.java:406)
        at org.codehaus.plexus.classworlds.launcher.Launcher.main (Launcher.java:347)

This is the pom in common module:

<?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>com.example.myapp</groupId>
            <artifactId>my-app</artifactId>
            <version>1.0-SNAPSHOT</version>
        </parent>
        <artifactId>my-app-common</artifactId>
        <version>1.0-SNAPSHOT</version>
        <packaging>jar</packaging>
    
        <!-- Add your cn1lib dependencies to this section -->
        <dependencies>
            <dependency>
                <groupId>com.codenameone</groupId>
                <artifactId>codenameone-core</artifactId>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>com.codenameone</groupId>
                <artifactId>coderad-lib</artifactId>
                <version>${coderad.version}</version>
                <type>pom</type>
            </dependency>
    
    
            <!-- INJECT DEPENDENCIES -->
            <dependency>
                <groupId>com.example.resources.commons</groupId>
                <artifactId>common-resources</artifactId>
                <version>1.0.0</version>
            </dependency>
        </dependencies>
    
        <!-- The following are profiles to cover special cases -->
        <profiles>
            <!-- A profile to install Codename One support libraries to your home directory if they aren't installed yet. -->
            <profile>
                <id>install-codenameone</id>
                <activation>
                    <file>
                        <missing>${user.home}/.codenameone/guibuilder.jar</missing>
                    </file>
                </activation>
                <build>
                    <plugins>
                        <plugin>
                            <groupId>org.apache.maven.plugins</groupId>
                            <artifactId>maven-antrun-plugin</artifactId>
                            <version>3.0.0</version>
                            <!--<version>3.1.0</version>-->
                            <executions>
                                <execution>
                                    <phase>validate</phase>
                                    <goals>
                                        <goal>run</goal>
                                    </goals>
                                    <configuration>
                                        <target name="install-cn1">
                                            <available file="${user.home}/.codenameone/guibuilder.jar" property="codenameone.present" />
    
                                            <mkdir dir="${user.home}/.codenameone" />
                                            <mkdir dir="${project.build.directory}/codenameone/tmpProject" />
                                            <get src="https://www.codenameone.com/files/updates/UpdateCodenameOne.jar" dest="${user.home}/UpdateCodenameOne.jar" skipexisting="true" />
                                            <java jar="${user.home}/UpdateCodenameOne.jar" fork="true">
                                                <arg value="${project.build.directory}/codenameone/tmpProject" />
                                                <arg value="force" />
                                            </java>
                                        </target>
                                    </configuration>
                                </execution>
                            </executions>
                        </plugin>
                    </plugins>
                </build>
    
            </profile>
    
            <!-- A profile to add kotlin support.  Activated if the src/main/kotlin directory exists -->
            <profile>
                <id>kotlin</id>
                <activation>
                    <file>
                        <!-- To enable Kotlin, add the following file to the project base dir -->
                        <exists>${basedir}/src/main/kotlin</exists>
                    </file>
                </activation>
                <properties>
                    <kotlin.version>1.3.72</kotlin.version>
                    <kotlin.compiler.incremental>true</kotlin.compiler.incremental>
                </properties>
                <dependencies>
                    <dependency>
                        <groupId>org.jetbrains.kotlin</groupId>
                        <artifactId>kotlin-stdlib</artifactId>
                        <version>${kotlin.version}</version>
                    </dependency>
    
                    <!-- https://mvnrepository.com/artifact/org.jetbrains.kotlin/kotlin-annotations-jvm -->
                    <!-- https://mvnrepository.com/artifact/org.jetbrains/annotations -->
                    <dependency>
                        <groupId>org.jetbrains</groupId>
                        <artifactId>annotations</artifactId>
                        <version>13.0</version>
                    </dependency>
                    <dependency>
                        <groupId>com.codenameone</groupId>
                        <artifactId>java-runtime</artifactId>
                        <scope>provided</scope>
                    </dependency>
                </dependencies>
                <build>
                    <plugins>
                        <plugin>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>properties-maven-plugin</artifactId>
                            <version>1.0.0</version>
                            <executions>
                                <execution>
                                    <phase>initialize</phase>
                                    <goals>
                                        <goal>read-project-properties</goal>
                                    </goals>
                                    <configuration>
                                        <files>
                                            <file>${basedir}/codenameone_settings.properties</file>
                                        </files>
                                    </configuration>
                                </execution>
                            </executions>
                        </plugin>
    
                        <plugin>
                            <groupId>org.jetbrains.kotlin</groupId>
                            <artifactId>kotlin-maven-plugin</artifactId>
                            <version>${kotlin.version}</version>
                            <executions>
                                <execution>
                                    <id>compile</id>
                                    <goals>
                                        <goal>compile</goal>
                                    </goals>
                                    <configuration>
                                        <sourceDirs>
                                            <sourceDir>${project.basedir}/src/main/kotlin</sourceDir>
                                            <sourceDir>${project.basedir}/src/main/java</sourceDir>
                                        </sourceDirs>
                                        <args>
                                            <arg>-no-reflect</arg>
                                            <arg>-no-jdk</arg> <!-- No JDK -->
                                        </args>
                                    </configuration>
                                </execution>
                                <execution>
                                    <id>test-compile</id>
                                    <goals>
                                        <goal>test-compile</goal>
                                    </goals>
                                    <configuration>
                                        <sourceDirs>
                                            <sourceDir>${project.basedir}/src/test/kotlin</sourceDir>
                                            <sourceDir>${project.basedir}/src/test/java</sourceDir>
                                        </sourceDirs>
                                        <args>
                                            <arg>-no-reflect</arg>
                                            <arg>-no-jdk</arg> <!-- No JDK -->
                                        </args>
                                    </configuration>
                                </execution>
                            </executions>
                        </plugin>
                    </plugins>
                </build>
            </profile>
    
            <profile>
                <id>javase</id>
                <activation>
                    <property>
                        <name>codename1.platform</name>
                        <value>javase</value>
                    </property>
                </activation>
                <properties>
                    <codename1.targetPlatform>javase</codename1.targetPlatform>
                </properties>
                <build>
                    <plugins>
                        <plugin>
                            <groupId>org.codehaus.mojo</groupId>
                            <artifactId>exec-maven-plugin</artifactId>
                            <configuration>
                                <executable>java</executable>
                                <longClasspath>true</longClasspath>
                                <arguments>
                                    <argument>-XX:MaxPermSize=128M</argument>
                                    <argument>-Xmx1024M</argument>
                                    <!--<argument>-Xdebug</argument>
                                    <argument>-Xrunjdwp:transport=dt_socket,address=8888,server=y,suspend=n</argument>-->
                                    <argument>-classpath</argument>
                                    <classpath />
                                    <argument>${exec.mainClass}</argument>
                                    <argument>${cn1.mainClass}</argument>
                                </arguments>
                            </configuration>
                        </plugin>
                    </plugins>
                </build>
            </profile>
    
            <profile>
                <!-- 
                    For running in simulator in process use: mvn cn1:java -P simulator
                    Fro running in simulator in forked process use: mvn cn1:simulator -P simulator
                -->
                <id>simulator</id>
                <properties>
                    <codename1.targetPlatform>javase</codename1.targetPlatform>
                </properties>
            </profile>
    
            <profile>
                <!-- For sending iOS debug builds use: mvn cn:build -P ios-debug -->
                <id>ios-debug</id>
                <properties>
                    <!-- Build server target type -->
                    <codename1.targetType>iphone</codename1.targetType>
                    <!-- Used for identifying native interfaces.  Should match correct subdirectory of native -->
                    <codename1.targetPlatform>ios</codename1.targetPlatform>
                </properties>
            </profile>
            <profile>
                <!-- For sending iOS debug builds use: mvn cn:build -P ios-release -->
                <id>ios-release</id>
                <properties>
                    <!-- Build server target type -->
                    <codename1.targetType>iphone</codename1.targetType>
                    <codename1.production>true</codename1.production>
                    <!-- Used for identifying native interfaces.  Should match correct subdirectory of native -->
                    <codename1.targetPlatform>ios</codename1.targetPlatform>
                    <codename1.appStoreBuild>true</codename1.appStoreBuild>
                </properties>
            </profile>
    
            <profile>
                <!-- For sending Javascript builds use: mvn cn:build -P javascript -->
                <id>javascript</id>
                <properties>
                    <codename1.targetType>javascript</codename1.targetType>
                    <codename1.targetPlatform>javascript</codename1.targetPlatform>
                </properties>
            </profile>
    
            <profile>
                <!-- For sending Android builds use: mvn cn:build -P android -->
                <id>android</id>
                <properties>
                    <codename1.targetType>android</codename1.targetType>
                    <codename1.targetPlatform>android</codename1.targetPlatform>
                </properties>
            </profile>
    
            <profile>
                <!-- For sending Windows UWP builds use: mvn cn:build -P uwp -->
                <id>uwp</id>
                <properties>
                    <codename1.targetType>windows</codename1.targetType>
                    <codename1.targetPlatform>win</codename1.targetPlatform>
                </properties>
            </profile>
            <profile>
                <!-- For sending Windows desktop builds use: mvn cn:build -P windows -->
                <id>windows</id>
                <properties>
                    <codename1.targetType>desktop_windows</codename1.targetType>
                    <codename1.targetPlatform>javase</codename1.targetPlatform>
                </properties>
            </profile>
    
            <profile>
                <!-- For sending Mac Desktop builds use: mvn cn:build -P mac -->
                <id>mac</id>
                <properties>
                    <codename1.targetType>desktop_macosx</codename1.targetType>
                    <codename1.targetPlatform>javase</codename1.targetPlatform>
                </properties>
            </profile>
        </profiles>
    
        <build>
            <testSourceDirectory>src/test/java</testSourceDirectory>
            <plugins>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-compiler-plugin</artifactId>
                    <configuration>
                        <source>1.8</source>
                        <target>1.8</target>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>properties-maven-plugin</artifactId>
                    <version>1.0.0</version>
                    <executions>
                        <execution>
                            <phase>initialize</phase>
                            <goals>
                                <goal>read-project-properties</goal>
                            </goals>
                            <configuration>
                                <files>
                                    <file>${basedir}/codenameone_settings.properties</file>
                                </files>
                            </configuration>
                        </execution>
                    </executions>
                </plugin>
    
                <plugin>
                    <groupId>com.codenameone</groupId>
                    <artifactId>codenameone-maven-plugin</artifactId>
                    <executions>
                        <execution>
                            <id>generate-gui-sources</id>
                            <phase>process-sources</phase>
                            <goals>
                                <goal>generate-gui-sources</goal>
                            </goals>
                        </execution>
                        <execution>
                            <id>cn1-process-classes</id>
                            <phase>process-classes</phase>
                            <goals>
                                <goal>compliance-check</goal>
                                <goal>css</goal>
                                <!--<goal>compile-javase-sources</goal>-->
                            </goals>
                        </execution>
                        <execution>
                            <id>attach-test-artifact</id>
                            <phase>test</phase>
                            <goals>
                                <goal>attach-test-artifact</goal>
                            </goals>
                        </execution>
                    </executions>
                </plugin>
            </plugins>
        </build>
    </project>

LabelPropertyView does not handle a null Date

I have a radLabel linked to a property which is a Date type, and uses the TimeAgo date format, like this:

<radLabel tag="Symbol.lastRefresh" dateFormat="TimeAgo" component.uiid="RefreshLabel" />

When the property value is null, I'd like to see "N/A", which is how the TimeAgoDateFormatter handles a null (quite nice, in my opinion). However, the logic in LabelPropertyView skips the formatter if the property value is null, and instead formats it as text (meaning I eventually see the text "null").

This is due to the implementation of LabelPropertyView._getText():

private String _getText() {
        Property prop = getPropertySelector().getLeafProperty();
        if (prop == null) {
            return "";
        }
        
        if (prop.getContentType().getRepresentationClass() == Date.class) {
            DateFormatterAttribute formatter = getField().getDateFormatter();
            if (formatter != null) {
                Date val = getPropertySelector().getDate(null);
                if (val != null) {
                    return formatter.getValue().format(val);
                }
            }
        }
                
        
        return getPropertySelector().getText("");
    }

Checking the various DateFormatter implementations, I think they all handle null in their own way, so I'd suggest removing the if (val != null) check.

Custom layout for EntityEditor

EntityEditor is a Container and theoretically I can set a custom layout for the container. However, my settings are ignored and some predefined layouts are used depending on what content is being rendered.

It would be very useful to be able to set a custom layouts for rendering EntityList.

My use case is to display list of files (images) and the best option would be GridLayout with 2 or 3 columns.

Could you please consider adding either a setting custom layout or just support for GridLayout for rendering EntityList?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.