K
karl.wettin
<http://wiki.snigel.net/se.snigel.vojne>
= Abstract =
GUI and/or document framework, originally written as an ad-hoc portable
document format for ["se.snigel.vojnevojne"]. It works with
interpreters and renderers in order to read and display the output of
any implementend format. That could be PDF, Swing, man-pages, HTML,
Java source code, or what not.
= Table of contents =
[[TableOfContents]]
= Why? =
* I don't belive that HTML is the top GUI-layer
* I don't like JSP
* I never took time to check out Struts
= Download =
BSD open source licence.
* attachment:vojne_20050303.tar.gz >> includes java source code,
compiled classes, distribution jar and deptendent libraries.
= Available composites =
Mostly primitives, but also list- and treeviews.
* Text
* Monospace
* Font >> color, size
* Bold
* Underline
* Italic
* Striketrough
* Subscript
* Superscript
* Pre-formatted text
* Paragraph
* Linefeed
* Horizontal seperator
* Table
* Bullet list
* Hyper link
* Image
* Tag
* Document >> chapters, table of contents
* Listview
* Treeview >> abstract
* Gnome treeview >> a gnome directory browser style treeview.
* Form
* Check box
* Button
* Text area
* Text input
= Example implementations =
== Creating a GUI ==
Below is the view part code of a ["model view controller pattern"] from
the software ["se.snigel.vojnevojne"]. The returned data from this
class is sent to a HTMLRenderer.
Basics: {{{new HTMLRenderer().render(out, doc);}}}
How renderers and interpreters work is demonstrated in the next
section.
{{{
package se.snigel.vojnevojne;
import se.snigel.net.servlet.ServletRequest;
import se.snigel.net.servlet.ServletResponse;
import se.snigel.vojne.composite.*;
import se.snigel.vojne.composite.form.Form;
import se.snigel.vojne.composite.form.TextInput;
import se.snigel.vojne.composite.form.Submit;
import se.snigel.vojne.renderer.Renderer;
import se.snigel.vojne.interpreter.macro.URI;
import se.snigel.util.Settings;
import se.snigel.vojnevojne.action.ActionManager;
import se.snigel.vojnevojne.action.Action;
import se.snigel.vojnevojne.plugs.PlugManager;
import se.snigel.vojnevojne.plugs.LuceneSearch;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
/**
* User: kalle
* Date: Feb 23, 2005
* Time: 11:28:51 PM
*/
public class LayoutImpl
implements Layout
{
public Composite renderLogin(String emailAddress)
{
Form form = new Form();
form.setContent(new ListView(new Composite[][]
{
{new Text("Username"), new Text("Password")},
{new TextInput("username", emailAddress), new
TextInput("password", "", true)}
}));
form.getContent().setNextComposite(new Submit("Authenticate"));
return form;
}
public Composite renderRegistration(String emailAddress, String
firstName, String lastName, String comment)
{
Form form = new Form();
form.setContent(new ListView(new Composite[][]
{
null, // left null means no horizontal headers.
{new Text("Email address"), new TextInput("username",
emailAddress)},
{new Text("Password"), new TextInput("password", "",
true)},
{new Text("First name"), new TextInput("firstName",
firstName)},
{new Text("Last name"), new TextInput("lastName",
lastName)},
{new Text("Your comment"), new TextInput("comment",
comment, false, "50")}
}));
form.getContent().setNextComposite(new Submit("Register"));
return form;
}
public void render(ServletRequest request, ServletResponse
response, Document document, Composite content, Renderer renderer,
Settings settings)
throws IOException
{
Account account = (Account)
request.getSession().getAttribute("VojneVojne.account");
/*
---------- preferences------
|LOGO|name|icons |
|--------------------------|
| quick links |
|--------------------------|
| content |
|--------------------------|
| search |
----------------------------
*/
int noOfCols = 3;
se.snigel.vojne.composite.Document doc = new
se.snigel.vojne.composite.Document();
Table table = new Table();
doc.getHeirarchyRoot().setContent(table);
Table.Row row;
Table.Column col;
table.setWidth("100%");
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
row.addColumn(col);
col.setRowspan(noOfCols);
col.setContent(new Image(settings.getString("logo url",
"/img/vojne.png"), 0, settings.getString("name", "vojne wiki")));
col = new Table.Column();
row.addColumn(col);
col.setRowspan(noOfCols);
if (account != null)
{
if (document != null)
col.setContent(new Text(document.getTitle()));
else
col.setContent(new Text("A plug made this page"));
// todo
}
else
{
col.setContent(new
Text(settings.getString("authentification title",
settings.getString("name"))));
}
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
row.addColumn(col);
if (account != null)
col.setContent(new HyperLink("UserPreferences", new
Text("preferences")));
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
if (account != null && document != null)
{
Composite lastComposite = null;
Iterator it =
ActionManager.getInstance().iterateActions();
while (it.hasNext())
{
try
{
Action action =
(Action)((Map.Entry)it.next()).getValue();
HyperLink link = new HyperLink("?action=" +
action.getKey(account, document, request), new
Image(action.getIconURL(account, document, request),
action.getKey(account, document, request),
action.getDescription(account, document, request)));
if (lastComposite == null)
col.setContent(link);
else
lastComposite.setNextComposite(link);
link.setNextComposite(new Text(" "));
lastComposite = link.getNextComposite();
}
catch (Exception e)
{
col.setContent(new Text("An error occured: " +
e.getMessage()));
break;
}
}
}
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
if (account != null)
{
/*
col.setContent(new Text("| "));
Composite tmp = col.getContent();
tmp = tmp.setNextComposite(new HyperLink("FrontPage",
new Text("FrontPage")));
for (int i = 0; i <
account.getSettings().getInt("navigation history size", 6); i++)
{
String history =
account.getSettings().getString("navigation history." + i);
if (history != null)
{
tmp = tmp.setNextComposite(new Text(" | "));
tmp = tmp.setNextComposite(new
HyperLink(history, new Text(history)));
}
}
tmp.setNextComposite(new Text(" |"));
"
for (int i = 1; i <
account.getSettings().getInt("navigation history size", 6); i++)
{
account.getSettings().putString("navigation
history." + i, account.getSettings().getString("navigation history." +
(i - 1)));
}
account.getSettings().putString("navigational
history.0", contextID);
*/
}
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
col.setContent(new HorizontalSeperator());
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
row.addColumn(col);
col.setColspan(noOfCols);
col.setContent(content);
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
col.setContent(new HorizontalSeperator());
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
if (account != null)
{
col.setContent(((LuceneSearch)PlugManager.getInstance().getPlug(LuceneSearch.class)).renderQueryForm(account,
request));
}
}
renderer.render(response.getWriter(), doc);
}
}
}}}
== Using interpreters ==
{{{
package se.snigel;
import se.snigel.vojne.renderer.HTMLRenderer;
import se.snigel.vojne.renderer.VojneRenderer;
import se.snigel.vojne.renderer.VojneRenderer;
import se.snigel.vojne.renderer.ASCIIArtRenderer;
import se.snigel.vojne.composite.Document;
import se.snigel.vojne.interpreter.VojneInterpreter;
import se.snigel.vojne.interpreter.macro.MacroManager;
import se.snigel.vojne.interpreter.lineparser.LineParserManager;
import java.util.Random;
import java.io.*;
import java.iutputStreamWriter;
import java.io.InputStreamReader;
import java.io.StringReader;
public class Test
{
public static void main (String[] args)
throws Exception
{
// add some VojneVojne line parsers. LineParserManager is a
VojneVojne wiki interpter class.
LineParserManager.getInstance().registerLineParser("se.snigel.vojne.interpreter.lineparser.BulletList");
LineParserManager.getInstance().registerLineParser("se.snigel.vojne.interpreter.lineparser.PreFormattedText");
// add some VojneVojne macros. Same with MacroManager.
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Bold");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Italic");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Subscript");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Superscript");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.TableOfContents");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.URI");
InputStream in = new
StringBufferInputStream("[[TableOfContents]]\n= first chapter =\nHello,
world. \n * ball\n * ball2\n * ball2.2 \n\n== inner chapter
==\n**bold//bolditalic//**^^super^^. = second chapter
=\n[http://wiki.snigel.net]");
OutputStreamWriter out = new OutputStreamWriter(System.out);
Document doc = new VojneInterpreter().getDocument(in); // todo
rename to VojneVojneInterpreter
// render this document as a
new HTMLRenderer().render(out, doc);
new VojneRenderer().render(out, doc);
new ASCIIArtRenderer().render(out, doc);
out.close();
}
}
}}}
= Abstract =
GUI and/or document framework, originally written as an ad-hoc portable
document format for ["se.snigel.vojnevojne"]. It works with
interpreters and renderers in order to read and display the output of
any implementend format. That could be PDF, Swing, man-pages, HTML,
Java source code, or what not.
= Table of contents =
[[TableOfContents]]
= Why? =
* I don't belive that HTML is the top GUI-layer
* I don't like JSP
* I never took time to check out Struts
= Download =
BSD open source licence.
* attachment:vojne_20050303.tar.gz >> includes java source code,
compiled classes, distribution jar and deptendent libraries.
= Available composites =
Mostly primitives, but also list- and treeviews.
* Text
* Monospace
* Font >> color, size
* Bold
* Underline
* Italic
* Striketrough
* Subscript
* Superscript
* Pre-formatted text
* Paragraph
* Linefeed
* Horizontal seperator
* Table
* Bullet list
* Hyper link
* Image
* Tag
* Document >> chapters, table of contents
* Listview
* Treeview >> abstract
* Gnome treeview >> a gnome directory browser style treeview.
* Form
* Check box
* Button
* Text area
* Text input
= Example implementations =
== Creating a GUI ==
Below is the view part code of a ["model view controller pattern"] from
the software ["se.snigel.vojnevojne"]. The returned data from this
class is sent to a HTMLRenderer.
Basics: {{{new HTMLRenderer().render(out, doc);}}}
How renderers and interpreters work is demonstrated in the next
section.
{{{
package se.snigel.vojnevojne;
import se.snigel.net.servlet.ServletRequest;
import se.snigel.net.servlet.ServletResponse;
import se.snigel.vojne.composite.*;
import se.snigel.vojne.composite.form.Form;
import se.snigel.vojne.composite.form.TextInput;
import se.snigel.vojne.composite.form.Submit;
import se.snigel.vojne.renderer.Renderer;
import se.snigel.vojne.interpreter.macro.URI;
import se.snigel.util.Settings;
import se.snigel.vojnevojne.action.ActionManager;
import se.snigel.vojnevojne.action.Action;
import se.snigel.vojnevojne.plugs.PlugManager;
import se.snigel.vojnevojne.plugs.LuceneSearch;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
/**
* User: kalle
* Date: Feb 23, 2005
* Time: 11:28:51 PM
*/
public class LayoutImpl
implements Layout
{
public Composite renderLogin(String emailAddress)
{
Form form = new Form();
form.setContent(new ListView(new Composite[][]
{
{new Text("Username"), new Text("Password")},
{new TextInput("username", emailAddress), new
TextInput("password", "", true)}
}));
form.getContent().setNextComposite(new Submit("Authenticate"));
return form;
}
public Composite renderRegistration(String emailAddress, String
firstName, String lastName, String comment)
{
Form form = new Form();
form.setContent(new ListView(new Composite[][]
{
null, // left null means no horizontal headers.
{new Text("Email address"), new TextInput("username",
emailAddress)},
{new Text("Password"), new TextInput("password", "",
true)},
{new Text("First name"), new TextInput("firstName",
firstName)},
{new Text("Last name"), new TextInput("lastName",
lastName)},
{new Text("Your comment"), new TextInput("comment",
comment, false, "50")}
}));
form.getContent().setNextComposite(new Submit("Register"));
return form;
}
public void render(ServletRequest request, ServletResponse
response, Document document, Composite content, Renderer renderer,
Settings settings)
throws IOException
{
Account account = (Account)
request.getSession().getAttribute("VojneVojne.account");
/*
---------- preferences------
|LOGO|name|icons |
|--------------------------|
| quick links |
|--------------------------|
| content |
|--------------------------|
| search |
----------------------------
*/
int noOfCols = 3;
se.snigel.vojne.composite.Document doc = new
se.snigel.vojne.composite.Document();
Table table = new Table();
doc.getHeirarchyRoot().setContent(table);
Table.Row row;
Table.Column col;
table.setWidth("100%");
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
row.addColumn(col);
col.setRowspan(noOfCols);
col.setContent(new Image(settings.getString("logo url",
"/img/vojne.png"), 0, settings.getString("name", "vojne wiki")));
col = new Table.Column();
row.addColumn(col);
col.setRowspan(noOfCols);
if (account != null)
{
if (document != null)
col.setContent(new Text(document.getTitle()));
else
col.setContent(new Text("A plug made this page"));
// todo
}
else
{
col.setContent(new
Text(settings.getString("authentification title",
settings.getString("name"))));
}
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
row.addColumn(col);
if (account != null)
col.setContent(new HyperLink("UserPreferences", new
Text("preferences")));
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
if (account != null && document != null)
{
Composite lastComposite = null;
Iterator it =
ActionManager.getInstance().iterateActions();
while (it.hasNext())
{
try
{
Action action =
(Action)((Map.Entry)it.next()).getValue();
HyperLink link = new HyperLink("?action=" +
action.getKey(account, document, request), new
Image(action.getIconURL(account, document, request),
action.getKey(account, document, request),
action.getDescription(account, document, request)));
if (lastComposite == null)
col.setContent(link);
else
lastComposite.setNextComposite(link);
link.setNextComposite(new Text(" "));
lastComposite = link.getNextComposite();
}
catch (Exception e)
{
col.setContent(new Text("An error occured: " +
e.getMessage()));
break;
}
}
}
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
if (account != null)
{
/*
col.setContent(new Text("| "));
Composite tmp = col.getContent();
tmp = tmp.setNextComposite(new HyperLink("FrontPage",
new Text("FrontPage")));
for (int i = 0; i <
account.getSettings().getInt("navigation history size", 6); i++)
{
String history =
account.getSettings().getString("navigation history." + i);
if (history != null)
{
tmp = tmp.setNextComposite(new Text(" | "));
tmp = tmp.setNextComposite(new
HyperLink(history, new Text(history)));
}
}
tmp.setNextComposite(new Text(" |"));
"
for (int i = 1; i <
account.getSettings().getInt("navigation history size", 6); i++)
{
account.getSettings().putString("navigation
history." + i, account.getSettings().getString("navigation history." +
(i - 1)));
}
account.getSettings().putString("navigational
history.0", contextID);
*/
}
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
col.setContent(new HorizontalSeperator());
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
row.addColumn(col);
col.setColspan(noOfCols);
col.setContent(content);
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
col.setContent(new HorizontalSeperator());
}
row = new Table.Row();
{
table.addRow(row);
col = new Table.Column();
col.setColspan(noOfCols);
row.addColumn(col);
if (account != null)
{
col.setContent(((LuceneSearch)PlugManager.getInstance().getPlug(LuceneSearch.class)).renderQueryForm(account,
request));
}
}
renderer.render(response.getWriter(), doc);
}
}
}}}
== Using interpreters ==
{{{
package se.snigel;
import se.snigel.vojne.renderer.HTMLRenderer;
import se.snigel.vojne.renderer.VojneRenderer;
import se.snigel.vojne.renderer.VojneRenderer;
import se.snigel.vojne.renderer.ASCIIArtRenderer;
import se.snigel.vojne.composite.Document;
import se.snigel.vojne.interpreter.VojneInterpreter;
import se.snigel.vojne.interpreter.macro.MacroManager;
import se.snigel.vojne.interpreter.lineparser.LineParserManager;
import java.util.Random;
import java.io.*;
import java.iutputStreamWriter;
import java.io.InputStreamReader;
import java.io.StringReader;
public class Test
{
public static void main (String[] args)
throws Exception
{
// add some VojneVojne line parsers. LineParserManager is a
VojneVojne wiki interpter class.
LineParserManager.getInstance().registerLineParser("se.snigel.vojne.interpreter.lineparser.BulletList");
LineParserManager.getInstance().registerLineParser("se.snigel.vojne.interpreter.lineparser.PreFormattedText");
// add some VojneVojne macros. Same with MacroManager.
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Bold");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Italic");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Subscript");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.Superscript");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.TableOfContents");
MacroManager.getInstance().registerMacro("se.snigel.vojne.interpreter.macro.URI");
InputStream in = new
StringBufferInputStream("[[TableOfContents]]\n= first chapter =\nHello,
world. \n * ball\n * ball2\n * ball2.2 \n\n== inner chapter
==\n**bold//bolditalic//**^^super^^. = second chapter
=\n[http://wiki.snigel.net]");
OutputStreamWriter out = new OutputStreamWriter(System.out);
Document doc = new VojneInterpreter().getDocument(in); // todo
rename to VojneVojneInterpreter
// render this document as a
new HTMLRenderer().render(out, doc);
new VojneRenderer().render(out, doc);
new ASCIIArtRenderer().render(out, doc);
out.close();
}
}
}}}