Prefuse
Predicates and Filters
Prefuse provides the ability to filter the rows in a table or graph based on the values of that rows attributes. Filters can be created in a couple different ways, the method I prefer is creating a Predicate object which can then be applied to any table or graph, and saved for later use. Before we get into using predicates, we need to build a table that we can use.
Building a Table
First create the table object :
Table table = new Table();
Now we create the table structure, for this example we'll have two columns in our table, one which stores a string and another which stores a number, adding columns to a table is pretty straightforward :
table.addColumn("text", String.class);
table.addColumn("number", Integer.class);
The table is created and ready for data, so let's add some. The table has an addRow() function which adds an empty row to the table and returns an the row number of the newly created row, with that row number you can set the data value for each field :
int row = table.addRow();
table.set(row, "text", "a text value");
table.set(row, "number", 300);
row = table.addRow();
table.set(row, "text", "another text value");
table.set(row, "number", 200);
row = table.addRow();
table.set(row, "text", "even more text");
table.set(row, "number", 100);
row = table.addRow();
table.set(row, "text", "this is silly");
table.set(row, "number", 100);
row = table.addRow();
table.set(row, "text", "very very silly");
table.set(row, "number", 200);
row = table.addRow();
table.set(row, "text", "okay, thats enough");
table.set(row, "number", 300);
Building The Query
Prefuse queries are constructed using the Prefuse Expression Language. It's documented in detail
Here, so I'm not going to spend much time on the language. It's a basic comparison language and should be fairly recognizable.
So lets say I want to find all the nodes with 300 in the number field, the first thing I do is build a query string and run it through the prefuse ExpressionParser :
String query = "id = 300";
Predicate myPredicate = (Predicate)ExpressionParser.parse(query);
This returns a predicate object, which we can then pass to the table object to get an iterator containing the row numbers of the table entries which match our query
IntIterator tableIterator = table.rows(myPredicate);
After that, it's simply a matter of looping through the iterator and printing out the text value of each row that comes up. The IntIterator class provides a hasNext() function which returns false once we've reached the end of the data set.
if (tableIterator.hasNext()){
row = tableIterator.nextInt();
System.out.println(table.getString(row, "text"));
}
Thats pretty much all there is to it. Note that if you want to search for a text string, you need to enclose that string in single quotes within the query string, otherwise you'll get some rather nasty errors :
String query = "text = 'a text value'";
Prefuse Database Interface
The Prefuse Database Interface, while fairly straightforward, is also somewhat limited. It does an excellent job of loading your mysql tables into prefuse table objects, but once they're in the table object there isn't an easy way to update the database, or even to extract the new data for manual update. Still, it's pretty useful.
First thing you do is set up your connection information, this is more or less the same methodology as the standard Java DBI :
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://somehost.somewhere.com:3306/databasetable";
String user = "jshmoe";
String pass = "apassword";
After you've got the connection information, you need to create ConnectionFactory and DatabaseDataSource objects. You want to actually create the ConnectionFactory object, but the DatabaseDataSource object should be set to null because it's instantiated in a try loop, and you'll get a compile error if you don't declare it before the loop :
ConnectionFactory cf = new ConnectionFactory();
DatabaseDataSource ds = null;
Once thats done, you use the connection factory to connect to the database and create the DataBaseDataSource object :
try{
ds = cf.getDatabaseConnection(driver, url, user, pass);
}
catch(Exception e){
e.printStackTrace();
}
Assuming nothing went wrong there, the next step is to load the data into a prefuse table. This also occurs in a try loop, so be sure to create a null table object before you try to fill it with data. Data for the table is selected with a MySQL query to the database, The table columns are automatically created and all the returned data is placed within the prefuse table :
Table DataTable = null
try{
DataTable = ds.getData("Select * From Data");
}
catch(Exception e){
e.printStackTrace();
}