Studio 12 BETA Published

Hello everyone,
We have just published the 12.0.BETA version of the CUBA Studio.

Notable changes of the release 12 include:

Screen Layout Designer rework

The Screen Layout Designer has been re-implemented using native IntelliJ UI components.
It now has better responsiveness, faster opening time. Many small improvements were made to the designer.
Let us know what you think about new designer UI!

Ability to generate event handlers and install delegates in the Screen Designer

In addition to the Palette and Properties tabs in the Screen Designer, a new Handlers tab has been added.
It shows existing handler methods and allows to quickly generate new handlers for the component events and component method delegates.
Just double-click the corresponding handler row to generate the method stub!

Scaffolding for various application event listeners

Now you can easily add reaction of your application for the following system events:

  • application lifecycle events: application started, application stopped etc.
  • authentication hooks: user logged in, before login, user session started etc.

Event listener generation is accessible in two ways:

  • Open existing Spring Bean in the core module and press “Subscribe to event” in the top actions panel of the source code editor.
  • In the “Middleware” section of the CUBA project tree invoke a right click → New → Event Listener context menu item.

Project-wide options for screen generation

A few settings affecting screen generation have been extracted as a project-wide Studio setting (and can be committed to VCS). These settings are used by the New → Screen… wizard.
To change the settings, open Main Menu → CUBA → Settings → Screen Generation Settings.
The following screen settings are available:

  • Form field width (450px by default) - used by entity editors
  • Keep editor actions at the bottom - used by entity editors that are opened as a “full screen” (not as dialog)
  • Force modal open type for editors - used by entity editors opened as a dialog

Build WAR and UberJAR UI improvements

Several sub-elements have been added to the WAR Settings and UberJAR Settings items located in the Deployment section of the CUBA project tree.
From now you can build WAR or UberJar just by double-clicking corresponding element “Build WAR” or “Build UberJAR”, if building the corresponding artifact is turned on.
Configuration files related to these artifacts (single-war-web.xml, logback.xml, jetty-env.xml etc) are now shown near to the WAR/UberJAR Settings project tree elements for convenient access.

Suggest Table column delegates from main “Install delegate” dialog

The Install Delegate dialog that is invoked from the screen controller now allows to generate formatter, custom column generator or value provider for any table column.

Beta Testing

We are now in the process of testing the new Studio version.
We will greatly appreciate if you try to use the beta version with your environment/project and let us know about any issues.

The 12.0.BETA release has been published to the separate plugins channel in the JetBrains plugins repository.
In order to try the beta version, you need to do the following:

  • Open the IDEA Settings → Plugins dialog.
  • Click to the :gear: icon and select Manage Plugin Repositories.
  • Click “+” (“Add”) and enter the following in the Repository URL field:
    https://plugins.jetbrains.com/plugins/beta/list
  • Switch to the Marketplace tab. You should immediately see that CUBA plugin requests for update to 12.0.BETA version.
  • Click Update.

If (when) you need to return back to stable plugin version, do the following:

  • Open the IDEA Settings → Plugins dialog.
  • Uninstall CUBA plugin
  • Click to the :gear: icon and select Manage Plugin Repositories.
  • Remove “beta” repository from the list
  • Install CUBA plugin again, it will come from the stable plugins channel.

We are looking forward to your feedback!

5 Likes

Looks great! I just have installed it and it’s running without any issues.

Quick question, could you please explain how the custom column generator works here? Sharing some screen-shot straight to the point that will help even better.

Hi
After doing some work in this version. I ma getting the following error signal:
image

Here is the log file extract.
error log.txt (82.8 KB)

Another observation:

When I have added a Associated Entity and want to user OptionsDatasource, it doesn’t save after selection in V12 BETA but when I have switched back to V11.x, it works.

image

New UI editor looks great! The only problem so far is small blurry icons in components tree on Hi DPI:

image

Thanks for reporting. Created a ticket, although not sure how quickly it’s going to be fixed.

