Avant de lire cette section, veuillez lire la section tooltip-uppercase . Cette section permet de gérer une nouvelle propriété CSS tooltip-content qui permet de gérer le contenu des ToolTips des Component Swing avec le style CSS suivant :
JLabel { tooltip-content:'bla bla bla content'; }
JLabel label = new JLabel(); label.setText("Jlabel text"); label.setToolTipText("bla bla bla...");
JLabel { tooltip-uppercase:true; tooltip-content:'bla bla bla content'; }
JLabel label = new JLabel(); label.setText("Jlabel text"); label.setToolTipText("bla bla bla...");
ICSSPropertyTooltipHandler traite plusieurs propriétés CSS. Il faut donc à un moment appliquer le bon code en fonction du nom de la propriété CSS. Dans la suite des examples, on souhaite être générique et pouvoir bénéficier du maximum de code pour une autre implémentation (SWT par exemple). Les exemples suivants suivent le même modèle que les implémentation des propriétés CSS2 de TK-UI, mais vous n'etes pas obligé d'effectuer ces modifications si vous souhaitez uniquement implémenter le moteur CSS Swing. Vous pouvez effectuer par exemple le test de la propriété comme ceci :
public void applyCSSProperty(Component component, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { if ("tooltip-uppercase".equals(property)) { Boolean isUpperCase = (Boolean)engine.convert(value, Boolean.class, null); if (isUpperCase.booleanValue()) { JComponent jComponent = (JComponent)component; String toolTipText = jComponent.getToolTipText(); toolTipText = toolTipText.toUpperCase(); jComponent.setToolTipText(toolTipText); } return; } if ("tooltip-content".equals(property)) { // Manage tooltip-content.... return; } }
Veuillez modifier l'interface ICSSPropertyTooltipHandler qui ajoute les méthodes applyCSSProperty* et retrieveCSSProperty* pour les 2 nouvelles propriétés CSS tooltip-uppercase et tooltip-content .
package com.mycompany.myapp.css.properties; import org.akrogen.tkui.css.core.dom.properties.ICSSPropertyHandler; import org.akrogen.tkui.css.core.engine.CSSEngine; import org.w3c.dom.css.CSSValue; public interface ICSSPropertyTooltipHandler extends ICSSPropertyHandler { public void applyCSSPropertyTooltipUpperCase(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception; public void applyCSSPropertyTooltipContent(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception; public String retrieveCSSPropertyTooltipContent(Object element, String property, CSSEngine engine) throws Exception; public String retrieveCSSPropertyTooltipUpperCase(Object element, String property, CSSEngine engine) throws Exception; }
Veuillez créer la classe abtraire AbstractCSSPropertyTooltipHandler dans le package com.mycompany.myapp.css.properties qui permet de router sur le bonne méthode applyCSSProperty(*) et retrieveCSSProperty(*) en fonction du nom de la propriété CSS. Cette classe est indépendante du moteur Swing et peut être utilisé dans une autre implémentation (comme SWT).
package com.mycompany.myapp.css.properties; import org.akrogen.tkui.css.core.engine.CSSEngine; import org.w3c.dom.css.CSSValue; public abstract class AbstractCSSPropertyTooltipHandler implements ICSSPropertyTooltipHandler { public boolean applyCSSProperty(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { if ("tooltip-uppercase".equals(property)) { applyCSSPropertyTooltipUpperCase(element, property, value, pseudo, engine); } if ("tooltip-content".equals(property)) { applyCSSPropertyTooltipContent(element, property, value, pseudo, engine); } return false; } public String retrieveCSSProperty(Object element, String property, CSSEngine engine) throws Exception { if ("tooltip-uppercase".equals(property)) { return retrieveCSSPropertyTooltipUpperCase(element, property, engine); } if ("tooltip-content".equals(property)) { return retrieveCSSPropertyTooltipContent(element, property, engine); } return null; } }
package com.mycompany.myapp.css.swing.properties; import javax.swing.JComponent; import org.akrogen.tkui.css.core.dom.properties.ICSSPropertyHandler; import org.akrogen.tkui.css.core.engine.CSSEngine; import org.akrogen.tkui.css.swing.helpers.SwingElementHelpers; import org.w3c.dom.css.CSSPrimitiveValue; import org.w3c.dom.css.CSSValue; import com.mycompany.myapp.css.properties.AbstractCSSPropertyTooltipHandler; public class CSSPropertyTooltipHandlerImpl extends AbstractCSSPropertyTooltipHandler { public static final ICSSPropertyHandler INSTANCE = new CSSPropertyTooltipHandlerImpl(); public boolean applyCSSProperty(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { JComponent component = (JComponent) SwingElementHelpers .getComponent(element); if (component == null) return false; super.applyCSSProperty(component, property, value, pseudo, engine); return true; } public String retrieveCSSProperty(Object element, String property, CSSEngine engine) throws Exception { JComponent component = (JComponent) SwingElementHelpers .getComponent(element); if (component == null) return null; return super.retrieveCSSProperty(component, property, engine); } public void applyCSSPropertyTooltipUpperCase(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { JComponent component = (JComponent) element; Boolean isUpperCase = (Boolean) engine.convert(value, Boolean.class, null); if (isUpperCase.booleanValue()) { String toolTipText = component.getToolTipText(); toolTipText = toolTipText.toUpperCase(); component.setToolTipText(toolTipText); } } public void applyCSSPropertyTooltipContent(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { JComponent component = (JComponent) element; if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { CSSPrimitiveValue primitiveValue = (CSSPrimitiveValue) value; String tooltipText = primitiveValue.getStringValue(); component.setToolTipText(tooltipText); } } public String retrieveCSSPropertyTooltipContent(Object element, String property, CSSEngine engine) throws Exception { System.out .println("CSSPropertyTooltipHandlerImpl#retrieveCSSPropertyTooltipContent"); return null; } public String retrieveCSSPropertyTooltipUpperCase(Object element, String property, CSSEngine engine) throws Exception { System.out .println("CSSPropertyTooltipHandlerImpl#retrieveCSSPropertyTooltipUpperCase"); return null; } }
public boolean applyCSSProperty(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { JComponent component = (JComponent) SwingElementHelpers .getComponent(element); if (component == null) return false; super.applyCSSProperty(component, property, value, pseudo, engine); return true; }
public void applyCSSPropertyTooltipContent(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { JComponent component = (JComponent) element; if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { CSSPrimitiveValue primitiveValue = (CSSPrimitiveValue) value; String tooltipText = primitiveValue.getStringValue(); component.setToolTipText(tooltipText); } }
A cette étape, il faut indiquer au moteur CSS que la propriété CSS tooltip-content est traitée par l'interface ICSSPropertyTooltipHandler comme comme ce qui a été fait pour la propriété tooltip_uppercase , à l'aide de la méthode registerCSSProperty . Veuillez modifier la classe MyCSSSwingEngineImpl comme ceci :
package com.mycompany.myapp.css.swing.engine; import org.akrogen.tkui.css.swing.engine.CSSSwingEngineImpl; import com.mycompany.myapp.css.properties.ICSSPropertyTooltipHandler; import com.mycompany.myapp.css.swing.properties.CSSPropertyTooltipHandlerImpl; public class MyCSSSwingEngineImpl extends CSSSwingEngineImpl { protected void initializeCSSPropertyHandlers() { super.initializeCSSPropertyHandlers(); super.registerCSSProperty("tooltip-uppercase", ICSSPropertyTooltipHandler.class); super.registerCSSProperty("tooltip-content", ICSSPropertyTooltipHandler.class); super.registerCSSPropertyHandler(ICSSPropertyTooltipHandler.class, CSSPropertyTooltipHandlerImpl.INSTANCE); } }
A cette étape il est possible de tester si la propriété CSS tooltip-content est enregistré correctement dans le moteur CSS et si elle s'applique bien à un JLabel. Créer la classe de test TestMyCSSSwingEngine avec le code suivant :
package com.mycompany.myapp.css.test; import java.io.StringReader; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JPanel; import org.akrogen.tkui.css.core.engine.CSSEngine; import com.mycompany.myapp.css.swing.engine.MyCSSSwingEngineImpl; public class TestMyCSSSwingEngine { public static void main(String[] args) { try { CSSEngine engine = new MyCSSSwingEngineImpl(); engine.parseStyleSheet(new StringReader("JLabel {tooltip-content:'bla bla bla content';}")); /*--- Start UI Swing ---*/ JFrame frame = new JFrame(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); JPanel panel = new JPanel(); frame.getContentPane().add(panel); // Label JLabel label = new JLabel(); label.setText("Jlabel text"); label.setToolTipText("bla bla bla..."); panel.add(label); /*--- End UI Swing ---*/ // Apply Styles engine.applyStyles(frame, true); frame.pack(); frame.setVisible(true); } catch (Exception e) { e.printStackTrace(); } } }
Après avoir lancé le test, le texte du tooltip du JLabel doit avoir le contenu bla bla bla content .
Dans cette partie on souhaite combiner les deux propriété CSS tooltip-uppercase et tooltip-content dans la même règle CSS. Faisons un premier test en écrivant le style CSS suivant :
JLabel { tooltip-content:'bla bla bla content'; tooltip-uppercase:true; }
engine.parseStyleSheet(new StringReader( "JLabel {tooltip-content:'bla bla bla content';tooltip-uppercase:true;}"));
JLabel { tooltip-uppercase:true; tooltip-content:'bla bla bla content'; }
engine.parseStyleSheet(new StringReader( "JLabel {tooltip-uppercase:true;tooltip-content:'bla bla bla content';}"));
Pour régler ce problème, il est impossible d'appliquer les 2 propriétés CSS tooltip-uppercase et tooltip-content directement sur les COmponent Swing car on ne maîtrise par l'ordre de ces propriétés. Pour résoudre, ce problème, il faut
CSSElementContext context = engine.getCSSElementContext(element);
CSSTooltipProperties tooltipProperties = (CSSTooltipProperties) context .getData("CSSTooltipProperties"); if (tooltipProperties == null) { tooltipProperties = new CSSTooltipProperties(); context.setData("CSSTooltipProperties", tooltipProperties); }
CSSElementContext context = engine.getCSSElementContext(element); CSSTooltipProperties tooltipProperties = (CSSTooltipProperties) context. getData("CSSTooltipProperties");
Créer la classe CSSTooltipProperties dans le package com.mycompany.myapp.css.properties :
package com.mycompany.myapp.css.properties; public class CSSTooltipProperties { private boolean uppercase = false; private String content; public boolean isUppercase() { return uppercase; } public void setUppercase(boolean uppercase) { this.uppercase = uppercase; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } }
Modifier la classe CSSPropertyTooltipHandlerImpl :
package com.mycompany.myapp.css.swing.properties; import javax.swing.JComponent; import org.akrogen.tkui.css.core.dom.properties.ICSSPropertyHandler; import org.akrogen.tkui.css.core.dom.properties.ICSSPropertyHandler2; import org.akrogen.tkui.css.core.engine.CSSElementContext; import org.akrogen.tkui.css.core.engine.CSSEngine; import org.akrogen.tkui.css.swing.helpers.SwingElementHelpers; import org.w3c.dom.css.CSSPrimitiveValue; import org.w3c.dom.css.CSSValue; import com.mycompany.myapp.css.properties.AbstractCSSPropertyTooltipHandler; import com.mycompany.myapp.css.properties.CSSTooltipProperties; public class CSSPropertyTooltipHandlerImpl extends AbstractCSSPropertyTooltipHandler implements ICSSPropertyHandler2 { public static final ICSSPropertyHandler INSTANCE = new CSSPropertyTooltipHandlerImpl(); public boolean applyCSSProperty(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { JComponent component = (JComponent) SwingElementHelpers .getComponent(element); if (component != null) { CSSElementContext context = engine.getCSSElementContext(element); CSSTooltipProperties tooltipProperties = (CSSTooltipProperties) context .getData("CSSTooltipProperties"); if (tooltipProperties == null) { tooltipProperties = new CSSTooltipProperties(); context.setData("CSSTooltipProperties", tooltipProperties); } super.applyCSSProperty(tooltipProperties, property, value, pseudo, engine); return true; } else { if (element instanceof CSSTooltipProperties) { super .applyCSSProperty(element, property, value, pseudo, engine); return true; } } return false; } public String retrieveCSSProperty(Object element, String property, CSSEngine engine) throws Exception { JComponent component = (JComponent) SwingElementHelpers .getComponent(element); if (component == null) return null; return super.retrieveCSSProperty(component, property, engine); } public void applyCSSPropertyTooltipUpperCase(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { CSSTooltipProperties tooltipProperties = (CSSTooltipProperties) element; Boolean isUpperCase = (Boolean) engine.convert(value, Boolean.class, null); tooltipProperties.setUppercase(isUpperCase.booleanValue()); } public void applyCSSPropertyTooltipContent(Object element, String property, CSSValue value, String pseudo, CSSEngine engine) throws Exception { CSSTooltipProperties tooltipProperties = (CSSTooltipProperties) element; if (value.getCssValueType() == CSSValue.CSS_PRIMITIVE_VALUE) { CSSPrimitiveValue primitiveValue = (CSSPrimitiveValue) value; String tooltipText = primitiveValue.getStringValue(); tooltipProperties.setContent(tooltipText); } } public String retrieveCSSPropertyTooltipContent(Object element, String property, CSSEngine engine) throws Exception { System.out .println("CSSPropertyTooltipHandlerImpl#retrieveCSSPropertyTooltipContent"); return null; } public String retrieveCSSPropertyTooltipUpperCase(Object element, String property, CSSEngine engine) throws Exception { System.out .println("CSSPropertyTooltipHandlerImpl#retrieveCSSPropertyTooltipUpperCase"); return null; } public void onAllCSSPropertiesApplyed(Object element, CSSEngine engine) throws Exception { JComponent component = (JComponent) SwingElementHelpers .getComponent(element); CSSElementContext context = engine.getCSSElementContext(element); CSSTooltipProperties tooltipProperties = (CSSTooltipProperties) context .getData("CSSTooltipProperties"); if(tooltipProperties != null) { String content = tooltipProperties.getContent(); if(content == null) content = component.getToolTipText(); if(content != null) { if (tooltipProperties.isUppercase()) content = content.toUpperCase(); } component.setToolTipText(content); } } }