Goal
Lightspeed raster and vector layers support a number of graphical effects that are applied to the layer as a whole, at the
pixel level, in contrast to ILspStyler
or ALspStyle
that perform styling per object.
For example, you can change the opacity of the entire layer, or you can map pixels of a certain color to another color.
These effects are represented by the class TLspLayerStyle
.
In this tutorial, we use the TLspLayerStyle
to toggle between a regular mode and a night mode for a layer:
-
In regular mode, the data is visualized with normal colors.
-
In night mode, we dim the display and use less saturated colors.


Initial setup
We start from a JFrame
containing a Lightspeed view with a single raster background layer:
public class LayerStylingTutorial {
final ILspAWTView fView = TLspViewBuilder.newBuilder().buildAWTView();
public JFrame createUI() {
JFrame frame = new JFrame("Layer Style tutorial");
ILspLayer rasterlayer = createRasterLayer();
fView.addLayer(rasterlayer);
frame.add(fView.getHostComponent(), BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
private ILspLayer createRasterLayer() {
String source = "Data/Earth/SanFrancisco/tilerepository.cfg";
ILcdModel model = decodeData(source);
return TLspRasterLayerBuilder.newBuilder()
.model(model)
.build();
}
private ILcdModel decodeData(String aSource) {
try {
TLcdCompositeModelDecoder modelDecoder =
new TLcdCompositeModelDecoder(TLcdServiceLoader.getInstance(ILcdModelDecoder.class));
return modelDecoder.decode(aSource);
} catch (IOException aE) {
//In a real application, we need proper error handling
throw new RuntimeException(aE);
}
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame frame = new LayerStylingTutorial().createUI();
frame.setVisible(true);
});
}
}
Adding support for night mode
We want to add a checkbox to the UI that allows users to activate night mode.
When the user activates night mode, we will:
-
Reduce the contrast and brightness
-
De-saturate the colors
We replace the TLspLayerStyle
instance of the layer with a custom one to set this up.
You create TLspLayerStyle
instances with a builder class:
-
You can adjust the contrast and the brightness directly on the builder
-
To desaturate the colors, you need to create a color matrix. This matrix serves to transform the RGBA color channel of each pixel.
Once you have the TLspLayerStyle
, you can apply it to the layer using the ILspLayer.setLayerStyle
method:
private JCheckBox createNightModeButton(ILspLayer layer) {
JCheckBox checkBox = new JCheckBox("Activate night mode");
checkBox.setSelected(false);
TLspLayerStyle originalLayerStyle = layer.getLayerStyle();
//Create a layer style representing night mode
//For night mode, we
//- Reduce the contrast and brightness
//- Desaturate the colors
TLspLayerStyle nightModeStyle = TLspLayerStyle.newBuilder()
.contrast(0.9f)
.brightness(0.65f)
.colorMatrix(createDesaturateMatrix(0.85f))
.build();
//Apply the correct layer style, depending on whether the checkbox is selected or not
checkBox.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
layer.setLayerStyle(nightModeStyle);
} else if (e.getStateChange() == ItemEvent.DESELECTED) {
layer.setLayerStyle(originalLayerStyle);
}
});
return checkBox;
}
private float[] createDesaturateMatrix(float desaturationFactory) {
return new float[]{0.21f * desaturationFactory + (1 - desaturationFactory), 0.72f * desaturationFactory, 0.07f * desaturationFactory, 0.0f, 0.0f,
0.21f * desaturationFactory, 0.72f * desaturationFactory + (1 - desaturationFactory), 0.07f * desaturationFactory, 0.0f, 0.0f,
0.21f * desaturationFactory, 0.72f * desaturationFactory, 0.07f * desaturationFactory + (1 - desaturationFactory), 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f};
}
We now create a tool bar containing the check box, and add it to the UI.
JToolBar toolBar = new JToolBar();
toolBar.add(createNightModeButton(rasterlayer));
frame.add(toolBar, BorderLayout.NORTH);
Full code
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ItemEvent;
import java.io.IOException;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JToolBar;
import javax.swing.WindowConstants;
import com.luciad.model.ILcdModel;
import com.luciad.model.ILcdModelDecoder;
import com.luciad.model.TLcdCompositeModelDecoder;
import com.luciad.util.service.TLcdServiceLoader;
import com.luciad.view.lightspeed.ILspAWTView;
import com.luciad.view.lightspeed.TLspViewBuilder;
import com.luciad.view.lightspeed.layer.ILspLayer;
import com.luciad.view.lightspeed.layer.raster.TLspRasterLayerBuilder;
import com.luciad.view.lightspeed.layer.style.TLspLayerStyle;
public class LayerStylingTutorial {
final ILspAWTView fView = TLspViewBuilder.newBuilder().buildAWTView();
public JFrame createUI() {
JFrame frame = new JFrame("Layer Style tutorial");
ILspLayer rasterlayer = createRasterLayer();
fView.addLayer(rasterlayer);
JToolBar toolBar = new JToolBar();
toolBar.add(createNightModeButton(rasterlayer));
frame.add(toolBar, BorderLayout.NORTH);
frame.add(fView.getHostComponent(), BorderLayout.CENTER);
frame.setSize(800, 600);
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
return frame;
}
private ILspLayer createRasterLayer() {
String source = "Data/Earth/SanFrancisco/tilerepository.cfg";
ILcdModel model = decodeData(source);
return TLspRasterLayerBuilder.newBuilder()
.model(model)
.build();
}
private ILcdModel decodeData(String aSource) {
try {
TLcdCompositeModelDecoder modelDecoder =
new TLcdCompositeModelDecoder(TLcdServiceLoader.getInstance(ILcdModelDecoder.class));
return modelDecoder.decode(aSource);
} catch (IOException aE) {
//In a real application, we need proper error handling
throw new RuntimeException(aE);
}
}
private JCheckBox createNightModeButton(ILspLayer layer) {
JCheckBox checkBox = new JCheckBox("Activate night mode");
checkBox.setSelected(false);
TLspLayerStyle originalLayerStyle = layer.getLayerStyle();
//Create a layer style representing night mode
//For night mode, we
//- Reduce the contrast and brightness
//- Desaturate the colors
TLspLayerStyle nightModeStyle = TLspLayerStyle.newBuilder()
.contrast(0.9f)
.brightness(0.65f)
.colorMatrix(createDesaturateMatrix(0.85f))
.build();
//Apply the correct layer style, depending on whether the checkbox is selected or not
checkBox.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
layer.setLayerStyle(nightModeStyle);
} else if (e.getStateChange() == ItemEvent.DESELECTED) {
layer.setLayerStyle(originalLayerStyle);
}
});
return checkBox;
}
private float[] createDesaturateMatrix(float desaturationFactory) {
return new float[]{0.21f * desaturationFactory + (1 - desaturationFactory), 0.72f * desaturationFactory, 0.07f * desaturationFactory, 0.0f, 0.0f,
0.21f * desaturationFactory, 0.72f * desaturationFactory + (1 - desaturationFactory), 0.07f * desaturationFactory, 0.0f, 0.0f,
0.21f * desaturationFactory, 0.72f * desaturationFactory, 0.07f * desaturationFactory + (1 - desaturationFactory), 0.0f, 0.0f,
0.00f, 0.00f, 0.00f, 1.0f, 0.0f};
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
JFrame frame = new LayerStylingTutorial().createUI();
frame.setVisible(true);
});
}
}