[TASK] Create observer window
This commit is contained in:
parent
48e01f493f
commit
896fe022a8
|
@ -6,21 +6,22 @@ import org.apache.log4j.PropertyConfigurator;
|
|||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import eu.larkc.csparql.common.utils.CsparqlUtils;
|
||||
import eu.larkc.csparql.common.utils.ReasonerChainingType;
|
||||
import eu.larkc.csparql.core.engine.ConsoleFormatter;
|
||||
import eu.larkc.csparql.core.engine.CsparqlEngine;
|
||||
import eu.larkc.csparql.core.engine.CsparqlEngineImpl;
|
||||
import eu.larkc.csparql.core.engine.CsparqlQueryResultProxy;
|
||||
import lu.jpt.csparqltest.gui.TextObserverWindow;
|
||||
import lu.jpt.csparqltest.rentacar.RentACarSimulation;
|
||||
import lu.jpt.csparqltest.util.RandomHelper;
|
||||
import lu.jpt.csparqltest.util.TestStreamGenerator;
|
||||
|
||||
public class Main {
|
||||
|
||||
private static Logger logger = LoggerFactory.getLogger(Main.class);
|
||||
public static TextObserverWindow observerWindow;
|
||||
|
||||
public static void main(String[] args) {
|
||||
Main.observerWindow = new TextObserverWindow("Result observer window");
|
||||
|
||||
// Determines the time the engine will be run for
|
||||
final long millisecondsToRun = 50 * 1000;
|
||||
|
||||
|
@ -71,7 +72,7 @@ public class Main {
|
|||
testGeneratorThread.start();
|
||||
|
||||
// Now build a query to run - interchangeable
|
||||
String query = Main.getNOTA();
|
||||
String query = Main.getSPO();
|
||||
//String query = RentACarSimulation.getEventUsingBackgroundKnowledge();
|
||||
|
||||
// Create a result proxy by registering the query at the engine
|
||||
|
@ -99,6 +100,7 @@ public class Main {
|
|||
|
||||
// Add ConsoleFormatter as observer so it gets notified of every query result
|
||||
resultProxy.addObserver(new ConsoleFormatter());
|
||||
resultProxy.addObserver(Main.observerWindow);
|
||||
|
||||
// Let it all run for some time
|
||||
try {
|
||||
|
|
|
@ -0,0 +1,251 @@
|
|||
package lu.jpt.csparqltest.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Insets;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Collection;
|
||||
import java.util.Observable;
|
||||
import java.util.Observer;
|
||||
import java.util.StringTokenizer;
|
||||
|
||||
import javax.swing.JCheckBox;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JTextPane;
|
||||
import javax.swing.text.AttributeSet;
|
||||
import javax.swing.text.Document;
|
||||
import javax.swing.text.SimpleAttributeSet;
|
||||
import javax.swing.text.StyleConstants;
|
||||
import javax.swing.text.StyleContext;
|
||||
|
||||
import eu.larkc.csparql.cep.api.RdfQuadruple;
|
||||
import eu.larkc.csparql.common.RDFTable;
|
||||
import eu.larkc.csparql.common.RDFTuple;
|
||||
import eu.larkc.csparql.core.engine.CsparqlQueryResultProxy;
|
||||
|
||||
/**
|
||||
* Multi-purpose text window to allow for easy viewing of RdfStream quadruples,
|
||||
* various logging or observing query results.
|
||||
*/
|
||||
public class TextObserverWindow extends JFrame implements Observer {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private JTextPane textPane;
|
||||
private volatile boolean autoScrollToBottom = true;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
* @param title of the window
|
||||
*/
|
||||
public TextObserverWindow(String title) {
|
||||
this.initWindow(title);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set whether the window is automatically scrolling to the bottom
|
||||
* @param autoScrollToBottom
|
||||
*/
|
||||
public void setAutoScrollToBottom(boolean autoScrollToBottom) {
|
||||
this.autoScrollToBottom = autoScrollToBottom;
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the given text in the window
|
||||
* @param text
|
||||
*/
|
||||
public void showText(String text) {
|
||||
this.showText(text, Color.BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show given text in the window using the given color
|
||||
* @param text
|
||||
* @param color
|
||||
*/
|
||||
public void showText(String text, Color color) {
|
||||
this.appendToTextPane(text, true, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the given token in the window without appending linebreaks
|
||||
* @param text
|
||||
*/
|
||||
public void showToken(String token) {
|
||||
this.showText(token, Color.BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show given token in the window using the given color without appending linebreaks
|
||||
* @param text
|
||||
* @param color
|
||||
*/
|
||||
public void showToken(String token, Color color) {
|
||||
this.appendToTextPane(token, false, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show given RdfQuadruple in the window
|
||||
* @param quad
|
||||
*/
|
||||
public void showQuadruple(RdfQuadruple quad) {
|
||||
this.showQuadruple(quad, Color.BLACK);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show given RdfQuadruple in window using given color
|
||||
* @param quad
|
||||
* @param color
|
||||
*/
|
||||
public void showQuadruple(RdfQuadruple quad, Color color) {
|
||||
this.appendToTextPane(quad.toString(), true, color);
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to set up the window and show it.
|
||||
* @param title of the window
|
||||
*/
|
||||
private void initWindow(String title) {
|
||||
// Little hack to be able to access myself from within ActionListeners
|
||||
final TextObserverWindow textObserverWindow = this;
|
||||
|
||||
this.setTitle(title);
|
||||
this.setResizable(true);
|
||||
this.setUndecorated(false);
|
||||
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
|
||||
Container contentPane = this.getContentPane();
|
||||
contentPane.setLayout(new BorderLayout());
|
||||
|
||||
// Get a TextPane ready
|
||||
this.textPane = new JTextPane();
|
||||
this.textPane.setEnabled(true);
|
||||
this.textPane.setFocusable(false);
|
||||
this.textPane.setAutoscrolls(true);
|
||||
this.textPane.setMargin(new Insets(5, 5, 5, 5));
|
||||
contentPane.add(this.textPane, BorderLayout.CENTER);
|
||||
|
||||
// Add a ScrollPane
|
||||
JScrollPane scrollPane = new JScrollPane(this.textPane);
|
||||
scrollPane.setPreferredSize(new Dimension(800, 500));
|
||||
contentPane.add(scrollPane, BorderLayout.CENTER);
|
||||
|
||||
// Add a checkbox to toggle autoscroll
|
||||
JCheckBox autoscrollCheckbox = new JCheckBox();
|
||||
autoscrollCheckbox.setText("Automatically scroll to bottom");
|
||||
autoscrollCheckbox.setEnabled(true);
|
||||
autoscrollCheckbox.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JCheckBox checkBox = (JCheckBox) e.getSource();
|
||||
textObserverWindow.setAutoScrollToBottom(checkBox.isSelected());
|
||||
}
|
||||
});
|
||||
contentPane.add(autoscrollCheckbox, BorderLayout.SOUTH);
|
||||
|
||||
this.setVisible(true);
|
||||
this.pack();
|
||||
}
|
||||
|
||||
/**
|
||||
* Internal method to append text to the textpane
|
||||
* @param text to show within the window
|
||||
* @param addLinebreak whether or not to add a linebreak (usually yes is better)
|
||||
* @param color to display the text in
|
||||
*/
|
||||
private void appendToTextPane(String text, boolean addLinebreak, Color color) {
|
||||
if (addLinebreak) text += "\n";
|
||||
StyleContext styleContext = StyleContext.getDefaultStyleContext();
|
||||
AttributeSet attributeSet = styleContext.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, color);
|
||||
attributeSet = styleContext.addAttribute(attributeSet, StyleConstants.FontFamily, "Lucida Console");
|
||||
attributeSet = styleContext.addAttribute(attributeSet, StyleConstants.Alignment, StyleConstants.ALIGN_JUSTIFIED);
|
||||
int oldCaretPosition = this.textPane.getCaretPosition();
|
||||
int length = this.textPane.getDocument().getLength();
|
||||
this.textPane.setCaretPosition(length);
|
||||
this.textPane.setCharacterAttributes(attributeSet, false);
|
||||
this.textPane.replaceSelection(text);
|
||||
// TODO: Fix behaviour when autoscroll is disabled!
|
||||
if(this.autoScrollToBottom) {
|
||||
Document textPaneDocument = this.textPane.getDocument();
|
||||
this.textPane.select(textPaneDocument.getLength(), textPaneDocument.getLength());
|
||||
} else {
|
||||
this.textPane.setCaretPosition(oldCaretPosition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generic method of Observer interface to allow for use as an observer.
|
||||
* In case no CsparqlQueryResultProxy is being observed, output can still be useful. :-)
|
||||
* @param observable the incoming observable object
|
||||
* @param argument the argument that came with it
|
||||
*/
|
||||
@Override
|
||||
public void update(Observable observable, Object argument) {
|
||||
if(observable instanceof CsparqlQueryResultProxy) {
|
||||
CsparqlQueryResultProxy result = (CsparqlQueryResultProxy) observable;
|
||||
RDFTable table = (RDFTable) argument;
|
||||
this.showCsparqlQueryResult(result, table);
|
||||
} else {
|
||||
// Debug output in case this is not used to observe
|
||||
this.showText(observable.getClass().toString(), Color.RED);
|
||||
this.showText(observable.toString(), Color.BLUE);
|
||||
this.showText(argument.getClass().toString(), Color.RED);
|
||||
this.showText(argument.toString(), Color.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to actually print the results of a Csparql query
|
||||
* @param CsparqlQueryResultProxy result
|
||||
* @param RDFTable table
|
||||
*/
|
||||
private void showCsparqlQueryResult(CsparqlQueryResultProxy result, RDFTable table) {
|
||||
String queryTupleNames = table.getNames().toString();
|
||||
Collection<RDFTuple> tuples = table.getTuples();
|
||||
this.showText(queryTupleNames, Color.BLACK);
|
||||
for(RDFTuple tuple : tuples) {
|
||||
// This one is separated with \t. Due to the implementation of RDFTuple, it is
|
||||
// implossible to access the list of its fields directly. Sorry for the mess. :-(
|
||||
String tupleString = tuple.toString();
|
||||
// Explode tupleString by \t and show each field with alternating color.
|
||||
StringTokenizer tokenizer = new StringTokenizer(tupleString);
|
||||
Color[] palette = this.getColorPaletteWithSize(tokenizer.countTokens());
|
||||
int tokenIndex = 0;
|
||||
while(tokenizer.hasMoreTokens()) {
|
||||
String token = tokenizer.nextToken()+"\t";
|
||||
this.showToken(token, palette[tokenIndex]);
|
||||
tokenIndex++;
|
||||
}
|
||||
this.showText("\n", Color.BLACK);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a color palette for the given number of colors
|
||||
* @param sizeOfPalette number of colors
|
||||
* @return color palette as an array
|
||||
*/
|
||||
private Color[] getColorPaletteWithSize(int sizeOfPalette) {
|
||||
if(sizeOfPalette == 0) {
|
||||
return new Color[] {Color.BLACK};
|
||||
}
|
||||
Color[] result = new Color[sizeOfPalette];
|
||||
float h = 0.0f;
|
||||
float s = 0.75f;
|
||||
float b = 0.75f;
|
||||
for(int i=0; i<sizeOfPalette; i++) {
|
||||
h = (((float) i)/((float) sizeOfPalette));
|
||||
result[i] = Color.getHSBColor(h, s, b);
|
||||
}
|
||||
return result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
package lu.jpt.csparqltest.util;
|
||||
|
||||
import eu.larkc.csparql.cep.api.RdfQuadruple;
|
||||
import eu.larkc.csparql.cep.api.RdfStream;
|
||||
|
||||
/**
|
||||
* Helper class to allow easy plugging of log mechanisms.
|
||||
*/
|
||||
public class LoggableRdfStream extends RdfStream {
|
||||
|
||||
public LoggableRdfStream(String iri) {
|
||||
super(iri);
|
||||
}
|
||||
|
||||
public void put(RdfQuadruple quad) {
|
||||
super.put(quad);
|
||||
// Call hook method to allow logging the RdfQuadruple.
|
||||
this.log(quad);
|
||||
}
|
||||
|
||||
/**
|
||||
* This hook method gets called for every RdfQuadruple that is fed into the stream.
|
||||
* @param quad that has been fed into the stream.
|
||||
*/
|
||||
public void log(RdfQuadruple quad) {
|
||||
// Default: Do nothing.
|
||||
}
|
||||
|
||||
}
|
|
@ -4,15 +4,18 @@ import org.slf4j.Logger;
|
|||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import eu.larkc.csparql.cep.api.RdfQuadruple;
|
||||
import eu.larkc.csparql.cep.api.RdfStream;
|
||||
import lu.jpt.csparqltest.gui.TextObserverWindow;
|
||||
|
||||
public class TestStreamGenerator extends RdfStream implements Runnable {
|
||||
public class TestStreamGenerator extends LoggableRdfStream implements Runnable {
|
||||
protected final Logger logger = LoggerFactory.getLogger(TestStreamGenerator.class);
|
||||
|
||||
private volatile boolean keepRunning = false;
|
||||
|
||||
private TextObserverWindow observerWindow;
|
||||
|
||||
public TestStreamGenerator(String iri) {
|
||||
super(iri);
|
||||
observerWindow = new TextObserverWindow("TestStreamGenerator");
|
||||
}
|
||||
|
||||
public void pleaseStop() {
|
||||
|
@ -44,5 +47,10 @@ public class TestStreamGenerator extends RdfStream implements Runnable {
|
|||
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void log(RdfQuadruple quad) {
|
||||
this.observerWindow.showQuadruple(quad);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue