CSS engine Swing

TK-UI provide several CSS engine implementation which are enable to apply CSS styles to Swing Component . Please read Download section to download CSS Swing engine distribution and Swing samples.

This section explains how use CSS Swing engine with simple samples. You can find more complex samples into test folder of the org.akrogen.tkui.css.swing* distribution. There are tow ways to apply CSS styles to Swing Component :

Selectors section describe all type of selectors that you can write with Swing Component.

CSS Swing engines are configurables, please read CSSEngine API section for more informations.

Swing CSS engine

Swing selector

Here basic sample Swing code which apply CSS style from style sheet with selector type of Swing (on other words, class name of Swing Component are used as selector) :
JLabel { 
  color:red;
} 

JTextField {
  background-color:green;
}
to Swing user interface composed with one JLabel and JTextField. In this sample the org.akrogen.tkui.css.swing.engine.CSSSwingEngineImpl class is used.
// Create Swing CSS Engine
CSSEngine engine = new CSSSwingEngineImpl();
// Parse style sheet
engine.parseStyleSheet(new StringReader(
	"JLabel {color:red;} JTextField {background-color:green;}"));

/*---   Start UI Swing ---*/
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();
frame.getContentPane().add(panel);

// Label
JLabel label1 = new JLabel();
label1.setText("Label 0");
panel.add(label1);

// Text
JTextField text1 = new JTextField();
text1.setText("bla bla bla...");
panel.add(text1);

/*---   End UI Swing  ---*/

// Apply Styles
engine.applyStyles(frame, true);

frame.pack();
frame.setVisible(true);
After executing this code, Swing window is displayed :

HTML selector

Here basic sample Swing code which apply CSS style from style sheet with selector type of HTML (on other words, HTML name of Swing Component are used as selector) :
label { 
  color:red;
} 

input {
  background-color:green;
}
to Swing user interface composed with one JLabel and JTextField. In this sample the org.akrogen.tkui.css.swing.engine.html.CSSSwingHTMLEngineImpljava class is used.
// Create Swing CSS Engine
CSSEngine engine = new CSSSwingHTMLEngineImpl();
// Parse style sheet
engine.parseStyleSheet(new StringReader(
	"JLabel {color:red;} JTextField {background-color:green;}"));

/*---   Start UI Swing ---*/
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();
frame.getContentPane().add(panel);

// Label
JLabel label1 = new JLabel();
label1.setText("Label 0");
panel.add(label1);

// Text
JTextField text1 = new JTextField();
text1.setText("bla bla bla...");
panel.add(text1);

/*---   End UI Swing  ---*/

// Apply Styles
engine.applyStyles(frame, true);

frame.pack();
frame.setVisible(true);
After executing this code, Swing window is displayed :

To manage HTML name as selector, a mapping between Swing Component and HTML name is done. with getLocalName method of the CSSStylableElement instance which wrap the Swing Component. Here mapping array of the HTML name/Swing Component :

HTML name Swing Component
body javax.swing.JFrame
textarea javax.swing.JTextArea
input[type=password] TODO
input[type=text] javax.swing.text.JTextComponent
input[type=radio] javax.swing.JRadioButton
input[type=checkbox] javax.swing.JCheckBox
input[type=button] javax.swing.JButton
select javax.swing.JComboBox
label javax.swing.JLabel
canva TODO
a TODO
div javax.swing.JRootPane, javax.swing.JPanel, javax.swing.JLayeredPane
tree javax.swing.JTree
listbox javax.swing.JTable

Inline style

Into HTML page, it's possible to define inline style into HTML element with style attribute :
<input type="text" 
    id="MyId" 
    style="color:red;background-color:yellow;" />
It's possible too to manage the style with Javascript like this :
var input = document.getElementById('MyId');
input.style.color='red';
input.style.backgroundColor='yellow';
CSS Swing engine implementation is able to manage this features.

Inline style (1)

By default, style attribute is managed with putClientProperty method of Swing JComponent by putting CSS inline style with style key like this :
JTextField text = new JTextField();
text.setText("bla bla bla");
text.putClientProperty("style", "color:red;background-color:yellow;");
...
engine.applyStyles(frame, true);

Inline style (2)

It is possible to get a org.w3c.dom.css.CSS2Properties instance which define the whole of CSS2 properties and therefore define style to use (like Javascript ) :
JTextField text = new JTextField();
text.setText("bla bla bla");
CSSStylableElement stylableElement = (CSSStylableElement) engine.getElement(text);
CSS2Properties style = stylableElement.getStyle();
style.setColor("red");
style.setBackgroundColor("yellow");

Inline style (3)

It's possible to use parseAndApplyStyleDeclaration method of the engine like this :
JTextField text = new JTextField();
text.setText("bla bla bla");
engine.parseAndApplyStyleDeclaration(text, "color:red;");

Selectors

This section follow spécification w3c selector and adapt it for the CSS Swing engine.

