Off-the-shelf UI component for table-to-table field mapping? - java

I wanted to check with the community if there is any existing off-the-shelf component or library that handles table-to-table field mappings, specifically, defining meta-data for the data fields.
Example (from Salesforce's UI):
Simply put, my inputs would be a list of source fields and target fields, and the UI component should allow the user to map one to the other, or have a source field not map to any target field at all.
Since I've seen this UI component so many times in various corporate systems, now that I need it I wanted to see if it was out there in one form or another before we start building. I'd be particularly interested in C# or Web (JS) oriented solutions, but would take anything for reference.
Thanks!

Related

JavaFX 8: Separation of model/domain from view

I am just learning JavaFX 8. It seems if you want to display something in a control, say a TableColumn, you need that something to be an instance of ObservableValue, for example, a SimpleStringProperty.
So, in the commonly used Person object, I might have a SimpleStringProperty for "firstName", and then I would be able to use that as the value of TableColumn, like this:
TableColumn<Person, String> firstNameCol =
new TableColumn<Person, String>("First Name");
firstNameCol.setCellValueFactory(
new PropertyValueFactory<Person, String>("firstName"));
But, Person is what I would call a "domain" class -- something that my model would freely refer to and use. I don't want my domain and model layers to be aware of / dependent on the fact that the application is displayed using JavaFX.
Am I right in thinking that the model/domain should be kept pure in that regard? If so, what is the best way to accomplish that using JavaFX? E.g., should I write adapter classes somehow for my domain objects to present them with ObservableValues?
It is certainly wise to keep your domain model pure, and not tie it to any specific framework as you may need to use those objects in other contexts (database storage, exposing them in a REST API, doing batch processing, etc.).
Changing your domain model to use JavaFX properties would add a lot of extra baggage to those classes that you need to avoid in other scenario's.
JavaFX however does have a standard way of dealing with this situation so you can connect your domain model to its controls easily, and it works in a way you already suggested, using adapters from its javafx.beans.property.adapter package.
Using these adapters however won't make your controls respond to values changing in your domain objects like they would with SimpleStringProperty for example.
It will depend on your requirements if that is a problem, if it is however you may consider modifying your domain model objects to add PropertyChangeListener support. This is a relatively light weight change (vs. full JavaFX Properties) and would not make you depend on JavaFX (only on java.beans which is less problematic).
See this answer for a thorough explanation of how to use domain model classes in JavaFX directly: JavaBean wrapping with JavaFX Properties
Why do you want to avoid using any JavaFX class at all?
JavaFX Properties (found in the javafx.beans.property package) are just an extension to the regular JavaBeans properties.
They are part of the JavaFX Properties and Bindings framework, which doesn't depend on the JavaFX Toolkit to have its functionality implemented, nor does it require your application to leverage the JavaFX UI classes in order to build its graphical user interface.
It can therefore be used as a standalone facility anywhere in your code, without having to worry about the model/domain being coupled to this particular implementation of the view.
You should consider the JavaFX Properties and Bindings framework a general utility that is inherently indipendent of the implementation of the view due to its nature, just like is any other general-purpose library (e.g. Guava). You could, for example, switch to a Swing application at any time, while still keep using it.
But if you still prefer to not leverage its functionality when possible, then there's a case when you can actually do so:
if what's being presented isn't going to change (e.g. the state corresponding to the table model in your domain class is immutable), and standard property getters are present, then, as per the PropertyValueFactory documentation:
There is fall-through support for attempting to call get<property>() or is<property>(). If a method matching this pattern exists, the value returned from this method is wrapped in a ReadOnlyObjectWrapper and returned to the TableCell. However, in this situation, this means that the TableCell will not be able to observe the ObservableValue for changes.
Avoid adapters; they are meant to be used with legacy code only that cannot be altered in any way.
Related Posts
JavaBean wrapping with JavaFX Properties
JavaFX Properties Design
Does the use of ObservableList in JavaFX go against Model-View-Controller separation?
The next version (8.6.0 in active dev) of JRebirth will allow to generate these FXJO (javaFX Java Object) from POJO (Plain Old Java Object) by using annotation processor.
Or by directly parsing an ecore file.
It can give you the opportunity to not alter your Business Model with UI related stuff like Properties.

Handling large number of Swing components

I'm doing a favor for an engineer friend by making him a program that helps him with the scheduling of his factory's production. Each type of product is broken down to a set of steps (they share a lot of them, but there are a few differences).
The programming issue:
Each time a new production process is registered I display a number of checkboxes representing the before mentioned steps. He can choose which steps he needs added for this particular product. If he checks a checkbox, two (or more) textfields appear where he can add additional information (starting date, duration, comments, etc...). My problem is that this is a lot of individual components and I am unsure how to handle them. Since I will need to have access to all of them at some point (the checkboxes to see if that step is needed and all the textfields for the data) I was thinking of having them all as fields, but that doesn't feel right...
Another approach could be to make a container class that groups the textfields together with the checkbox. Something like this:
ArrayList<MyComponentGroup> group;
for (MyComponentGroup cg : group) {
if (cg.getCheckBox().isSelected()) {
//access and read the data from all the textfields in this object
}
}
What is the Java programming convention or the most commonly used method to handle this situation?
Here's what I would do when dealing with tons of components and similar requirements:
I would model the relationship between options (available through checkbox selections) and the related data to fill (requirements). This model may already be available for you.
I would attempt to use PropertyEditor instances and map them to model elements.
When the time comes to save or use the data filled by the user, I would just walk the model represented on the screen, grab the associated editors and deal with the value of those editors.
I think that the approach that I described above will give you less work and potentially and it will bring more flexibility for your friend.
You'd only pay the initial cost of getting the components relationships/dependencies in a nice model as well as registering the relevant PropertyEditors for visual editing.
One approach is to consistently give each JComponent a unique name. Use something hierarchical to fit the complex process, like "Whites.Rinsecycle.enableCB". For completeness, store this String as a clientProperty in the JComponent. Then you can use that as a key in a large Map to access all the components.
Maybe not the most "elegant" (I'd tend to go with a hierarchy of JPanels with relevant fields) but for a slightly quick and dirty, moderate sized project this is reasonable.

Java Swing Properties Editor

Is there an existing library that automatically creates a Java Swing form from a Properties (or Properties-like) object? i.e. shows 2 columns, as many rows as there are properties, properly justified Property names on the left, JTextFields for the values on the right.
I do not have access to the property names (or expected types) at compile time.
In addition, the solution must allow some value fields to be set read-only after construction.
A great solution would :
allow some property values to be specified as sensitive, requiring a JPasswordField
provide input format checking, e.g. against an object type (such as URL, Double, etc)
or by type-sensitive so that appropriate widgets (or buttons to bring up appropriate widgets) are used instead of JTextField for standard object types. e.g. JFileChooser for properties expected to be of a File type, SwingX Colour/Date selection, numerical format checking)
Getting into type-specific properties starts to sound like JavaBeans. I'd rather not go down the JavaBeans route unless there is a really easy - not a big framework - solution for this for an object that is a Javabean.
(I already know how to manually do this and could write a simple implementation myself that ignores sensitivity/type information - anyone answering along those lines will be shot down! I only want to know if such a beast already exists, preferably in a well maintained library)
UPDATE: related to Java Beans - creating an inspector window
No such thing exists. However, I wrote a rudimentary feature (and released it OSS) for https://github.com/fommil/zibaldone
We use JIDE, which not open-source.
If you don't mind that, take their Property Grid for a spin - it seem to match all your requirements.

Alfresco - Best practices for custom document lifecycle (Java?)

After talking with some people at the DevCon in London and after looking at Records Management source code I noticed that there's actually no good example of how to implement custom documents lifecycle.
I know there's examples of rules and content modeling and even workflows but that solutions can't be really used to implement something more serious like Records Management.
What I'm wondering is how to effectively map a Java solution (I have more experience with OO and Java than Alfresco) to Alfresco. What should be defined as Java class and what should be type/aspect in content model. When to favor behaviour over rules and when to actually use workflows. In my first few projects I used workflows to implement document lifecycle, I wrote quite a lot of bussines/domain logic in workflow nodes - as actions (JS). I found out later that this is quite hard to maintain since you have some code in workflows, some in repository as scripts (Data Dictionary/Scripts) some Java, ...
Is the Records Management good example to start learning from and see some best practices in implementing full document lifecycle? Are there any other resources?
I'm strugling the most with how to implement full lifecycle in java and how to "centralize" the bussines/domain logic.
The scope of ECM is huge, and therefore it's quite hard to come up with completely general guidelines: you really need to stick with the use case you have to address and find the best solution to it. RM is a great example of how to implement a records management solution on top of Alfresco, but it's absolutely useless when it comes to implementing a web publishing process, for which the WCM QS is what you want to look at as a starting point.
On the whole of APIs Alfresco offers to developers, their inner characteristics are ultimately the best resource to understand when to use them. Let's see if I can make sense of (at least most important among) them.
Content Types
This is where you always need to start implementing an Alfresco project. You need to closely work with someone with deep domain knowledge of the documental processed you need to implement, and define root elements for different document lifecycles. In Alfresco you must assign one and only one content type to a given node. This is done at content creation time, and it's not often changed along the content lifecycle. Thus, content types are normally used to identify content items with radically different lifecycles (e.g. cm:document and ws:article), and defining a content type means to extract the basic meta data properties that will be used or useful along the whole document lifecycle.
Aspects
While content types are basically a static vertical classification and enrichment of documents, aspects are their dynamic cousins. As opposed to content types, you can apply or remove aspects dynamically with lesser-to-none destructive consequences to the content nodes. They can or not enrich the document with more metadata, and can be applied to items regardless of their content types. These characteristics make aspects possibly the most flexible feature of the Alfresco content model: you can use them to to mark content or enable/disable operations shared among different content lifecycles (e.g. cm:versionable, rma:filePlanComponent). By nature, aspects are meant to handle cross cutting concepts that occur in several distinct lifecycles or lifecycle steps.
Behaviors
Here we start an overview of how to add logic in your Alfresco solution. Behaviors are automatic computations that are fired by specific triggers, where triggers are defined as a [type/aspect, policy] pair (e.g. [cm:versionable, onCreateNode]). They are in general executed within the same transaction of the event that fires the trigger, there's no guarantee on the order of execution and there's no coordination or orchestration. This makes them perfect for automatic content generation or handling (e.g. creating a thumbnail or updating some metadata) which needs to be integral parts of the content lifecycle, but that are not strictly part of a formalized process.
They're rather accessory or supplementary operations for normal operations or workflows. They require Java coding, thus forming a rather fixed part of your solution. You normally identify and design behaviors right after finishing the content modeling phase and before starting designing the workflows.
Rules
Similar to behaviors, rules are triggered upon specific events, but they're a much more generic and dynamic than them. You can configure rules only on folders, at runtime, and bind them to events that happen within the folder. This makes them ideal to create special buckets within your content repository (e.g. send an email whenever content is added to a specific folder), where side effects happen when you deal with content within it. They're implemented as hidden nodes within folders, thus being integral parts of an export: you can in theory borrow them in different Alfresco implementations, provided the required pieces are available.
They normally are used when a piece of logic applies to content of several different types, but possibly not all the items of the affected types, and only when you can store all the affected content nodes within a sub branch of the repository. Even if such constraint might sound heavy, rules turn out to be quite a handy tool (e.g. generate a thumbnail for all the png documents with mime type image/png in /images).
Actions
Actions are bundled pieces of logic that can be invoked against a node on demand. They're the building blocks for rules, and often used within workflows (e.g. send an email). They are also handy to be directly bound to UI components/buttons, in order to allow the user to be directly exposed to available features of your application. You normally end up developing an action when you need (of want to enable) reusing the same piece of logic in different contextes, such as a workflow, a rule and/or direct user interaction.
Workflows
This is probably the core business of document management: workflows allow you to build a coordinated process that guides users through a defined sequence of steps, basically implementing a human algorithm. Workflows allow you to write custom code, but for the sake of maintainability you probably want to limit such code to the bare minimum of what the workflow itself needs in order to execute, and externalize more complex operations to actions or scripts.
If you're doing document management, the design and implementation of a workflow can start right after content modeling, possibly spawning several other development activities such as accessory actions and scripts, and they're likely to last until you call your code feature complete, and you start fiddling with all the infinite change requests or leftovers on the UI :-)

