relevant packages
java.security.* |
check the permissions for a new Socket connection
System.getSecurityManager().checkPermission(new SocketPermission("www.google.com", "connect"));
Keypairs Or Public And Private Keys ‹↑›
generate a public/private key pair with dsa algorithm, sun provider
import java.security.*;
public class GenSig {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: GenSig nameOfFileToSign");
}
else try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();
} catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
}
}
sign a file with a public/private key pair
import java.io.*;
import java.security.*;
public class GenSig {
public static void main(String[] args) {
if (args.length != 1) {
System.out.println("Usage: GenSig nameOfFileToSign");
}
else try {
KeyPairGenerator keyGen = KeyPairGenerator.getInstance("DSA", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
keyGen.initialize(1024, random);
KeyPair pair = keyGen.generateKeyPair();
PrivateKey priv = pair.getPrivate();
PublicKey pub = pair.getPublic();
// sign file data with the keys
Signature dsa = Signature.getInstance("SHA1withDSA", "SUN");
dsa.initSign(priv);
FileInputStream fis = new FileInputStream(args[0]);
BufferedInputStream bufin = new BufferedInputStream(fis);
byte[] buffer = new byte[1024];
int len;
while ((len = bufin.read(buffer)) >= 0) {
dsa.update(buffer, 0, len);
};
bufin.close();
byte[] realSig = dsa.sign();
/* save the signature in a file */
FileOutputStream sigfos = new FileOutputStream("sig");
sigfos.write(realSig);
sigfos.close();
/* save the public key in a file */
byte[] key = pub.getEncoded();
FileOutputStream keyfos = new FileOutputStream("suepk");
keyfos.write(key);
keyfos.close();
} catch (Exception e) {
System.err.println("Caught exception " + e.toString());
}
}
}
Policy Files ‹↑›
the default java security policy file is at
$JAVA_HOME/jre/lib/security/java.policy
Data Storage ‹↑›
In this context data storage referrs to the 'permanent' storage
of data, and where to do it- eg database, textfile, filesystem.
Properties Files ‹↑›
Properties files are plain text files which have a particular simple
structure, or format. Basically they are in the format 'key=value' with
one key per line. The convenience of java properties files is that they
can be read and loaded into a Properties object without any parsing. Then
the modified Properties object. Possibly they are the
simplest (but very limited) form of permanent structured data storage
available in java
an example of the contents of a .properties file
# a comment, this line is ignored
! a comment, this line is also ignored
a = a simple string
b = a string with escape sequences \t \n \r \\ \" \' \ (space) \u0123
c = a string with a continuation line \
continuation line
d.e.f = another string
In the example below, because the streams are implicit it is not
possible to close them.
read and write the 'data.properties' properties file, simplified
/* read */
Properties p = new Properties();
try {
p.load(new FileInputStream("data.properties"));
} catch (IOException e) { }
/* write */
try {
p.store(new FileOutputStream("data.properties"), null);
} catch (IOException e) { }
read and write and access the keys
Properties prop = new Properties();
try {
FileInputStream in = new FileInputStream("a.properties");
prop.load(in);
String str = prop.getProperty("name");
System.out.println(str);
fis.close();
FileOutputStream fos = null;
prop.setProperty("name", "adam");
prop.store((fos = new FileOutputStream("a.properties")), "Author: jasonX");
} catch (IOException e) {
e.printStackTrace();
}
Reading Or Loading Properties Files ‹↑›
load a Properties object by reading a properties file
Properties p = new Properties();
InputStream is = null;
try {
is = new FileInputStream("data.properties");
p.load(is);
} catch (IOException e) {
System.out.println("Couldnt read file: " + e);
} finally {
if (null != is)
try { is.close(); } catch (IOException e) { /* .... */ }
}
Xml (for extensible markup language) is a text data transfer and
storage format in which informational metadata is added to text
content with the use of 'tags' (which take the form '<name>adam</name>'
http://www.rgagnon.com/javadetails/java-0511.html
How to generate xml from a jdbc ResultSet.
Jdbc And Databases ‹↑›
This section deals with relational databases, sql and java's way of
interacting with those databases, jdbc.
Apache Derby, or Java DB (the same thing) is a small 2M database
included in the JDK (since Java 6 in December 2006)
A java database app to retrieve data must do the following.
establish a connection |
create a Statement with conn.createStatement() |
executeQuery(...) to get a ResultSet |
loop through the ResultSet object with results.next() |
close the ResultSet with results.close() |
close the Statement with statement.close() |
extract some data from a jdbc datase
import java.sql.*;
...
Statement stmt = conn.createStatement();
ResultSet results = stmt.executeQuery("select * from " + tableName);
while (results.next())
{
int id = results.getInt(1);
String restName = results.getString(2);
String cityName = results.getString(3);
System.out.println(id + "\t\t" + restName + "\t\t" + cityName);
}
results.close();
stmt.close();
...
CONNECTING TO A DATABASE ....
ODBC JDBC BRIDGE ....
* connect to an 'access' database with a jdbc-odbc bridge (ms windows)
import java.net.URL;
import java.sql.*;
publi class JdbcOdbc {
static Connection theConn;
public static void main (String args[]) {
try {
theConn = MyConnection.getConnection();
String sql = "select subject from Email";
Statement stmt = theConn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) System.out.println(rs.getString("subject"));
rs.close(); stmt.close();
}
catch (Exception e) { e.printStackTrace(); }
finally {
try { if (theConn != null) theConn.close(); }
catch (Exception e) {}
}
}
}
class MyConnection {
public static Connection getConnection() throws Exception {
Driver d = (Driver)Class.forName
("sun.jdbc.odbc.JdbcOdbcDriver").newInstance();
Connection c = DriverManager.getConnection(
"jdbc:odbc:Driver={Microsoft Access Driver (*.mdb)};DBQ=c:/tech97.mdb"
);
return c;
}
}
use an already defined ODBC Datasource
String URL = "jdbc:odbc:myDSN";
Connection c = DriverManager.getConnection(URL, "user", "pwd");
Insert Data Into A Table ‹↑›
a simple sql insert- vulnerable to sql injection in a web app
Statement stmt;
String sql;
int rows;
sql = "INSERT INTO tCust "
+ "(custId, custName, custAddr) "
+ "VALUES "
+ "('" + custId + "',"
+ "('" + custName + "',"
+ "('" + custAddr + "')";
stmt = theConn.createStatement();
rows = stmt.executeUpdate(sql);
theConn.dbConn.commit();
stmt.close();
a complete jdbc example with Apache Derby (also called Java DB)
import java.sql.*;
public class Restaurants
{
private static String dbURL =
"jdbc:derby://localhost:1527/myDB;create=true;user=me;password=mine";
private static String tableName = "restaurants";
// jdbc Connection
private static Connection conn = null;
private static Statement stmt = null;
public static void main(String[] args) {
createConnection();
insertRestaurants(5, "LaVals", "Berkeley");
selectRestaurants();
shutdown();
}
private static void createConnection()
{
try {
Class.forName("org.apache.derby.jdbc.ClientDriver").newInstance();
conn = DriverManager.getConnection(dbURL);
}
catch (Exception except) {
except.printStackTrace();
}
}
private static void insertRestaurants(int id, String restName, String cityName)
{
try {
stmt = conn.createStatement();
stmt.execute(
String.format("insert into %s values (%d,'%s','%s')",
tableName, id, restName, cityName));
stmt.close();
}
catch (SQLException sqlExcept) {
sqlExcept.printStackTrace();
}
}
private static void selectRestaurants() {
try {
stmt = conn.createStatement();
ResultSet results = stmt.executeQuery("select * from " + tableName);
ResultSetMetaData rsmd = results.getMetaData();
int numberCols = rsmd.getColumnCount();
for (int i=1; i<=numberCols; i++)
{
//print Column Names
System.out.print(rsmd.getColumnLabel(i)+"\t\t");
}
System.out.println("\n---------------------------------");
while (results.next())
{
int id = results.getInt(1);
String restName = results.getString(2);
String cityName = results.getString(3);
System.out.println(id + "\t\t" + restName + "\t\t" + cityName);
}
results.close();
stmt.close();
}
catch (SQLException sqlExcept) {
sqlExcept.printStackTrace();
}
}
private static void shutdown()
{
try {
if (stmt != null) { stmt.close(); }
if (conn != null) {
DriverManager.getConnection(dbURL + ";shutdown=true");
conn.close();
}
}
catch (SQLException sqlExcept) {}
}
}
To change the above to use an embedded database (not a daemon) use
Driver name: org.apache.derby.jdbc.EmbeddedDriver
Database connection URL: jdbc:derby:myDB;create=true;user=me;password=mine
Updating Data ‹↑›
modify data
PreparedStatement p;
try {
p = theConn.prepareStatement
("UPDATE CustomerTable SET custName = ? WHERE custId = ?");
p.setString(1,"Smith");
p.setString(2, cust_id.getText());
p.executeUpdate();
conn.commit();
p.close();
}
catch (Exception e) { e.printStackTrace(); }
Delete Data ‹↑›
delete some data from a table
PreparedStatement p;
try {
p = connection.prepareStatement
("DELETE FROM CustomerTable WHERE custId = ?");
p.setString(1, jtextfield.getText());
p.executeUpdate();
connection.commit();
p.close();
}
catch (Exception e) { e.printStackTrace(); }
Select Query Or Retrieve Data ‹↑›
check if the query returned any results
boolean found;
ResultSet rs;
. // execute the query |
found = rs.next();
if (found)
System.out.println("Record found");
else
System.out.println("RECORD NOT FOUND");
,,,
retrieve data from a database using a prepared statement
String name = cust_name.getText();
try {
Statement stmt;
String sql = "select custName from tCust where custName = "
+ "'" + name + "'";
stmt = theConn.createStatement();
ResultSet rs = stmt.executeQuery();
while (rs.next()) {
System.out.println(rs.getString("custName"));
}
rs.close();
stmt.close();
}
catch (Exception e) {
e.printStackTrace();
}
,,,
The setFetchSize() method provides a hint to the jdbc driver about
how many rows to retrieve on each iteration. This can increase
performance when retrieving large datasets.
retrieve a large amount of data from an oracle data using fetchsize
import java.io.FileWriter;
import java.io.IOException;
import java.sql.*;
public class PerfSelect {
public static void main(String[] args) throws ClassNotFoundException,
SQLException, IOException {
Class.forName("oracle.jdbc.driver.OracleDriver");
String url = "jdbc:oracle:thin:@//oracle.server:1529/company";
Connection conn = DriverManager.getConnection(url, "scott", "tiger");
conn.setAutoCommit(false);
String sql = "SELECT * FROM Company.Employees";
Statement stmt = conn.createStatement(); stmt.setFetchSize(200);
ResultSet rs = stmt.executeQuery(sql);
FileWriter fw = new FileWriter("d:/temp/test.out");
while (rs.next())
fw.write(rs.getString(1) + " " + rs.getString(2) + "\n");
stmt.close(); rs.close();
fw.flush(); fw.close();
}
}
Displaying Data ‹↑›
display data from a table in a JTable component
String[] tableColumnsName = {"col 1","col 2","col 3"};
DefaultTableModel aModel = (DefaultTableModel) aTable.getModel();
aModel.setColumnIdentifiers(tableColumnsName);
ResultSet rs =
statement.executeQuery("select col1,col2,col3 from mytable");
java.sql.ResultSetMetaData meta = rs.getMetaData();
int colNo = meta.getColumnCount();
while (rs.next()) {
Object[] objects = new Object[colNo];
for (int i=0;i<colNo;i++) {
objects[i]=rs.getObject(i+1);
}
aModel.addRow(objects);
}
jtable.setModel(aModel);
Preparedstatements ‹↑›
use query parameters in prepared statements
PreparedStatement stm = c.prepareStatement("UPDATE user_table SET name=? WHERE id=?");
stm.setString(1, "the name");
stm.setInt(2, 345);
stm.executeUpdate();
,,,,
METADATA ABOUT DATABASES
Metadata refers to information about the database itself, as
opposed to the information contained in the tables of the database.
* check if a database contains the table 'employee'
Connection c = ...
DatabaseMetaData dbm = c.getMetaData();
ResultSet tables = dbm.getTables(null, null, "employee", null);
if (rs.next()) { /* Table exists */ }
else { /* Table does not exist */ }
Ij Tool ‹↑›
The 'ij' tool allows you to create and interact with a Derby database
from a console window.
start the interactive sql query tool for Apache Derby
java org.apache.derby.tools.ij
create a new derby database called Phone
ij> connect 'jdbc:derby:Phone;create=true';
connect to an existing derby database
ij> connect 'jdbc:derby:MyDbTest';
connect to a database in a different directory (not the current working folder)
ij> connect 'jdbc:derby:/home/bill/databases/MyDbTest';
example sql commands using the ij tool and derby
ij> create table Address(num int, street varchar(40));
ij> insert into Address values (1956,'Webster St.');
ij> insert into Address values (1910,'Union St.');
ij> update Address set num=180, street='Grand Ave.' where num=1956;
ij> select * from Address;
disconnect from the current database
ij> disconnect;
exit ij and shutdown the database
ij> exit;
run a sql script with ij
ij> run 'my_file.sql';
run an sql script from the command line
java org.apache.derby.tools.ij my_file.sql
Installing Java ‹↑›
There are several versions of the java 'run-time engine', libraries
and 'java development kit', but the most complete still seems
to be the version from Sun Microsystems, the inventors of Java.
Installing The Java Runtime Engine ‹↑›
This can involve installing a plugin for a browser or installing
directly on the computer.
Installing The Java Development Kit ‹↑›
On Microsoft Windows ‹↑›
On Microsoft windows computers one needs to set the 'path'
environment variable manually after the installer has completed
On Unix ‹↑›
The process is basically: download a .tar.gz file, unpack and
uncompress it with tar xvzf ...., copy the files to somewhere, maybe
/opt/ set permissions, and more.
All this is necessary because Sun/Oracle do not provide a .deb or
.rpm package file which would make the process much simpler.
Download the 32bit or 64bit Linux "compressed binary file" - it has a
".tar.gz" file extension and uncompress it
unpack the .tar.gz file
tar -xvf jre-7-linux-i586.tar.gz
a folder such as ./jre1.7.0 is created
move this new folder into the /usr/lib/jvm/ folder
sudo mv ./jre1.7.0* /usr/lib/jvm/jre1.7.0
choose the sun version of the jre
sudo update-alternatives --config java
and more stuff ....
Development Tools For Java ‹↑›
On Microsoft Windows ‹↑›
I am assuming that the Ms Windows computer is borrowed and that you dont
really want to spend all your time developing in that environment.
My preferences:
install Vim, and GVim from www.vim.org - this is an somewhat annoying but
useful text editor.
install 'putty' and 'pscp' or 'pftp' so that you can upload your java
files to some server. If you like, just put the .exe files for these
programs in the directory where you are developing, otherwise add the
location of the .exe files to the microsoft 'path' environment variable.
Set up some useful mappings in the _vimrc file. See the section 'Vim
and Java' for a long list of useful mappings. Put your _vimrc file
somewhere like c:\program files\Vim
Vim And Java ‹↑›
Its possible, though possibly not advisable to use the vim
text editor as a java editor. By using mappings and commands we
can simplify the process of compiling and running java programs.
When using Microsoft windows the format of some of these commands are
slightly different owing to the use of the \ backslash in Windows file
names and the different command line syntax used by the Windows console
(for example & and && used to separated multiple commands on one line)
For a great deal of detailed information and recipes about how to use Vim
see bumble.sf.net/books/vim/vim-book.txt
save the current file to a sourceforge server
:!scp % user,project@web.sf.net:folder/subfolder/ (## unix)
:!pscp % user,project@web.sf.net:folder/subfolder/ (## windows)
For the ms windows command, this requires that the pscp program has
been installed, available from the 'putty' website.
look up the word under the cursor with the ClassInfo java class
nmap ,cc :!java -cp eg ClassInfo <cword> &<cr>
show java api docs for the word under the cursor using JavaDocPanel
nmap ,jd :!java -cp eg JavaDocPanel <cword> &<cr>
make a command 'Sav' (placed in vimrc) to save the current file to sourceforge
com Sav !scp % user,project@web.sf.net:folder/subfolder/
com Sav !pscp % user,project@web.sf.net:folder/subfolder/ (## windows)
The user can upload the current file to the sourceforge server by typing ':Sav'
map the key sequence ';jr' to compile and run the current file with java
map ;jr :!javac % && java %:r<cr>
When the user types ';jr' in normal mode (not insert mode) the current
file will be compiled and run. If the compilation with javac fails, then
the mapping aborts
run a java fragment changing file name to class name, yay!
map ,jr :?^ *---?+1,/^ *,,,/-1w! Test.java \| !name=$(sed -n '/^ *public class/{s/^ *public class \([^ ]*\).*/\1/p;q}' Test.java); cp Test.java $name.java; javac $name.java; java $name<cr>
Abbreviations And Skeleton Code ‹↑›
insert some java skeleton code into the current document
:com! -nargs=1 Skel
\ .s/^/
\ import javax.swing.*;<cr>
\ public class <args> extends JPanel {<cr>
\ public <args>() {}<cr>
\ public static void main(String[] args) {<cr>
\ SwingUtilities.invokeLater(new Runnable() {<cr>
\ public void run() {<cr>
\ JOptionPane.showMessageDialog(null, new <args>());<cr>
\ }<cr>
\ });<cr>
\ }<cr>
\ }<cr>/
a command to put some skeleton class code in the file
:com! -nargs=1 Skel .s/^/public <args> \n/
make an abbreviation to insert the main method in the file
ab jjmain public static void main(String[] args) {<cr>}
an abbreviation to insert a template
ab jjtemplate public class SomeClass {<cr> public static void main(String[] args) {}<cr> }
make a mapping of ',jt' which inserts a simple skeleton program
map ,jt 0i public class Test {<cr> public static void main(String[] args) {}<cr>}
save a fragment (between '*' and ',,,') to a file
:?\*?+1,/,,,/-1w Test.java
save a fragment to a file even if it exists
:?\*?+1,/,,,/-1w! Test.java
save a fragment to a file and compile
:?^ *---?+1,/,,,/-1w! Test.java | !javac Test.java
compile and run a java program (between '---' and ',,,')
:?^ *---?+1,/,,,/-1w! Test.java | !javac Test.java; java Test
Note that the java program between the markers must be complete with a main method
the same as above but also works on a Microsoft Windows computer
:?^ *---?+1,/,,,/-1w! Test.java | !javac Test.java && java Test
map ',jf' to compile and run a java program in the document on a unix system
:map ,jf :?^ *---?+1,/,,,/-1w! Test.java \| !javac Test.java; java Test<cr>
and on Microsoft windows compile and run a java program
:map ,jf :?^ *---?+1,/,,,/-1w! Test.java \| !javac Test.java && java Test<cr>
Actually the Windows mapping will also work on Unix systems, since && has the
same meaning in Unix (only execute the second command if the first was successful)
For example, if the document contains the following text containing
a simple java program.
the simplest java program
---
public class Test {
public static void main(String[] args) {
System.out.println("hi");
}
}
,,,
Then typing ',jf' in 'normal' or 'command' mode will extract
and compile and then run the java program contained within the
lines containing '---' and ',,,' The only problem is that
the code must use the class 'Test'
save and compile a java multiline fragment, inserting a class
:?^ *---?+1,/,,,/-1w ! (echo -e 'public class Test {\n public static void main(String[] args) {'; sed 's/a/a/'; echo -e ' }\n}') > Test.java; javac Test.java; java Test.java
create a mapping which compiles and runs a java fragment
map ,jfr :?^ *---?+1,/,,,/-1w ! (echo -e 'public class Test {\n public static void main(String[] args) {'; sed 's/a/a/'; echo -e ' }\n}') > Test.java; javac Test.java; java Test.java
The above will compile and run a fragment of java code in the
current document which is contained between '---' and ',,,,'
Extracting The Java Class Name With Vim ‹↑›
These recipes below are working towards a function which will extract
the java class name from a program within a text document.
put the text of the current line into a variable
:let t = getline('.') | echo t
set a vim variable to the text of the line just above the next empty one
:let line = search("^$") - 1
:let text = getline(line)
set a vim variable to the text of the next line containing the word elephant
:let line = search("elephant")
:let text = getline(line)
set the variable 't' to the next line containing the word 'public'
:let l = search("public") | let t = getline(l) | echo t
split the words of the current line into an array and display the second word
:let text = getline('.') | let words = split(text) | echo words[1]
Using a one character variable name for the array doesnt seem to work.
use a variable as part of a shell command.
:let n = '..' | exe "!dir " . n
In order to use the value of the variable in the shell command we need to
use the exe command which evaluates the concatenated string as a vim command
split the current line on each '(' character
:let t = getline(".") | let res = split(t, '(') | echo res[0]
go back to the first line above which contains split
:exe "?split?"
find the next java class name definition
exe "/^ *public class /" | let words = split(getline('.')) | echo words[2]
just a fragment to test the mapping below
public class Person {
private String first;
private String last;
public Person(String f, String l)
{ this.first = f; this.last = l; }
public void print()
{ System.out.println(this.first + " " + this.last); }
public static void main(String[] args) {
Person t = new Person("Bill", "King");
t.print();
}
}
a mapping to extract the class name from a java program in a document
:map ;jj ?^ *---?<cr> \| :let l = search("^ *public class ") \| echo split(getline(l))[2] <cr>
The beginning of the java program in the document is marked by a line
which starts with '---'
a mapping to extract the class name from a java program in a document
:map ;jj ?^ *---?<cr> \| :let l = search("^ *public class ") \| echo split(getline(l))[2] \| :?^ *---?+1,/,,,/-1w! Frag.java <cr>
extract the class name from a fragment and write to a file with that name
:map ,jr ?^ *---?<cr> \| :let l = search("^ *public class ") \| let class = split(getline(l))[2] \| exe ":?^ *---?+1,/,,,/-1w! " . class . ".java" <cr>
save, compile and run a fragment using the java class name
:map ,jr ?^ *---?<cr> \| :let l = search("^ *public class ") \| let class = split(getline(l))[2] \| exe ":?^ *---?+1,/,,,/-1w! " . class . ".java" \| exe "!javac " . class . ".java && java " . class <cr>
The mapping above is the culmination of the entire preceding section. It
uses several tricky aspects of Vims scripting language and variables.
First is searches backwards for the start of the java code (---), then
it finds the line with the java class name definition, then it assigned
the class name to a variable by calling 2 functions to create an list of
words and getting the 3rd word. Then it uses the "exe" function which
is like an "eval" function in other languages to construct a shell
command using the value of the variable which contains the Java class
name. Finally it compiles and runs the java class
:map ,jf :?^ *---?+1,/,,,/-1w! Test.java \| !javac Test.java && java Test<cr>
Viewing Methods With Vim ‹↑›
a dubious but useful way to show public method declarations
:g/^ *public.*) *{*$/
a command to show most public methods in a java file
:command! Me g/^ *public.*) *{*$/
Indenting Within Vim ‹↑›
a mapping to indent a java fragment within a document using astyle
map ,ji :?^ *---?+1,/^ *,,,/-1! astyle -s2<cr>
a mapping to indent a java fragment and indent the result 2 spaces
map ,ji :?^ *---?+1,/^ *,,,/-1! astyle -s2 <bar> sed 's/^/ /'<cr>
indent the whole java file
:%! astyle -s2
:%! astyle -bs2
map ',jii' to indent the whole java file with a 2 space indent
:map ,jii %! astyle -s2<cr>
2 space indent with open brace on the same line
If you are developing in java using vim on a microsoft computer, you
will almost certainly want to use gvim, since the fonts are much nicer.
In gvim select the font which you like, and then type
:set guifont
If you have select 'courier new' size 20, you will see something like
guifont=Courier_New:h20:cANSI
Now open the _vimrc file (windows) or .vimrc file (unix) and put the
following line in the vimrc file
set guifont=Courier_New:h20:cANSI
This will ensure that everytime that gvim starts it will use the specified
font. To do the same for the colorscheme, place the following in the vimrc file
colorscheme elflord
where you replace 'elflord' with whatever colorscheme you like.
Bash And Java ‹↑›
The power and flexibility of the bash shell may help us
in the somewhat clumsy process of developing java applications.
a bash alias to start a java application in the users 'java/eg' folder
alias mail="java -cp ~/java/eg/ EmailSender"
a bash function to show the methods and constructors of a java class
function jcl
{
cat << xxx > JJJ.java
import java.lang.reflect.*;
public class JJJ {
public static void main(String args[]) throws Exception {
Class c = Class.forName("java.lang.$1");
Constructor cc[] = c.getDeclaredConstructors();
Method m[] = c.getMethods();
for (int i = 0; i < cc.length; i++) System.out.println(cc[i]);
for (int i = 0; i < m.length; i++) System.out.println(m[i]);
}
}
xxx
javac JJJ.java; java JJJ
}
Indenting ‹↑›
astyle
* view a java file nicely indented with 2 spaces
cat test.java | astyle -s2 | less
The indent program was written for the c language but may be
used with java. astyle may be better.
People Influential In Java ‹↑›
Bill Joy
One time head of sunf, programmer.
josh bloch
designed java collections framework, book author, google
employee
chet haase
a graphics and gui expert.
romain guy
another gui expert
Knowledgable Programmers ‹↑›
elliott hughes
android developer, writing dalvik explorer etc, also
evergreen which is a kind of acme (by Rob Pike) a programmers ide
http://en.wikipedia.org/wiki/Acme_(text_editor). Acme is the
succesor of sam which was also written by Rob Pike. This is
of interest because sam was/is the preferred text editor of
Brian Kernighan of awk, pic, nroff, c, unix fame.
chris campbell
java2d and images expert (sun employee)
fred swartz
made some good notes, at leepoint.net
Vineet Reynolds @ stackoverflow
knows about stuff in java
Andrew Thompson @ stackoverflow -
a contributor to the stack overflow site. Writes very complete code
examples on a range of java topics
Howard @ stackoverflow -
knows stuff about swing.
x4u @ stackoverflow
knows about images
dkarp @ stack
knows about javamail
camickr @ stackoverflow
irritable but knowledgable
Probably rob camick who also has an advanced java swing blog
http://tips4java.wordpress.com/
BalusC @ stackoverflow. seems knowledgable
Dave Ray @ stackoverflow
Knowledgable about swing at least, documentlisteners etc
Jeff Friesen
knows about java text stuff
Peter Boughton @ stackoverflow
knowledgable chap about regexes
Jerry Huxtable
java image operations person
adam paynter@stackoverflow
comes up with some interesting answers
skip head@stackoverflow
good answer about reflection
robert gamble@stackoverflow
reflection knowledge
basszero@stackoverflow
knows alot about drag and drop
david flanagan
author of some java in a nutshell books, writer of lots of
java examples on the net.
Apps And Small Programs ‹↑›
This section contains some small programs written in java by me that I
personally find useful. Some of them wont be useful for anybody except me.
Filesearch ‹↑›
This application is a simple file search-utility which searches for
files in a folder heirarchy having a particular String in the
name or path. A SwingWorker is used to search and update the JList
component without freezing the user interface.
Using the "WHEN_IN_FOCUSED_WINDOW" InputMap from the JPanel seems to
work well. The KeyStrokes are available no matter what component
in the panel has the focus (including the JTextFields). But the
WHEN_FOCUSED input map only works when the application starts up, I
suppose when the JPanel has focus.
Ideas:
- make the search case insensitive.
- add a on-the-fly search JTextField to search the results returned
by a search (similar to the technique used in the SearchPage
example). Use keystrokes to show and hide the search box. This
prevents the user having to do another time-consuming search if
too many results are returned.
- add some kind of a help facility to show what keystrokes are
available.
- add a 'search history' list to the filename box. Maybe a JPopupMenu
or else a JComboBox. write this history to a textfile for future use.
- improve speed of search
- determine if unix hidden folders should be searched. etc
- publish the number of folders searched through the Result class
so that the user feels like something is being done even when very
few (or no) files are being found.
performance: on a netbook eee pc (cpu 800 mhz) searching for 'e' (java 1.6)
files found: 43078, folders searched: 3263, time taken: 3251 ms
The speed of the search varies widely from time to time, probably
depending on the operating system. Making the FileFilter an anonymous
inner class doesnt seem to affect performance.
Changes:
7 sept 2012
- added an indeterminate progress bar at the bottom of the screen
- added some search and cancel search keystrokes (escape, control S etc)
- added paste to system clipboard when the user selects an item in
the search result list. This at least makes it a bit easier to
use the results, you can then paste the file name into a browser
for example.
enhanced file search with an information label
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.util.*;
import java.awt.event.*;
import java.awt.*;
import java.util.concurrent.*;
import java.awt.datatransfer.*;
public class FileSearch extends JPanel
implements ActionListener, ListSelectionListener {
JList list;
JButton button;
JButton cancelButton;
JTextField field;
JTextField rootField;
JLabel info;
JProgressBar bar;
SearchTask search;
public FileSearch() {
super(new BorderLayout());
Font georgia = new Font("Georgia", Font.ITALIC, 20);
this.list = new JList(new DefaultListModel());
this.list.addListSelectionListener(this);
this.button = new JButton(new StartSearchAction());
this.button.setFont(georgia);
this.cancelButton = new JButton(new CancelSearchAction());
this.cancelButton.setFont(georgia);
this.field = new JTextField(".mp3", 15);
this.field.setFont(georgia);
this.field.addActionListener(new StartSearchAction());
this.rootField = new JTextField("/home/", 15);
this.rootField.setFont(georgia);
this.rootField.addActionListener(new StartSearchAction());
this.info = new JLabel("info:");
this.info.setFont(georgia);
this.bar = new JProgressBar();
this.bar.setStringPainted(true);
JPanel infoPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
infoPanel.add(this.bar); infoPanel.add(this.info);
JPanel topPanel = new JPanel();
topPanel.add(this.button); topPanel.add(this.cancelButton);
topPanel.add(this.field); topPanel.add(this.rootField);
this.add(new JScrollPane(this.list), BorderLayout.CENTER);
this.add(topPanel, BorderLayout.NORTH);
this.add(infoPanel, BorderLayout.SOUTH);
this.setActionKeys();
}
/** paste the item to the clipboard when the user selects an item*/
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting() == false) {
if (list.getSelectedIndex() == -1) { /* No selection */ }
else {
System.out.println(list.getSelectedValue());
Clipboard c = Toolkit.getDefaultToolkit().getSystemClipboard();
StringSelection text =
new StringSelection(list.getSelectedValue().toString());
c.setContents(text, text);
}
}
}
public void actionPerformed(ActionEvent e) {}
private void setActionKeys() {
ActionMap actionMap = this.getActionMap();
InputMap inputMap =
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
inputMap.put(KeyStroke.getKeyStroke("ESCAPE"), "cancel-search");
actionMap.put("cancel-search", new CancelSearchAction());
inputMap.put(KeyStroke.getKeyStroke("control S"), "start-search");
inputMap.put(KeyStroke.getKeyStroke("ENTER"), "start-search");
actionMap.put("start-search", new StartSearchAction());
}
public void cancelSearch() {
this.search.cancel(true);
this.bar.setIndeterminate(false);
this.bar.setString("Search Cancelled");
this.info.setText("search cancelled");
}
public void startSearch() {
((DefaultListModel)this.list.getModel()).removeAllElements();
this.info.setText("");
this.bar.setIndeterminate(true);
this.bar.setString("Searching");
this.search =
new SearchTask(this.field.getText(), this.rootField.getText());
this.search.execute();
}
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("Search for Files");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new FileSearch());
f.pack(); f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setVisible(true);
}
});
}
class StartSearchAction extends AbstractAction {
public StartSearchAction() {
putValue(Action.NAME, "Start Search");
putValue(Action.SHORT_DESCRIPTION,
"Starts a new search for file with matching names");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_S));
}
public void actionPerformed(ActionEvent e) {
FileSearch.this.startSearch();
}
}
class CancelSearchAction extends AbstractAction {
public CancelSearchAction() {
putValue(Action.NAME, "Cancel search");
putValue(Action.SHORT_DESCRIPTION,
"Cancels the current search");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_C));
}
public void actionPerformed(ActionEvent e) {
FileSearch.this.cancelSearch();
}
}
class SearchTask extends SwingWorker<Void, File>
implements FileFilter {
int filesFound;
int foldersSearched;
String text;
File root;
long searchTime;
public SearchTask(String text, String root) {
super();
this.filesFound = 0;
this.foldersSearched = 0;
this.text = text;
this.root = new File(root);
this.searchTime = -1;
}
public SearchTask(String text) {
super();
this.filesFound = 0;
this.foldersSearched = 0;
this.text = text;
this.root = new File("/home/");
this.searchTime = -1;
}
protected Void doInBackground() {
this.searchTime = System.currentTimeMillis();
this.list(this.root);
this.searchTime = System.currentTimeMillis() - this.searchTime;
return null;
}
protected void done() {
FileSearch.this.info.setText(String.format(
"<html>Files found: <font color='blue'>%d</font>, Folders searched: %d, Time taken: %d ms, " +
" Root folder: %s", this.filesFound, this.foldersSearched,
this.searchTime, this.root));
FileSearch.this.bar.setIndeterminate(false);
FileSearch.this.bar.setString("Search Finished");
}
protected void process(java.util.List<File> results) {
FileSearch.this.info.setText(String.format(
"Files found: %d, Folders searched: %d",
this.filesFound, this.foldersSearched));
DefaultListModel model =
(DefaultListModel) FileSearch.this.list.getModel();
for (File file: results) { model.addElement(file); }
}
/** the FileFilter for the list() method */
public boolean accept(File file) {
return ((file.getAbsolutePath().indexOf(this.text)>0) ||
file.isDirectory());
}
/** a case insensitive regex FileFilter for the list() method */
public boolean xaccept(File file) {
String pattern = "(?i).*" + this.text + ".*";
return ((file.getAbsolutePath().matches(pattern)) ||
file.isDirectory());
}
/** find files with names matching a certain string */
public void list(File dir) {
if (this.isCancelled()) return;
this.foldersSearched++;
for (File f: dir.listFiles(this)) {
if (f.isDirectory()) this.list(f);
else {
this.publish(f);
this.filesFound++;
}
}
}
}
}
/** a simple class to hold number of folders searched & last file found */
class Result {
File lastFound; int foldersSearched;
public Result(File lastFound, int foldersSearched) {
this.lastFound = lastFound;
this.foldersSearched = foldersSearched;
}
public File getFile() { return this.lastFound; }
public int getFoldersSearched() { return this.foldersSearched; }
}
Javadocpanel ‹↑›
The code below is a basic but useful java documentation browser, the
hyperlinks work, and the user can select a class by typing its name in
the JTextField. The code also searches for the class name in the rt.jar
file if an unqualified name (eg JList) is given. The java api docs
(available from Oracle in zip format) must be unzipped in a local folder.
The font for the JEditorPane is increased in size using css rules applied
to the EditorKit. Also package names ending with a star such as
javax.swing.* will display the 'package-summary.html' page for that
package.
Bugs: sometimes the class search finds a non-standard class first
(eg String finds some org.apache string class for which there are
no docs) and throws a file not found exception
A back button would be useful but is not essential. Other enhancements
would be to allow keyboard cut and paste,
I could improve the logic of the searchForClass() method, which was
hacked together late at night, etc. Also, when a link is clicked, show
the class name plus reference, not the file name.
More improvements to make: when the user presses enter, select the
whole class name, to make changes easier, also focus the scrollpane
so that keyboard navigation doesnt write text into the JTextField.
This program can be used from the command line with for example
java JavaDocPanel JButton
We can then integrate this with the Vim text editor with a
mapping, for example we can put in the vimrc file something like
nmap ,jd :!java -cp eg JavaDocPanel <cword> &<cr>
which assumes that the JavaDocPanel class is in the 'eg' subfolder.
All this is surprisingly useful.
ideas:
stop exception being thrown when no doc for the class
Some of the functionality of showClassDoc should actually be
in searchForClass.
changes:
Case insensitive classname search, but not regex
28 august 2012
added the SearchPage component to display the page. This allows
searching of the html document. Added a history to SearchPage
The code seems to be working quite well.
31 august 2012
added a popup menu when more than one class is returned by a search.
Need to add some kind of menu title. also added regular expression
matching in the class search.
JavaDocPanel a javadoc api doc browser with searching
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.*;
import java.net.*;
import java.io.File;
import java.awt.*;
import java.awt.event.*;
import java.util.jar.*;
import java.util.zip.*;
import java.util.*;
public class JavaDocPanel extends JPanel implements ActionListener {
SearchPage ed;
JTextField field;
String className;
java.util.List history;
URL page;
final static String docHome = "/usr/lib/jvm/java-6-sun/docs/api";
public JavaDocPanel(String className) {
super(new BorderLayout());
this.field = new JTextField(className);
this.field.setFont(new Font("Monospaced", Font.PLAIN, 18));
this.field.addActionListener(this);
this.className = new String("");
this.ed = new SearchPage();
this.showClassDoc(className);
this.history = new ArrayList();
this.add(this.field, BorderLayout.NORTH);
this.add(this.ed, BorderLayout.CENTER);
}
/** shows a message in the JTextField and selects all the message */
private void fieldMessage(String message) {
this.field.setText(message);
this.field.setSelectionStart(0);
this.field.setSelectionEnd(this.field.getText().length());
}
public String[] searchForClass(String className) {
java.util.List<String> list = new ArrayList<String>();
String pattern = ".*(?i)/" + className + ".class$";
try {
JarFile jar = new JarFile(
new File(System.getProperty("java.home") + "/lib/rt.jar"));
Enumeration<? extends JarEntry> enumeration = jar.entries();
while (enumeration.hasMoreElements()) {
ZipEntry zipEntry = enumeration.nextElement();
//System.out.println(zipEntry.getName().replace("/", "."));
if (zipEntry.getName().matches(pattern)) {
list.add(zipEntry.getName()
.replace("/", ".").replace(".class", ""));
}
}
} catch (java.io.IOException e) {
e.printStackTrace();
}
return list.toArray(new String[list.size()]);
}
/** show the api docs for a particular class */
public void showClassDoc(String searchName) {
String[] names = new String[]{};
if (searchName.indexOf(".") < 0) {
names = this.searchForClass(searchName);
if (names.length == 0) {
this.fieldMessage("class '" + searchName + "' was not found");
return;
}
else if (names.length > 1) {
JPopupMenu menu = new JPopupMenu();
for (String className: names) {
Action a = new ShowClassDocAction(className);
menu.add(a);
menu.getComponent(menu.getComponentCount()-1)
.setFont(new Font("Georgia", Font.ITALIC, 20));
}
this.fieldMessage("Choose a class from the list");
if (this.isVisible()) menu.show(this, 300, 100);
}
else { this.className = names[0]; }
}
else {
if (searchName.endsWith(".*"))
this.className=searchName.replace(".*","") + ".package-summary";
else
this.className = searchName;
}
try {
this.page = new URL(String.format("file:%s/%s.html",
this.docHome, this.className.replace(".", "/")));
this.field.setText(this.className.replace(".class", ""));
if (!(new File(this.page.toURI()).exists())) {
this.fieldMessage("no html document for " + this.page);
return;
}
this.ed.newPage(page.toString());
}
catch (java.net.MalformedURLException e) { e.printStackTrace(); }
catch (java.net.URISyntaxException e) { e.printStackTrace(); }
catch (java.io.IOException e) { e.printStackTrace(); }
}
public void actionPerformed(ActionEvent e) {
this.showClassDoc(this.field.getText());
}
public static void main(String[] args) throws Exception {
System.setProperty("awt.useSystemAAFontSettings","on");
String className = "java.util.*";
if (args.length > 0) className = args[0];
JavaDocPanel j = new JavaDocPanel(className);
JFrame f = new JFrame("View java api docs"); f.add(j);
f.pack(); f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
class ShowClassDocAction extends AbstractAction {
String className;
public ShowClassDocAction(String className) {
this.className = className;
putValue(Action.NAME, className);
putValue(Action.SHORT_DESCRIPTION, String.format(
"Shows the java API document for the '%s' class",
this.className));
}
public void actionPerformed(ActionEvent e) {
JavaDocPanel.this.showClassDoc(this.className);
}
}
}
Javadocpanel Old Version ‹↑›
Below is the old version without searching
a simple viewer for (local) java api documentation, with class search
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.text.html.*;
import java.net.*;
import java.io.File;
import java.util.Enumeration;
import java.awt.*;
import java.awt.event.*;
import java.util.jar.*;
import java.util.zip.*;
public class JavaDocPanel extends JPanel
implements ActionListener, HyperlinkListener {
JEditorPane ed;
JTextField field;
String className;
URL page;
final static String docHome = "/usr/lib/jvm/java-6-sun/docs/api";
public JavaDocPanel(String className) {
super(new BorderLayout());
this.field = new JTextField(className);
this.field.setFont(new Font("Monospaced", Font.PLAIN, 18));
this.field.addActionListener(this);
this.className = new String("");
this.ed = new JEditorPane();
this.ed.setEditable(false);
this.showClassDoc(className);
this.ed.addHyperlinkListener(this);
StyleSheet styles =
((HTMLEditorKit)this.ed.getEditorKit()).getStyleSheet();
styles.addRule("body {font-size: x-large; color:#000; font-family:Georgia; margin: 20px; }");
styles.addRule("code {font-size: large; }");
this.add(this.field, BorderLayout.NORTH);
KeyScrollPane scroll = new KeyScrollPane(this.ed);
/*
JScrollPane scroll = new JScrollPane(this.ed);
JScrollBar vertical = scroll.getVerticalScrollBar();
vertical.setUnitIncrement(20);
InputMap im = vertical.getInputMap(
JComponent.WHEN_IN_FOCUSED_WINDOW);
im.put(KeyStroke.getKeyStroke("G"), "minScroll");
im.put(KeyStroke.getKeyStroke("shift G"), "maxScroll");
im.put(KeyStroke.getKeyStroke("J"), "positiveUnitIncrement");
im.put(KeyStroke.getKeyStroke("DOWN"), "positiveUnitIncrement");
im.put(KeyStroke.getKeyStroke("shift J"), "positiveBlockIncrement");
im.put(KeyStroke.getKeyStroke("K"), "negativeUnitIncrement");
im.put(KeyStroke.getKeyStroke("UP"), "negativeUnitIncrement");
im.put(KeyStroke.getKeyStroke("shift K"), "negativeBlockIncrement");
*/
this.add(scroll, BorderLayout.CENTER);
}
public String searchForClass(String className) {
try {
JarFile jar = new JarFile(
new File(System.getProperty("java.home") + "/lib/rt.jar"));
Enumeration<? extends JarEntry> enumeration = jar.entries();
while (enumeration.hasMoreElements()) {
ZipEntry zipEntry = enumeration.nextElement();
//System.out.println(zipEntry.getName().replace("/", "."));
if (zipEntry.getName().endsWith("/" + className + ".class")) {
return zipEntry.getName().replace("/", ".").replace(".class", "");
}
}
} catch (java.io.IOException e) {
e.printStackTrace();
}
return "not.found";
}
public void showClassDoc(String searchName) {
String name = new String();
if (searchName.indexOf(".") < 0) {
name = this.searchForClass(searchName);
if (name.equals("not.found")) {
this.field.setText("class " + searchName + " not found");
this.className = name;
return;
} else { this.className = name; }
}
else {
if (searchName.endsWith(".*"))
this.className=searchName.replace(".*","") + ".package-summary";
else
this.className = searchName;
}
try {
this.page = new URL(String.format("file:%s/%s.html",
this.docHome, this.className.replace(".", "/")));
this.ed.setPage(page);
}
catch (java.net.MalformedURLException e) { e.printStackTrace(); }
catch (java.io.IOException e) { e.printStackTrace(); }
}
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
if (e.getURL().sameFile(this.page)) {
try {
this.ed.scrollToReference(e.getURL().getRef());
} catch (Throwable t) {
t.printStackTrace();
}
}
else if (!e.getURL().sameFile(this.page)) {
try {
this.ed.setPage(e.getURL());
this.field.setText(e.getURL().toString());
} catch (Throwable t) {
t.printStackTrace();
}
}
}
}
public void actionPerformed(ActionEvent e) {
this.showClassDoc(this.field.getText());
}
public static void main(String[] args) throws Exception
{
System.setProperty("awt.useSystemAAFontSettings","on");
String className;
if (args.length > 0) className = args[0];
else className = "java.util.*";
JavaDocPanel j = new JavaDocPanel(className);
JFrame f = new JFrame("JavaDocPanel: view class api docs"); f.add(j);
f.pack(); f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);
//System.out.println(ed.getText());
}
}
Searchpage ‹↑›
The idea of this application is to allow an html document to be quickly
searched using keystrokes. The only really tricky point about its
implementation is iterating through the HTMLDocument to then search each
fragment. The code seems to be working well, and with a few additions and
polishings should be useful. This component is used by the JavadocPanel
to display html java api documentation
The code is based on the example SearchHtmlPane.
features
The 1st or Nth match is displayed about 1/3 of the way down
the JScrollPane (see the CaretScroll example for this technique).
case insensitive searching - is this a good idea?
The 'n' key goes to and highlights the next match
The 'N' key goes to and highlights the previous match
the current match is highlighted in a different colour.
display the number of matches and the current match in a label
next to the search box.
The enter key hides the search box.
The '/' key shows and focuses the search box.
28 aug 2012
added font bigger and smaller keys (B/b) and shift +/-
also added KeyScrollPane. Added a HyperlinkListener.
Need to remove highlights when search string 2 chars or less.
Added a history list and keystroke navigation of the list.
30 aug 2012
added a basic keystroke help feature when the user presses 'i'
to display the keystrokes and what they do. Ideas, format the
help more nicely- icons of the keys, a better toString method
for keystrokes.
Ideas: a nicer painter for the highlighter.
Add a plain text (not regular expression) search, and see if it is any
faster for big documents.
Add a 'big test document' method which creates a large
html document in order to test searching big documents.
When the current highlight is over a hyperlink, make 'enter'
activate the link.
A searchable JEditorPane displaying html
import java.io.*;
import java.net.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.event.*;
import javax.swing.text.html.*;
import java.util.regex.*;
import java.util.*;
public class SearchPage extends JPanel
implements DocumentListener, HyperlinkListener {
JTextField field;
JLabel searchInfo;
JPanel searchPanel;
JEditorPane area;
JScrollPane scroll;
URL page;
java.util.List<URL> history;
int historyIndex;
java.util.List<Match> matches;
int currentMatch;
int fontSize;
public SearchPage() {
super();
this.setLayout(new BorderLayout());
this.currentMatch = 0;
this.fontSize = 18;
this.matches = new ArrayList<Match>();
this.history = new ArrayList<URL>();
this.field = new JTextField(40);
this.field.getDocument().addDocumentListener(this);
this.field.setFont(new Font("Georgia", Font.ITALIC, 24));
this.field.addActionListener(new HideSearchAction());
this.searchInfo = new JLabel(); this.searchInfo();
this.area = new JEditorPane();
this.area.addHyperlinkListener(this);
this.setActionKeys();
this.scroll = new KeyScrollPane(this.area);
this.searchPanel = new JPanel(new BorderLayout(10, 10));
this.searchPanel.add(this.field, BorderLayout.WEST);
this.searchPanel.add(this.searchInfo, BorderLayout.EAST);
this.searchPanel.setVisible(false);
this.add(searchPanel, BorderLayout.NORTH);
this.add(this.scroll, BorderLayout.CENTER);
try { this.page = new URL("file:/nowhere"); }
catch (MalformedURLException e) {}
this.newPage("file:/usr/lib/jvm/java-6-sun-1.6.0.15/docs/api/" +
"javax/swing/JTree.html");
this.historyIndex = this.history.size() - 1;
this.setFontSize(18);
//this.state();
}
/** determine which keystrokes will activate which actions */
private void setActionKeys() {
InputMap im = this.area.getInputMap(WHEN_FOCUSED);
ActionMap am = this.area.getActionMap();
im.put(KeyStroke.getKeyStroke("I"), "x.help");
im.put(KeyStroke.getKeyStroke("shift SLASH"), "x.help");
am.put("x.help", new HelpAction());
im.put(KeyStroke.getKeyStroke("H"), "x.back");
am.put("x.back", new BackAction());
im.put(KeyStroke.getKeyStroke("L"), "x.forward");
am.put("x.forward", new ForwardAction());
im.put(KeyStroke.getKeyStroke("shift B"), "x.bigger.font");
im.put(KeyStroke.getKeyStroke("shift EQUALS"), "x.bigger.font");
am.put("x.bigger.font", new BiggerFontAction());
im.put(KeyStroke.getKeyStroke("B"), "x.smaller.font");
im.put(KeyStroke.getKeyStroke("shift MINUS"), "x.smaller.font");
am.put("x.smaller.font", new SmallerFontAction());
im.put(KeyStroke.getKeyStroke("N"), "x.next.match");
am.put("x.next.match", new NextMatchAction());
im.put(KeyStroke.getKeyStroke("shift N"), "x.prev.match");
am.put("x.prev.match", new PreviousMatchAction());
im.put(KeyStroke.getKeyStroke("S"), "x.show.search");
im.put(KeyStroke.getKeyStroke('/'), "x.show.search");
am.put("x.show.search", new ShowSearchAction());
}
/** show the internal state of the SearchPage */
private void state() {
System.out.format("this.page: %s\nthis.historyIndex: %d\n",
this.page, this.historyIndex);
int ii = 0;
for (URL u: this.history) {
System.out.format("%d: %s\n", ii, u.toString());
ii++;
}
}
/** returns an html list of keystrokes and actions */
public String keyStrokeHelp() {
InputMap im = this.area.getInputMap(WHEN_FOCUSED);
ActionMap am = this.area.getActionMap();
StringBuilder sb = new StringBuilder();
sb.append("<h3>keystrokes and actions</h3>");
sb.append("<dl>");
for (KeyStroke key: im.keys()) {
String actionKey = (String)im.get(key);
Action action = am.get(actionKey);
sb.append(String.format("<dt>%s<dd>%s",
key.toString(), action.getValue(Action.SHORT_DESCRIPTION)));
}
sb.append("</dl>");
return sb.toString();
}
/** display the help for what keystrokes do what */
public void showKeyHelp() {
String help = new String(String.format(
"<html><head>" +
"<style type='text/css'> dd { font-style: italic; }</style>" +
"</head><body style='font-family:Georgia;'>%s",
this.keyStrokeHelp()));
JLabel label = new JLabel(help);
JOptionPane.showMessageDialog(null, new JScrollPane(label));
}
/** display some help in the search box */
public void searchHelpMessage() {
this.field.setText("search for text");
this.field.setSelectionStart(0);
this.field.setSelectionEnd(this.field.getText().length());
}
/** displays a page and adds it to the history list */
public void newPage(String page) {
this.setPage(page);
this.history.add(this.page);
this.historyIndex = this.history.size() - 1;
}
/** clears the stream to force the page to be reloaded */
public void reloadPage() {
try {
Document doc = this.area.getDocument();
doc.putProperty(Document.StreamDescriptionProperty, null);
this.area.setPage(this.page);
} catch (IOException err) { err.printStackTrace(); }
}
/** go to the previous page in the history list */
private void back() {
if (this.history.size() < 2) {
System.out.println("1 or no pages in history");
return;
}
if (this.historyIndex == 0) {
System.out.println("At first page in history");
return;
}
this.historyIndex--;
URL lastPage = this.history.get(this.historyIndex);
this.setPage(lastPage.toString());
this.state();
}
/** go to the next page in the history list */
private void forward() {
if (this.history.size() < 2) {
System.out.println("1 or no pages in history");
return;
}
if (this.historyIndex == (this.history.size()-1)) {
System.out.println("At last page in history");
return;
}
this.historyIndex++;
this.setPage(this.history.get(this.historyIndex).toString());
this.state();
}
/** set the display (html) page for the JEditorPane */
public void setPage(String page) {
try {
URL newPage = new URL(page);
if (newPage.sameFile(this.page)) {
if (newPage.getRef() == null)
this.scroll.getVerticalScrollBar().setValue(0);
//this.area.setCaretPosition(0);
else
this.area.scrollToReference(newPage.getRef());
}
else {
this.area.setPage(newPage);
this.field.setText("");
this.hideSearchPanel();
}
this.page = newPage;
this.area.setEditable(false);
}
catch (MalformedURLException e) {
JOptionPane.showMessageDialog(null,
String.format("The url '%s' is not in a valid format", page));
}
catch (IOException e) {
JOptionPane.showMessageDialog(null, String.format(
"It was not possible to read the file '%s'", page));
e.printStackTrace();
}
}
public void insertUpdate(DocumentEvent e) { this.search(); }
public void removeUpdate(DocumentEvent e) { this.search(); }
public void changedUpdate(DocumentEvent e) { }
/** HyperlinkListener method */
public void hyperlinkUpdate(HyperlinkEvent e) {
if (e.getEventType() == HyperlinkEvent.EventType.ACTIVATED) {
this.newPage(e.getURL().toString());
this.state();
}
}
/** sets the size of the Font using css styles */
public void setFontSize(int size) {
this.fontSize = size;
StyleSheet styles =
((HTMLEditorKit) this.area.getEditorKit()).getStyleSheet();
styles.addRule(String.format(
"body {font-size: %dpx; color:#000; " +
" font-family:Georgia; margin: 20px; }", this.fontSize));
styles.addRule(String.format(
"code {font-size: %dpx; }", this.fontSize-1));
styles.addRule(String.format(
"font {font-size: %dpx; }", this.fontSize-1));
this.reloadPage();
}
private void searchInfo() {
String s = String.format("<html><big>%d / %d</big><html>",
this.currentMatch + 1, this.matches.size());
this.searchInfo.setText(s);
}
/** searches the html document for matching text */
public void search() {
String search = this.field.getText();
if (search.length() < 2) {
this.area.getHighlighter().removeAllHighlights();
this.searchInfo.setText("");
return;
}
int matchCount = 0; int matchStart = 0; int matchEnd = 0;
Pattern pattern = Pattern.compile("(?i)" + search);
HTMLDocument document = (HTMLDocument) this.area.getDocument();
HTMLDocument.Iterator it = document.getIterator(HTML.Tag.CONTENT);
while (it.isValid()) {
try {
String fragment = document.getText(
it.getStartOffset(), it.getEndOffset() - it.getStartOffset());
Matcher matcher = pattern.matcher(fragment);
while (matcher.find()) {
if (matchCount == 0) {
this.matches.clear();
this.currentMatch = 0;
this.field.setBackground(Color.WHITE);
}
matchStart = it.getStartOffset() + matcher.start();
matchEnd = it.getStartOffset() + matcher.end();
this.matches.add(new Match(matchStart, matchEnd));
if (matchCount == 1) { this.goToMatch(); }
matchCount++;
}
} catch (BadLocationException ex) {
System.out.println("bad location:");
}
it.next();
}
this.highlight();
if (matchCount == 0) {
this.area.getHighlighter().removeAllHighlights();
this.field.setBackground(Color.PINK);
this.searchInfo.setText("");
return;
}
}
/** highlights matches found by the search() method */
public void highlight() {
int ii = 0;
this.searchInfo();
DefaultHighlighter.DefaultHighlightPainter orangepainter =
new DefaultHighlighter.DefaultHighlightPainter(Color.orange);
DefaultHighlighter.DefaultHighlightPainter painter =
new DefaultHighlighter.DefaultHighlightPainter(Color.green);
this.area.getHighlighter().removeAllHighlights();
try {
for (Match m: this.matches) {
if (ii == this.currentMatch) {
this.area.getHighlighter().addHighlight(
m.start, m.end, orangepainter);
}
else {
this.area.getHighlighter().addHighlight(
m.start, m.end, painter);
}
ii++;
}
} catch (BadLocationException e) {}
}
/** scrolls the page to the current match and highlights it */
public void goToMatch() {
if (this.matches.isEmpty()) return;
this.area.setCaretPosition(
this.matches.get(this.currentMatch).start);
this.highlight();
try {
Dimension view = this.scroll.getViewport().getExtentSize();
JScrollBar bar = this.scroll.getVerticalScrollBar();
bar.setValue(this.area.modelToView(
this.area.getCaretPosition()).y - view.height/3);
} catch (BadLocationException ex) {
System.out.println("bad location:");
}
}
public void hideSearchPanel() {
this.searchPanel.setVisible(false);
this.revalidate();
}
public void showSearchPanel() {
this.searchPanel.setVisible(true);
this.revalidate();
this.field.requestFocusInWindow();
//if (SearchPage.this.field.getText().length() == 0)
// SearchPage.this.searchHelpMessage();
}
public static void main(String args[]) {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("SearchPane: Searchable Html Text");
f.add(new SearchPage());
f.pack(); f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setVisible(true);
}
});
}
/* actions for keystrokes */
class HelpAction extends AbstractAction {
public HelpAction() {
putValue(Action.NAME, "show help");
putValue(Action.SHORT_DESCRIPTION,
"Displays keystrokes and what functions they perform");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_I));
}
public void actionPerformed(ActionEvent e) {
SearchPage.this.showKeyHelp();
}
}
class ShowSearchAction extends AbstractAction {
public ShowSearchAction() {
putValue(Action.NAME, "show search");
putValue(Action.SHORT_DESCRIPTION,
"Displays the search panel for searching the page");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_S));
}
public void actionPerformed(ActionEvent e) {
SearchPage.this.showSearchPanel();
}
}
class HideSearchAction extends AbstractAction {
public HideSearchAction() {
putValue(Action.NAME, "hide search ");
putValue(Action.SHORT_DESCRIPTION,
"Hides the search panel for searching the page");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_H));
}
public void actionPerformed(ActionEvent e) {
SearchPage.this.hideSearchPanel();
}
}
class NextMatchAction extends AbstractAction {
public NextMatchAction() {
putValue(Action.NAME, "next match");
putValue(Action.SHORT_DESCRIPTION,
"scrolls to and highlights the next search string match");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_N));
}
public void actionPerformed(ActionEvent e) {
if (matches.isEmpty()) return;
currentMatch++;
currentMatch = currentMatch % matches.size();
/*
System.out.println(
String.format("currentMatch: %d\nmatches.size:%d\n",
currentMatch, matches.size()));
*/
SearchPage.this.goToMatch();
}
}
class PreviousMatchAction extends AbstractAction {
public PreviousMatchAction() {
putValue(Action.NAME, "previous match");
putValue(Action.SHORT_DESCRIPTION,
"scrolls to and highlights the previous search string match");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_N));
}
public void actionPerformed(ActionEvent e) {
if (matches.isEmpty()) return;
currentMatch = (currentMatch==0)?matches.size()-1:currentMatch-1;
SearchPage.this.goToMatch();
}
}
class BiggerFontAction extends AbstractAction {
public BiggerFontAction() {
putValue(Action.NAME, "Make the font bigger");
putValue(Action.SHORT_DESCRIPTION,
"Makes the font of the html page bigger");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_B));
}
public void actionPerformed(ActionEvent e) {
SearchPage.this.setFontSize(SearchPage.this.fontSize+2);
}
}
class SmallerFontAction extends AbstractAction {
public SmallerFontAction() {
putValue(Action.NAME, "Make the font smaller");
putValue(Action.SHORT_DESCRIPTION,
"Makes the font of the html page smaller");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_S));
}
public void actionPerformed(ActionEvent e) {
SearchPage.this.setFontSize(SearchPage.this.fontSize-2);
}
}
class BackAction extends AbstractAction {
public BackAction() {
putValue(Action.NAME, "Previous page");
putValue(Action.SHORT_DESCRIPTION,
"Go to the previous page in the history list");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_H));
}
public void actionPerformed(ActionEvent e) {
SearchPage.this.back();
}
}
class ForwardAction extends AbstractAction {
public ForwardAction() {
putValue(Action.NAME, "Next page");
putValue(Action.SHORT_DESCRIPTION,
"Go to the next page (if any) in the history list");
putValue(Action.MNEMONIC_KEY, new Integer(KeyEvent.VK_L));
}
public void actionPerformed(ActionEvent e) {
SearchPage.this.forward();
}
}
}
/** just hold the start and end indexes of a match */
class Match {
public int start;
public int end;
public Match(int start, int end) {
this.start = start; this.end = end;
}
}
Sourceforge Text Editor ‹↑›
This program is designed to edit a text file on the sourceforge
server in conjunction with a cgi script. I would like to write this
as an applet. It is for taking notes and mainly for adding to the
java-book.txt
In the example below, when the user presses the 'enter' key in
the JTextField the text in the JTextArea is submitted (posted, sent,
uploaded) to the webserver.
Things to do: font resize- add an input/action map to save text
with control S. make enter in text field load the file named there.
control B to save the file with a backup name (timestamped).
Also save the file locally, to usb etc.
post text from a JTextArea to a sf cgi script
import java.net.*;
import java.io.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
public class ForgeNote extends JPanel implements ActionListener {
JTextField field;
JTextArea area;
JLabel label;
String fileName;
String fullName;
String savePath;
String localSavePath;
final static String cgiPage =
"http://bumble.sourceforge.net/cgi-bin/save.x.cgi";
public ForgeNote() {
super(new BorderLayout());
Font f = new Font(Font.MONOSPACED, Font.PLAIN, 20);
/*
this.fileName = new String("");
this.fullName = new String("");
this.savePath = new String("");
/
this.setFileName("books/java/test.txt");
this.field = new JTextField("books/java/test.txt");
this.field.addActionListener(this);
this.field.setFont(f);
this.area = new JTextArea(20, 75);
this.area.setFont(f);
this.label = new JLabel("info");
this.label.setFont(f);
this.add(this.field, BorderLayout.NORTH);
this.add(new JScrollPane(this.area), BorderLayout.CENTER);
this.add(this.label, BorderLayout.SOUTH);
this.getFile();
}
public void setFileName(String fileName) {
this.fileName = fileName;
this.fullName = "http://bumble.sourceforge.net/" + fileName;
this.savePath = "../htdocs/" + fileName;
System.out.format("fileName:%s\nfullName:%s\nsavePath:%s\n",
this.fileName, this.fullName, this.savePath);
}
public void getFile() {
try {
URL url = new URL(this.fullName);
BufferedReader in = new BufferedReader(
new InputStreamReader(url.openStream()));
String line;
//InputStreamReader in = new InputStreamReader(fis, "UTF-8");
this.area.read(in, null);
in.close();
}
catch (Exception e) { e.printStackTrace(); }
}
public void postText() {
System.out.println("posting ...");
Authenticator.setDefault(new Auth());
// String page = "http://bumble.sourceforge.net/cgi-bin/save.x.cgi";
this.setFileName(this.field.getText());
String filecontents = this.area.getText();
try {
URL siteUrl = new URL(this.cgiPage);
HttpURLConnection conn =
(HttpURLConnection) siteUrl.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setRequestProperty(
"Content-Type", "application/x-www-form-urlencoded");
DataOutputStream out =
new DataOutputStream(conn.getOutputStream());
String content = String.format(
"filename=%s&filecontents=%s",
URLEncoder.encode(this.savePath, "UTF-8"),
URLEncoder.encode(filecontents, "UTF-8"));
System.out.println(content);
out.writeBytes(content);
out.flush(); out.close();
BufferedReader in =
new BufferedReader(new InputStreamReader(conn.getInputStream()));
String line = "";
while ((line=in.readLine())!=null) {
System.out.println(line);
}
in.close();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (FileNotFoundException e) {
//could find the url
e.printStackTrace();
}
catch (IOException e) {
// couldnt connect to the internet
e.printStackTrace();
}
}
public void actionPerformed(ActionEvent e) {
this.postText();
}
public static void main(String[] args) {
JFrame f = new JFrame("submit text to a webserver");
f.getContentPane().add(new ForgeNote());
f.pack(); f.setExtendedState(JFrame.MAXIMIZED_BOTH);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
class Auth extends Authenticator {
protected PasswordAuthentication getPasswordAuthentication() {
String prompt = String.format(
"The host '%s' replied '%s'\nplease enter 'name:password'",
this.getRequestingHost(), this.getRequestingPrompt());
String namepass = JOptionPane.showInputDialog(
prompt, "<name:password>");
String[] info = namepass.split(":", 2);
System.out.format("name:%s,pass:%s", info[0], info[1]);
return new PasswordAuthentication(info[0], info[1].toCharArray());
}
}
,,,
Imagepanel ‹↑›
This section may contain some useful but hopefully small, image
manipulation applications.
The following app uses keystrokes to scale and save an image. I should
change this.imageName to a java.io.File variable. Also change the
constructor to a File (not string). Also change how new files are loaded
(since the JFileChooser is annoying)
Bug: if the first image doesnt load well, then we get null
pointer exceptions on subsequent loads
Ideas: change the KeyListener to a set of Actions and modify the
ActionMap and InputMap to set up the KeyStrokes that activate the actions.
an app which can scale and save an image
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.*;
public class ImagePanel extends JPanel implements KeyListener {
BufferedImage original;
BufferedImage image;
String imageName;
File saveFile;
ImageComponent imageDisplay;
JLabel info;
String lastOperation;
long opTime; // how many milliseconds for the last operation
public ImagePanel(String imageName) {
super(new BorderLayout());
this.opTime = 0;
this.lastOperation = new String("");
this.imageName = new String(imageName);
this.saveFile = new File("test.save.jpg");
try {
this.image = ImageIO.read(new File(imageName));
this.imageDisplay = new ImageComponent(this.image);
this.info = new JLabel(String.format(
"Image: %s, Dimensions: %dx%d",
imageName, this.image.getWidth(), this.image.getHeight()));
this.add(this.imageDisplay, BorderLayout.CENTER);
this.add(this.info, BorderLayout.SOUTH);
}
catch (IOException e) {
this.add(new JLabel("Image file couldnt be read"));
}
}
/** executes actions depending on what key is typed */
public void keyTyped(KeyEvent e) {
switch (e.getKeyChar()) {
case 'l':
JFileChooser chooser = new JFileChooser();
int result = chooser.showOpenDialog(this);
File file = chooser.getSelectedFile();
this.loadImage(file);
break;
case 'f':
String saveFile =
JOptionPane.showInputDialog("Save File?");
this.saveFile = new File(saveFile);
break;
case 's':
this.scale(0.8f); break;
case 'S':
this.scale(0.5f); break;
case 'b':
this.scale(1.2f); break;
case 'B':
this.scale(2.0f); break;
case 'w':
this.write(); break;
case 'x':
System.exit(0); break;
default:
break;
}
this.setInfo();
//repaint();
}
public void keyPressed(KeyEvent e) {}
public void keyReleased(KeyEvent e) {}
public void loadImage(File imageFile) {
long start = System.currentTimeMillis();
System.out.println(imageFile.getAbsolutePath());
BufferedImage test;
try {
test = ImageIO.read(imageFile);
if (test != null) {
this.image = test;
this.imageDisplay.setImage(this.image);
this.imageName = imageFile.getName();
this.opTime = System.currentTimeMillis() - start;
this.lastOperation = "load " + this.imageName;
}
else
this.info.setText(imageFile.getName() + " is not an image");
}
catch (IOException e) {
this.info.setText(String.format(
"Image File %s could not be read",
imageFile.getAbsolutePath()));
}
this.repaint();
}
/** displays information about the last operation in a JLabel */
private void setInfo() {
String s = String.format(
"<html><em>Image:</em> %s, <em>Dimensions:</em> %dx%d," +
" Time taken to %s: %d ms",
this.imageName, this.image.getWidth(), this.image.getHeight(),
this.lastOperation, this.opTime);
this.info.setText(s);
}
private void scale(float factor) {
long start = System.currentTimeMillis();
int newWidth = (int) (this.image.getWidth() * factor);
int newHeight = (int) (this.image.getHeight() * factor);
int type = (this.image.getTransparency() == Transparency.OPAQUE) ?
BufferedImage.TYPE_INT_RGB : BufferedImage.TYPE_INT_ARGB;
BufferedImage tmp = new BufferedImage(newWidth, newHeight, type);
Graphics2D g2 = tmp.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2.drawImage(this.image, 0, 0, newWidth, newHeight, null);
g2.dispose();
this.opTime = System.currentTimeMillis() - start;
this.lastOperation = "scale";
this.image = tmp;
this.imageDisplay.setImage(this.image);
//this.revalidate();
this.repaint();
}
private void write() {
long start = System.currentTimeMillis();
try {
ImageIO.write(this.image, "jpeg", this.saveFile);
} catch (Exception e) { e.printStackTrace(); }
this.opTime = System.currentTimeMillis() - start;
this.lastOperation = String.format(
"write to %s (file size: %d bytes)",
this.saveFile.getName(), this.saveFile.length());
}
public static void main(String[] args) {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {}
ImagePanel p = new ImagePanel("test.jpg");
JFrame f = new JFrame("Image App");
f.addKeyListener(p);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(p); f.pack(); f.setExtendedState(Frame.MAXIMIZED_BOTH);
f.setVisible(true);
}
}
class ImageComponent extends JComponent {
BufferedImage image;
public ImageComponent(BufferedImage image) {
this.image = image;
}
public BufferedImage getImage() {
return this.image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
int x = 0; int y = 0;
// draw the image in the center of the component
if (this.getSize().getWidth() > this.image.getWidth())
x = (int)(this.getSize().getWidth() - this.image.getWidth())/2;
if (this.getSize().getHeight() > this.image.getHeight())
y = (int)(this.getSize().getHeight() - this.image.getHeight())/2;
g.drawImage(this.image, x, y, null);
}
public Dimension getPreferredSize() {
//return new Dimension(400, 400);
Dimension screen = Toolkit.getDefaultToolkit().getScreenSize();
if (this.image.getWidth() >= screen.getWidth() ||
this.image.getHeight() >= screen.getHeight())
return this.getParent().getSize();
else
return new Dimension(this.image.getWidth(), this.image.getHeight());
}
}
Some Java Applications ‹↑›
This section will contain references to important applications
written in the Java language, preferably open source.
JLatexEditor
is an editor for the LaTeX markup language
JEdit
A text and java code editor
http://lobobrowser.org/java-browser.jsp
A webbrowser written in java.
Design Patterns ‹↑›
Design patterns are a way of talking about object oriented design.
This section will contain very brief notes on a small selection of
patterns.
Flyweight pattern
used in wordprocessors (wysiwyg). Shared state of objects stored in
external class to minimize memory usage. Eg: class for a glyph in a
document.
Builder pattern set state of object using methods
eg: Search s = new Search().recursive()...
Factory (method)
used instead of constructors to create instances of objects
with the aim to cache and share
immutable objects (which would otherwise drain memory resources)
Proxy or Surrogate
An object which appears to be performing a task but is really handing
the task to another object. An example is a local RMI stub object
Glossary ‹↑›
Tooltip -
A little (usually yellow) that pops up when you move your mouse over
an element in a Java Gui Application. The box is supposed to contain
explanatory or helpful text relation to how to use the element highlighted.
Data hiding:
Garbage collection
Memory Management:
Decoupling
Patterns:
JVM:
Testing ‹↑›
initialization
public class Test {
public int x;
public double d;
public static void main(String[] args) {
Test t = new Test();
System.out.println("x=" + t.d);
}
}
infinite recursion
public class RecursionTest {
public static void while()
{ Test.while(); }
public static void main(String[] args) {
Test.while();
System.out.println("=");
}
}
testing char casts
public class Test {
public static void main(String[] args) {
char c = 'e';
int i = (int)'A';
if ((c >= 'a') && (c <= 'z'))
{
System.out.println("c=" + (int)c);
System.out.println("i=" + i);
}
}
}
parseint
public class Test {
public static void main(String[] args) {
String s = "-123";
int i = Integer.parseInt(s);
System.out.println("i=" + i);
}
}
testing char casts
public class Test {
public static void main(String[] args) {
char c = 'e';
int i = (int)'A';
if ((c >= 'a') && (c <= 'z'))
{
System.out.println("c=" + (int)c);
System.out.println("i=" + i);
}
}
}
testing char casts
public class Test {
public static void main(String[] args) {
char c = 'a' + 4;
System.out.println("c=" + c);
}
}
This section contains notes which havent been placed in
their appropriate chapter or section yet.
load an application resource from a jar (not a user resource)
URL iconUrl = this.getClass().getResource("/icons/copy.jpg");
The code above has the disadvantage of downloading the images from
the internet each time they are used.
display a (buffered) image in a message box
JOptionPane.showMessageDialog(parent, new JLabel(new ImageIcon(theImage)));
a logger which publishes to the console
import java.util.logging.*;
class LoggingLevels {
public static void main(String[] args) {
Logger logger = Logger.getAnonymousLogger();
// LOG this level to the log
logger.setLevel(Level.FINER);
ConsoleHandler handler = new ConsoleHandler();
// PUBLISH this level
handler.setLevel(Level.FINER);
logger.addHandler(handler);
System.out.println("Logging level is: " + logger.getLevel());
for (int ii=0; ii<3; ii++) {
logger.log(Level.FINE, ii + " " + (ii*ii));
logger.log(Level.INFO, ii + " " + (ii*ii));
}
}
}
produces output like
Logging level is: FINER
Jun 11, 2011 9:39:23 PM LoggingLevels main
INFO: 0 0
Jun 11, 2011 9:39:24 PM LoggingLevels main
INFO: 1 1
Jun 11, 2011 9:39:24 PM LoggingLevels main
INFO: 2 4
,,,
to investigate, writing log files with the logging package
import java.util.logging.*;
private Logger logger = Logger.getAnonymousLogger();
logger.log(Level.FINER, "Get column styles");
update look and feel after gui has been displayed
try {
UIManager.setLookAndFeel(plafInfos[index].getClassName() );
SwingUtilities.updateComponentTreeUI(frame);
// not necessary to pack but good
frame.pack();
frame.setMinimumSize(frame.getSize());
} catch(Exception e) {
e.printStackTrace();
}
get a screen shot of a jframe component (using BufferedImage)
http://stackoverflow.com/questions/5853879/java-swing-obtain-image-of-jframe/5853992#5853992
set a window location depending on os
jframe.setLocationByPlatform(true);
http://www.daniweb.com/software-development/java/threads/94567/writing-string-to-a-file
a nice visual effect of highlighted words with shadows
use the built in javascript engine in java 1.6 to evaluate a sum
import javax.script.ScriptEngineManager;
import javax.script.ScriptEngine;
public class Test {
public static void main(String[] args) throws Exception{
ScriptEngineManager mgr = new ScriptEngineManager();
ScriptEngine engine = mgr.getEngineByName("JavaScript");
String foo = "40+2";
System.out.println(engine.eval(foo));
}
}
,,,
- www: http://stackoverflow.com/questions/4458982/repaint-swing-button-with-different-gradient/5845007#5845007
-
set the colour gradient on abutton
(com.sun.awt.AWTUtilities) to make your JFrame really transparent.
import com.sun.awt.AWTUtilities;
/* "this" is the JFrame */
this.setUndecorated(true);
AWTUtilities.setWindowOpaque(this, true);
AWTUtilities.setWindowOpacity(this, 0.5f);
AWTUtilities.setWindowShape(this, new RoundRectangle2D.Float(0f, 0f, (float) getWidth(), (float) getHeight(), 15f, 15f));
http://oreilly.com/catalog/java2d/chapter/ch04.html
a chapter on painting from an oreilly book
idea: to create an angled stripy effect with two colours, use
a gradient paint in cycle mode with the gradient very small, or tight.
Then you could animate the gradient paint to create moving stripes.
This technique can fill a shape with lots of stripes.
make an italic font in the same family
Font f = g.deriveFont(Font.ITALIC);
make a text box with an image in it
use CompoundBorder and MatteBorder
get a buffered image of a jframe and write it to a png file
Component c = f.getContentPane();
BufferedImage i = getScreenShot(c);
try {
ImageIO.write(img, "png", new File("screenshot.png"));
} catch (Exception e) { e.printStackTrace(); }
public static BufferedImage getScreenShot(Component component) {
BufferedImage image = new BufferedImage(
component.getWidth(), component.getHeight(),
BufferedImage.TYPE_INT_RGB
);
component.paint(image.getGraphics());
return image;
}
,,,
create a jlabel with icon from a scaled buffered image
BufferedImage img = ...;
JLable l = new JLabel(
new ImageIcon(img.getScaledInstance(
img.getWidth(null)/2, img.getHeight(null)/2, Image.SCALE_SMOOTH)));
,,,
get a screen shot of a jframe component (using BufferedImage)
http://stackoverflow.com/questions/5853879/java-swing-obtain-image-of-jframe/5853992#5853992
set a window location depending on os
jframe.setLocationByPlatform(true);
set the native system look and feel.
public static void main(String[] args) {
SwingUtilities.invokeLater( new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {}
initGui();
}
});
}
,,,
read a file into a string buffer
----
BufferedReader br = new BufferedReader(fr);
String buffer;
StringBuffer result = new StringBuffer();
while ((buffer = br.readLine()) != null) {
result.append(buffer);
}
,,,
It would probably be faster to read into a larger buffer (8k ?) rather than
just one line.
jlist with a list model
----
import java.awt.*;
import javax.swing.*;
public class List extends JFrame {
public static void main(String[] args) {
List t = new List();
ListModel bigData = new AbstractListModel() {
public int getSize() { return Short.MAX_VALUE; }
public Object getElementAt(int index) { return "Index " +
index; }
};
JList bigDataList = new JList(bigData);
//use the following method for performance reasons
bigDataList.setPrototypeCellValue("Index 1234567890");
JScrollPane js = new JScrollPane(bigDataList);
t.getContentPane().add(js);
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.setVisible(true);
}
}
,,,
displays a file list in the center of the screen
------
import java.awt.*;
import javax.swing.*;
import java.io.*;
public class List extends JFrame {
public static void main(String[] args) {
List t = new List();
JList bigDataList = new JList((new File(".")).listFiles());
JScrollPane js = new JScrollPane(bigDataList);
JPanel pl = new JPanel(); pl.add(js);
t.getContentPane().add(pl);
t.setSize(new Dimension(300, 300));
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.setLocationRelativeTo(null);
t.setVisible(true);
}
}
,,,
display list of files in the current folder in a list box
------
import java.awt.*;
import javax.swing.*;
import java.io.*;
public class List extends JFrame {
public static void main(String[] args) {
List t = new List();
File dir = new File(".");
File[] files = dir.listFiles();
JList bigDataList = new JList(files);
JScrollPane js = new JScrollPane(bigDataList);
JPanel pl = new JPanel(); pl.add(js);
t.getContentPane().add(pl);
t.setSize(new Dimension(300, 300));
t.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
t.setVisible(true);
}
}
,,,
a simple file directory TreeModel for use with a JTree element
---------
import javax.swing.*;
import javax.swing.tree.*;
import javax.swing.event.*;
import java.io.*;
public class FileSystemModel implements TreeModel {
String root;
public FileSystemModel() {
this( System.getProperty( "user.home" ) );
}
public FileSystemModel( String startPath )
{ root = startPath; }
public Object getRoot()
{ return new File( root ); }
public Object getChild( Object parent, int index ) {
File directory = (File)parent;
String[] children = directory.list();
return new File( directory, children[index] );
}
public int getChildCount( Object parent ) {
File fileSysEntity = (File)parent;
if ( fileSysEntity.isDirectory() ) {
String[] children = fileSysEntity.list();
if (children == null) return 0;
return children.length;
}
return 0;
}
public boolean isLeaf( Object node )
{ return ((File)node).isFile(); }
public void valueForPathChanged( TreePath path, Object newValue ) {}
public void removeTreeModelListener(TreeModelListener l) {}
public void addTreeModelListener(TreeModelListener l) {}
public int getIndexOfChild( Object parent, Object child ) {
File directory = (File)parent;
File fileSysEntity = (File)child;
String[] children = directory.list();
int result = -1;
for ( int i = 0; i < children.length; ++i ) {
if ( fileSysEntity.getName().equals( children[i] ) ) {
result = i; break;
}
}
return result;
}
public static void main(String[] args)
{
JFrame f = new JFrame();
JTree t = new JTree(new FileSystemModel());
f.getContentPane().add(t);
f.setVisible(true);
}
}
,,,
Debugging ‹↑›
debugging tools:
sscce (sscce.org)
This is a technique to create all required files needed to
reproduce a bug in a java application
Bugs In Java Apis ‹↑›
Like all big pieces of software the Java apis have bugs, many
many bugs.
http://bugs.sun.com/bugdatabase/
View all the known java api bugs (including ones that have been
fixed)
History Of Java ‹↑›
Bill Joy was an influential figure in the elaboration of the
Berkeley Standard Distribution (BSD) of the Unix operating system at
the University of California, Berkeley in the late 1960s / 1970s. He
was also involved in writing one of the first implementations of the
tcp/ip protocol while still a student as well as creating the 'vi'
text editor.
He then went on to co-found Sun Microsystems, where he sponsored the
development of the Java language. James Gosling, who had previously
worked on the development of the emacs text editor worked on Java.
Versions Of Java ‹↑›
choose which version to use of the jre or jdk on a Linux Debian system
sudo update-alternatives --config java
Version History ‹↑›
It is often important to know when a particular feature was
introduced into java when one is targeting a particular version
of the java virtual machine
JDK 1.0 ....
(January 23, 1996)
The first stable version was the JDK 1.0.2. is called Java 1
JDK 1.1 ....
(February 19, 1997)
major changes
an extensive retooling of the AWT event model |
inner classes added to the language |
JavaBeans |
JDBC |
RMI |
reflection - Introspection only | no modification at runtime |
J2SE 1.2 ....
(December 8, 1998)
rebranded Java 2 and the version name "J2SE" (Java 2 Platform, Standard
Edition) replaced JDK to distinguish the base platform from J2EE (Java 2
Platform, Enterprise Edition) and J2ME (Java 2 Platform, Micro Edition).
major changes
strictfp keyword |
the Swing graphical API was integrated into the core classes |
Just in Time compiler - |
Java Plug-in |
Java IDL | an IDL implementation for CORBA interoperability |
Collections framework |
J2SE 1.3 ....
(May 8, 2000)
major changes
HotSpot JVM included (first released in April | 1999 for J2SE 1.2 JVM) |
RMI was modified to support optional compatibility with CORBA |
JavaSound |
Java Naming and Directory Interface (JNDI) in core libraries |
Java Platform Debugger Architecture (JPDA) |
Synthetic proxy classes |
javax.swing.InputMaps |
J2SE 1.4 ....
(February 6, 2002)
This was the first release of the Java platform developed under the Java
Community Process as JSR 59.
major changes
assert keyword |
regular expressions modeled after Perl regular expressions |
exception chaining - exceptions can encapsulate lower-level exception |
Internet Protocol version 6 (IPv6) support |
non-blocking IO (named NIO) (New Input/Output) |
logging API |
image IO - reading and writing images in formats eg JPEG and PNG |
integrated XML parser and XSLT processor (JAXP) |
integrated security and cryptography extensions (JCE | JSSE, JAAS) |
Java Web Start - first released in March | 2001 for J2SE 1.3 |
Preferences API (java.util.prefs) |
Drag-and-drop api reworked |
J2SE 5.0
(September 30, 2004)
Also numbered as java 1.5
J2SE 5.0 entered its end-of-life on April 8, 2008 and is no longer
supported by Sun as of November 3, 2009.
Java 5 is the last release of Java to officially support the Microsoft
Windows 9x line (Windows 95, Windows 98, Windows ME). Unofficially,
Java SE 6 Update 7 (1.6.0.7) is the last version of Java to be shown
working on this family of operating systems.
Java 5 is the default version of Java installed on Apple Mac OS X 10.5
(Leopard). Java 6 can be installed and set as the default to be used on
64-bit (Core 2 Duo and higher) processor machines. Java 6 is also
supported by 32-bit machines running Mac OS X 10.6 (Snow Leopard).
language changes:
Generics - compile-time type checking for collections | less typecasts |
annotations - tag classes/methods with metadata eg @override |
auto conversions between primitives and wrapper classes |
enum type - an enumerated data type |
varargs - variable number of arguments eg void drawText(String... s) |
foreach loop - loop over any iterable with a simple syntax |
fix java memory model - improves threads |
static imports - |
synth - a new look and feel for swing |
Automatic stub generation for RMI objects. |
concurrency utilities in package java.util.concurrent |
Scanner class - parse data from streams and buffers |
JAVA SE 6 ....
(December 11, 2006)
The name "J2SE" replace with "Java SE"
developers numbering remains 1.6.0.
important changes
Java compiler api - allows programatic compilition |
swing performance improvements - |
pluggable annotations |
SwingWorker included in api - a swing worker thread |
Drag and Drop api changes - TransferHandler.TransferSupport class |
table sorting and filtering | |
Swing double-buffering - eliminates gray-area effect |
JAXB 2.0 - integration of a StAX parser. |
Scripting Language Support -integration with scripting languages |
Mozilla JavaScript Rhino integration |
Improved Web Service support through JAX-WS |
JDBC 4.0 support |
Support for older Win9x versions dropped. Unofficially Java 6 Update 7
is the last release of Java shown to work on these versions of Windows.
JVM improvements: synchronization and compiler performance
optimizations, new algorithms and upgrades to existing garbage
collection algorithms, and application start-up performance.
JAVA 6 UPDATE 10
15 oct 2010
major changes
Java Deployment Toolkit - JavaScript functions for applets | Web Start |
Java Kernel - small installer with only commonly used JRE classes |
Enhanced updater. |
Enhanced versioning and pack200 support |
Java Quick Starter - improve cold start-up time. |
Improved performance of Java2D graphics primitives on Windows |
A new Swing look and feel called Nimbus and based on synth |
new Java Plug-In - applets in a separate process with features of Web Start |
JAVA SE 7 ....
released: july 28, 2011
see the OpenJDK 7 project feature lists for many changes.
Small language changes were grouped under a project named Coin
Lambda (Java's implementation of lambda functions), Jigsaw (Java's
implementation of modules), and parts of Coin were dropped from Java 7.
Java 8 will be released with the remaining features in summer 2013.
major changes
JVM support for dynamic languages |
Compressed 64-bit pointers - in Java 6 with -XX:+UseCompressedOops |
cast from an Object type to a primitive type directly |
Strings in switch statements |
Automatic resource management in try-statement |
Improved type inference for generic instance creation |
Simplified varargs method declaration |
Binary integer literals |
Allowing underscores in numeric literals |
Catching multiple exception types | rethrowing exceptions |
Concurrency utilities |
file I/O library for platform independence | metadata, symbolic links. |
new packages are java.nio.file and java.nio.file.attribute |
Elliptic curve cryptography algorithms |
An XRender pipeline for Java 2D |
New platform APIs for new graphics features |
Enhanced library-level support for new network protocols | including SCTP and Sockets Direct Protocol |
Upstream updates to XML and Unicode |
Investigate And Noncategorised ‹↑›
This section contains subjects and code snippets in java to
investigate
what does this mean, a raster is a kind of pixel map
WritableRaster wr = screen.getRaster();
investigate Maps
Map<?, ?> properties = ((TAudioFileFormat) fileFormat).properties();
xml parsing code, zip extracting, logging code, by A. Thompson
http://stackoverflow.com/questions/8509302/is-this-ods-reader-functional
investigate using JWindows for pop up dialogs or tool tips
JWindow
transfer a file via scp, Jsch has a reputation for being tricky to use
use JSch
an alternative to jsch is sshj
https://github.com/shikhar/sshj
Java Runtime Engine ‹↑›
The compiled classes for the JRE are contained in the file 'rt.jar'
or 'classes.jar' on an Apple system.
Crashes Of The Runtime Engine ‹↑›
This almost always indicates a bug in a java api. Eg doing a
RescaleOp on certain types of images. It may be possible catch these
crashes with a Throwable?
Java Virtual Machine ‹↑›
Java is based on a virtual machine. The Sun/oracle implementation is
called 'Hotspot' ... The Android java machine is called Dalvik. The Sun
machine is a stack machine, where as Dalvik is a register based machine
The virtual machine can be thought of, simplistically as consisting
of a heap and a stack. The heap is a memory area where objects are
created. The stack is used for method calls and local variables.
Heap In The Virtual Machine ‹↑›
Stack In The Virtual Machine ‹↑›
The jvm is considered to be a 'stack machine' as opposed to a register
machine. The stack is used, among other things to store information about
method calls. Since method calls can, and almost always are, nested, the
stack is ideally suited to this purpose. It is possible to inspect this
stack from within a running java program.
print the stack for the current Thread
public class StackTrace {
public static void main(String[] args) {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
for (StackTraceElement e: stack) {
System.out.println(e.toString());
}
}
}
get the name of the last method executed in the current thread
public class StackTrace {
public static void main(String[] args) {
StackTraceElement[] stack = Thread.currentThread().getStackTrace();
StackTraceElement main = stack[stack.length - 1];
String mainClass = main.getClassName();
System.out.println(mainClass);
}
}
javap is a utility which forms part of the jdk which displays
java bytecode (extracted from .class files) in a disassembled format
(displays mnemonics instead of instruction numbers). This is useful
if one needs to analyse the bytecode for performance or debugging
reasons.
use javap to display compiled bytecode or java assembly for a class
3: dup
4: ldc #3; //String bu
6: invokespecial #4; //Method StringBuilder."<init>":(String;)V
9: astore_1
10: ldc #5; //String b
12: astore_2
13: ldc #6; //String u
,,,
Implementations Of Java ‹↑›
jvm and api implementations
sun - the primary one |
Openjdk - the open source version of the Sun platform |
gcj - the gnu version |
Android Java ‹↑›
This is another big topic and maybe should be a separate booklet but I
would have to repeat lots of java info.
Android java api is based on 'Harmony' and uses a different
virtual machine (Dalvik).
Android Glossary ‹↑›
Android uses a different terminology when referring to applications
and their components.
activity
similar to a 'window', but can be used by other applications
service
a non-visual background task (thread)
content provider
an abstraction of a storage medium (database, filesystem)
intent
The way that applications use activities from other applications.
A form of communication between two applications
notes from the file java-notes.txt
create a hashmap of actions and their names, but why?
HashMap<Object, Action> actions = new HashMap<Object, Action>();
Action[] actionsArray = textComponent.getActions();
for (int i = 0; i < actionsArray.length; i++) {
Action a = actionsArray[i];
actions.put(a.getValue(Action.NAME), a);
}
another bizarre hashtable action example, the web proliferates with these.
public static Action findAction(Action actions[], String key) {
Hashtable<Object, Action> commands = new Hashtable<Object, Action>();
for (int i = 0; i < actions.length; i++) {
Action action = actions[i];
commands.put(action.getValue(Action.NAME), action);
}
return commands.get(key);
}
Vi Implementation ‹↑›
In order to implement a vi style escape from insert mode while typing in
a textcomponent we can use the technique in the example below. When the
user types say >> we can go to normal mode as its called in vi. This cant
be done with a documentlistener because we cant alter the document from a
doc listener.
DOCUMENT-NOTES: