Estilos CSS no JMine

Definição de estilo

Estilo no contexto do JMine se refere a todo o conjunto necessário para que a aplicação funcione com um determinado Look and Feel. Isto compreende:

  • Um nome que identifique unicamente o estilo;
  • Um MenuCreator que descreva como o menu da aplicação deve ser criado;
  • Configurações específicas que descrevam recursos extras que são necessários para este estilo, como arquivos CSS, e scripts em Javascript.

Estes estilos são representados pela classe Style e podem ser definidos via Spring, como no exemplo:

<bean id="myStyle" class="jmine.tec.web.wicket.styles.Style" lazy-init="false">
    <property name="styleName" value="myStyle"/>
    <property name="menuCreator" ref="menuCreator"/>
    <property name="styleConfigs">
        <list>
            <ref bean="templateConfig"/>
        </list>
    </property>
</bean>

Configurações específicas de estilo

As configurações específicas de estilo (bean templateConfig do exemplo na seção anterior) são responsáveis por duas configurações do estilo da aplicação:

  • Listar os arquivos CSS e JS a serem carregados por padrão
  • Especificar uma fábrica de componentes capaz de definir que componentes devem ser usados para renderizar determinadas Páginas e Painéis da Aplicação.

Os AbstractHeaderInitializer são as classes responsáveis por indicar os arquivos CSS e JS que devem ser utilizados na aplicação. Caso seja desejável utilizar os CSSs e Javascripts já presents no JMine, pode-se utilizar o JmineHeaderInitializer, que além de já carregar os arquivos presentes no Jmine, procura automaticamente os arquivos existentes nos pacotes css e javascript, sendo suficiente fornecer ao HeaderInitializer o nome do arquivo que deve ser carregado como no exemplo:

<bean id="templateHeaderInitializer" class="jmine.tec.web.wicket.header.JmineHeaderInitializer">
    <constructor-arg>
        <list>
            <value>globals.js</value>
            <value>get_window_height.js</value>
            <value>set_heights.js</value>
            <value>focusStartPage.js</value>
            <value>onload.js</value>
        </list>
    </constructor-arg>
    <constructor-arg>
        <list>
            <value>global.css</value>
            <value>template.css</value>
            <value>page.css</value>
            <value>wicket.css</value>
        </list>
    </constructor-arg>
</bean>

Registro de estilos

Após a definição do estilo desejado, é necessário registrá-lo para permitir seu uso pela aplicação, o que pode ser feito pelo Spring através da infraestrutura de Receivers do JMine, definindo um StyleRegistry, vomo no exemplo abaixo:

<bean id="styleRegistry" class="jmine.tec.web.wicket.styles.StyleRegistry"
    singleton="true" lazy-init="false" />

<bean id="applicationStyles" class="jmine.tec.utils.register.Registrar">
    <property name="receiver" ref="styleRegistry" />
    <property name="registers">
        <list>
            <ref bean="myStyle"/>
        </list>
    </property>
</bean>

Com os estilos registrados, é necessário configurar a aplicação para utilizar o estilo desejado, o que pode ser feito adicionando a propriedade style na sua JMineWicketWebApplication.

Ferramentas, práticas e classes utilitárias

Além da configuração de estilos, existem ferramentas, práticas e classes utilitárias para auxiliar o uso.

StyleHelper

A classe utilitária StyleHelper (jmine.tec.web.wicket.styles.StyleHelper) auxilia na recuperação de informações sobre o atual estilo da aplicação.

  • getCurrentStyleName() - recupera o nome do estilo atual da aplicação.
  • getStyle() - recupera um valor enumerado do estilo atual da aplicação, podendo ser DEFAULT, para o estilo padrão do Jmine, BOOTSTRAP, para o estilo Bootstrap e CUSTOM, caso seja um estilo customizado.

StyleSwitcherPanel

No estilo padrão e bootstrap, o StyleSwitcherPanel (jmine.tec.web.wicket.styles.StyleSwitcherPanel) já é incluído no rodapé da aplicação, apenas no escopo de desenvolvimento. Esse painel contém um combo-box que permite alterar entre os estilos registrados na aplicação.

StyleConfigTransformer

Caso queira alterar um IStyleConfig já definido, o StyleConfigTransformer (jmine.tec.web.wicket.styles.StyleConfigTransformer) permite você adicionar e/ou remover HeaderInitializers configurados nele.

  • setRemoveHeaderInitializer(List<AbstractHeaderInitializer> initializers) - para remover uma lista de HeaderIntializers da configuração.
  • setAddHeaderInitializer(List<AbstractHeaderInitializer> initializers) - para adicionar uma lista de HeaderInitializers à configuração.

Versões específicas dos recursos para estilos específicos

O Wicket permite você definir versões específicas para um recurso específico. Essa definição foi integrada com a estrutura de estilos. Você pode manter versões específicas dos recursos utilizados pela aplicação (CSS, Javascript, HTML, imagens, etc) adicionando o nome do estilo no sufixo do recurso.

Exemplo:

MyPage.html             //Minha página, sem nenhum estilo.
MyPage_mystyle.html     //Minha página, no estilo mystyle
MyCss.css               //Meu CSS, sem nenhum estilo.
MyCss_mystyle.css       //Meu CSS, no estilo mystyle