How Do You Implement an Editable Grid Control in Html/JavaScript that Binds to a Collection of Java Objects?

Consider a simple POJO Java Object:
class MyObj {
String a, b;
Integer c;
}
My application executes a Struts action and sets a Collection of these on the Http Request:
request.setAttribute("myObjects", getCollectionOfMyObj());
The action then forwards to a JSP page, and this is where my questions centres:
What is the simplest way I can
bind this collection into a grid,
such that is renders a table with
three columns (a, b, c) and one row
per object in the passed collection.
A key characteristic I require,
is that I can add a new field to the
Java object and it requires no (or
minimal) changes to the UI code,
i.e. the object is being
introspected and displayed so that I don't have D-R-Y
violations in the UI?
How can I make the grid
editable, so that any changes to a
row are reflected back into a new (or the existing)
Collection of Java objects in the
request for use by other Actions
(e.g. to persist the changes)?
Many thanks in advance for your help, please let me know if you need further clarification.
Arun
If you need to display only your data without editing it I recommend using displaytag, its a custom tag that is used to render tabulated data, and its highly customizable.
However, If you want to edit your data, I advise you to move to some javascript solutions, dhtmlxgrid is one good option, there are many many other solutions in javascript that you could use, however here you will be working with XML data and AJAX, this would be easier to you, and it will make your table more dynamic to changes. After mastering your chosen javascript-solution that best fits you, you could wrap it into a custom tag and generalize it ;-).
There are tons of different ways you can achieve the above. But since you are already using Struts I would recommend stick to Struts UI Tags . It will make things little bit easy to start with

Categories