Tasti funzione - Help in linea

Buongiorno,

avrei necessità di intercettare la pressione del tasto F1, per richiamare un help in linea, possibilmente avendo indietro il riferimento allo screen dove e’ stato premuto.

Non sono pero’ riuscito a trovare niente del genere nella documentazione.

Qualcuno mi sa dare un’indicazione da che parte cominciare?

Saluti

Marco

Ciao Marco!

E’ molto semplice, devi implementare una custom action, eccotela:

package com.company.helpapp.web.actions;

import com.haulmont.cuba.gui.components.AbstractAction;
import com.haulmont.cuba.gui.components.ActionType;
import com.haulmont.cuba.gui.components.Component;
import com.haulmont.cuba.gui.meta.StudioAction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

@StudioAction(description = "Attiva il supporto help contestuale")
@ActionType(HelpAction.ID)
public class HelpAction extends AbstractAction {

    public static final String ID = "help";
    public static final String SHORTCUT = "F1";
    private static final Logger log = LoggerFactory.getLogger(HelpAction.class);

    public HelpAction() {
        super(ID, SHORTCUT);
    }

    public HelpAction(String shortcut) {
        super(ID, shortcut);
    }

    @Override
    public void actionPerform(Component component) {
        String frameId = ((Component.BelongToFrame) component).getFrame().getId();
        log.debug("HELP INVOKED ON FRAME {} !!!", frameId);
    }
}

In actionPerform fai la logica che vuoi, qua ti loggo semplicemente l’ID del frame dove hai agganciato l’azione. Puoi anche cambiare lo shortcut di default (F1) passandolo al costruttore.

Adesso devi abilitare la scansione delle azioni in web-spring.xml:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:gui="http://schemas.haulmont.com/cuba/spring/cuba-gui.xsd">

    <!-- Annotation-based beans -->
    <context:component-scan base-package="com.company.helpapp"/>
    
    <gui:screens base-packages="com.company.helpapp.web"/>
<!-- questa riga di seguito con il tuo package che contiene le custom actions -->
    <gui:actions base-packages="com.company.helpapp.web.actions"/>
</beans>

Infine devi registrare questa azione a livello di screen:

package com.company.helpapp.web.screens;

import com.company.helpapp.web.actions.HelpAction;
import com.haulmont.cuba.gui.components.Actions;
import com.haulmont.cuba.gui.screen.Screen;
import com.haulmont.cuba.gui.screen.Subscribe;
import com.haulmont.cuba.gui.screen.UiController;
import com.haulmont.cuba.gui.screen.UiDescriptor;

import javax.inject.Inject;

@UiController("helpapp_SomeScreen")
@UiDescriptor("some-screen.xml")
public class SomeScreen extends Screen {
    @Inject
    protected Actions actions;

    @Subscribe
    protected void onInit(InitEvent event) {
        getWindow().addAction(actions.create(HelpAction.ID));
    }
}

Potresti anche automatizzare l’inject nel controller creando un cosiddetto “mixin”:

package com.company.helpapp.web.mixins;

import com.company.helpapp.web.actions.HelpAction;
import com.haulmont.cuba.core.global.AppBeans;
import com.haulmont.cuba.gui.components.Actions;
import com.haulmont.cuba.gui.screen.Screen;
import com.haulmont.cuba.gui.screen.ScreenContext;
import com.haulmont.cuba.gui.screen.Subscribe;
import com.haulmont.cuba.gui.screen.UiControllerUtils;

public interface WithHelp {
    @Subscribe
    default void initHelp(Screen.InitEvent event) {
        final Screen thisScreen = event.getSource();
        thisScreen.getWindow().addAction(AppBeans.get(Actions.class).create(HelpAction.ID));
    }
}

A questo punto è sufficiente implementare WithHelp nei tuoi controller:

package com.company.helpapp.web.screens;

import com.company.helpapp.web.actions.HelpAction;
import com.company.helpapp.web.mixins.WithHelp;
import com.haulmont.cuba.gui.components.Actions;
import com.haulmont.cuba.gui.screen.Screen;
import com.haulmont.cuba.gui.screen.Subscribe;
import com.haulmont.cuba.gui.screen.UiController;
import com.haulmont.cuba.gui.screen.UiDescriptor;

import javax.inject.Inject;

@UiController("helpapp_SomeScreen")
@UiDescriptor("some-screen.xml")
public class SomeScreen extends Screen implements WithHelp {
}

In questo modo eviti la duplicazione di codice in ogni controller, e puoi ancora estendere i tuoi controller da una base class dato che implementi un’interfaccia (e puoi avere infiniti mixins per un controller con questa tecnica).

Fammi sapere se tutto chiaro :wink:

A presto e buon lavoro,
Paolo

Ciao Paolo,
intanto grazie per la pronta ed esauriente risposta, cosi’ a prima vista non ho capito proprio tutto :slight_smile: , nel we ci studio con calma e in maniera approfondita.
Ti faccio sapere
Grazie per ora
Marco

Ciao Marco,
sei riuscito a provare? Funziona tutto o hai ancora qualche dubbio?

Buona giornata
Paolo

Buongiorno Paolo,
ancora non sono riuscito a guardarlo con calma, sono un po’ in affanno…
Spero nel prossimo we.
Comunque ti faccio sapere.
Marco

Ciao Paolo,
mi pareva a prima vista che non fosse una cosa semplicissima :frowning:
Conosco ancora troppo poco Cuba, devo andare per gradi.
Prima cosa, la classe dove la devo creare nell’albero dell’applicazione?
L’unico posto ad ora dove sono riuscito a creare delle classi e’ dentro Services.
Services
E’ questo il posto corretto dove creare HelpAction?
Marco

Ciao,
per passare al “livello successivo” devi abbandonare la vista CUBA dell’albero di progetto.
Devi lavorare nella vista di progetto normale di IntelliJ IDEA (CUBA Studio se usi la loro versione free). Una volta in quella vista puoi lavorare su tutto, e non solo sulle cose basilari che ti vengono proposte nella vista CUBA. Purtroppo quello che vedi e puoi fare nel ramo CUBA è solo una piccola parte del framework, considerata la più comune da cui iniziare progetti basati sui dati.

Screenshot 2021-01-29 at 00.07.39

Per vedere dove ho creato le classi basta che guardi la prima riga package ... e crei i package di conseguenza, ma è solo una convenzione, puoi creare le classi dove ti pare e fare un calderone unico, ma sai che poi te ne pentirai fra qualche mese o anno…

Qui vedi un’organizzazione basilare per custom actions e mixins (tutte devono risiedere nel modulo web dato che sono fruibili e consumabili solo da quel tier, nel core sarebbero inutili):

Screenshot 2021-01-29 at 00.10.46

Nei docs di CUBA trovi tutti i dettagli sulle actions di CUBA e come crearne di custom, e anche un articolo su cosa sono i mixins e come si creano (anche se di base te l’ho scritto nel mio post).

Paolo