Se sua aplicação for uma aplicação Jmine (jmine.tec.web.wicket.application.JMineWicketWebApplication), basta na definição do bean da aplicação informar o estilo pela propriedade style.

Exemplo:

<bean id="webApplication" class="jmine.tec.web.pages.app.JMineTestApplication">
        <property name="securityManager" ref="securityManager" />
        <property name="authorizationStrategy" ref="authorizationStrategy" />
        <property name="beanWirer" ref="persistenceAwareBeanWirer" />
        <property name="style" value="default" />
</bean>

Caso sua aplicação não seja uma aplicação Jmine, você deve prover de alguma forma o estilo para a sessão da sua aplicação.

É importante que a sessão de sua aplicação defina o estilo ao inicializar. Por padrão, a aplicação do Jmine já faz isso. Caso utilize uma sessão específica, você deve definir o estilo da aplicação também na sua sessão.

Exemplo:

public Session newSession(Request request, Response response) {
    SecureSession session = new SecureSession(request);
    if (!StringUtils.isEmpty(this.style)) {
        session.setStyle(this.style);
    }
    return session;
}

Importação de arquivos CSS

Como apresentado na primeira seção, o Jmine fornece a possibilidade de configuração de um Estilo para a aplicação, com arquivos CSS e Javascript que serão carregados em todas as páginas da aplicação.

Além dos estilos fornecidos pelo estilo, é uma prática comum o carregamento de CSS únicos para uma página, que se referem a um comportamento ou componente específico. Isto pode ser feito, no Jmine, através do método renderHead que existe em todos os componentes do Wicket.

Por exemplo, na página do Cockpit, onde é necessário adicionar o CSS específico para a página:

    public void renderHead(IHeaderResponse response) {
        super.renderHead(response);
        response.renderCSSReference(ResourceReferenceUtils.getCSSResource("CockpitPage.css", this));
    }

Para criar a representação do recurso a ser importado, pode-se usar um dos vários métodos utilitários implementados em ResourceReferenceUtils.

Em casos que seja necessário um controle mais fino das opções da referência sendo carregada, pode-se instanciar diretamente um GroupedCSSResourceReference, que é a classe devolvida pelo ResourceReferenceUtils. Esta classe recebe como parâmetros:

    public GroupedCSSResourceReference(JmineResourceSections group, int loadOrder, Class<?> scope, String name) {
        super(scope, name);
        this.group = group;
        this.loadOrder = loadOrder;
    }
  • O grupo CSS ao qual a referência deve ser adicionada (ver abaixo para mais informações sobre agrupamento de css)
  • A posição em que a referência deve ser inserida dentro do grupo
  • O escopo da referência (uma página ou componente, por exemplo)
  • O nome do arquivo a ser carregado

Agrupamento de CSS

Uma técnica comum para diminuir o tempo de resposta de requisições Web é a agregação de diversos conteúdos em um único arquivo, a fim de diminuir o número de requisições necessárias para carregar a página. No JMine isto é realizado apenas com os arquivos CSS, através da definição de Grupos CSS para as referências carregadas.

Atualmente são definidos sete grupos CSS, em JmineResourceSections:

  • UNKNOWN: Contém referências adicionadas sem um grupo definido. Por padrão os recursos dessa seção não são agrupados em um único arquivo.
  • GLOBAL: Contém referências que devem ser carregadas em todas as páginas da aplicação, geralmente adicionadas em nível de Estilo ou aplicação
  • JQUERY: CSS relacionados à biblioteca jQuery e plugins para a mesma
  • BOOTSTRAP: CSS relacionados ao framework Bootstrap [1] e suas extensões, e ao tema de mesmo nome
  • PAGE: CSS específicos da página sendo carregada. É o grupo típico para recursos adicionados diretamente em uma página.
  • COMPONENT: CSS referentes a um componente específico da página sendo carregadas.
  • CUSTOM: CSS que, normalmente por questões de compatibilidade, precisam ser carregados por último durante o carregamento da página.
[1]O estilo padrão fornecido pelo JMine utiliza a versão 2.3.2 do Bootstrap
Desta forma, apenas um arquivo CSS por grupo será transmitido a cada requisição, agrupando o conteúdo de todos os recursos CSS daquele grupo. A única exceção é o grupo UNKNOWN, como já citado. Além disso, os CSS agrupados serão carregados na página na ordem em que se encontram listados acima.

Ativando/Desativando o agrupamento de CSS

O agrupamento de CSS em grupos encontra-se ligado por padrão no JMine. Caso seja necessário, porém, pode-se desligar este agrupamento, fazendo com que os CSS sejam carregados individualmente e o Wicket se encarregue de definir a ordem em que serão carregados.

Para desligar esta configuração, basta configurar a propriedade useAggregatedResources da Application do projeto, o que pode ser feito ou diretamente via código, utilizando o método setUseAggregatedResources da JMineWicketWebApplication ou via Spring (configurando esta propriedade no bean da aplicação, como no exemplo):

<bean id="webApplication" class="jmine.tec.web.pages.app.JMineTestApplication">
    <property name="securityManager" ref="securityManager" />
    <property name="authorizationStrategy" ref="authorizationStrategy" />
    <property name="beanWirer" ref="webBeanWirer" />
    <property name="style" value="bootstrap" />
    <property name="useAggregatedResources" value="false"/>
</bean>