();
/** The latest WindowID. */
private static int wid;
/** The latest ViewID. */
private static int vid;
/** World map texture. */
public static Texture worldTex;
/** World map texture. */
public static Texture blankTex;
/** Skybox texture. */
public static Texture skyboxTexTop;
/** Skybox texture. */
public static Texture skyboxTexBottom;
/** Skybox texture. */
public static Texture skyboxTexSide1;
/** Skybox texture. */
public static Texture skyboxTexSide2;
/** Skybox texture. */
public static Texture skyboxTexSide3;
/** Skybox texture. */
public static Texture skyboxTexSide4;
/** If true, the predefined textures are loaded. */
public static boolean texturesLoaded = false;
/** The size of the console input buffer */
public static final int CONSOLE_INPUT_CAPACITY = 8;
/** */
//public static final int STANDARD_INPUT_CAPACITY = 8;
/** */
//public static final int MESSAGE_INPUT_CAPACITY = 256;
/** The maximum size of incoming messages. */
public static final int MESSAGE_MAX_WIDTH = 1024;
/** A buffer used for storing user input messages. */
public static RawBuffer consoleInputBuffer;
/** */
//public static RawBuffer standardInputBuffer;
/** */
//public static RawBuffer messageInputBuffer;
//public static StandardInputListener standardInputListener;
/** The console. Use VI.d.d("debug"); to print text. */
public static ConsolePanel d;
/** Maintains a connection to the database. */
//public static DBCom dbcon;
/** Parsing strategy. */
public static int STRAT_NODE_HOST_VALUE = 0;
/** Parsing strategy. */
public static int STRAT_NODE_HOST_CAT_VALUE = 1;
/** Parsing strategy. */
public static int STRAT_NODE_HOST_CAT_VALUE_N = 2;
/** Parsing strategy. */
public static int STRAT_REL_HOST_VALUE = 3;
/** Parsing strategy. */
public static int STRAT_REL_HOST_VALUE_2 = 4;
/** The null category. */
public static int NULL_CATEGORY = 0;
/** A space character. */
public static final String SPACE = " ";
/** An underscore. */
public static final String UNDERSCORE = "_";
/** A null character. */
public static final String NULL_CHAR = "\0";
/** The current time. */
public static long currentTimeStamp = 0;
/** If this value is set to zero, time out time is assumed to be infinite. */
public static long timeOut = 0;
/** The default value used for the timeout. */
public static float defaultValue = 0.0f;
/** The current bar type. */
public static int barType = 0;
/** An array of nodes. */
public static NodeType[] nodeTypeArr;
/**
* Calculate the normalized color from a normalized value and a color range.
* Note: Uses linear scaling.
*
* @param c1 A color RGB triple. Start color of the gradient.
* @param c2 A color RGB triple. End color of the gradient.
* @param vn A normalized value in the range [0.0 1.0].
* @return the normalized color.
*/
public static float[] normalizedColor(float[] c1, float[] c2, float vn) {
float[] ret = new float[3];
ret[0] = c1[0] + (c2[0] - c1[0]) * vn;
ret[1] = c1[1] + (c2[1] - c1[1]) * vn;
ret[2] = c1[2] + (c2[2] - c1[2]) * vn;
return ret;
}
/**
* Request a new window ID. This method is thread safe.
*
* @return The requested window ID.
*/
public static synchronized int requestWindowID() {
wid++;
return wid;
}
/**
* Request a new view ID.This method is thread safe.
*
* @return The requested view ID.
*/
public static synchronized int requestViewID() {
vid++;
return vid;
}
/**
* Read a save file and load the settings into a view panel.
* @param file A save file.
* @param view A view panel.
*/
public static void readSave(File file, ViewPanel view) {
int v = 0;
int labelCount = 0;
int subsetCount = 0;
int[] subsetArr = null;
String[] token = null;
try {
BufferedReader reader = new BufferedReader(new FileReader(file));
String input = null;
if ((input = reader.readLine()) != null) {
try {
// 900 = 0.9 and forward
if (900 <= Integer.parseInt(input)) {
VI.d.def("The save file is not compatible with this version.");
return;
}
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
input = null;
if ((input = reader.readLine()) != null) {
try {
subsetCount = Integer.parseInt(input);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
input = null;
subsetArr = new int[subsetCount];
for (int i = 0; i < subsetCount; i++) {
if ((input = reader.readLine()) != null) {
try {
subsetArr[i] = Integer.parseInt(input);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
input = null;
if ((input = reader.readLine()) != null) {
labelCount = 0;
token = input.split(" ");
if (token[0].equals("view")) {
try {
//Integer.parseInt(token[1]);
view.barsOn = Boolean.parseBoolean(token[2]);
view.brushingMarkersOn = Boolean.parseBoolean(token[3]);
view.graphNodesOn = Boolean.parseBoolean(token[4]);
view.graphRelationsOn = Boolean.parseBoolean(token[5]);
view.texturesOn = Boolean.parseBoolean(token[6]);
view.viewTitleOn = Boolean.parseBoolean(token[7]);
view.labelsOn = Boolean.parseBoolean(token[8]);
view.subsetOn = Boolean.parseBoolean(token[9]);
view.subsetEmpty = Boolean.parseBoolean(token[10]);
view.defaultNodeColorsOn = Boolean.parseBoolean(token[11]);
view.levelNodeShadingOn = Boolean.parseBoolean(token[12]);
labelCount = Integer.parseInt(token[13]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
if (token[0].equals("nodeData")) {
try {
view.nodeData = Integer.parseInt(token[1]);
view.nodeSelectedIndex = Integer.parseInt(token[2]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
if (token[0].equals("relData")) {
try {
view.relData = Integer.parseInt(token[1]);
view.relSelectedIndex = Integer.parseInt(token[2]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
if (token[0].equals("barData")) {
int count = 0;
try {
count = Integer.parseInt(token[1]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
for (int j = 0; j < count; j++) {
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
try {
view.barData[j] = Integer.parseInt(token[0]);
view.barsSelectedIndex[j] = Integer.parseInt(token[1]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
}
}
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
if (token[0].equals("histData")) {
int count = 0;
try {
count = Integer.parseInt(token[1]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
for (int j = 0; j < count; j++) {
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
try {
view.histData[j] = Integer.parseInt(token[0]);
view.histSelectedIndex[j] = Integer.parseInt(token[1]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
}
}
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
if (token[0].equals("nodeOfTypeOn")) {
int count = 0;
try {
count = Integer.parseInt(token[1]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
for (int j = 0; j < count; j++) {
try {
view.nodeOfTypeOn[j] = Boolean.parseBoolean(token[2+j]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
}
for (int j = 0; j < labelCount; j++) {
input = null;
if ((input = reader.readLine()) != null) {
token = input.split(" ");
try {
view.nodeArrFull[j].highlighted = Boolean.parseBoolean(token[0]);
view.nodeArrFull[j].label.xPlane = Float.parseFloat(token[1]);
view.nodeArrFull[j].label.yPlane = Float.parseFloat(token[2]);
view.nodeArrFull[j].label.zPlane = Float.parseFloat(token[3]);
view.nodeArrFull[j].label.xGlobe = Float.parseFloat(token[4]);
view.nodeArrFull[j].label.yGlobe = Float.parseFloat(token[5]);
view.nodeArrFull[j].label.zGlobe = Float.parseFloat(token[6]);
view.nodeArrFull[j].label.x = Float.parseFloat(token[7]);
view.nodeArrFull[j].label.y = Float.parseFloat(token[8]);
view.nodeArrFull[j].label.z = Float.parseFloat(token[9]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
}
view.nodeArr = view.nodeArrFull;
} else {
VI.d.def("The save file is corrupt.");
return;
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
view.createSubset(subsetArr);
}
/**
* Writes the viewsettings to file.
* @param file a file to write to.
* @param view a view.
*/
public static void writeSave(File file, ViewPanel view) {
try {
BufferedWriter writer = new BufferedWriter(new FileWriter(file));
String output = "";
writer.write("" + build); // build number
writer.newLine();
writer.write("" + view.nodeArrSubset.length);
writer.newLine();
for (int i = 0; i < view.nodeArrSubset.length; i++) {
writer.write("" + view.nodeArrSubset[i].id);
writer.newLine();
}
output = "view " + view.id + " ";
output = output + view.barsOn + " ";
output = output + view.brushingMarkersOn + " ";
output = output + view.graphNodesOn + " ";
output = output + view.graphRelationsOn + " ";
output = output + view.texturesOn + " ";
output = output + view.viewTitleOn + " ";
output = output + view.labelsOn + " ";
output = output + view.subsetOn + " ";
output = output + view.subsetEmpty + " ";
output = output + view.defaultNodeColorsOn + " ";
output = output + view.levelNodeShadingOn + " ";
output = output + view.nodeArr.length + " ";
writer.write(output);
writer.newLine();
output = "nodeData " + view.nodeData + " " + view.nodeSelectedIndex;
writer.write(output);
writer.newLine();
output = "relData " + view.relData + " " + view.relSelectedIndex;
writer.write(output);
writer.newLine();
output = "barData " + view.barData.length;
writer.write(output);
writer.newLine();
for (int i = 0; i < view.barData.length; i++) {
output = view.barData[i] + " " + view.barsSelectedIndex[i];
writer.write(output);
writer.newLine();
}
output = "histData " + view.histData.length;
writer.write(output);
writer.newLine();
for (int i = 0; i < view.histData.length; i++) {
output = view.histData[i] + " " + view.histSelectedIndex[i];
writer.write(output);
writer.newLine();
}
/*
output = "nodeOfLevelOn " + view.nodeOfLevelOn.length + " ";
for (int i = 0; i < view.nodeOfLevelOn.length; i++) {
output = output + view.nodeOfLevelOn[i] + " ";
}
writer.write(output);
writer.newLine();
*/
output = "nodeOfTypeOn " + view.nodeOfTypeOn.length + " ";
for (int i = 0; i < view.nodeOfTypeOn.length; i++) {
output = output + view.nodeOfTypeOn[i] + " ";
}
writer.write(output);
writer.newLine();
for (int i = 0; i < view.nodeArrFull.length; i++) {
output = view.nodeArrFull[i].highlighted + " ";
output = output + view.nodeArrFull[i].label.xPlane + " ";
output = output + view.nodeArrFull[i].label.yPlane + " ";
output = output + view.nodeArrFull[i].label.zPlane + " ";
output = output + view.nodeArrFull[i].label.xGlobe + " ";
output = output + view.nodeArrFull[i].label.yGlobe + " ";
output = output + view.nodeArrFull[i].label.zGlobe + " ";
output = output + view.nodeArrFull[i].label.x + " ";
output = output + view.nodeArrFull[i].label.y + " ";
output = output + view.nodeArrFull[i].label.z + " ";
writer.write(output);
writer.newLine();
}
writer.flush();
writer.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
/**
* Reads topology information from a file pointed to by the xml-file. The file should have the following formatting:
*
* C
* nodeID nodeTypeID nodeTypeName nodeHierarchyName Xpos Ypos
* ...
* relationID nodeAID nodeBID
* ...
*
* Example:
*
* 1
* 1 1 xnode 11b 0.4 1.102
* 2 2 ynode 11b 0.11 -0.3
* rID 1 2
*
*/
public static void readTopologyFromFile(String fileName) {
int C = 0;
int nID = 0;
int nodeTypeID = 0;
String nodeTypeName = "";
String nodeHierarchyName = "";
float nodeX = 0;
float nodeY = 0;
int rID = 0;
int nodeA = 0;
int nodeB = 0;
try {
BufferedReader reader = new BufferedReader(new FileReader(fileName));
String input = null;
if ((input = reader.readLine()) != null) {
try {
C = Integer.parseInt(input);
} catch (NumberFormatException e) {
e.printStackTrace();
}
}
input = null;
while ((input = reader.readLine()) != null) {
String[] token = input.split(" ");
if (token[0].equals("node")) {
try {
nID = Integer.parseInt(token[1]);
nodeTypeID = Integer.parseInt(token[2]);
nodeTypeName = token[3];
nodeHierarchyName = token[4];
nodeX = Float.parseFloat(token[5]);
nodeY = Float.parseFloat(token[6]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
GraphNode node = new GraphNode( nID,
nodeTypeArr[nodeTypeID],
nodeTypeName + nodeHierarchyName,
nodeX,
nodeY,
0.0f);
nodeList.add(node);
nodeID.put(nodeTypeName + nodeHierarchyName, new Integer(nID));
} else if (token[0].equals("rel")) {
try {
rID = Integer.parseInt(token[1]);
nodeA = Integer.parseInt(token[2]);
nodeB = Integer.parseInt(token[3]);
} catch (NumberFormatException e) {
e.printStackTrace();
}
GraphNode nA = null;
GraphNode nB = null;
ListIterator iter = nodeList.listIterator();
GraphNode nU = null;
while (iter.hasNext()) {
nU = (GraphNode)iter.next();
if (nU.id == nodeA) {
nA = nU;
}
if (nU.id == nodeB) {
nB = nU;
}
}
nodeRelList.add(new GraphNodeRel(rID, nA, nB));
relID.put(nA.title + "_" + nB.title, new Integer(rID));
}
}
reader.close();
} catch (Exception e) {
e.printStackTrace();
System.exit(1);
}
}
/**
* Prepares all global data structures.
*/
public static void prepareDataStructures() {
// the order in which nodes, categories and relations are
// fetched is bound by some dependencies in the datastructures
// so it is adviced you do not change the order of the code beyond this point.
try {
udpOutPort = Integer.parseInt(XMLInterface.masterPort);
} catch (NumberFormatException e) {
System.out.println("VI.java > master port number is not an integer!");
System.exit(1);
}
try {
udpInPort = Integer.parseInt(XMLInterface.inputPort);
} catch (NumberFormatException e) {
System.out.println("VI.java > input port number is not an integer!");
System.exit(1);
}
try {
keepAlivePort = Integer.parseInt(XMLInterface.keepAlivePort);
} catch (NumberFormatException e) {
System.out.println("VI.java > keep alive port number is not an integer!");
System.exit(1);
}
VI.udpOutHost = XMLInterface.masterHost;
VI.keepAliveHost = XMLInterface.keepAliveHost;
VI.windowTitle = XMLInterface.windowTitle;
VI.defaultValue = XMLInterface.defaultValue;
VI.timeOut = XMLInterface.timeOut;
VI.barType = XMLInterface.defaultBarType;
nodeTypeArr = new NodeType[XMLInterface.totalNodeTypes];
for (int i = 0; i < XMLInterface.totalNodeTypes; i++) {
if (i == 0) {
nodeTypeArr[i] = new NodeType(0, "null", -1);
} else {
nodeTypeArr[i] = new NodeType(
XMLInterface.topologyNodeTypeId[i-1],
XMLInterface.topologyNodeTypeName[i-1],
XMLInterface.topologyNodeTypeLevel[i-1],
XMLInterface.topologyNodeTypeNullColor[i-1]);
}
}
for (int i = 0; i < XMLInterface.totalCategories; i++) {
if (i == 0) {
CategoryItem[] arr = new CategoryItem[1];
arr[0] = new CategoryItem(0, "null", "null");
categoryList.add(new Category(i, arr, "Null Category"));
catID.put("null", new Integer(0));
} else {
LinkedList categoryItemList = new LinkedList();
CategoryItem[] categoryItemArr = null;
for (int k = 0; k < XMLInterface.totalCategoryItems[i-1]; k++) {
CategoryItem item = new CategoryItem(
k+1,
XMLInterface.categoriesCategoryCategoryItemName[i-1][k],
XMLInterface.categoriesCategoryCategoryItemParseName[i-1][k]);
item.color = XMLInterface.categoriesCategoryCategoryItemColor[i-1][k][0];
categoryItemList.add(item);
catID.put(
XMLInterface.categoriesCategoryCategoryItemParseName[i-1][k],
new Integer(k+1));
}
categoryItemArr = categoryItemList.toArray(new CategoryItem[0]);
VI.categoryList.add(new Category(i, categoryItemArr, XMLInterface.categoriesCategoryName[i-1]));
}
}
// read the topology from the save file.
VI.readTopologyFromFile(XMLInterface.topologyFileName);
categoryArr = categoryList.toArray(new Category[0]);
nodeArr = nodeList.toArray(new GraphNode[0]);
nodeRelArr = nodeRelList.toArray(new GraphNodeRel[0]);
dataArr = new Data[XMLInterface.totalData];
// if the naming conventions seems confusing...
// consult the file: XMLInterface.java
for (int i = 0; i < XMLInterface.totalData; i++) {
dataArr[i] = new Data( XMLInterface.dataDataSetId[i],
XMLInterface.dataDataSetName[i],
XMLInterface.dataDataSetPName[i],
XMLInterface.dataDataSetSet[i],
categoryArr[XMLInterface.dataDataSetCat[i]],
XMLInterface.dataDataSetParseStrat[i],
XMLInterface.dataDataSetDimension[i],
nodeTypeArr[XMLInterface.dataDataSetNodeType[i]],
XMLInterface.dataDataSetMax[i],
XMLInterface.dataDataSetMin[i],
XMLInterface.dataDataSetColor[i]);
}
commandArr = new Command[XMLInterface.totalCommands];
for (int i = 0; i < XMLInterface.totalCommands; i++) {
commandArr[i] = new Command(
XMLInterface.commandsCommandId[i],
XMLInterface.commandsCommandName[i],
XMLInterface.commandsCommandMessagePrefix[i],
XMLInterface.commandsCommandMessage[i]);
}
for (int i = 0; i < dataArr.length; i++) {
if ( dataArr[i].category.id == 0 &&
dataArr[i].set == Data.SET_NODES) {
nodeSingularDataList.add(dataArr[i]);
}
if ( dataArr[i].category.id == 0 &&
dataArr[i].set == Data.SET_REL) {
relsDataList.add(dataArr[i]);
}
if (dataArr[i].set == Data.SET_NODES) {
nodeMultiDataList.add(dataArr[i]);
}
}
nodeSingularData = nodeSingularDataList.toArray(new Data[0]);
nodeMultiData = nodeMultiDataList.toArray(new Data[0]);
relsData = relsDataList.toArray(new Data[0]);
nodeSingularDataStrings = new String[VI.nodeSingularData.length];
nodeMultiDataStrings = new String[VI.nodeMultiData.length];
relsDataStrings = new String[VI.relsData.length];
for (int i = 0; i < VI.nodeSingularData.length; i++) {
nodeSingularDataStrings[i] = VI.nodeSingularData[i].name;
}
for (int i = 0; i < VI.nodeMultiData.length; i++) {
nodeMultiDataStrings[i] = VI.nodeMultiData[i].name;
}
for (int i = 0; i < VI.relsData.length; i++) {
relsDataStrings[i] = VI.relsData[i].name;
}
for (int i = 0; i < nodeRelArr.length; i++) {
nodeRelArr[i].createControlPoints();
}
for (int i = 0; i < dataArr.length; i++) {
dataID.put(dataArr[i].parseName, new Integer(dataArr[i].id));
}
consoleInputBuffer = new RawBuffer(
MESSAGE_MAX_WIDTH, CONSOLE_INPUT_CAPACITY);
}
/**
* Clones an array of nodes.
*
* @return An array of nodes.
*/
public static GraphNode[] cloneNodeArr() {
GraphNode[] ret = new GraphNode[nodeArr.length];
for (int i = 0; i < nodeArr.length; i++) {
try {
ret[i] = (GraphNode)nodeArr[i].clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
return ret;
}
/**
* Clones an array of relations.
*
*@param gNode An array of nodes.
* @return An array of relations.
*/
public static GraphNodeRel[] cloneNodeRelArr(GraphNode[] gNode) {
GraphNodeRel[] ret = new GraphNodeRel[nodeRelArr.length];
for (int i = 0; i < nodeRelArr.length; i++) {
try {
ret[i] = (GraphNodeRel)nodeRelArr[i].clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
ret[i].a = gNode[nodeRelArr[i].a.id-1];
ret[i].b = gNode[nodeRelArr[i].b.id-1];
}
return ret;
}
/**
* Initialize the environment and start the GUI.
*
* @param args Not used.
*/
public static void main(String[] args) {
// uncomment for windows version (requires jgoodies plugin)
// you also need to uncomment the import statement
// at the top of this file. search for JGOODIESCOMMENT
// try { UIManager.setLookAndFeel(new Plastic3DLookAndFeel()); }
// catch (Exception e) { e.printStackTrace(); }
// 1. read the xml-file and prepare all of the datastructures
XMLInterface.readConfiguration();
VI.prepareDataStructures();
// 2. start reading the input socket and user input from the commandline
try {
BufferReader bufferReader = new BufferReader(udpInPort);
} catch (SocketException e) {
e.printStackTrace();
System.out.println("VI.main > Unable to open a socket! Exiting...");
System.exit(1);
}
// 3. start the time-out timer if and only if the timeout is a positive integer
if (VI.timeOut > 0) {
TimeOutTimer timer = new TimeOutTimer();
}
// 4. start the main GUI window and add it to the list of windows
GUI window = new GUI();
VI.windowList.add(window);
// 5. (optional) start the KeepAlive class which gives feedback about the current
// up-state of the VI so that the server knows if it is any point
// sending any data.
try {
new KeepAlive(udpInPort, keepAliveHost, keepAlivePort);
} catch (UnknownHostException e) {
e.printStackTrace();
}
}
}