Pattern matching

Pattern Meaning Described in section
* Matches any Swing Component.
E Matches any Swing Component E. E is defined with class name of the Swing Component (CSSSwingEngineImpl) or HTML name of the Swing Component (CSSSwingHTMLEngineImpl).
E F Matches any Swing Component Swing F that is a descendant of a Swing Component E (ex : JLabel into JPanel). Descendant selectors
E:focus, E:hover Matches any Swing Component during certain user actions. The dynamic pseudo-classes
E[foo="warning"] Matches any Swing Component E whose "foo" attribute value is exactly equal to "warning".. Attribute selectors
E.className Matches any Swing Component E which have class with className name. Class selectors
E#myid Matches any Swing Component which are id equals to "myid". ID selectors

Descendant selectors

JPanel JLabel { 
  color:red;
} 
JLabel { 
  color:green;
}

Attribute selectors

Matching attributes and attribute values

It's possible to use attributes into CSS styles with Swing. It exist several kind of attributes :

  • getter attribute type : this type allow to retrieve with introspection the value of a Swing Component getter. For instance JTextField has isEditable method which return true if the Component is editable. It's possible to write style like this :
    JTextField[editable=true] { 
      color:red;
    }
  • custom attribute type : this type d'attribut allow to manage attributes values with putClientProperty method of Swing JComponent. If you define putClientProperty like this :
    JTextField text = ... 
    text.putClientProperty("foo", "warning");
    You can write CSS style like this :
    JTextField[foo="warning"] { 
      color:red;
    }

Class selectors

By default class information is managed with putClientProperty method of Swing JComponent:

.redColor { 
  color:red;
} 

.greenColor {
  color:green;
}
JLabel label = new JLabel();
label.putClientProperty("class", "redClass");

ID selectors

By default id information is managed with putClientProperty method of Swing JComponent:
JLabel#MyId { 
  color:red;
} 

JLabel {
  color:green;
}
JLabel label = new JLabel();
label.putClientProperty("id", "MyId");

Pseudo-classes

The dynamic pseudo-classes : :hover, :active, and :focus

JTextField:focus { 
  color:red;
} 

JTextField:hover {
  color:green;
}

JToolTip

It is possible to manage Swing Component tooltip to apply for instance this CSS style :

JToolTip {
	background-color:yellow; 
	font:14 bold;
}

JLabel JToolTip {
	background-color:orange; 
	font:20 Serif italic normal;
	border-color:red;
}
This sample distinguish the JToolTip of any Swing Component to the JToolTip of the JLabel Swing Component.

JToolTip Components are particulary because they are detroyed when tooltip disappear and re-created when tooltip appear. CSS style apply must be done when JToolTip is added to the Swing user interface. Swing provide addAWTEventListener from ToolKit to detect when a Swing Component is added. To manage JToolTip, you must add this code :

// Apply styles CSS to JToolTip
Toolkit.getDefaultToolkit().addAWTEventListener(
new AWTEventListener() {
	public void eventDispatched(AWTEvent e) {
		ContainerEvent cevt = (ContainerEvent) e;
		Component component = cevt.getChild();
		if (component instanceof JToolTip) {
			JToolTip toolTip = (JToolTip) component;
			engine.applyStyles(toolTip, false);
		}
	}
}, AWTEvent.CONTAINER_EVENT_MASK);
Here the whole sample :

// Create Swing CSS Engine
final CSSEngine engine = new CSSSwingEngineImpl();
// Parse style sheet
engine.parseStyleSheet(new StringReader(
	"JLabel {color:red;} " +
	"JTextField {background-color:green;}" +
	"JToolTip {background-color:yellow; font:14 bold;}" +
	"JLabel JToolTip {background-color:orange; font:20 Serif italic normal;border-color:red;}"));

/*---   Start UI Swing ---*/
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

JPanel panel = new JPanel();
frame.getContentPane().add(panel);

// Label
JLabel label1 = new JLabel();
label1.setText("Label 0");
label1.setToolTipText("JLabel tool tip.");
panel.add(label1);

// Text
JTextField text1 = new JTextField();
text1.setText("bla bla bla...");
text1.setToolTipText("JTextField tool tip.");
panel.add(text1);

/*---   End UI Swing  ---*/

// Apply Styles
engine.applyStyles(frame, true);

// Apply styles CSS to JToolTip
Toolkit.getDefaultToolkit().addAWTEventListener(
		new AWTEventListener() {
			public void eventDispatched(AWTEvent e) {
				ContainerEvent cevt = (ContainerEvent) e;
				Component component = cevt.getChild();
				if (component instanceof JToolTip) {
					JToolTip toolTip = (JToolTip) component;
					engine.applyStyles(toolTip, false);
				}
			}
		}, AWTEvent.CONTAINER_EVENT_MASK);
frame.pack();
frame.setVisible(true);