Hi,
Thanks for reporting. In Studio v12 “optionsDatasource” selector looks not perfect. But I am not sure what you meant by “doesnt save after selection”, it did work for me when I tried.

Hi,

This error looks like a JVM crush. I don’t think it relates to Studio changes.

Comprehensive information about generated columns is available in the developer’s manual:
https://doc.cuba-platform.com/manual-7.0/gui_Table.html#gui_Table_addGeneratedColumn

1 Like

I unsure if it is a JVM crush as my backup copy of the application works.

There might had some unknown problem, but it’s now working and didn’t behave like that again so far. I am using the beta version in my project development. Thanks for your help.

1 Like

Hi
When I am trying to edit properties of a DataContainer in one of the Editor screens, the IDE is becoming freeze with the following error. I have tried this several times by even restarting my computer but it is happening again and again.

java.lang.Throwable: Write-unsafe context! Model changes are allowed from write-safe contexts only. Please ensure you're using invokeLater/invokeAndWait with a correct modality state (not "any"). See TransactionGuard documentation for details.
  current modality=ModalityState.NON_MODAL
  known modalities:
ModalityState:{}, writingAllowed=true;
ModalityState:{}, writingAllowed=true;
ModalityState.NON_MODAL, writingAllowed=true;
ModalityState:{}, writingAllowed=true;
ModalityState:{}, writingAllowed=true
	at com.intellij.openapi.diagnostic.Logger.error(Logger.java:145)
	at com.intellij.openapi.application.TransactionGuardImpl.assertWriteActionAllowed(TransactionGuardImpl.java:232)
	at com.intellij.psi.impl.PsiModificationTrackerImpl.fireEvent(PsiModificationTrackerImpl.java:94)
	at com.intellij.psi.impl.PsiModificationTrackerImpl.incCountersInner(PsiModificationTrackerImpl.java:102)
	at com.intellij.psi.impl.PsiModificationTrackerImpl.treeChanged(PsiModificationTrackerImpl.java:119)
	at com.intellij.psi.impl.PsiManagerImpl.fireEvent(PsiManagerImpl.java:344)
	at com.intellij.psi.impl.PsiManagerImpl.beforeChildrenChange(PsiManagerImpl.java:237)
	at com.intellij.psi.impl.BlockSupportImpl.sendBeforeChildrenChangeEvent(BlockSupportImpl.java:420)
	at com.intellij.pom.core.impl.PomModelImpl.startTransaction(PomModelImpl.java:328)
	at com.intellij.pom.core.impl.PomModelImpl.lambda$runTransaction$2(PomModelImpl.java:136)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:586)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:532)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:86)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeNonCancelableSection(CoreProgressManager.java:192)
	at com.intellij.pom.core.impl.PomModelImpl.runTransaction(PomModelImpl.java:135)
	at com.intellij.psi.impl.source.xml.XmlTagImpl.addInternal(XmlTagImpl.java:1105)
	at com.intellij.psi.impl.source.xml.XmlTagImpl.addInternal(XmlTagImpl.java:1054)
	at com.intellij.psi.impl.source.tree.CompositePsiElement.addInnerBefore(CompositePsiElement.java:321)
	at com.intellij.psi.impl.source.tree.CompositePsiElement.add(CompositePsiElement.java:151)
	at com.intellij.psi.impl.source.xml.XmlTagImpl.setAttribute(XmlTagImpl.java:972)
	at com.haulmont.studio.ui.sd.layout.model.baseprop.StringComponentProperty._toXml(SourceFile:46)
	at com.haulmont.studio.ui.sd.layout.model.baseprop.ComponentProperty.lambda$commitToTag$2(SourceFile:288)
	at com.intellij.openapi.command.WriteCommandAction$BuilderImpl$1.run(WriteCommandAction.java:124)
	at com.intellij.openapi.application.RunResult.run(RunResult.java:35)
	at com.intellij.openapi.command.WriteCommandAction.lambda$null$1(WriteCommandAction.java:263)
	at com.intellij.openapi.application.impl.ApplicationImpl.runWriteAction(ApplicationImpl.java:1054)
	at com.intellij.openapi.command.WriteCommandAction.lambda$performWriteCommandAction$2(WriteCommandAction.java:262)
	at com.intellij.openapi.command.WriteCommandAction.lambda$doExecuteCommand$4(WriteCommandAction.java:319)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:220)
	at com.intellij.openapi.command.impl.CoreCommandProcessor.executeCommand(CoreCommandProcessor.java:188)
	at com.intellij.openapi.command.WriteCommandAction.doExecuteCommand(WriteCommandAction.java:321)
	at com.intellij.openapi.command.WriteCommandAction.performWriteCommandAction(WriteCommandAction.java:262)
	at com.intellij.openapi.command.WriteCommandAction.execute(WriteCommandAction.java:244)
	at com.intellij.openapi.command.WriteCommandAction$BuilderImpl.run(WriteCommandAction.java:126)
	at com.haulmont.studio.ui.sd.layout.ScreenWriteCommandAction.run(SourceFile:15)
	at com.haulmont.studio.ui.sd.layout.model.baseprop.ComponentProperty.commitToTag(SourceFile:270)
	at com.haulmont.studio.intellij.ui.sd.designer.EditorTools.componentPropertyChange(SourceFile:293)
	at com.haulmont.studio.intellij.ui.sd.designer.ScreenLayoutDesigner.fireComponentPropertyChange(SourceFile:248)
	at com.haulmont.studio.intellij.ui.sd.designer.ScreenLayoutDesigner.setComponentProperty(SourceFile:235)
	at com.haulmont.studio.intellij.ui.sd.designer.prop.SdPropertyItem.lambda$setValue$1(SourceFile:60)
	at com.haulmont.studio.ui.util.UiWrapper.lambda$runComponent$0(SourceFile:17)
	at com.haulmont.studio.ui.util.UiWrapper.lambda$compute$2(SourceFile:48)
	at com.vaadin.ui.UI.accessSynchronously(UI.java:1392)
	at com.haulmont.studio.ui.util.UiWrapper.compute(SourceFile:46)
	at com.haulmont.studio.ui.util.UiWrapper.computeComponent(SourceFile:30)
	at com.haulmont.studio.ui.util.UiWrapper.runComponent(SourceFile:16)
	at com.haulmont.studio.intellij.ui.sd.designer.prop.SdPropertyItem.setValue(SourceFile:58)
	at com.haulmont.studio.intellij.ui.ptable.PTableModel.setValueAt(SourceFile:67)
	at javax.swing.JTable.setValueAt(JTable.java:2741)
	at javax.swing.JTable.editingStopped(JTable.java:4723)
	at javax.swing.AbstractCellEditor.fireEditingStopped(AbstractCellEditor.java:141)
	at javax.swing.AbstractCellEditor.stopCellEditing(AbstractCellEditor.java:85)
	at com.haulmont.studio.intellij.ui.sd.designer.prop.sdeditor.SdTableCellEditor.stopCellEditing(SourceFile:49)
	at javax.swing.JTable.columnMarginChanged(JTable.java:4592)
	at javax.swing.table.DefaultTableColumnModel.fireColumnMarginChanged(DefaultTableColumnModel.java:628)
	at javax.swing.table.DefaultTableColumnModel.propertyChange(DefaultTableColumnModel.java:691)
	at java.beans.PropertyChangeSupport.fire(PropertyChangeSupport.java:335)
	at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:327)
	at javax.swing.event.SwingPropertyChangeSupport.firePropertyChange(SwingPropertyChangeSupport.java:92)
	at java.beans.PropertyChangeSupport.firePropertyChange(PropertyChangeSupport.java:263)
	at javax.swing.table.TableColumn.firePropertyChange(TableColumn.java:278)
	at javax.swing.table.TableColumn.firePropertyChange(TableColumn.java:284)
	at javax.swing.table.TableColumn.setWidth(TableColumn.java:514)
	at javax.swing.JTable$2.setSizeAt(JTable.java:3232)
	at javax.swing.JTable$5.setSizeAt(JTable.java:3322)
	at javax.swing.JTable.adjustSizes(JTable.java:3358)
	at javax.swing.JTable.adjustSizes(JTable.java:3326)
	at javax.swing.JTable.setWidthsFromPreferredWidths(JTable.java:3240)
	at javax.swing.JTable.doLayout(JTable.java:3128)
	at com.intellij.ui.table.JBTable.doLayout(JBTable.java:392)
	at java.awt.Container.validateTree(Container.java:1696)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validateTree(Container.java:1705)
	at java.awt.Container.validate(Container.java:1631)
	at java.awt.Window.dispatchEventImpl(Window.java:2744)
	at java.awt.Component.dispatchEvent(Component.java:4725)
	at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:764)
	at java.awt.EventQueue.access$500(EventQueue.java:98)
	at java.awt.EventQueue$3.run(EventQueue.java:715)
	at java.awt.EventQueue$3.run(EventQueue.java:709)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
	at java.awt.EventQueue$4.run(EventQueue.java:737)
	at java.awt.EventQueue$4.run(EventQueue.java:735)
	at java.security.AccessController.doPrivileged(Native Method)
	at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
	at java.awt.EventQueue.dispatchEvent(EventQueue.java:734)
	at com.intellij.ide.IdeEventQueue.defaultDispatchEvent(IdeEventQueue.java:729)
	at com.intellij.ide.IdeEventQueue._dispatchEvent(IdeEventQueue.java:678)
	at com.intellij.ide.IdeEventQueue.dispatchEvent(IdeEventQueue.java:373)
	at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
	at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
	at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
	at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

