Makeover Regimen
> Mixing Swing & JavaFX
> Easy Eye Candy> Styling with CSS
> 3D Illusion
> Finale
Mixing Swing & JavaFX
> Create JavaFX Stage
> Embed Swing components in scene
> Create listeners to wire JavaFX to Swing
Create JavaFX Stage
def STAGE_MIN_WIDTH = 845;
def STAGE_MIN_HEIGHT = 700;
def stage = Stage {
style: StageStyle.TRANSPARENT
scene: scene = Scene {
width: STAGE_MIN_WIDTH
height: STAGE_MIN_HEIGHT
fill: null
content: CaspianFrame {
// scene contents....
}
}
}
// CaspianFrame is home-grown class implementing top-level
// window shape/decorations (authored by Jasper Potts)
Embedding Swing Components
> Any Swing class can be embedded in scene
javafx.ext.swing.SwingComponent
> Can be treated like any node:
• opacity (!), rotate, scale, translate, etc
• Resizable and work with scene graph layout
> But treated as single node
• node transforms only on whole component
• cannot transform or animate component internals
Embedding Swing Components
continued
> Can invoke Java/Swing apis from JavaFX script
def map = new HashMap();
var table = new JTable();
> Cannot use JavaFX script features on Components
• no binding to Java bean properties
> Can create JavaFX wrapper classes to help
• SDK provides wrappers for many Swing classes
javafx.ext.swing.*
> JavaFX strictly single-threaded
• non-gui thread execution must happen in Java code
Embed Swing Components in Scene
var body:Panel;
var toolbar:ToolBar;
var mailboxArea:BackDrop;
var messageListArea:RoundedPanel;
var messageArea:RoundedPanel;
var swingMessageList = new MessageListPanel(); // Swing class
var swingMessagePanel = new MessagePanel(); //Swing class
body = Panel {
content: [
toolbar = ToolBar { ... }
mailboxArea = BackDrop { ... }
messageListArea = RoundedPanel {
node: SwingComponent.wrap(swingMessageList);
}
messageHeaderArea = BackDrop { ... }
messageArea = RoundedPanel {
node: SwingComponent.wrap(swingMessagePane);
}
]
}
Create Listeners for Wiring JavaFX to Swing
class PropChangeListener extends PropertyChangeListener {
public var onPropChange:function(event:PropertyChangeEvent):Void;
override function propertyChange(event:PropertyChangeEvent):Void {
onPropChange(event);
}
}
def pcl:PropChangeListener = PropChangeListener {
onPropChange: function(event:PropertyChangeEvent):Void {
if (event.getPropertyName().equals("selectedMessage")) {
// handle property change in FX
}
}
}
// add listener to Swing component
messageListPanel.addPropertyChangeListener(pcl);