Above, Below, and Beyond Tech Talk

by Rahel Lüthy

May 3, 2016

Programmatic JavaFX Styling

JavaFX components can be styled via CSS. This is great, but sometimes wiring up a separate CSS file to set a simple background color is a bit over the top. That’s where the setStyle method comes in handy:

Label label = new Label("Hello");
label.setStyle("-fx-background-color: deeppink");

CSS classes are used to style more advanced components. A ScatterChart’s plot background can e.g. be styled via the chart-plot-background class. This is how the styling would look like in a CSS file:

.chart-plot-background {
    -fx-background-color: transparent;
}

Unfortunately, we cannot simply cram the same CSS into the setStyle method:

NumberAxis xAxis = new NumberAxis();
NumberAxis yAxis = new NumberAxis();
ScatterChart<Number, Number> chart = new ScatterChart<>(xAxis, yAxis);

// DOES NOT COMPILE
chart.setStyle(
        ".chart-plot-background {\n" +
        "    -fx-background-color: transparent;\n" +
        "}"
);

Instead, the lookup method can be used to navigate the CSS hierarchy:

chart.lookup(".chart-plot-background").setStyle("-fx-background-color: transparent");

In case you were wondering why you would ever want to have a transparent chart background: The ScatterChart component does not support line connections. Using a StackPane to layer a ScatterChart and a LineChart can serve as a simple workaround. The chart in the top layer must then have a transparent background.


November 11, 2015

Play Audio via Elm

In preparation for a MaKey-MaKey-workshop, I needed a simple HTML page which plays a sound whenever any key is pressed. I am using all sorts of excuses to write Elm lately, so here’s how I ended up triggering the audio clip (full sources on GitHub, deployed version here).

First, we need a signal that indicates whether any key is currently down:

isAnyKeyDown : Signal Bool
isAnyKeyDown =
  Signal.map (\keys -> not (Set.isEmpty keys)) Keyboard.keysDown

For debugging, let’s visualize our events by displaying a small note image:

view : Bool -> Html
view isAnyKeyDown =
  if | isAnyKeyDown -> img [ src "note.png" ] []
     | otherwise -> div [] []

main : Signal Html
main =
  Signal.map view isAnyKeyDown

Next, we need to actually play the audio. Elm itself does not support this out-of-the-box, but triggering it via HTML5 and JavaScript is quite straight forward:

<body>
    <audio id="audio" src="piano.ogg" preload="auto"></audio>
</body>
var audio = document.getElementById('audio')
function playAudio() {
    // reset if already running
    audio.pause();
    audio.currentTime = 0;

    // go!
    audio.play();
}

Finally, we need to wire our JS function to our Elm signal. This is where Elm ports come in:

port playAudio : Signal ()
port playAudio =
  Signal.map (\_ -> ()) (Signal.filter identity False isAnyKeyDown)

There are two things to note here: First, we’re filtering our isAnyKeyDown to no longer contain key release events. Second, we’re mapping our signal of boolean values to a signal of unit types () to match the signature of our parameter-less JS function.

All there is left, is to actually trigger the JS callback whenever Elm sends an event:

    var app = Elm.fullscreen(Elm.Main, {});
    app.ports.playAudio.subscribe(playAudio);

July 25, 2015

Mac OSX Tips & Tricks #8: Finding Files via Terminal

This is how you recursively search all notes.txt files in your home directory (~) for the text snippet foo (from an OSX terminal):

mdfind -name notes.txt -onlyin ~ -0 | xargs -0 grep -i "foo"

It has at least 3 advantages over the traditional find/grep combo:

Happy searching!


Older Posts » Archive