Another issue, JPA QL Exitor pop-up in screen designer doesn’t suggest (not context sensitive) in legacy screen.

Hi,
the new plugin is really a good progress - thanks for your efforts.

Following observation in the data model designer:
when you create a entity with perant ‘StandardEntity’ you will see the field ‘on delete’ for an attribute of type composition.
If you use as perant ‘BaseStringIdEntity’ you didn’t see the field ‘on delete’ at all (not in the Add attribute dialog, nor in the list when you select an existing property) for an attribute of type composition.

Regards,
Steven

Hi,

another issue in the data model designer:

Creating a new entity with perant ‘BaseStringIdEntity’ will automatically select ‘hasUuid’ which add an entry in the related messages.properties for the uuid.
If you unselect the ‘hasUuid’ the related line in the messages.properties will not deleted.
Also if you have unselected the ‘hasUuid’ after creation and delete the whole entity (class) then there is still the line for the uuid attribute in the messages.properties.

Regards,
Steven

This version is really fast noticeably and it is significant when one has a large project! Bravo CUBA team!

I legacy screen design, I am noticing activating or inactivating a field doesn’t change but it worked when I changed it in xml.

Just a proposal, When we add a new attribute to an entity which is object as below example, if you please populate the name from the “Type” field automatically that will increase the productivity and avoid typo.

image

We know about this bug: https://youtrack.cuba-platform.com/issue/STUDIO-6904

Could not reproduce, sorry.

Hi,
Let me show you the OnDelete declaration:

/**
 * Marks a link to other entity for specific soft deletion behaviour.<br>
 * <b>Taken into account by persistence when "this" entity is deleted.</b><br>
 * See also {@link DeletePolicy}
 *
 */
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD})
public @interface OnDelete

OnDelete relates to soft-deletion. Therefore it is shown only for those entities which implement SoftDelete.
So if you mark BaseStringIdEntity-descendant as SoftDelete - then OnDelete is shown.

Thanks, created a ticket.