Created
January 4, 2017 06:25
-
-
Save uphy/f4b81823c005c7bf783f0336d643a1f3 to your computer and use it in GitHub Desktop.
How to develop KNIME node with JavaFX
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package it.pkg; | |
import java.awt.BorderLayout; | |
import java.util.concurrent.Callable; | |
import java.util.concurrent.Semaphore; | |
import java.util.concurrent.atomic.AtomicReference; | |
import javax.swing.JPanel; | |
import org.knime.core.node.InvalidSettingsException; | |
import org.knime.core.node.NodeDialogPane; | |
import org.knime.core.node.NodeSettingsRO; | |
import org.knime.core.node.NodeSettingsWO; | |
import org.knime.core.node.NotConfigurableException; | |
import org.knime.core.node.port.PortObjectSpec; | |
import javafx.application.Platform; | |
import javafx.embed.swing.JFXPanel; | |
import javafx.scene.Scene; | |
import javafx.scene.control.TextField; | |
import javafx.scene.layout.VBox; | |
/** | |
* Node extension with JavaFX example. | |
* | |
* <p> | |
* To make this class work, you need to append following settings to Knime.ini. | |
* | |
* <pre> | |
* -Dosgi.framework.extensions=org.eclipse.fx.osgi | |
* -Dorg.osgi.framework.bundle.parent=ext | |
* </pre> | |
* </p> | |
* | |
* @author uphy.jp | |
*/ | |
public class JavaFXDialog extends NodeDialogPane { | |
private TextField count; | |
protected JavaFXDialog() { | |
super(); | |
final JPanel panel = new JPanel(new BorderLayout()); | |
final JFXPanel fxpanel = new JFXPanel(); | |
runOnJavaFXThread(() -> { | |
final VBox vbox = new VBox(); | |
count = new TextField(); | |
vbox.getChildren().add(count); | |
final Scene scene = new Scene(vbox); | |
fxpanel.setScene(scene); | |
Platform.setImplicitExit(false); | |
}); | |
panel.add(fxpanel, BorderLayout.CENTER); | |
addTab("Options", panel); | |
} | |
@Override | |
protected void saveSettingsTo(NodeSettingsWO settings) throws InvalidSettingsException { | |
settings.addInt(TestModel.CFGKEY_COUNT, runOnJavaFXThread(() -> Integer.parseInt(count.getText()))); | |
} | |
@Override | |
protected void loadSettingsFrom(NodeSettingsRO settings, PortObjectSpec[] specs) throws NotConfigurableException { | |
final int countInt = settings.getInt(TestModel.CFGKEY_COUNT, 100); | |
runOnJavaFXThread(() -> count.setText(String.valueOf(countInt))); | |
} | |
private void runOnJavaFXThread(Runnable task) { | |
runOnJavaFXThread(() -> { | |
task.run(); | |
return null; | |
}); | |
} | |
private <V> V runOnJavaFXThread(Callable<V> task) { | |
Semaphore s = new Semaphore(0); | |
AtomicReference<V> ref = new AtomicReference<>(); | |
Platform.runLater(() -> { | |
try { | |
V result = task.call(); | |
ref.set(result); | |
} catch (Throwable e) { | |
e.printStackTrace(); | |
} | |
s.release(); | |
}); | |
try { | |
s.acquire(); | |
} catch (InterruptedException e) { | |
e.printStackTrace(); | |
} | |
return ref.get(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment