commit 7625c200d905478ab1e39549fa13ab9dea908db7 Author: Harald Wolff Date: Thu May 15 03:29:32 2014 +0200 Repair diff --git a/.classpath b/.classpath new file mode 100644 index 0000000..205b5b3 --- /dev/null +++ b/.classpath @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6669990 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +.DS_Store +bin/* + +/bin diff --git a/.project b/.project new file mode 100644 index 0000000..3da0cf5 --- /dev/null +++ b/.project @@ -0,0 +1,17 @@ + + + org.hwo + + + + + + org.eclipse.jdt.core.javabuilder + + + + + + org.eclipse.jdt.core.javanature + + diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs new file mode 100644 index 0000000..8000cd6 --- /dev/null +++ b/.settings/org.eclipse.jdt.core.prefs @@ -0,0 +1,11 @@ +eclipse.preferences.version=1 +org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled +org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.6 +org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve +org.eclipse.jdt.core.compiler.compliance=1.6 +org.eclipse.jdt.core.compiler.debug.lineNumber=generate +org.eclipse.jdt.core.compiler.debug.localVariable=generate +org.eclipse.jdt.core.compiler.debug.sourceFile=generate +org.eclipse.jdt.core.compiler.problem.assertIdentifier=error +org.eclipse.jdt.core.compiler.problem.enumIdentifier=error +org.eclipse.jdt.core.compiler.source=1.6 diff --git a/contrib/cglib-nodep-3.1.jar b/contrib/cglib-nodep-3.1.jar new file mode 100644 index 0000000..c0ac121 Binary files /dev/null and b/contrib/cglib-nodep-3.1.jar differ diff --git a/contrib/hibernate-jpa-2.0-api-1.0.1.Final.jar b/contrib/hibernate-jpa-2.0-api-1.0.1.Final.jar new file mode 100755 index 0000000..1e9f71b Binary files /dev/null and b/contrib/hibernate-jpa-2.0-api-1.0.1.Final.jar differ diff --git a/contrib/javassist-3.15.0-GA.jar b/contrib/javassist-3.15.0-GA.jar new file mode 100755 index 0000000..5af8eae Binary files /dev/null and b/contrib/javassist-3.15.0-GA.jar differ diff --git a/src/native/libhwoio.dylib b/src/native/libhwoio.dylib new file mode 100755 index 0000000..9d2dd93 Binary files /dev/null and b/src/native/libhwoio.dylib differ diff --git a/src/native/libhwoio.so b/src/native/libhwoio.so new file mode 100755 index 0000000..f9b1b15 Binary files /dev/null and b/src/native/libhwoio.so differ diff --git a/src/org/hwo/BitField.java b/src/org/hwo/BitField.java new file mode 100644 index 0000000..c492a15 --- /dev/null +++ b/src/org/hwo/BitField.java @@ -0,0 +1,61 @@ +package org.hwo; + +import org.w3c.dom.Element; +import org.w3c.dom.NodeList; + +public class BitField { + + private String[] labels; + + public BitField() + { + labels = new String[32]; + initialize(); + } + + public String[] getLabels() + { + return labels; + } + + public BitField(Element element) + { + labels = new String[32]; + + initialize(); + + NodeList bits = element.getElementsByTagName("Bit"); + for (int i=0;i0) + sb.append(", "); + sb.append(labels[i]); + } + } + + return sb.toString(); + } + +} diff --git a/src/org/hwo/ChkSum.java b/src/org/hwo/ChkSum.java new file mode 100644 index 0000000..5934e05 --- /dev/null +++ b/src/org/hwo/ChkSum.java @@ -0,0 +1,33 @@ +package org.hwo; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +public class ChkSum { + + public static short chksum(byte[] buffer) + { + return chksum(buffer, 0, buffer.length); + } + + public static short chksum(byte[] buffer,int offset,int len) + { + int sum = 0, + xor = 0; + + for (int n = offset; n < (offset + len); n++) + { + sum += buffer[n]; + xor ^= buffer[n]; + } + + byte[] t = new byte[12]; + ByteBuffer bb = ByteBuffer.wrap(t).order(ByteOrder.LITTLE_ENDIAN); + bb.putInt(0, sum); + bb.putInt(4, xor); + bb.put(8,bb.get(0)); + bb.put(9,bb.get(4)); + + return bb.getShort(8); + } +} diff --git a/src/org/hwo/DBProfile.java b/src/org/hwo/DBProfile.java new file mode 100644 index 0000000..655637b --- /dev/null +++ b/src/org/hwo/DBProfile.java @@ -0,0 +1,118 @@ +package org.hwo; + +import java.util.prefs.BackingStoreException; +import java.util.prefs.Preferences; + + +public class DBProfile +{ + private Integer profileno; + private String bezeichnung; + private String hostname; + private String database; + private Integer port; + private String username; + private String password; + + public DBProfile(Preferences pref,int profileno) + { + this.setProfileno(profileno); + load(pref); + } + + public int getProfileno() { + return profileno; + } + + public void load(Preferences pref) + { + Preferences prefs = pref.node("database").node(profileno.toString()); + + hostname = prefs.get("hostname", "localhost"); + database = prefs.get("database", "hworganizer"); + username = prefs.get("username", ""); + password = prefs.get("password", ""); + port = prefs.getInt("port", 5432); + bezeichnung = prefs.get("bezeichnung", "Profil " + profileno.toString()); + } + + public void save(Preferences pref) + { + Preferences prefs = pref.node("database").node(profileno.toString()); + + prefs.put("hostname", hostname); + prefs.put("database", database); + prefs.put("username", username); + prefs.put("password", password); + prefs.putInt("port", port); + prefs.put("bezeichnung", bezeichnung); + + try + { + prefs.flush(); + } catch (BackingStoreException bse) + { + System.err.println("Einstellungen konnten nicht gespeichert werden!"); + System.err.println(bse.toString()); + bse.printStackTrace(); + } + } + + public void setProfileno(int profileno) { + this.profileno = profileno; + } + + public String getHostname() { + return hostname; + } + + public void setHostname(String hostname) { + this.hostname = hostname; + } + + public String getDatabase() { + return database; + } + + public void setDatabase(String database) { + this.database = database; + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public Integer getPort() { + return port; + } + + public void setPort(Integer port) { + this.port = port; + } + + public String getBezeichnung() { + return bezeichnung; + } + + public void setBezeichnung(String bezeichnung) { + this.bezeichnung = bezeichnung; + } + + @Override + public String toString() { + return getBezeichnung(); + } + +} \ No newline at end of file diff --git a/src/org/hwo/Reverse.java b/src/org/hwo/Reverse.java new file mode 100644 index 0000000..8b12d73 --- /dev/null +++ b/src/org/hwo/Reverse.java @@ -0,0 +1,39 @@ +package org.hwo; + +public class Reverse { + + byte[] reverseTable; + + public Reverse() + { + reverseTable = new byte[256]; + buildReverseTable(); + } + + private void buildReverseTable() + { + for (short i=0;i<256;i++) + { + short in = i; + byte out = 0; + for (int n=0;n<8;n++) + { + out <<= 1; + if ((in & 0x01)==0x01) + out |= 0x01; + in >>= 1; + } + reverseTable[in] = out; + } + + } + + public byte reverse(byte in) + { + short s = Unsigned.byte2short(in); + return reverseTable[s]; + } + + + +} diff --git a/src/org/hwo/Unsigned.java b/src/org/hwo/Unsigned.java new file mode 100644 index 0000000..4c74bf0 --- /dev/null +++ b/src/org/hwo/Unsigned.java @@ -0,0 +1,20 @@ +package org.hwo; + +public class Unsigned { + + + static public short byte2short(byte by) + { + short s; + + if (by < 0) + { + s = (short)(128 | (by & 0x7f)); + } else + s = by; + + return s; + + } + +} diff --git a/src/org/hwo/beacon/Beacon.java b/src/org/hwo/beacon/Beacon.java new file mode 100644 index 0000000..db298b9 --- /dev/null +++ b/src/org/hwo/beacon/Beacon.java @@ -0,0 +1,243 @@ +package org.hwo.beacon; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.net.DatagramPacket; +import java.net.DatagramSocket; +import java.net.InetAddress; +import java.net.ServerSocket; +import java.net.Socket; +import java.net.SocketException; +import java.net.UnknownHostException; +import java.util.Date; +import java.util.Hashtable; +import java.util.Properties; +import java.util.Timer; +import java.util.TimerTask; +import java.util.UUID; + +import javax.net.SocketFactory; + +public class Beacon extends Thread{ + + public class BeaconSender + { + private Properties properties; + private InetAddress inetAddress; + + private Long lastBeacon; + + public BeaconSender() + { + properties = new Properties(); + lastBeacon = 0l; + } + + public InetAddress getInetAddress() { + return inetAddress; + } + + public void setInetAddress(InetAddress inetAddress) { + this.inetAddress = inetAddress; + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public Long getLastBeacon() { + return lastBeacon; + } + + public void setLastBeacon(Long lastBeacon) { + this.lastBeacon = lastBeacon; + } + + + } + + public static void main(String[] args) + { + int mode = 0; + + for (String arg:args) + { + if (arg.equals("-s")) + mode = 1; + } + + Beacon beacon = new Beacon(44999); + beacon.setBeaconName("Test beacon"); + + if (mode == 1) + { + beacon.start(); + + System.console().printf("Press Enter to exit!"); + System.console().readLine(); + System.console().printf("exiting..."); + beacon.exit(); + + } else + { + beacon.ping(); + } + } + + private int port; + private boolean exit; + private DatagramSocket socket; + private Properties properties; + private Integer intervall; + private String beaconName; + private UUID uuid; + + private Hashtable beaconSenders; + + public Beacon(int port) + { + this.port = port; + this.socket = null; + this.properties = new Properties(); + this.intervall = 5000; + this.beaconSenders = new Hashtable(); + this.beaconName = "DefaultBeacon"; + this.uuid = UUID.randomUUID(); + } + + public synchronized void exit() + { + exit = true; + } + + public synchronized boolean getExit() + { + return exit; + } + + @Override + public void run() { + + Timer pingTimer = new Timer(); + pingTimer.schedule(new TimerTask() { + + @Override + public void run() { + ping(); + } + }, intervall, intervall); + + try { + socket = new DatagramSocket(this.port); + DatagramPacket packet = new DatagramPacket(new byte[1500], 1500); + + while (!getExit()) + { + try { + socket.receive(packet); + + ByteArrayInputStream bis = new ByteArrayInputStream(packet.getData(),0,packet.getLength()); + + BeaconSender bs = beaconSenders.get(packet.getAddress().getHostAddress()); + if (bs == null) + { + bs = new BeaconSender(); + bs.setInetAddress(packet.getAddress()); + } + bs.setLastBeacon((new Date()).getTime()); + bs.getProperties().load(bis); + + if (bs.getProperties().getProperty("beacon.uuid").equals(uuid.toString())) + { + System.err.println("Received Local Echo."); + } else + { + System.err.println(String.format("Beacon from %s",packet.getAddress().getHostAddress())); + System.err.println(String.format("Beacon: %s", bs.getProperties().getProperty("beacon.name"))); + beaconSenders.put(packet.getAddress().getHostAddress(), bs); + }; + + } catch (IOException e) { + e.printStackTrace(); + } + } + + } catch (SocketException e) { + e.printStackTrace(); + } + + pingTimer.cancel(); + + } + + public void ping() + { + DatagramSocket sock = socket; + try { + if (sock == null) + sock = new DatagramSocket(); + } catch (SocketException e1) { + e1.printStackTrace(); + } + + properties.setProperty("beacon.name", beaconName); + properties.setProperty("beacon.uuid", uuid.toString()); + + try { + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + properties.store(bos, null); + + byte[] bytes = bos.toByteArray(); + + DatagramPacket packet = new DatagramPacket(bytes,bytes.length); + + packet.setPort(this.port); + packet.setAddress(InetAddress.getByName("255.255.255.255")); + sock.send(packet); + + } catch (UnknownHostException e) { + e.printStackTrace(); + } catch (IOException e) { + e.printStackTrace(); + } + + } + + public Properties getProperties() { + return properties; + } + + public void setProperties(Properties properties) { + this.properties = properties; + } + + public Integer getIntervall() { + return intervall; + } + + public void setIntervall(Integer intervall) { + this.intervall = intervall; + } + + public Hashtable getBeaconSenders() { + return beaconSenders; + } + + public void setBeaconSenders(Hashtable beaconSenders) { + this.beaconSenders = beaconSenders; + } + + public String getBeaconName() { + return beaconName; + } + + public void setBeaconName(String beaconName) { + this.beaconName = beaconName; + } + +} diff --git a/src/org/hwo/buffer/BitStream.java b/src/org/hwo/buffer/BitStream.java new file mode 100644 index 0000000..15c0ab1 --- /dev/null +++ b/src/org/hwo/buffer/BitStream.java @@ -0,0 +1,112 @@ +package org.hwo.buffer; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + +public class BitStream { + + private boolean byteOrder; + + private int pByte; + private byte pBit; + + private List buffer; + + public BitStream() + { + initialize(); + + buffer = new ArrayList(); + } + + public BitStream(byte[] source) + { + initialize(); + + buffer = new ArrayList(); + for (byte b:source) + buffer.add(b); + } + + public BitStream(Byte[] source) + { + initialize(); + + buffer = new ArrayList(Arrays.asList(source)); + } + + private void initialize() + { + pByte = 0; + pBit = 0; + } + + private short unsigned2short(byte by) + { + short s; + + if (by < 0) + { + s = (short)(128 | (by & 0x7f)); + } else + s = by; + + return s; + } + + public short read(byte bits) + { + short symbol = 0; + byte position = 0; // Bit-Position im symbol + + while (bits > 0) + { + symbol <<= 1; + + short s = (short)( unsigned2short(buffer.get(pByte))); + + if (byteOrder) + { + s >>= pBit; + if ((s & 0x01) == 0x01) + symbol |= 0x01; + } else + { + s <<= pBit; + if ((s & 0x80) == 0x80) + symbol |= 0x01; + }; + + pBit++; + if (pBit == 8) + { + pBit = 0; + pByte++; + } + bits--; + } + return symbol; + } + + + + public byte[] getBuffer() + { + int len = buffer.size(); + byte[] out = new byte[ len ]; + for (int i=0;i stringTable; + ArrayList omega; + + LinkedList uncompressed; + BitStream compressed; + + private boolean byteOrder; + + public LZW() + { + stringTable = new ArrayList(); + omega = new ArrayList(); + uncompressed = new LinkedList(); + compressed = new BitStream(); + } + + private void initializeStringTable() + { + stringTable.clear(); + for (short n=0;n<256;n++) + stringTable.add(new Byte[]{ (byte)n }); + + stringTable.add(new Byte[0]); + stringTable.add(new Byte[0]); + + } + + private byte getSymbolLength() + { + if (stringTable.size() < 511) + return 9; + if (stringTable.size() < 1023) + return 10; + if (stringTable.size() < 2047) + return 11; + return 12; + } + + public void compress() + { + + } + + public void decompress() + { + short symbol, + lastsymbol = 0; + + uncompressed.clear(); + initializeStringTable(); + + try + { + + while ( (symbol = compressed.read(getSymbolLength())) != ENDOFINFORMATION) + { + if (symbol == CLEARCODE) + { + initializeStringTable(); + symbol = compressed.read(getSymbolLength()); + if (symbol == ENDOFINFORMATION) + break; + + uncompressed.addAll(Arrays.asList(stringTable.get(symbol))); + lastsymbol = symbol; + } else + { + if (symbol < stringTable.size()) + { + Byte[] codeString = stringTable.get(symbol); + uncompressed.addAll(Arrays.asList(codeString)); + + Byte[] b = stringTable.get(lastsymbol); + Byte[] nb = Arrays.copyOf(b, b.length + 1 ); + nb[ b.length ] = codeString[0]; + stringTable.add(nb); + } else + { + Byte[] b = stringTable.get(lastsymbol); + Byte[] nb = Arrays.copyOf(b, b.length + 1 ); + nb[ b.length ] = b[0]; + stringTable.add(nb); + uncompressed.addAll(Arrays.asList(nb)); + } + lastsymbol = symbol; + } + } + + + } catch (Exception e) + { + e.printStackTrace(); + } + } + + + + public Byte[] getBoxedUncompressedData() + { + return uncompressed.toArray(new Byte[0]); + } + public byte[] getUncompressedData() + { + Byte[] boxed = getBoxedUncompressedData(); + byte[] unboxed = new byte[ boxed.length ]; + + for (int i=0;i records; + + private char separator; + private char enclosedBy; + + boolean isEnclosed; + List parserRecord; + List parserField; + char lastChar; + + public CSV() + { + this.records = new LinkedList(); + this.setSeparator(';'); + this.setEnclosedBy('\"'); + + this.parserRecord = new ArrayList(); + this.parserField = new ArrayList(); + } + + private void nextRecord() + { + nextField(); + + this.records.add(parserRecord.toArray(new String[]{})); + parserRecord.clear(); + } + + private void nextField() + { + char fieldChars[] = new char[ parserField.size() ]; + + for (int i=0;i0) + writer.write(separator); + + if (record[i] != null) + { + if (String.class.isInstance(record[i])) + writer.write(enclosedBy); + + writer.write(record[i]); + + if (String.class.isInstance(record[i])) + writer.write(enclosedBy); + } + } + writer.write("\n"); + } + + writer.close(); + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + + } + + public String getValue(int row,int column) + { + try + { + return this.records.get(row)[column]; + } catch (ArrayIndexOutOfBoundsException ex) + { + return ""; + } + } + + public List getCells() + { + return this.records; + } + + public List getCellsAsObjects() + { + List ol = new ArrayList(); + + for (String[] record:records) + { + Object[] ro = new Object[record.length]; + for (int i=0;i changeListeners; + private JSpinner spHours; + private JSpinner spMinutes; + private JSpinner spSeconds; + private JLabel lColon2; + + private boolean hideSeconds; + + + public JTimeOfDay() { + GridBagLayout gridBagLayout = new GridBagLayout(); + gridBagLayout.columnWidths = new int[]{0, 0, 0, 0, 0, 0}; + gridBagLayout.rowHeights = new int[]{0, 0}; + gridBagLayout.columnWeights = new double[]{1.0, 0.0, 1.0, 0.0, 1.0, Double.MIN_VALUE}; + gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE}; + setLayout(gridBagLayout); + + spHours = new JSpinner(); + spHours.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + timeOfDay.setHours((Integer)spHours.getValue()); + fireChange(); + } + }); + spHours.setModel(new SpinnerNumberModel(0, 0, 23, 1)); + GridBagConstraints gbc_spHours = new GridBagConstraints(); + gbc_spHours.fill = GridBagConstraints.HORIZONTAL; + gbc_spHours.insets = new Insets(0, 0, 0, 5); + gbc_spHours.gridx = 0; + gbc_spHours.gridy = 0; + add(spHours, gbc_spHours); + + JLabel lblNewLabel = new JLabel(":"); + GridBagConstraints gbc_lblNewLabel = new GridBagConstraints(); + gbc_lblNewLabel.insets = new Insets(0, 0, 0, 5); + gbc_lblNewLabel.gridx = 1; + gbc_lblNewLabel.gridy = 0; + add(lblNewLabel, gbc_lblNewLabel); + + spMinutes = new JSpinner(); + spMinutes.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + timeOfDay.setMinutes((Integer)spMinutes.getValue()); + fireChange(); + } + }); + spMinutes.setModel(new SpinnerNumberModel(0, 0, 59, 1)); + GridBagConstraints gbc_spMinutes = new GridBagConstraints(); + gbc_spMinutes.fill = GridBagConstraints.HORIZONTAL; + gbc_spMinutes.insets = new Insets(0, 0, 0, 5); + gbc_spMinutes.gridx = 2; + gbc_spMinutes.gridy = 0; + add(spMinutes, gbc_spMinutes); + + lColon2 = new JLabel(":"); + GridBagConstraints gbc_lColon2 = new GridBagConstraints(); + gbc_lColon2.insets = new Insets(0, 0, 0, 5); + gbc_lColon2.gridx = 3; + gbc_lColon2.gridy = 0; + add(lColon2, gbc_lColon2); + + spSeconds = new JSpinner(); + spSeconds.addChangeListener(new ChangeListener() { + public void stateChanged(ChangeEvent e) { + timeOfDay.setSeconds((Integer)spSeconds.getValue()); + fireChange(); + } + }); + spSeconds.setModel(new SpinnerNumberModel(0, 0, 59, 1)); + GridBagConstraints gbc_spSeconds = new GridBagConstraints(); + gbc_spSeconds.fill = GridBagConstraints.HORIZONTAL; + gbc_spSeconds.gridx = 4; + gbc_spSeconds.gridy = 0; + add(spSeconds, gbc_spSeconds); + + initialize(); + } + + void initialize() + { + setSecondsHidden(false); + + changeListeners = new LinkedList(); + timeOfDay = new TimeOfDay(); + } + + public void addChangeListener(ChangeListener changeListener) + { + changeListeners.add(changeListener); + } + public void removeChangeListener(ChangeListener changeListener) + { + changeListeners.remove(changeListener); + } + + public Boolean getSecondsHidden() + { + return this.hideSeconds; + } + + public void setSecondsHidden(Boolean hideSeconds) + { + this.hideSeconds = hideSeconds; + if (hideSeconds) + { + lColon2.setVisible(false); + spSeconds.setVisible(false); + spSeconds.setValue(0); + } else + { + lColon2.setVisible(true); + spSeconds.setVisible(true); + } + this.validate(); + } + + void fireChange() + { + for (ChangeListener l:changeListeners) + l.stateChanged(new ChangeEvent(this)); + } + + void updateView() + { + spHours.setValue(timeOfDay.getHours()); + spMinutes.setValue(timeOfDay.getMinutes()); + spSeconds.setValue(timeOfDay.getSeonds()); + } + + public TimeOfDay getTimeOfDay() + { + return timeOfDay; + } + + public void setTimeOfDay(TimeOfDay timeOfDay) + { + this.timeOfDay = timeOfDay; + updateView(); + } + + +} diff --git a/src/org/hwo/datetime/TimeOfDay.java b/src/org/hwo/datetime/TimeOfDay.java new file mode 100644 index 0000000..a8021d6 --- /dev/null +++ b/src/org/hwo/datetime/TimeOfDay.java @@ -0,0 +1,79 @@ +package org.hwo.datetime; + +public class TimeOfDay { + + public static int getHours(int secondsOfDay) + { + return secondsOfDay / 3600; + } + public static int getMinutes(int secondsOfDay) + { + return (secondsOfDay % 3600) / 60; + } + public static int getSeconds(int secondsOfDay) + { + return (secondsOfDay % 60); + } + + private int secondsOfDay; + + public TimeOfDay() + { + secondsOfDay = 0; + } + public TimeOfDay(int sod) + { + secondsOfDay = sod; + } + public TimeOfDay(int hour,int minute,int second) + { + initialize(hour, minute, second); + } + + private void initialize(int hour,int minute,int second) + { + secondsOfDay = (hour * 3600) + (minute * 60) + second; + } + + public int getSeondsOfDay() + { + return secondsOfDay; + } + public void setSecondsOfDay(int secondsOfDay) + { + this.secondsOfDay = secondsOfDay; + } + + public int getHours() + { + return getHours(secondsOfDay); + } + + public int getMinutes() + { + return getMinutes(secondsOfDay); + } + + public int getSeonds() + { + return getSeconds(secondsOfDay); + } + + public void setHours(int hours) + { + initialize(hours, getMinutes(), getSeonds()); + } + + public void setMinutes(int minutes) + { + initialize(getHours(), minutes, getSeonds()); + } + + public void setSeconds(int seconds) + { + initialize(getHours(), getMinutes(), seconds); + } + + + +} diff --git a/src/org/hwo/fifo/FiFo.java b/src/org/hwo/fifo/FiFo.java new file mode 100644 index 0000000..eaa8eac --- /dev/null +++ b/src/org/hwo/fifo/FiFo.java @@ -0,0 +1,45 @@ +package org.hwo.fifo; + +import java.util.LinkedList; +import java.util.List; + +public class FiFo { + + private LinkedList elements; + + public FiFo() + { + elements = new LinkedList(); + } + + public void push(T element) + { + elements.add(element); + } + + public T pull() + { + return elements.poll(); + } + + public T peek() + { + return elements.peek(); + } + + public List getElements() + { + return elements; + } + + public boolean isEmpty() + { + return elements.isEmpty(); + } + + public boolean hasElements() + { + return !elements.isEmpty(); + } + +} diff --git a/src/org/hwo/i18n/Messages.java b/src/org/hwo/i18n/Messages.java new file mode 100644 index 0000000..4e7b22d --- /dev/null +++ b/src/org/hwo/i18n/Messages.java @@ -0,0 +1,84 @@ +package org.hwo.i18n; + +import java.util.LinkedList; +import java.util.List; +import java.util.Locale; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +public class Messages { + + protected static Messages pInstance; + protected static List instanceList; + protected static Locale activeLocale; + + protected String BUNDLE_NAME = "org.hwo.i18n.messages"; + + + private ResourceBundle defaultResourceBundle; + private ResourceBundle localeResourceBundle; + + protected Messages() { + initialize(); + } + + protected Messages(String bundleName) + { + BUNDLE_NAME = bundleName; + initialize(); + } + + private void initialize() + { + System.err.println(this.getClass().getName() + ": Using Locale:" + activeLocale.getCountry() + " / " + activeLocale.getLanguage()); + defaultResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME); + localeResourceBundle = ResourceBundle.getBundle(BUNDLE_NAME,activeLocale); + + instanceList.add(this); + } + + public static String getString(String key) { + for (Messages messages: instanceList) + { + if (messages.hasKey(key)) + return messages.getInstanceString(key); + } + return '!' + key + '!'; + } + + public boolean hasKey(String key) + { + return localeResourceBundle.containsKey(key) | defaultResourceBundle.containsKey(key); + } + + public String getInstanceString(String key) + { + try { + if (localeResourceBundle.containsKey(key)) + return localeResourceBundle.getString(key); + if (defaultResourceBundle.containsKey(key)) + return defaultResourceBundle.getString(key); + return '!' + key + '!'; + } catch (MissingResourceException e) { + return '!' + key + '!'; + } + + } + + public static Messages getInstance() + { + return pInstance; + } + + static { + if (activeLocale == null) + activeLocale = Locale.getDefault(); + + if (instanceList == null) + instanceList = new LinkedList(); + + if (pInstance == null) + pInstance = new Messages(); + } + +} diff --git a/src/org/hwo/i18n/messages.properties b/src/org/hwo/i18n/messages.properties new file mode 100644 index 0000000..f2b863a --- /dev/null +++ b/src/org/hwo/i18n/messages.properties @@ -0,0 +1,6 @@ +org.hwo=HWOs Java Framework +interface=Schnittstelle +ok=OK +cancel=abbrechen +SerialPortChooser.0=Schnittstelle w\u00E4hlen + diff --git a/src/org/hwo/i18n/messages_en_US.properties b/src/org/hwo/i18n/messages_en_US.properties new file mode 100644 index 0000000..0c940a9 --- /dev/null +++ b/src/org/hwo/i18n/messages_en_US.properties @@ -0,0 +1,6 @@ +org.hwo=HWOs Java Framework +interface=Interface +ok=OK +cancel=Cancel +SerialPortChooser.0=Select Interface + diff --git a/src/org/hwo/image/ImageFile.java b/src/org/hwo/image/ImageFile.java new file mode 100644 index 0000000..0494cc2 --- /dev/null +++ b/src/org/hwo/image/ImageFile.java @@ -0,0 +1,23 @@ +package org.hwo.image; + +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.File; + +public interface ImageFile { + + public ImageFile newInstance(); + + public Boolean identify(File imageFile); + + public void reset(); + public void load(File imageFile); + public void save(File imageFile); + + public Integer getNumPages(); + public BufferedImage getPage(Integer pageNo); + + public void addPage(BufferedImage image); + + +} diff --git a/src/org/hwo/image/ImageProvider.java b/src/org/hwo/image/ImageProvider.java new file mode 100644 index 0000000..9651dd6 --- /dev/null +++ b/src/org/hwo/image/ImageProvider.java @@ -0,0 +1,65 @@ +package org.hwo.image; + +import java.awt.image.BufferedImage; +import java.io.File; + +import org.hwo.image.imageio.ImageIOFile; +import org.hwo.image.tiff.TiffFile; + +public class ImageProvider { + + private static ImageProvider imageProvider; + + public static ImageProvider instance() + { + if (imageProvider == null) + imageProvider = new ImageProvider(); + return new ImageProvider(); + } + + ImageFile[] imageFiles = { + new TiffFile(), + new ImageIOFile("png"), + new ImageIOFile("jpg") + }; + + + protected ImageProvider() + { + } + + public ImageFile load(File file) + { + for (ImageFile imageFile:imageFiles) + { + if (imageFile.identify(file)) + { + ImageFile ifile = imageFile.newInstance(); + ifile.load(file); + return ifile; + } + } + return null; + } + + public ImageFile load(String path) + { + return load(new File(path)); + } + + public void save(BufferedImage image,File imageFile) + { + for (ImageFile ifile:imageFiles) + { + if (ifile.identify(imageFile)) + { + ImageFile writer = ifile.newInstance(); + writer.addPage(image); + writer.save(imageFile); + return; + } + } + + } + +} diff --git a/src/org/hwo/image/UnsupportedFormatException.java b/src/org/hwo/image/UnsupportedFormatException.java new file mode 100644 index 0000000..589a122 --- /dev/null +++ b/src/org/hwo/image/UnsupportedFormatException.java @@ -0,0 +1,15 @@ +package org.hwo.image; + +public class UnsupportedFormatException extends RuntimeException { + + public UnsupportedFormatException() + { + super(); + } + + public UnsupportedFormatException(String message) + { + super(message); + } + +} diff --git a/src/org/hwo/image/imageio/ImageIOFile.java b/src/org/hwo/image/imageio/ImageIOFile.java new file mode 100644 index 0000000..2c7ae7b --- /dev/null +++ b/src/org/hwo/image/imageio/ImageIOFile.java @@ -0,0 +1,111 @@ +package org.hwo.image.imageio; + +import java.awt.image.BufferedImage; +import java.io.File; +import java.io.IOException; +import java.util.LinkedList; + +import javax.imageio.ImageIO; +import javax.imageio.ImageReader; +import javax.imageio.ImageWriter; +import javax.imageio.stream.ImageInputStream; +import javax.imageio.stream.ImageOutputStream; + +import org.hwo.image.ImageFile; + +public class ImageIOFile implements ImageFile { + + private String imageType; + private ImageReader imageReader; + private ImageWriter imageWriter; + + private LinkedList images; + + public ImageIOFile(String imageType) + { + this.imageType = imageType; + imageReader = ImageIO.getImageReadersByFormatName(imageType).next(); + imageWriter = ImageIO.getImageWritersByFormatName(imageType).next(); + images = new LinkedList(); + } + + @Override + public ImageFile newInstance() { + return new ImageIOFile(imageType); + } + + @Override + public Boolean identify(File imageFile) { + return imageFile.getName().endsWith("." + imageType); + } + + @Override + public void reset() { + imageReader.reset(); + imageWriter.reset(); + } + + @Override + public void load(File imageFile) { + reset(); + + try + { + ImageInputStream iis = ImageIO.createImageInputStream(imageFile); + imageReader.setInput(iis); + + images.clear(); + + int nImages = imageReader.getNumImages(true); + + for (int n=0;n entries; + + BufferedImage bufferedImage; + + protected IFD(TiffFile tiffFile) + { + this.tiffFile = tiffFile; + decoded = false; + entries = new HashMap(); + bufferedImage = null; + + numEntries = this.tiffFile.sourceBuffer.getShort(); + System.err.println(String.format("readIFD(): reading %d entries",numEntries)); + + for (int i=0;i(); + } + + public boolean isDecoded() + { + return decoded; + } + + private BufferedImage decode() + { + System.err.println("TiffFile: Decoding..."); + if (isDecoded()) + return bufferedImage; + + int width = getWidth(), + height = getHeight(); + + Short compression = getCompression(); + + short[] bitsPerSample = getBitsPerSample(); + PHOTOMETRIC photometric = getPhotometric(); + short samplesPerPixel = getSamplesPerPixel(); + + System.err.println(String.format("Size: %dx%d TYPE: %s COMP: %d BPS: %s",width,height,photometric.toString(),compression,Arrays.toString(bitsPerSample))); + + BufferedImage image = new BufferedImage(width, height, getJImageType(photometric, bitsPerSample)); + + int rowsPerStrip = getRowsPerStrip(); + int[] stripOffsets = getStripOffsets(); + int[] stripByteCounts = getStripByteCounts(); + + if (stripOffsets.length != stripByteCounts.length) + throw new UnsupportedFormatException("StripOffset.length != StripbyteCount.length"); + + if ((stripOffsets.length * rowsPerStrip) < height) + throw new UnsupportedFormatException("stripped lines < scanlines"); + + ArrayList strips = new ArrayList(); + + for (int i=0;i strips) + { + PHOTOMETRIC photometric = getPhotometric(); + + int width = getWidth(), + height = getHeight(); + + short[] bitsPerSample = getBitsPerSample(); + short samplesPerPixel = getSamplesPerPixel(); + + + + switch (bitsPerSample[0]) + { + case 1: + case 4: + case 8: + break; + default: + throw new UnsupportedFormatException(); + } + + int y = 0; + short predictor = getPredictor(); + + for (Strip strip:strips) + { + ByteBuffer buffer = strip.getBuffer(); + int p = 0; + + for (int row=0; (row < strip.rowcount) && (y + row < height); row++) + { + int[] lastPixel = new int[0]; + + for (int column = 0; column < width ; column++) + { + int[] pixel = new int[1]; + + pixel[0] = Unsigned.byte2short(buffer.get(p)); + if (predictor == 2 && column > 0) + pixel[0] += lastPixel[0]; + + image.getRaster().setPixel(column, y + row, pixel); + + p += samplesPerPixel; + lastPixel = pixel; + } + } + y += strip.rowcount; + } + + + + } + + private void decodeRGB(BufferedImage image,List strips) + { + int width = getWidth(), + height = getHeight(); + + short[] bitsPerSample = getBitsPerSample(); + short samplesPerPixel = getSamplesPerPixel(); + + switch (samplesPerPixel) + { + case 3: + break; + case 4: + break; + default: + throw new UnsupportedFormatException(); + } + + for (int i=0;i 0) + { + pixel[n] += lastPixel[n]; + } + } + + image.getRaster().setPixel(column, y + row, pixel); + + p += samplesPerPixel; + lastPixel = pixel; + } + } + y += strip.rowcount; + } + } + + public BufferedImage getBufferedImage() + { + if (bufferedImage == null) + bufferedImage = decode(); + return bufferedImage; + } + + int getJImageType(PHOTOMETRIC p,short[] bitsPerSample) + { + switch (p) + { + case WHITE: + case BLACK: + return BufferedImage.TYPE_BYTE_GRAY; + case RGB: + switch (bitsPerSample.length) + { + case 3: + return BufferedImage.TYPE_3BYTE_BGR; + case 4: + return BufferedImage.TYPE_4BYTE_ABGR; + } + break; + case PALETTE: + return BufferedImage.TYPE_3BYTE_BGR; + } + throw new UnsupportedFormatException(); + } + + IFDEntry getEntry(short tag) + { + if (entries.containsKey(tag)) + return entries.get(tag); + return null; + } + + int getWidth() + { + IFDEntry e = getEntry((short)256); + if (e == null) + throw new UnsupportedFormatException("missing width tag"); + return ((NumericEntry)e).getInteger(); + } + + int getHeight() + { + IFDEntry e = getEntry((short)257); + if (e == null) + throw new UnsupportedFormatException("missing width tag"); + return ((NumericEntry)e).getInteger(); + } + + short getPageNumber() + { + ShortEntry e = (ShortEntry)entries.get((short)297); + if (e == null) + return -1; + return e.getShort(); + } + + + PHOTOMETRIC getPhotometric() + { + ShortEntry e = (ShortEntry)entries.get((short)262); + if (e == null) + return PHOTOMETRIC.WHITE; + return PHOTOMETRIC.fromCode(e.getShort()); + } + + short[] getBitsPerSample() + { + ShortEntry e = (ShortEntry)entries.get((short)258); + if (e == null) + return new short[]{1}; + return e.getShortArray(); + } + Integer getRowsPerStrip() + { + NumericEntry e = (NumericEntry)entries.get((short)278); + if (e == null) + return 0; + return e.getInteger(); + } + short getSamplesPerPixel() + { + ShortEntry e = (ShortEntry)entries.get((short)277); + if (e == null) + return 1; + return e.getShort(); + } + int[] getStripOffsets() + { + NumericEntry e = (NumericEntry)entries.get((short)273); + if (e == null) + return new int[0]; + return e.getIntArray(); + } + int[] getStripByteCounts() + { + NumericEntry e = (NumericEntry)entries.get((short)279); + if (e == null) + return new int[0]; + return e.getIntArray(); + } + short getCompression() + { + ShortEntry e = (ShortEntry)entries.get((short)259); + if (e == null) + return 1; + return e.getShort(); + } + short getPredictor() + { + ShortEntry e = (ShortEntry)entries.get((short)317); + if (e == null) + return 1; + return e.getShort(); + } + short getFillOrder() + { + ShortEntry e = (ShortEntry)entries.get((short)266); + if (e == null) + return 1; + return e.getShort(); + } + + +} \ No newline at end of file diff --git a/src/org/hwo/image/tiff/IFDEntry.java b/src/org/hwo/image/tiff/IFDEntry.java new file mode 100644 index 0000000..d7bd333 --- /dev/null +++ b/src/org/hwo/image/tiff/IFDEntry.java @@ -0,0 +1,112 @@ +package org.hwo.image.tiff; + +import java.nio.ByteBuffer; +import java.nio.ByteOrder; + +import org.hwo.image.UnsupportedFormatException; + +abstract class IFDEntry +{ + public static IFDEntry read(IFD ifd) + { + int save = ifd.tiffFile.sourceBuffer.position(); + + ifd.tiffFile.sourceBuffer.getShort(); + TAGTYPE tagType = TAGTYPE.fromCode(ifd.tiffFile.sourceBuffer.getShort()); + + ifd.tiffFile.sourceBuffer.position(save); + + switch (tagType) + { + case ASCII: + return new StringEntry(ifd); + case LONG: + return new IntegerEntry(ifd); + case SHORT: + return new ShortEntry(ifd); + default: // Skip Entry + ifd.tiffFile.sourceBuffer.getInt(); + ifd.tiffFile.sourceBuffer.getInt(); + ifd.tiffFile.sourceBuffer.getInt(); + return null; + } + } + + private final IFD ifd; + + Short tag; + TAGTYPE tagType; + + ByteBuffer buffer; + + + public IFDEntry(IFD ifd) + { + this.ifd = ifd; + System.err.println(String.format("readIFD(): reading entry at 0x%08x",this.ifd.tiffFile.sourceBuffer.position())); + + Integer count, + offset; + + tag = this.ifd.tiffFile.sourceBuffer.getShort(); + tagType = TAGTYPE.fromCode(this.ifd.tiffFile.sourceBuffer.getShort()); + + System.err.println(String.format("TAG: %d TYPE: %s", tag, tagType)); + + count = this.ifd.tiffFile.sourceBuffer.getInt(); + offset = this.ifd.tiffFile.sourceBuffer.getInt(); + + int fieldSize = tagType.getSize() * count; + + byte[] ba = new byte[ fieldSize ]; + + if (fieldSize <= 4) + offset = this.ifd.tiffFile.sourceBuffer.position() - 4; + + int save = this.ifd.tiffFile.sourceBuffer.position(); + + this.ifd.tiffFile.sourceBuffer.position(offset); + this.ifd.tiffFile.sourceBuffer.get(ba); + + this.ifd.tiffFile.sourceBuffer.position(save); + + buffer = ByteBuffer.wrap(ba); + buffer.order( this.ifd.tiffFile.bigEndian ? ByteOrder.BIG_ENDIAN : ByteOrder.LITTLE_ENDIAN ); + + decodeBuffer(); + } + + public IFDEntry(IFD ifd,Short tag,TAGTYPE tagType) + { + this.ifd = ifd; + this.tag = tag; + this.tagType = tagType; + } + + ByteBuffer getBuffer() + { + return buffer; + } + + void releaseBuffer() + { + buffer = null; + } + + protected void decodeBuffer() + { + } + + protected void encodeBuffer() + { + } + + abstract public Object getValues(); + + @Override + public String toString() { + return String.format("TAG: %d TYPE: %s",tag,tagType.toString()); + } + + +} \ No newline at end of file diff --git a/src/org/hwo/image/tiff/IntegerEntry.java b/src/org/hwo/image/tiff/IntegerEntry.java new file mode 100644 index 0000000..4883f07 --- /dev/null +++ b/src/org/hwo/image/tiff/IntegerEntry.java @@ -0,0 +1,61 @@ +package org.hwo.image.tiff; + +public class IntegerEntry extends NumericEntry{ + + int[] values; + + public IntegerEntry(IFD ifd) + { + super(ifd); + } + + public IntegerEntry(IFD ifd,Short tag) + { + super(ifd,tag,TAGTYPE.LONG); + } + + @Override + protected void decodeBuffer() + { + values = new int[ getBuffer().asIntBuffer().capacity() ]; + getBuffer().asIntBuffer().get(values); + releaseBuffer(); + } + + @Override + protected void encodeBuffer() + { + } + + @Override + public int[] getIntArray() + { + return values; + } + + @Override + public short[] getShortArray() + { + short[] svalues = new short[values.length]; + for (int i=0;i ifds; + List pages; + + + public TiffFile() + { + reset(); + } + + @Override + public ImageFile newInstance() { + return new TiffFile(); + } + + @Override + public void reset() { + bigEndian = false; + ifds = new LinkedList(); + + pages = new LinkedList(); + sourceBuffer = null; + } + + @Override + public void load(File imageFile) { + + if (!identify(imageFile)) + throw new UnsupportedFormatException(); + + Integer firstIFD = sourceBuffer.getInt(0x0004); + sourceBuffer.position(firstIFD); + + ifds.add(0, new IFD(this)); + + reorderPages(); + + } + + private void reorderPages() + { + System.err.println("Testing Page Order"); + + if (ifds.size() == 0) // Keine Seiten vorhanden + return; + + if (ifds.get(0).getPageNumber() == -1) // Keine Seitenzahlen angegeben + return; + + System.err.println("Reorder..."); + + IFD[] ifdsOrdered = new IFD[ ifds.size() ]; + + for (int n=0; n editor(); + +} diff --git a/src/org/hwo/interactiveobjects/InteractiveObjectHelper.java b/src/org/hwo/interactiveobjects/InteractiveObjectHelper.java new file mode 100644 index 0000000..9e24822 --- /dev/null +++ b/src/org/hwo/interactiveobjects/InteractiveObjectHelper.java @@ -0,0 +1,62 @@ +package org.hwo.interactiveobjects; + +import java.util.Hashtable; + +public class InteractiveObjectHelper { + + + private static Hashtable p_editors = new Hashtable(); + + private static InteractiveObject getInteractiveObject(Class clazz) + { + InteractiveObject io = clazz.getAnnotation(InteractiveObject.class); + if (io != null) + return io; + if (clazz.getSuperclass() != null) + return getInteractiveObject(clazz.getSuperclass()); + return null; + } + + private static InteractiveObject getInteractiveObject(Object item) + { + Class clazz = item.getClass(); + return getInteractiveObject(clazz); + } + + public static boolean isInteractiveObject(Class clazz) + { + return (getInteractiveObject(clazz)!=null); + } + + public static IInteractiveObjectEditor getEditor(Object item) + { + InteractiveObject io = getInteractiveObject(item); + + if (io != null) + { + if (!p_editors.containsKey(item)) + { + try + { + IInteractiveObjectEditor editor = io.editor().newInstance(); + p_editors.put(item, editor); + } catch (Exception ex) + { + System.err.println(ex.toString()); + ex.printStackTrace(); + return null; + } + } + return p_editors.get(item); + } + return null; + } + + public static void showEditor(Object o) + { + IInteractiveObjectEditor editor = getEditor(o); + editor.setInteractiveObject(o); + editor.setVisible(true); + } + +} diff --git a/src/org/hwo/io/NativeSerialPort.java b/src/org/hwo/io/NativeSerialPort.java new file mode 100644 index 0000000..066fb64 --- /dev/null +++ b/src/org/hwo/io/NativeSerialPort.java @@ -0,0 +1,106 @@ +package org.hwo.io; + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; +import java.util.ArrayList; +import java.util.concurrent.TimeoutException; + +import org.hwo.fifo.FiFo; +import org.hwo.nativeloader.NativeLoader; + +public class NativeSerialPort extends SerialPort { + + class SerialPortInputStream extends InputStream + { + @Override + public int read() throws IOException { + if (!isOpen()) + throw new IOException("Port nicht gešffnet!"); + + int ch = native_getch(nativeHandle,getTimeout()); + //System.err.println(String.format("RX: 0x%08x", ch)); + if (ch < 0) + throw new IOException(String.format("native_getch: returned: %d",ch)); + return ch; + } + + } + + class SerialPortOutputStream extends OutputStream + { + @Override + public void write(int arg0) throws IOException { + if (!isOpen()) + throw new IOException("Port nicht gešffnet!"); + //System.err.println(String.format("TX: 0x%08x", arg0)); + native_putch(nativeHandle, getTimeout(), arg0); + } + } + + + private static native int native_open(String portName); + private static native int native_close(int handle); + private static native int native_send(int handle,byte[] data); + private static native int native_recv(int handle,byte[] data); + + private static native int native_getch(int handle,int timeout); + private static native int native_putch(int handle,int timeout,int ch); + + private int nativeHandle; + + private SerialPortInputStream inputStream; + private SerialPortOutputStream outputStream; + + public NativeSerialPort() + { + nativeHandle = -1; + inputStream = new SerialPortInputStream(); + outputStream = new SerialPortOutputStream(); + } + + @Override + public boolean isOpen() { + return (nativeHandle >= 0); + } + + @Override + public boolean open() { + if (isOpen()) + return false; + + nativeHandle = native_open(getPortName()); + System.err.println(String.format("NativeSerialPort: nativeHandle: %d",nativeHandle)); + if (nativeHandle < 0) + return false; + + return true; + } + + @Override + public void close() { + if (nativeHandle >= 0) + { + System.err.println(String.format("NativeSerialPort: Closing nativeHandle %d",nativeHandle)); + native_close(nativeHandle); + } + nativeHandle = -1; + } + + @Override + public InputStream getInputStream() { + return inputStream; + } + + @Override + public OutputStream getOutputStream() { + return outputStream; + } + + static { + NativeLoader.loadLibrary("hwoio"); + } + +} diff --git a/src/org/hwo/io/SerialPort.java b/src/org/hwo/io/SerialPort.java new file mode 100644 index 0000000..68ef084 --- /dev/null +++ b/src/org/hwo/io/SerialPort.java @@ -0,0 +1,76 @@ +package org.hwo.io; + +import java.io.InputStream; +import java.io.OutputStream; +import org.hwo.os.OsDetect; + +public abstract class SerialPort { + + static public String[] getPortNames() + { + switch (OsDetect.getOperatingSystem()) + { + case OSX: + return SerialPortOSX.getPortNames(); + case WINDOWS: + return SerialPortWINDOWS.getPortNames(); + case LINUX: + return SerialPortLINUX.getPortNames(); + default: + return new String[]{}; + } + } + + static public SerialPort newInstance() + { + switch (OsDetect.getOperatingSystem()) + { + case OSX: + return new SerialPortOSX(); + case WINDOWS: + return new SerialPortWINDOWS(); + case LINUX: + return new SerialPortLINUX(); + default: + return null; + } + } + + private String portName; + private int timeout; // 0 = Non-Blocking, -1 = Block forever + + protected SerialPort() + { + this.portName = ""; + this.timeout = -1; + } + + abstract public boolean isOpen(); + abstract public boolean open(); + abstract public void close(); + + abstract public InputStream getInputStream(); + abstract public OutputStream getOutputStream(); + + + + public String getPortName() { + return portName; + } + + public void setPortName(String portName) { + this.portName = portName; + } + + public int getTimeout() { + return timeout; + } + + public void setTimeout(int timeout) { + this.timeout = timeout; + } + + + + +} diff --git a/src/org/hwo/io/SerialPortChooser.java b/src/org/hwo/io/SerialPortChooser.java new file mode 100644 index 0000000..4aa90e4 --- /dev/null +++ b/src/org/hwo/io/SerialPortChooser.java @@ -0,0 +1,153 @@ +package org.hwo.io; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; + +import java.awt.Dialog.ModalExclusionType; +import java.awt.Dialog.ModalityType; +import java.awt.GridBagLayout; + +import org.hwo.i18n.Messages; +import org.hwo.ui.JComboBoxEx; + +import java.awt.GridBagConstraints; + +import javax.swing.JLabel; + +import java.awt.Insets; +import java.awt.event.ActionListener; +import java.awt.event.ActionEvent; + +public class SerialPortChooser extends JDialog { + + + public static SerialPort execute() + { + return execute(null); + } + public static SerialPort execute(String selectedPortName) + { + SerialPortChooser spc = new SerialPortChooser(); + + if (selectedPortName != null) + spc.setSelectedSerialPort(selectedPortName); + + spc.setVisible(true); + + return spc.getSelectedSerialPort(); + } + + + private final JPanel contentPanel = new JPanel(); + + private SerialPort selectedSerialPort; + private JComboBoxEx cbPortList; + + /** + * Create the dialog. + */ + public SerialPortChooser() { + setTitle(Messages.getString("SerialPortChooser.0")); + setModalityType(ModalityType.APPLICATION_MODAL); + setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE); + setModal(true); + setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); + setBounds(100, 100, 491, 169); + getContentPane().setLayout(new BorderLayout()); + contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + getContentPane().add(contentPanel, BorderLayout.CENTER); + GridBagLayout gbl_contentPanel = new GridBagLayout(); + gbl_contentPanel.columnWidths = new int[]{0, 0, 0}; + gbl_contentPanel.rowHeights = new int[]{0, 0}; + gbl_contentPanel.columnWeights = new double[]{0.0, 1.0, Double.MIN_VALUE}; + gbl_contentPanel.rowWeights = new double[]{0.0, Double.MIN_VALUE}; + contentPanel.setLayout(gbl_contentPanel); + { + JLabel lblSchnittstelle = new JLabel(Messages.getString("interface")); + GridBagConstraints gbc_lblSchnittstelle = new GridBagConstraints(); + gbc_lblSchnittstelle.insets = new Insets(0, 0, 0, 5); + gbc_lblSchnittstelle.anchor = GridBagConstraints.EAST; + gbc_lblSchnittstelle.gridx = 0; + gbc_lblSchnittstelle.gridy = 0; + contentPanel.add(lblSchnittstelle, gbc_lblSchnittstelle); + } + { + cbPortList = new JComboBoxEx(); + GridBagConstraints gbc_cbPortList = new GridBagConstraints(); + gbc_cbPortList.fill = GridBagConstraints.HORIZONTAL; + gbc_cbPortList.gridx = 1; + gbc_cbPortList.gridy = 0; + contentPanel.add(cbPortList, gbc_cbPortList); + } + { + JPanel buttonPane = new JPanel(); + buttonPane.setLayout(new FlowLayout(FlowLayout.RIGHT)); + getContentPane().add(buttonPane, BorderLayout.SOUTH); + { + JButton okButton = new JButton(Messages.getString("ok")); + okButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent arg0) { + accept(); + } + }); + okButton.setActionCommand("OK"); + buttonPane.add(okButton); + getRootPane().setDefaultButton(okButton); + } + { + JButton cancelButton = new JButton(Messages.getString("cancel")); + cancelButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + cancel(); + } + }); + cancelButton.setActionCommand("Cancel"); + buttonPane.add(cancelButton); + } + } + + initialize(); + } + + private void initialize() + { + selectedSerialPort = null; + + cbPortList.removeAllItems(); + + for (String portName: SerialPort.getPortNames()) + cbPortList.addItem(portName); + } + + private void accept() + { + selectedSerialPort = SerialPort.newInstance(); + selectedSerialPort.setPortName(cbPortList.getSelectedItem().toString()); + + setVisible(false); + } + + private void cancel() + { + selectedSerialPort = null; + setVisible(false); + } + + public SerialPort getSelectedSerialPort() { + return selectedSerialPort; + } + + public void setSelectedSerialPort(SerialPort selectedSerialPort) { + cbPortList.selectEqualItem(selectedSerialPort.getPortName()); + } + + public void setSelectedSerialPort(String portName) { + cbPortList.selectEqualItem(portName); + } + +} diff --git a/src/org/hwo/io/SerialPortLINUX.java b/src/org/hwo/io/SerialPortLINUX.java new file mode 100644 index 0000000..3be6626 --- /dev/null +++ b/src/org/hwo/io/SerialPortLINUX.java @@ -0,0 +1,31 @@ +package org.hwo.io; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; + +public class SerialPortLINUX extends NativeSerialPort{ + + static public String[] getPortNames() + { + ArrayList portNames = new ArrayList(); + + File devDir = new File("/dev"); + File[] list = devDir.listFiles(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg1) { + if (arg1.startsWith("ttyS") || arg1.startsWith("ttyACM")) + return true; + return false; + } + }); + + for (File file:list) + portNames.add("/dev/" + file.getName()); + + return portNames.toArray(new String[0]); + } + + +} diff --git a/src/org/hwo/io/SerialPortOSX.java b/src/org/hwo/io/SerialPortOSX.java new file mode 100644 index 0000000..78faa3f --- /dev/null +++ b/src/org/hwo/io/SerialPortOSX.java @@ -0,0 +1,31 @@ +package org.hwo.io; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; + +public class SerialPortOSX extends NativeSerialPort { + + static public String[] getPortNames() + { + ArrayList portNames = new ArrayList(); + + File devDir = new File("/dev"); + File[] list = devDir.listFiles(new FilenameFilter() { + + @Override + public boolean accept(File arg0, String arg1) { + if (arg1.startsWith("tty.")) + return true; + return false; + } + }); + + for (File file:list) + portNames.add("/dev/" + file.getName()); + + return portNames.toArray(new String[0]); + } + + +} diff --git a/src/org/hwo/io/SerialPortWINDOWS.java b/src/org/hwo/io/SerialPortWINDOWS.java new file mode 100644 index 0000000..1fcf58e --- /dev/null +++ b/src/org/hwo/io/SerialPortWINDOWS.java @@ -0,0 +1,31 @@ +package org.hwo.io; + +import java.io.File; +import java.io.FilenameFilter; +import java.util.ArrayList; + +public class SerialPortWINDOWS extends NativeSerialPort { + + + static public String[] getPortNames() + { + ArrayList portNames = new ArrayList(); + + SerialPortWINDOWS sp = new SerialPortWINDOWS(); + + for (int i = 1; i < 32; i++) + { + sp.setPortName(String.format("COM%d:",i)); + if (sp.open()) + { + portNames.add(String.format("COM%d:",i)); + sp.close(); + } + } + + return portNames.toArray(new String[0]); + } + + + +} diff --git a/src/org/hwo/io/servicelink/BitFieldEditor.java b/src/org/hwo/io/servicelink/BitFieldEditor.java new file mode 100644 index 0000000..f3bc432 --- /dev/null +++ b/src/org/hwo/io/servicelink/BitFieldEditor.java @@ -0,0 +1,120 @@ +package org.hwo.io.servicelink; + +import java.awt.Component; +import java.util.Arrays; + +import javax.swing.JCheckBox; +import javax.swing.JPanel; + +import org.hwo.io.servicelink.ServiceLink.ServiceNode; +import org.hwo.io.servicelink.ServiceLink.ServiceNode.ServiceNodeRegister; +import java.awt.FlowLayout; +import javax.swing.JScrollPane; +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; +import javax.swing.BoxLayout; + +public class BitFieldEditor extends JPanel implements RegisterEditorControl { + + private ServiceNodeRegister serviceNodeRegister; + + private JCheckBox[] checkboxes; + private JScrollPane scrollPane; + private JPanel pBits; + + public BitFieldEditor() { + GridBagLayout gridBagLayout = new GridBagLayout(); + gridBagLayout.columnWidths = new int[]{0, 0}; + gridBagLayout.rowHeights = new int[]{0, 0}; + gridBagLayout.columnWeights = new double[]{1.0, Double.MIN_VALUE}; + gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE}; + setLayout(gridBagLayout); + + scrollPane = new JScrollPane(); + GridBagConstraints gbc_scrollPane = new GridBagConstraints(); + gbc_scrollPane.fill = GridBagConstraints.BOTH; + gbc_scrollPane.gridx = 0; + gbc_scrollPane.gridy = 0; + add(scrollPane, gbc_scrollPane); + + pBits = new JPanel(); + scrollPane.setViewportView(pBits); + pBits.setLayout(new BoxLayout(pBits, BoxLayout.Y_AXIS)); + + checkboxes = new JCheckBox[0]; + } + + private void initialize() + { + for (JCheckBox cb:checkboxes) + { + remove(cb); + } + + if (serviceNodeRegister != null) + { + checkboxes = new JCheckBox[32]; + for (int i=0;i<32;i++) + { + if (serviceNodeRegister.getBitField().getLabels()[i]!=null) + { + checkboxes[i] = new JCheckBox(); + checkboxes[i].setText(serviceNodeRegister.getBitField().getLabels()[i]); + + pBits.add(checkboxes[i]); + }; + } + synchronize(); + } + invalidate(); + } + + public void synchronize() + { + for (int i=0;i<32;i++) + { + if (checkboxes[i]!=null) + checkboxes[i].setSelected( + (serviceNodeRegister.getIntValue() & (1<= 0)) + ch = getSerialPort().getInputStream().read(); + + getSerialPort().getInputStream().read(rxbuffer,0,5); + + request = bb.get(); + achse = bb.get(); + knoten = bb.get(); + register = bb.getShort(); + + if ((request & (REQ_READ | REQ_ACK)) == (REQ_READ | REQ_ACK)) + { + getSerialPort().getInputStream().read(rxbuffer,bb.position(),4); + bb.get(value); + }; + getSerialPort().getInputStream().read(rxbuffer,bb.position(),2); + short chksum = bb.getShort(); + + if (chksum != ChkSum.chksum(rxbuffer, 0, bb.position() - 2)) + throw new ServiceLinkException(); + + } catch (IOException e) { + getSerialPort().close(); + + System.err.println(e.toString()); + throw new ServiceLinkException(e); + } + } + + } + + public class ServiceNode + { + @InteractiveObject(editor=RegisterEditor.class) + public class ServiceNodeRegister + { + @TableColumn(label="Register",readonly=true,width=60) + Integer register; + @TableColumn(label="Bezeichnung",readonly=true,width=150) + String label; + + private Float floatValue; + private Integer intValue; + + boolean floatType; + + private BitField bitField; + + public ServiceNodeRegister(int register,boolean floatType) + { + this.label = String.format("%d", register); + this.register = register; + this.floatType = floatType; + } + public ServiceNodeRegister(int register,String label,boolean floatType) + { + this.label = label; + this.register = register; + this.floatType = floatType; + } + + public boolean isBitField() + { + return (bitField != null); + } + + public boolean isFloat() + { + return floatType; + } + + public boolean isInteger() + { + return (!isBitField() && !isFloat()); + } + + @TableColumn(label="Wert",width=500) + public String value() + { + if (bitField != null) + return bitField.toText(intValue); + if (intValue != null) + return String.format("%d", intValue); + if (floatValue != null) + return String.format("%f", floatValue); + return "N/A"; + } + + public void setValue(String value) + { + if (floatType) + floatValue = new Float(value); + else + intValue = new Integer(value); + } + + public void read() + { + try { + if (floatType) + floatValue = ServiceNode.this.readFloat(register); + else + intValue = ServiceNode.this.readInt(register); + } catch (Exception e) { + floatValue = null; + intValue = 0; + e.printStackTrace(); + }; + } + + public void write() + { + try + { + if (floatType) + ServiceNode.this.writeFloat(register, floatValue); + else + ServiceNode.this.writeInt(register, intValue); + } catch (Exception e) + { + e.printStackTrace(); + } + } + public BitField getBitField() { + return bitField; + } + public void setBitField(BitField bitField) { + this.bitField = bitField; + } + public Integer getIntValue() { + return intValue; + } + public void setIntValue(Integer intValue) { + this.intValue = intValue; + } + public Float getFloatValue() { + return floatValue; + } + public void setFloatValue(Float floatValue) { + this.floatValue = floatValue; + } + + + } + + private byte achse; + private byte knoten; + + List registers; + + public ServiceNode(byte achse,byte knoten) + { + this.achse = achse; + this.knoten = knoten; + this.registers = new ArrayList(); + } + + public ServiceNodeRegister createRegister(int register,String label,boolean floatType) + { + return new ServiceNodeRegister(register, label, floatType); + } + + public List getRegisters() + { + return registers; + } + + public void read() + { + for (ServiceNodeRegister r:registers) + r.read(); + } + + public ServiceLink getServiceLink() + { + return ServiceLink.this; + } + + public int readInt(int register) throws IOException, ServiceLinkException + { + for (int n=0;n lineCharacters = new LinkedList(); + float x = 0; + + while ( position < characters.length ) + { + + } + + + + //return String.valueOf(lineCharacters.toArray(new char[0])); + return ""; + } + + public Font getFont() { + return font; + } + + public void setFont(Font font) { + this.font = font; + + BufferedImage img = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB); + Graphics2D g2d = img.createGraphics(); + g2d.setFont(font); + this.metrics = g2d.getFontMetrics(); + } + + + + +} diff --git a/src/org/hwo/models/Column.java b/src/org/hwo/models/Column.java new file mode 100644 index 0000000..275cacb --- /dev/null +++ b/src/org/hwo/models/Column.java @@ -0,0 +1,132 @@ +package org.hwo.models; + +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; + +public class Column { + private int MODE_FIELD = 1; + private int MODE_GETSET = 2; + + private int mode; + private String fieldName; + private boolean readonly; + private Class p_class; + private Field field; + private Method getter; + private Method setter; + + public Column(Class classInfo,String fieldName,boolean readonly) throws NoSuchFieldException + { + this.fieldName = fieldName; + this.readonly = readonly; + this.p_class = classInfo; + this.getter = null; + this.setter = null; + + try + { + mode = MODE_FIELD; + this.field = this.p_class.getDeclaredField(fieldName); + this.field.setAccessible(true); + } catch (NoSuchFieldException nsfex) + { + mode = MODE_GETSET; + // Kein deklariertes Feld, also suchen wir eine get... und set... Methode... + Method[] methods = this.p_class.getDeclaredMethods(); + for (Method method : methods) { + // passender getter? + if (("get"+fieldName.toLowerCase()).equals(method.getName().toLowerCase())) + getter = method; + // passender setter? + if (("set"+fieldName.toLowerCase()).equals(method.getName().toLowerCase())) + setter = method; + } + if (getter == null) + throw nsfex; + } + } + + + public String getFieldName() + { + return this.fieldName; + } + + public boolean getReadOnly() + { + if ((mode == MODE_GETSET) && (setter == null)) + return true; + + return this.readonly; + } + public void setReadOnly(boolean readOnly) + { + this.readonly = readOnly; + } + + public Class getColumnClass() + { + if (mode == MODE_GETSET) + return this.getter.getReturnType(); + + return this.field.getType(); + } + + Object getValue(Object o) + { + try + { + if (mode == MODE_GETSET) + { + try + { + Object ro = this.getter.invoke(o, null); + return ro; + } catch (InvocationTargetException itex) + { + System.err.println(itex.toString()); + itex.printStackTrace(); + } + } + return this.field.get(o); + } catch (IllegalArgumentException e) { + System.err.println("IllegalArgument! " + e.toString()); + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + System.err.println("IllegalAccess! " + e.toString()); + e.printStackTrace(); + } + return null; + } + void setValue(Object o,Object value) + { + try + { + if (mode == MODE_GETSET) + { + if (this.setter != null) + { + try + { + this.setter.invoke(o,new Object[]{ value }); + } catch (InvocationTargetException itex) + { + System.err.println(itex.toString()); + itex.printStackTrace(); + } + } + } + this.field.set(o,value); + } catch (IllegalArgumentException e) { + System.err.println("IllegalArgument! " + e.toString()); + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + System.err.println("IllegalAccess! " + e.toString()); + e.printStackTrace(); + } + return; + } +} diff --git a/src/org/hwo/models/FlexibleObjectListModel.java b/src/org/hwo/models/FlexibleObjectListModel.java new file mode 100644 index 0000000..859b1a9 --- /dev/null +++ b/src/org/hwo/models/FlexibleObjectListModel.java @@ -0,0 +1,55 @@ +package org.hwo.models; + +import java.util.ArrayList; +import java.util.List; +import javax.swing.AbstractListModel; + +public class FlexibleObjectListModel extends AbstractListModel { + + private List items; + + public FlexibleObjectListModel() { + this.items = new ArrayList(); + } + + @Override + public Object getElementAt(int index) { + return this.items.get(index); + } + + @Override + public int getSize() { + return this.items.size(); + } + + public void clear() + { + this.items.clear(); + fireContentsChanged(this, 0, getSize()); + } + + public List getItems() { + return items; + } + + public void setItems(List items) { + this.items = items; + fireContentsChanged(this, 0, getSize()); + } + + public void addItem(T o) + { + this.items.add(o); + fireContentsChanged(this, 0, getSize()); + } + + public void removeItem(T o) + { + int index = this.items.indexOf(o); + this.items.remove(o); + fireContentsChanged(this, 0, getSize()); + } + + + +} diff --git a/src/org/hwo/models/FlexibleObjectTableModel.java b/src/org/hwo/models/FlexibleObjectTableModel.java new file mode 100644 index 0000000..7e4ea39 --- /dev/null +++ b/src/org/hwo/models/FlexibleObjectTableModel.java @@ -0,0 +1,115 @@ +package org.hwo.models; + +import java.util.ArrayList; +import java.util.List; +import javax.swing.table.AbstractTableModel; + +public class FlexibleObjectTableModel extends AbstractTableModel{ + + List columns; + List rows; + + Class p_classinfo; + + public FlexibleObjectTableModel(Class tClass) + { + this.columns = new ArrayList(); + this.rows = new ArrayList(); + + this.p_classinfo = tClass; + } + + + public void addColumn(String fieldName) + { + this.addColumn(fieldName,true); + } + public void addColumn(String fieldName,boolean readOnly) + { + try + { + this.columns.add(new Column(this.p_classinfo,fieldName,readOnly)); + fireTableStructureChanged(); + } catch (NoSuchFieldException nsfex) + { + System.err.println(nsfex.toString()); + nsfex.printStackTrace(); + } + } + + + public List getRows() + { + return this.rows; + } + public void setRows(List rows) + { + this.rows = rows; + this.fireTableDataChanged(); + } + + public int indexOf(Object o) + { + return this.rows.indexOf(o); + } + + public void addRow(T o) + { + this.rows.add(o); + this.fireTableDataChanged(); + } + + public void removeRow(T o) + { + this.rows.remove(o); + this.fireTableDataChanged(); + } + public void removeRow(int row) + { + this.rows.remove(row); + this.fireTableDataChanged(); + } + + @Override + public int getColumnCount() { + return this.columns.size(); + } + + @Override + public int getRowCount() { + return this.rows.size(); + } + + @Override + public Object getValueAt(int arg0, int arg1) { + return this.columns.get(arg1).getValue(this.rows.get(arg0)); + } + + @Override + public String getColumnName(int columnIndex) + { + return this.columns.get(columnIndex).getFieldName(); + } + + @Override + public void setValueAt(Object aValue, + int rowIndex, + int columnIndex) + { + this.columns.get(columnIndex).setValue(this.rows.get(rowIndex), aValue); + } + + @Override + public boolean isCellEditable(int rowIndex,int columnIndex) + { + return !this.columns.get(columnIndex).getReadOnly(); + } + + @Override + public Class getColumnClass(int columnIndex) + { + return this.columns.get(columnIndex).getColumnClass(); + } + + +} diff --git a/src/org/hwo/models/ListTableModel.java b/src/org/hwo/models/ListTableModel.java new file mode 100644 index 0000000..5932dee --- /dev/null +++ b/src/org/hwo/models/ListTableModel.java @@ -0,0 +1,56 @@ +package org.hwo.models; + +import java.util.ArrayList; +import java.util.List; + +import javax.swing.table.AbstractTableModel; + +public class ListTableModel extends AbstractTableModel { + + private List rows; + + public ListTableModel() + { + rows = new ArrayList(); + rows.add(new Object[]{"Eins","Zwei","Drei"}); + } + + + private Integer calcColumnCount() + { + Integer max = 0; + + for (Object[] record:rows) + if (record.length > max) + max = record.length; + + return max; + } + + @Override + public int getColumnCount() { + return calcColumnCount(); + } + + @Override + public int getRowCount() { + return rows.size(); + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + return rows.get(rowIndex)[columnIndex]; + } + + + public List getRows() { + return rows; + } + + + public void setRows(List rows) { + this.rows = rows; + fireTableStructureChanged(); + } + +} diff --git a/src/org/hwo/models/TableMapper/AbstractTableMapperListener.java b/src/org/hwo/models/TableMapper/AbstractTableMapperListener.java new file mode 100644 index 0000000..499771f --- /dev/null +++ b/src/org/hwo/models/TableMapper/AbstractTableMapperListener.java @@ -0,0 +1,10 @@ +package org.hwo.models.TableMapper; + +public abstract class AbstractTableMapperListener implements + TableMapperListener { + + @Override + public void ValueChanged(int row, int column) { + } + +} diff --git a/src/org/hwo/models/TableMapper/TableColumn.java b/src/org/hwo/models/TableMapper/TableColumn.java new file mode 100644 index 0000000..bd4efda --- /dev/null +++ b/src/org/hwo/models/TableMapper/TableColumn.java @@ -0,0 +1,17 @@ +package org.hwo.models.TableMapper; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface TableColumn { + + String label() default ""; + boolean readonly() default false; + boolean visible() default true; + int width() default 100; + String after() default ""; + boolean firstColumn() default false; +} + + diff --git a/src/org/hwo/models/TableMapper/TableMapper.java b/src/org/hwo/models/TableMapper/TableMapper.java new file mode 100644 index 0000000..68b4e6c --- /dev/null +++ b/src/org/hwo/models/TableMapper/TableMapper.java @@ -0,0 +1,637 @@ +package org.hwo.models.TableMapper; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.io.File; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JTable; +import javax.swing.event.ListSelectionListener; +import javax.swing.table.AbstractTableModel; + +import org.hwo.csv.CSV; +import org.hwo.interactiveobjects.InteractiveObjectHelper; + +public class TableMapper extends AbstractTableModel +{ + + private static final long serialVersionUID = -6556060772230310664L; + + public class ColumnInfo + { + private TableColumn p_annotation; + + private Field p_field; + private Method p_method; + private String p_label; + private boolean p_readonly; + private Class p_columnclass; + private int width; + private TableColumn tableColumn; + + private ColumnInfo nextColumn; + + protected ColumnInfo(TableColumn tc,Field field) + { + tableColumn = tc; + p_annotation = field.getAnnotation(TableColumn.class); + + p_method = null; + p_field = field; + p_columnclass = field.getType(); + + initialize(); + + if (p_label.equals("")) + p_label = field.getName(); + + field.setAccessible(true); + } + protected ColumnInfo(TableColumn tc,Method method) + { + tableColumn = tc; + p_annotation = method.getAnnotation(TableColumn.class); + + p_method = method; + p_field = null; + p_columnclass = method.getReturnType(); + + initialize(); + + if (p_label.equals("")) + p_label = method.getName(); + + method.setAccessible(true); + + p_readonly = true; + } + + private void initialize() + { + p_label = p_annotation.label(); + p_readonly = p_annotation.readonly(); + setWidth(p_annotation.width()); + } + + public void appendAtEnd(ColumnInfo column) + { + if (nextColumn == null) + nextColumn = column; + else + nextColumn.appendAtEnd(column); + } + + public List toList() + { + List list = new LinkedList(); + appendToList(list); + return list; + } + + public void appendToList(List list) + { + list.add(this); + if (nextColumn != null) + nextColumn.appendToList(list); + } + + public void removeColumn(ColumnInfo ci) + { + if (nextColumn == ci) + { + nextColumn = ci.nextColumn; + ci.nextColumn = null; + } else if (nextColumn != null) + nextColumn.removeColumn(ci); + } + + public ColumnInfo findColumnByName(String name) + { + if (this.p_label.equals(name)) + return this; + if (nextColumn!=null) + return nextColumn.findColumnByName(name); + else + return null; + } + + public void append(ColumnInfo ci) + { + ci.nextColumn = nextColumn; + nextColumn = ci; + } + + + public String getLabel() + { + return this.p_label; + } + public void setLabel(String label) + { + this.p_label = label; + } + + public boolean getReadOnly() + { + return this.p_readonly; + } + public void setReadOnly(boolean readOnly) + { + this.p_readonly = readOnly; + } + + public void setColumnClass(Class cl) + { + this.p_columnclass = cl; + } + public Class getColumnClass() + { + return this.p_columnclass; + } + + public Object getValue(Object instance) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException + { + if (p_field != null) + return p_field.get(instance); + if (p_method != null) + return p_method.invoke(instance, null); + return null; + } + + public void setValue(Object instance,Object value) throws IllegalAccessException + { + if (p_field != null) + p_field.set(instance, value); + } + + public int getWidth() { + return width; + } + + public void setWidth(int width) { + this.width = width; + } + + public ColumnInfo getNextColumn() { + return nextColumn; + } + + public void setNextColumn(ColumnInfo nextColumn) { + this.nextColumn = nextColumn; + } + + public TableColumn getTableColumn() { + return tableColumn; + } + + public void setTableColumn(TableColumn tableColumn) { + this.tableColumn = tableColumn; + } + + } + + + private Class p_class; + + private ColumnInfo firstColumn; + + private List p_rows; + private List p_columns; + private boolean p_readonly; // Table readonly... + + private TableMapperColumnModel + columnModel; + + private JTable jTable; + + private TableMapperObject + tableMapperObject; + private Field editorObjectField; + private Class editorObjectClass; + + private MouseAdapter mouseAdapter; + + private boolean editorEnabled; + + private LinkedList tableMapperListeners; + + public TableMapper(Class clazz,JTable table) + { + this.tableMapperListeners = new LinkedList(); + this.p_class = clazz; + this.jTable = table; + + this.firstColumn = null; + + this.p_rows = new LinkedList(); + this.p_columns = new ArrayList(); + this.p_readonly = false; + + initializeMapper(); + initializeColumnInfo(); + + table.setModel(this); + table.setColumnModel(new TableMapperColumnModel(this)); + + table.setAutoCreateRowSorter(true); + + mouseAdapter = new MouseAdapter() { + + @Override + public void mouseClicked(MouseEvent e) { + switch (e.getButton()) + { + case 1: + if (e.getClickCount()==2) + { + openEditor(); + } + } + } + }; + + + if (InteractiveObjectHelper.isInteractiveObject(editorObjectClass)) + setEditorEnabled(true); + + } + + private void initializeMapper() + { + tableMapperObject = p_class.getAnnotation(TableMapperObject.class); + if (tableMapperObject != null) + { + if (tableMapperObject.editorField() != null) + { + try { + editorObjectField = p_class.getDeclaredField(tableMapperObject.editorField()); + editorObjectField.setAccessible(true); + + editorObjectClass = editorObjectField.getType(); + + } catch (SecurityException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (NoSuchFieldException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + } else + { + editorObjectClass = p_class; + } + + } + + public void addListSelectionListener(ListSelectionListener listener) + { + jTable.getSelectionModel().addListSelectionListener(listener); + } + public void removeListSelectionListener(ListSelectionListener listener) + { + jTable.getSelectionModel().removeListSelectionListener(listener); + } + + public void addTableMapperListener(TableMapperListener listener) + { + tableMapperListeners.add(listener); + } + public void removeTableMapperListener(TableMapperListener listener) + { + tableMapperListeners.remove(listener); + } + + protected void fireValueChanged(int row,int column) + { + for (TableMapperListener listener: tableMapperListeners) + listener.ValueChanged(row, column); + } + + private Object getEditorObject() + { + if (jTable.getSelectedRow()!=-1) + { + int row = jTable.convertRowIndexToModel(jTable.getSelectedRow()); + Object rowObject = p_rows.get(row); + if (editorObjectField == null) + return rowObject; + + try { + Object editorObject = editorObjectField.get(rowObject); + return editorObject; + + } catch (IllegalArgumentException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } catch (IllegalAccessException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + + } + return null; + } + + private void openEditor() + { + Object editorObject = getEditorObject(); + if (editorObject!=null) + InteractiveObjectHelper.showEditor(editorObject); + } + + public List getColumnInfo() + { + return p_columns; + } + + public void setRows(List rows) + { + this.p_rows = rows; + fireTableDataChanged(); + } + public List getRows() + { + return this.p_rows; + } + + public List getRows(Class clazz) + { + return (List) p_rows; + } + + public void clear() + { + this.p_rows.clear(); + fireTableDataChanged(); + } + + public boolean isEditorEnabled() + { + return editorEnabled; + } + + public void setEditorEnabled(boolean enabled) + { + if (enabled) + jTable.addMouseListener(mouseAdapter); + else + jTable.removeMouseListener(mouseAdapter); + + editorEnabled = enabled; + } + + private void addColumnInfo(ColumnInfo ci) + { + if (ci.getTableColumn().firstColumn()) + p_columns.add(0,ci); + else + p_columns.add(ci); + /* + if (firstColumn == null) + firstColumn = ci; + else + { + if (ci.getTableColumn().firstColumn()) + { + ci.setNextColumn(firstColumn); + firstColumn = ci; + } else + firstColumn.appendAtEnd(ci); + } + */ + } + + private void addFieldsOfClass(Class clazz) + { + if (clazz.getSuperclass() != null) + addFieldsOfClass(clazz.getSuperclass()); + + for (Field field: clazz.getDeclaredFields()) + { + if (field.getAnnotation(TableColumn.class)!=null) + { + ColumnInfo ci = new ColumnInfo(field.getAnnotation(TableColumn.class),field); + addColumnInfo(ci); + } + } + + for (Method method: clazz.getDeclaredMethods()) + { + if (method.getAnnotation(TableColumn.class)!=null) + { + ColumnInfo ci = new ColumnInfo(method.getAnnotation(TableColumn.class),method); + addColumnInfo(ci); + } + } + + } + + + private int findColumnIndexByName(String name) + { + for (int i=0;i lc = new ArrayList(p_columns); + + for (ColumnInfo ci:lc) + { + if (!ci.getTableColumn().after().equals("")) + { + int indColumn = p_columns.indexOf(ci); + int indBefore = findColumnIndexByName(ci.getTableColumn().after()); + if (indBefore != -1) + { + if (indBefore < indColumn) + { + List subset = new ArrayList(p_columns.subList(indColumn, p_columns.size())); + p_columns.removeAll(subset); + p_columns.addAll(indBefore+1, subset); + } else + { + List subset = new ArrayList(p_columns.subList(indColumn, indBefore)); + p_columns.removeAll(subset); + p_columns.addAll(indColumn+1, subset); + } + } + } + } + } + + private void initializeColumnInfo() + { + addFieldsOfClass(p_class); + reorderColumns(); + } + + public void setReadOnly(boolean readOnly) + { + this.p_readonly = readOnly; + } + public boolean getReadOnly() + { + return this.p_readonly; + } + + public void addRow(Object row) + { + this.p_rows.add(row); + //fireTableRowsInserted(getRowCount()-1, getRowCount()-1); + fireTableDataChanged(); + } + public void removeRow(Object row) + { + int index = this.p_rows.indexOf(row); + if (index != -1) + { + this.p_rows.remove(index); + fireTableRowsDeleted(index, index); + }; + } + + public Object getRow(int index) + { + return this.p_rows.get(index); + } + + public T getRow(int index,Class clazz) + { + return (T)this.p_rows.get(index); + } + + public Object appendNewInstance() + { + try + { + Object instance = this.p_class.newInstance(); + if (instance != null) + addRow(instance); + return instance; + } catch (Exception ex) + { + return null; + } + } + + + + @Override + public int getColumnCount() { + return this.p_columns.size(); + } + + @Override + public int getRowCount() { + return this.p_rows.size(); + } + + @Override + public Object getValueAt(int rowIndex, int columnIndex) { + if ( (rowIndex < this.p_rows.size()) && (columnIndex < this.p_columns.size())) + { + try + { + return this.p_columns.get(columnIndex).getValue(this.p_rows.get(rowIndex)); + } catch (Exception ex) + { + System.err.println("Exception: " + ex); + ex.printStackTrace(); + } + } + return ""; + } + + + @Override + public void setValueAt(Object aValue, + int rowIndex, + int columnIndex) + { + try + { + this.p_columns.get(columnIndex).setValue(this.p_rows.get(rowIndex), aValue); + fireValueChanged(rowIndex, columnIndex); + } catch (IllegalAccessException ex) + { + System.err.println("IllegalAccessException: " + ex); + ex.printStackTrace(); + } + } + + @Override + public boolean isCellEditable(int rowIndex,int columnIndex) + { + if (this.p_readonly) + return false; + return !this.p_columns.get(columnIndex).getReadOnly(); + } + + @Override + public Class getColumnClass(int columnIndex) + { + Class c = this.p_columns.get(columnIndex).getColumnClass(); + return c; + } + + @Override + public String getColumnName(int columnIndex) + { + return this.p_columns.get(columnIndex).getLabel(); + } + + public Object getSelectedRow() + { + if (jTable.getSelectedRow()!=-1) + { + return this.p_rows.get(jTable.convertRowIndexToModel(jTable.getSelectedRow())); + } + return null; + } + + public boolean exportToFile(File exportFile) + { + CSV csv = new CSV(); + + List cells = csv.getCells(); + + String[] header = new String[ getColumnCount() ]; + for (int i=0;i listeners; + + private ArrayList tableColumns; + + private int margin; + + private ListSelectionModel listSelectionModel; + + public TableMapperColumnModel(TableMapper tableMapper) + { + this.tableMapper = tableMapper; + this.listeners = new LinkedList(); + this.tableColumns = new ArrayList(); + this.listSelectionModel = new DefaultListSelectionModel(); + + for (int i=0;i getColumns() { + return new Vector(tableColumns).elements(); + } + + @Override + public int getSelectedColumnCount() { + return 0; + } + + @Override + public int[] getSelectedColumns() { + return new int[0]; + } + + @Override + public ListSelectionModel getSelectionModel() { + return listSelectionModel; + } + + @Override + public int getTotalColumnWidth() { + int width = 0; + for (TableColumn tc:tableColumns) + width += tc.getWidth(); + return width; + } + + @Override + public void moveColumn(int columnIndex, int newIndex) { + + } + + @Override + public void removeColumn(TableColumn column) { + + } + + @Override + public void setColumnMargin(int newMargin) { + margin = newMargin; + fireColumnMarginChanged(); + } + + @Override + public void setColumnSelectionAllowed(boolean flag) { + + } + + @Override + public void setSelectionModel(ListSelectionModel newModel) { + listSelectionModel = newModel; + } + +} diff --git a/src/org/hwo/models/TableMapper/TableMapperListener.java b/src/org/hwo/models/TableMapper/TableMapperListener.java new file mode 100644 index 0000000..ebc3ea2 --- /dev/null +++ b/src/org/hwo/models/TableMapper/TableMapperListener.java @@ -0,0 +1,7 @@ +package org.hwo.models.TableMapper; + +public interface TableMapperListener { + + public void ValueChanged(int row,int column); + +} diff --git a/src/org/hwo/models/TableMapper/TableMapperObject.java b/src/org/hwo/models/TableMapper/TableMapperObject.java new file mode 100644 index 0000000..871ce2f --- /dev/null +++ b/src/org/hwo/models/TableMapper/TableMapperObject.java @@ -0,0 +1,11 @@ +package org.hwo.models.TableMapper; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; + +@Retention(RetentionPolicy.RUNTIME) +public @interface TableMapperObject { + + String editorField(); + +} diff --git a/src/org/hwo/nativeloader/NativeLoader.java b/src/org/hwo/nativeloader/NativeLoader.java new file mode 100644 index 0000000..6fedc89 --- /dev/null +++ b/src/org/hwo/nativeloader/NativeLoader.java @@ -0,0 +1,80 @@ +package org.hwo.nativeloader; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.OutputStream; + +import javax.management.RuntimeErrorException; + +import org.hwo.os.OsDetect; + +public class NativeLoader { + + public static void loadLibrary(String libName) + { + try + { + System.loadLibrary(libName); + return; + } catch (UnsatisfiedLinkError e) + { + System.err.println("Native Library not found, trying to load from JAR-File"); + System.err.println(e); + e.printStackTrace(); + } + + String platformLibName; + String resourcePath; + + switch (OsDetect.getOperatingSystem()) + { + case LINUX: + platformLibName = String.format("lib%s.so",libName); + break; + case OSX: + platformLibName = String.format("lib%s.dylib",libName); + break; + case WINDOWS: + platformLibName = String.format("%s.dll",libName); + break; + default: + throw new RuntimeException("Betriebssystem nicht unterstźtzt!"); + } + + System.err.println(String.format("NativeLoader: Platform dependent Name: %s",platformLibName)); + + resourcePath = "/native/" + platformLibName; + System.err.println(String.format("NativeLoader: Resource name: %s",resourcePath)); + + InputStream libInputStream = NativeLoader.class.getResourceAsStream(resourcePath); + if (libInputStream == null) + { + System.err.println("Resource wurde nicht gefunden!"); + } + + try { + File tempLibFile = File.createTempFile("native-", platformLibName); + FileOutputStream fos = new FileOutputStream(tempLibFile); + + System.err.println(String.format("Using Temp File: %s",tempLibFile.getAbsoluteFile())); + System.err.println(String.format("Size: %d",libInputStream.available())); + + byte[] buffer = new byte[libInputStream.available()]; + libInputStream.read(buffer); + fos.write(buffer); + fos.close(); + + System.err.println(String.format("Loading: %s", tempLibFile.getAbsolutePath())); + System.load(tempLibFile.getAbsolutePath()); + + } catch (Exception e) { + throw new RuntimeException(e); + + } + + } + + +} diff --git a/src/org/hwo/net/ServerObject.java b/src/org/hwo/net/ServerObject.java new file mode 100644 index 0000000..ea42708 --- /dev/null +++ b/src/org/hwo/net/ServerObject.java @@ -0,0 +1,19 @@ +package org.hwo.net; + +import java.io.IOException; + +import org.hwo.net.serverobjects.ServerObjectRequest; + +public interface ServerObject { + + public ServerObject getRootObject(); + public ServerObject getParent(); + public ServerObject[] getChildren(); + public ServerObject getNamedChild(String childName); + + public void addNamedChild(String childName,ServerObject serverObject); + + public void climb(ServerObjectRequest request) throws IOException; + public void request(ServerObjectRequest request) throws IOException; + +} diff --git a/src/org/hwo/net/ServerObjectProvider.java b/src/org/hwo/net/ServerObjectProvider.java new file mode 100644 index 0000000..38fa38d --- /dev/null +++ b/src/org/hwo/net/ServerObjectProvider.java @@ -0,0 +1,7 @@ +package org.hwo.net; + +public interface ServerObjectProvider { + + + +} diff --git a/src/org/hwo/net/http/HttpRequestURI.java b/src/org/hwo/net/http/HttpRequestURI.java new file mode 100644 index 0000000..c0464c7 --- /dev/null +++ b/src/org/hwo/net/http/HttpRequestURI.java @@ -0,0 +1,66 @@ +package org.hwo.net.http; + +import java.util.Arrays; + +public class HttpRequestURI { + + private String requestPath; + private HttpServerRequest request; + + private String path; + private String[] elements; + private String queryString; + private String hostname; + private Integer port; + + public HttpRequestURI(HttpServerRequest request,String path) + { + this.requestPath = path; + this.request = request; + } + + public void decode() + { + if (requestPath.indexOf('?')>0) + { + queryString = requestPath.substring(requestPath.indexOf('?')+1); + this.path = requestPath.substring(0,requestPath.indexOf('?')); + } else + { + queryString = ""; + this.path = requestPath; + } + + String ptokens[] = this.path.split("/"); + if (ptokens.length>0) + elements = Arrays.copyOfRange(ptokens, 1, ptokens.length); + else + elements = new String[0]; + + hostname = request.getRequestHeader("Host"); + if (hostname.indexOf(':')>0) + { + String[] tokens = hostname.split(":"); + hostname = tokens[0]; + port = Integer.parseInt(tokens[1]); + } + } + + public String getPath() + { + return path; + } + + public String getQueryString() + { + return queryString; + } + + public String[] getPathElements() + { + return elements; + } + + + +} diff --git a/src/org/hwo/net/http/HttpServer.java b/src/org/hwo/net/http/HttpServer.java new file mode 100644 index 0000000..729be88 --- /dev/null +++ b/src/org/hwo/net/http/HttpServer.java @@ -0,0 +1,90 @@ +package org.hwo.net.http; + +import java.io.IOException; +import java.net.HttpRetryException; +import java.net.ServerSocket; +import java.net.Socket; + +import org.hwo.net.requesthandler.ServerObjectHandler; +import org.hwo.net.serverobjects.VirtualRootObject; + +public class HttpServer extends Thread { + + private int port; + private ServerSocket serverSocket; + + private HttpServerConnectionFactory connectionFactory; + private HttpServerRequestFactory requestFactory; + private HttpServerRequestHandler requestHandler; + + public HttpServer(int port) + { + this.port = port; + this.connectionFactory = new HttpServerConnection.Factory(); + this.requestFactory = new HttpServerRequest.Factory(); + + this.requestHandler = new HttpServerRequestHandler() { + + @Override + public void doRequest(HttpServerRequest httpRequest) throws IOException{ + httpRequest.setResponseHeader("Content-Type", "text/plain"); + httpRequest.getResponseWriter().write("This Page has no other content than this text."); + } + }; + } + + public HttpServerConnectionFactory getConnectionFactory() + { + return connectionFactory; + } + public void setConnectionFactory(HttpServerConnectionFactory factory) + { + connectionFactory = factory; + } + + + public HttpServerRequestFactory getRequestFactory() + { + return requestFactory; + } + public void setRequestFactory(HttpServerRequestFactory factory) + { + requestFactory = factory; + } + + public HttpServerRequestHandler getRequestHandler() { + return requestHandler; + } + + public void setRequestHandler(HttpServerRequestHandler requestHandler) { + this.requestHandler = requestHandler; + } + + @Override + public void run() { + + try { + serverSocket = new ServerSocket(port); + + while (true) + { + Socket clientSocket = serverSocket.accept(); + + HttpServerConnection connection = getConnectionFactory().createHttpServerConnection(this, clientSocket); + connection.start(); + } + + } catch (IOException e) { + e.printStackTrace(); + } + } + + public static void main(String[] args) { + HttpServer httpServer = new HttpServer(8080); + ServerObjectHandler soh = new ServerObjectHandler(); + + httpServer.setRequestHandler(soh); + + httpServer.start(); + } +} diff --git a/src/org/hwo/net/http/HttpServerConnection.java b/src/org/hwo/net/http/HttpServerConnection.java new file mode 100644 index 0000000..386cb6b --- /dev/null +++ b/src/org/hwo/net/http/HttpServerConnection.java @@ -0,0 +1,89 @@ +package org.hwo.net.http; + +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.net.Socket; + +public class HttpServerConnection extends Thread { + + public static class Factory implements HttpServerConnectionFactory + { + @Override + public HttpServerConnection createHttpServerConnection( + HttpServer httpServer, Socket clientSocket) throws IOException { + return new HttpServerConnection(httpServer, clientSocket); + } + } + + private HttpServer httpServer; + private Socket clientSocket; + + private BufferedReader bufferedReader; + private BufferedWriter bufferedWriter; + + public HttpServerConnection(HttpServer httpServer,Socket clientSocket) throws IOException + { + this.httpServer = httpServer; + this.clientSocket = clientSocket; + this.bufferedReader = new BufferedReader(new InputStreamReader(clientSocket.getInputStream())); + this.bufferedWriter = new BufferedWriter(new OutputStreamWriter(clientSocket.getOutputStream())); + } + + public HttpServer getHttpServer() + { + return httpServer; + } + + public Socket getClientSocket() + { + return clientSocket; + } + + public BufferedReader getBufferedReader() + { + return bufferedReader; + } + + public BufferedWriter getBufferedWriter() + { + return bufferedWriter; + } + + + private void close() throws IOException + { + clientSocket.close(); + } + + + @Override + public void run() { + + try + { + while (!clientSocket.isClosed()) + { + HttpServerRequest request = httpServer.getRequestFactory().createRequest(this); + + doRequest(request); + + request.sendResponse(); + } + + close(); + } catch (IOException exception) + { + exception.printStackTrace(); + } + } + + public void doRequest(HttpServerRequest httpRequest) throws IOException + { + httpServer.getRequestHandler().doRequest(httpRequest); + } + +} diff --git a/src/org/hwo/net/http/HttpServerConnectionFactory.java b/src/org/hwo/net/http/HttpServerConnectionFactory.java new file mode 100644 index 0000000..0cc1452 --- /dev/null +++ b/src/org/hwo/net/http/HttpServerConnectionFactory.java @@ -0,0 +1,10 @@ +package org.hwo.net.http; + +import java.io.IOException; +import java.net.Socket; + +public interface HttpServerConnectionFactory { + + public HttpServerConnection createHttpServerConnection(HttpServer httpServer,Socket clientSocket) throws IOException; + +} diff --git a/src/org/hwo/net/http/HttpServerRequest.java b/src/org/hwo/net/http/HttpServerRequest.java new file mode 100644 index 0000000..771eed5 --- /dev/null +++ b/src/org/hwo/net/http/HttpServerRequest.java @@ -0,0 +1,188 @@ +package org.hwo.net.http; + +import java.io.BufferedWriter; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.OutputStream; +import java.io.OutputStreamWriter; +import java.util.Arrays; +import java.util.Enumeration; +import java.util.Properties; + +public class HttpServerRequest { + + public static class Factory implements HttpServerRequestFactory + { + @Override + public HttpServerRequest createRequest(HttpServerConnection connection) throws IOException { + return new HttpServerRequest(connection); + } + } + + HttpServerConnection connection; + + String requestLine; + String requestMethod; + String requestProtocol; + HttpRequestURI + requestURI; + + Properties header; + + Integer resultCode; + Properties responseHeader; + byte[] responseBody; + + ByteArrayOutputStream + responseOutputStream; + BufferedWriter + responseBufferedWriter; + + boolean responseSent; + + + public HttpServerRequest(HttpServerConnection httpServerConnection) throws IOException + { + this.connection = httpServerConnection; + this.header = new Properties(); + + readRequest(); + readHeader(); + + requestURI.decode(); + + resultCode = 400; + responseHeader = new Properties(); + responseOutputStream = new ByteArrayOutputStream(); + responseBufferedWriter = new BufferedWriter(new OutputStreamWriter(responseOutputStream)); + + } + + public boolean isResponseSent() + { + return responseSent; + } + + private void readRequest() throws IOException + { + this.requestLine = connection.getBufferedReader().readLine(); + String[] tokens = this.requestLine.split(" ",3); + requestMethod = tokens[0]; + if (tokens.length > 1) + requestURI = new HttpRequestURI(this,tokens[1]); + if (tokens.length > 2) + requestProtocol = tokens[2]; + + } + + private void readHeader() throws IOException + { + String line; + String headerName = null; + StringBuilder headerValue = new StringBuilder(); + + while (true) + { + line = connection.getBufferedReader().readLine(); + if ((line.length() == 0) || (line.charAt(0) > 32)) + { + if (headerName != null) + { + header.setProperty(headerName, headerValue.toString()); + } + if (line.length() > 0) + { + headerName = line.substring(0,line.indexOf(':')); + headerValue = new StringBuilder(); + headerValue.append(line.substring(line.indexOf(':')+1).trim()); + } else + return; + } else + { + if (headerName != null) + headerValue.append(line.trim()); + } + + + } + } + + public HttpRequestURI getRequestURI() + { + return requestURI; + } + + public String getRequestHeader(String headerName) + { + return header.getProperty(headerName); + } + + + public OutputStream getResponseOutputStream() + { + return responseOutputStream; + } + public BufferedWriter getResponseWriter() + { + return responseBufferedWriter; + } + + public void setResponseHeader(String headerName,String headerValue) + { + responseHeader.setProperty(headerName, headerValue); + } + + + public void sendResponse(int code,byte[] responseBody) throws IOException + { + this.responseBody = responseBody; + this.resultCode = code; + sendResponse(); + } + + public void sendResponse(int code) throws IOException + { + this.resultCode = code; + sendResponse(); + } + + + public void sendResponse() throws IOException + { + if (responseSent) + throw new IOException("The Response has already been sent."); + + responseSent = true; + + if (responseBody == null) + { + responseBufferedWriter.flush(); + if (responseOutputStream.size() > 0) + { + responseBody = responseOutputStream.toByteArray(); + } else + responseBody = new byte[0]; + } + + responseHeader.setProperty("Content-Length", String.format("%d", responseBody.length)); + + String protocol = "HTTP/1.0"; + if (requestProtocol != null) + protocol = requestProtocol; + + connection.getBufferedWriter().write(String.format("%s %d\r\n", protocol, resultCode)); + + Enumeration headerEnum = responseHeader.keys(); + + while (headerEnum.hasMoreElements()) + { + String headerName = (String)headerEnum.nextElement(); + connection.getBufferedWriter().write(String.format("%s: %s\r\n", headerName, responseHeader.getProperty(headerName))); + } + + connection.getBufferedWriter().write("\r\n"); + connection.getBufferedWriter().flush(); + connection.getClientSocket().getOutputStream().write(responseBody); + } + +} diff --git a/src/org/hwo/net/http/HttpServerRequestFactory.java b/src/org/hwo/net/http/HttpServerRequestFactory.java new file mode 100644 index 0000000..85579ad --- /dev/null +++ b/src/org/hwo/net/http/HttpServerRequestFactory.java @@ -0,0 +1,9 @@ +package org.hwo.net.http; + +import java.io.IOException; + +public interface HttpServerRequestFactory { + + public HttpServerRequest createRequest(HttpServerConnection connection) throws IOException; + +} diff --git a/src/org/hwo/net/http/HttpServerRequestHandler.java b/src/org/hwo/net/http/HttpServerRequestHandler.java new file mode 100644 index 0000000..ce532a4 --- /dev/null +++ b/src/org/hwo/net/http/HttpServerRequestHandler.java @@ -0,0 +1,10 @@ +package org.hwo.net.http; + +import java.io.IOException; + +public interface HttpServerRequestHandler { + + public void doRequest(HttpServerRequest httpRequest) throws IOException; + + +} diff --git a/src/org/hwo/net/requesthandler/ServerObjectHandler.java b/src/org/hwo/net/requesthandler/ServerObjectHandler.java new file mode 100644 index 0000000..820e7fc --- /dev/null +++ b/src/org/hwo/net/requesthandler/ServerObjectHandler.java @@ -0,0 +1,47 @@ +package org.hwo.net.requesthandler; + +import java.io.IOException; +import java.util.HashMap; + +import org.hwo.net.ServerObject; +import org.hwo.net.http.HttpServerRequest; +import org.hwo.net.http.HttpServerRequestHandler; +import org.hwo.net.serverobjects.ServerObjectRequest; +import org.hwo.net.serverobjects.VirtualRootObject; + +public class ServerObjectHandler implements HttpServerRequestHandler{ + + private ServerObject rootObject; + private HashMap errorObjects; + private ServerObject defaultErrorObject; + + + public ServerObjectHandler() + { + rootObject = new VirtualRootObject(); + } + + public ServerObject getRootObject() + { + return rootObject; + } + + public ServerObject getErrorObject(Integer code) + { + if (errorObjects.containsKey(code)) + return errorObjects.get(code); + return defaultErrorObject; + } + + + @Override + public void doRequest(HttpServerRequest httpRequest) throws IOException { + ServerObjectRequest sor = new ServerObjectRequest(httpRequest); + + rootObject.climb(sor); + } + + + + +} diff --git a/src/org/hwo/net/serverobjects/AbstractServerObject.java b/src/org/hwo/net/serverobjects/AbstractServerObject.java new file mode 100644 index 0000000..1359ef9 --- /dev/null +++ b/src/org/hwo/net/serverobjects/AbstractServerObject.java @@ -0,0 +1,68 @@ +package org.hwo.net.serverobjects; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; + +import org.hwo.net.ServerObject; +import org.hwo.net.http.HttpServerRequest; + +public abstract class AbstractServerObject implements ServerObject { + + private ServerObject parentObject; + HashMap mappedChildren; + + public AbstractServerObject() + { + mappedChildren = new HashMap(); + } + + + @Override + public ServerObject getRootObject() { + if (getParent() == null) + return this; + return getParent().getRootObject(); + } + + @Override + public ServerObject getParent() { + return parentObject; + } + + @Override + public ServerObject[] getChildren() { + return (new ArrayList(mappedChildren.values())).toArray(new ServerObject[0]); + } + + @Override + public void addNamedChild(String childName, ServerObject serverObject) { + mappedChildren.put(childName, serverObject); + + } + + @Override + public ServerObject getNamedChild(String childName) { + if (!mappedChildren.containsKey(childName)) + return null; + return mappedChildren.get(childName); + } + + @Override + public void climb(ServerObjectRequest request) throws IOException { + String nextChildName = request.popNextElement(); + + if (nextChildName == null) + { + request(request); + } else + { + ServerObject nextChild = getNamedChild(nextChildName); + if (nextChild == null) + throw new ServerObjectNotFoundException(request,nextChildName); + nextChild.climb(request); + } + + } + +} diff --git a/src/org/hwo/net/serverobjects/ServerObjectNotFoundException.java b/src/org/hwo/net/serverobjects/ServerObjectNotFoundException.java new file mode 100644 index 0000000..7fcf1c8 --- /dev/null +++ b/src/org/hwo/net/serverobjects/ServerObjectNotFoundException.java @@ -0,0 +1,24 @@ +package org.hwo.net.serverobjects; + +public class ServerObjectNotFoundException extends RuntimeException { + + private ServerObjectRequest objectRequest; + private String childName; + + public ServerObjectNotFoundException(ServerObjectRequest request) + { + objectRequest = request; + childName = null; + } + public ServerObjectNotFoundException(ServerObjectRequest request,String childName) + { + objectRequest = request; + this.childName = childName; + } + + public ServerObjectRequest getObjectRequest() + { + return objectRequest; + } + +} diff --git a/src/org/hwo/net/serverobjects/ServerObjectRequest.java b/src/org/hwo/net/serverobjects/ServerObjectRequest.java new file mode 100644 index 0000000..6bc5176 --- /dev/null +++ b/src/org/hwo/net/serverobjects/ServerObjectRequest.java @@ -0,0 +1,51 @@ +package org.hwo.net.serverobjects; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + +import org.hwo.net.http.HttpServerRequest; + +public class ServerObjectRequest { + + private HttpServerRequest httpRequest; + + private Stack pathToClimb; + private Stack pathClimbed; + + public ServerObjectRequest(HttpServerRequest httpRequest) + { + this.httpRequest = httpRequest; + pathToClimb = new Stack(); + pathClimbed = new Stack(); + + initialize(); + } + + private void initialize() + { + pathToClimb = new Stack(); + pathToClimb.addAll(Arrays.asList(httpRequest.getRequestURI().getPathElements())); + } + + public HttpServerRequest getHttpRequest() + { + return httpRequest; + } + + public String popNextElement() + { + if (pathToClimb.empty()) + return null; + String n = pathToClimb.pop(); + return n; + } + + public void pushLastElement(String element) + { + pathClimbed.push(element); + } + +} diff --git a/src/org/hwo/net/serverobjects/VirtualRootObject.java b/src/org/hwo/net/serverobjects/VirtualRootObject.java new file mode 100644 index 0000000..c1fa9a0 --- /dev/null +++ b/src/org/hwo/net/serverobjects/VirtualRootObject.java @@ -0,0 +1,17 @@ +package org.hwo.net.serverobjects; + +import java.io.IOException; + +import org.hwo.net.ServerObject; +import org.hwo.net.http.HttpServerRequest; + +public class VirtualRootObject extends AbstractServerObject { + + + @Override + public void request(ServerObjectRequest request) throws IOException{ + request.getHttpRequest().setResponseHeader("Content-Type", "text/plain"); + request.getHttpRequest().getResponseWriter().write("This is the virtual root of this application server."); + } + +} diff --git a/src/org/hwo/os/OsDetect.java b/src/org/hwo/os/OsDetect.java new file mode 100644 index 0000000..762510e --- /dev/null +++ b/src/org/hwo/os/OsDetect.java @@ -0,0 +1,19 @@ +package org.hwo.os; + +public class OsDetect { + + public enum OsType { UNKNOWN, LINUX, OSX, WINDOWS}; + + public static OsType getOperatingSystem() + { + if (System.getProperty("os.name").equals("Mac OS X")) + return OsType.OSX; + if (System.getProperty("os.name").equals("Linux")) + return OsType.LINUX; + if (System.getProperty("os.name").startsWith("Windows")) + return OsType.WINDOWS; + + return OsType.UNKNOWN; + } + +} diff --git a/src/org/hwo/proxy/AbstractInterceptor.java b/src/org/hwo/proxy/AbstractInterceptor.java new file mode 100644 index 0000000..042f66b --- /dev/null +++ b/src/org/hwo/proxy/AbstractInterceptor.java @@ -0,0 +1,20 @@ +package org.hwo.proxy; + +import java.lang.reflect.Method; + +public abstract class AbstractInterceptor implements Interceptor { + + + @Override + public abstract Object invoke(Method method, Object target, Object[] params); + + public Object invokeTarget(Method method, Object target, Object[] params) + { + try { + return method.invoke(target, params); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + +} diff --git a/src/org/hwo/proxy/Interceptor.java b/src/org/hwo/proxy/Interceptor.java new file mode 100644 index 0000000..fdf7ec5 --- /dev/null +++ b/src/org/hwo/proxy/Interceptor.java @@ -0,0 +1,10 @@ +package org.hwo.proxy; + +import java.lang.reflect.Method; + + +public interface Interceptor { + + public Object invoke(Method method,Object target,Object[] params); + +} diff --git a/src/org/hwo/proxy/ProxyTest.java b/src/org/hwo/proxy/ProxyTest.java new file mode 100644 index 0000000..9fba90d --- /dev/null +++ b/src/org/hwo/proxy/ProxyTest.java @@ -0,0 +1,27 @@ +package org.hwo.proxy; + +import java.lang.reflect.Method; + +import org.hwo.buffer.BitStream; +import org.hwo.fifo.FiFo; + +public class ProxyTest { + + public static void main(String[] args) { + + Interceptor mi = new AbstractInterceptor() { + + @Override + public Object invoke(Method method, Object target, Object[] params) { + System.err.println("INVOKE: " + method.getName()); + return invokeTarget(method, target, params); + } + }; + + + + + } + + +} diff --git a/src/org/hwo/proxy/ProxyWrapper.java b/src/org/hwo/proxy/ProxyWrapper.java new file mode 100644 index 0000000..f259131 --- /dev/null +++ b/src/org/hwo/proxy/ProxyWrapper.java @@ -0,0 +1,31 @@ +package org.hwo.proxy; + +import java.lang.reflect.Method; + +import net.sf.cglib.proxy.Enhancer; +import net.sf.cglib.proxy.MethodInterceptor; +import net.sf.cglib.proxy.MethodProxy; + +public class ProxyWrapper { + + public ProxyWrapper() + { + } + + public U proxyForObject(Class clazz,U object) + { + Enhancer e = new Enhancer(); + e.setSuperclass(clazz); + e.setCallback(new MethodInterceptor() { + @Override + public Object intercept(Object proxy, Method method, Object[] args, + MethodProxy methodProxy) throws Throwable { + return null; + } + }); + return clazz.cast(e.create()); + } + + + +} diff --git a/src/org/hwo/tasklet/Tasklet.java b/src/org/hwo/tasklet/Tasklet.java new file mode 100644 index 0000000..a493e40 --- /dev/null +++ b/src/org/hwo/tasklet/Tasklet.java @@ -0,0 +1,7 @@ +package org.hwo.tasklet; + +public interface Tasklet { + + public void run(Object arg); + +} diff --git a/src/org/hwo/tasklet/TaskletThread.java b/src/org/hwo/tasklet/TaskletThread.java new file mode 100644 index 0000000..2861c63 --- /dev/null +++ b/src/org/hwo/tasklet/TaskletThread.java @@ -0,0 +1,70 @@ +package org.hwo.tasklet; + +import java.util.LinkedList; +import java.util.List; +import java.util.Stack; + +import org.hwo.fifo.FiFo; + +public class TaskletThread extends Thread { + + private class QueuedTasklet + { + private Tasklet tasklet; + private Object argument; + + public QueuedTasklet(Tasklet tasklet,Object argument) + { + this.tasklet = tasklet; + this.argument = argument; + } + } + + private FiFo queuedTasklets = new FiFo(); + + public TaskletThread() { + start(); + } + + public void queue(Tasklet tasklet,Object arg) + { + synchronized (queuedTasklets) { + queuedTasklets.push(new QueuedTasklet(tasklet,arg)); + } + queuedTasklets.notify(); + } + + @Override + public void run() { + while (true) + { + QueuedTasklet queuedTasklet = null; + + synchronized (queuedTasklets) { + try { + queuedTasklets.wait(100); + queuedTasklet = queuedTasklets.pull(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + if (queuedTasklet != null) + { + try + { + queuedTasklet.tasklet.run(queuedTasklet.argument); + } catch (Exception ex) + { + System.err.println("Tasklet throwed Exception: " + ex.toString()); + ex.printStackTrace(); + } + } + + if (isInterrupted()) + return; + } + } + + +} diff --git a/src/org/hwo/test/BitStreamTest.java b/src/org/hwo/test/BitStreamTest.java new file mode 100644 index 0000000..2b336ab --- /dev/null +++ b/src/org/hwo/test/BitStreamTest.java @@ -0,0 +1,17 @@ +package org.hwo.test; + +import org.hwo.buffer.BitStream; + +public class BitStreamTest { + + public static void main(String[] args) { + + BitStream bs = new BitStream(new byte[]{ 0x55,0x55,0x55,0x55 }); + + for (int i=0;i<6;i++) + System.err.println(String.format("Pattern: 0x%x",bs.read((byte)i))); + + + } + +} diff --git a/src/org/hwo/thread/ThreadedOperation.java b/src/org/hwo/thread/ThreadedOperation.java new file mode 100644 index 0000000..01ffbde --- /dev/null +++ b/src/org/hwo/thread/ThreadedOperation.java @@ -0,0 +1,70 @@ +package org.hwo.thread; + +import java.util.ArrayList; +import java.util.EventListener; +import java.util.List; + +public abstract class ThreadedOperation extends Thread{ + + List updateListeners; + private String operationName; + + + public ThreadedOperation() + { + updateListeners = new ArrayList(); + operationName = "AktivitŠt..."; + } + + public void addThreadedOperationUpdateListener(ThreadedOperationUpdateListener listener) + { + updateListeners.add(listener); + } + public void removeThreadedOperationUpdateListener(ThreadedOperationUpdateListener listener) + { + updateListeners.remove(listener); + } + + protected void fireUpdate(ThreadedOperationUpdateArgs updateArgs) + { + for (ThreadedOperationUpdateListener listener:updateListeners) + listener.threadedOperationUpdate(updateArgs); + } + protected void fireUpdate(Integer progressOperation,Integer progressStep) + { + fireUpdate(new ThreadedOperationUpdateArgs(progressOperation,progressStep)); + } + + protected void fireUpdate(Integer progressOperation,Integer progressStep,String statusText) + { + fireUpdate(new ThreadedOperationUpdateArgs(progressOperation,progressStep,statusText)); + } + + protected void fireUpdate(Integer progressOperation,Integer progressStep,String statusText,String stepLabel) + { + fireUpdate(new ThreadedOperationUpdateArgs(progressOperation,progressStep,statusText,stepLabel)); + } + + protected void fireFinished(int code) + { + for (ThreadedOperationUpdateListener listener:updateListeners) + listener.threadedOperationFinished(code); + } + protected void fireFinished() + { + fireFinished(0); + } + + public abstract void run(); + + public String getOperationName() { + return operationName; + } + + public void setOperationName(String operationName) { + this.operationName = operationName; + } + + + +} diff --git a/src/org/hwo/thread/ThreadedOperationUpdateArgs.java b/src/org/hwo/thread/ThreadedOperationUpdateArgs.java new file mode 100644 index 0000000..8c946f1 --- /dev/null +++ b/src/org/hwo/thread/ThreadedOperationUpdateArgs.java @@ -0,0 +1,77 @@ +package org.hwo.thread; + +public class ThreadedOperationUpdateArgs { + + private Integer progressOperation; + private Integer progressStep; + private String stepLabel; + private String statusText; + private String titleText; + + public ThreadedOperationUpdateArgs() + { + } + public ThreadedOperationUpdateArgs(Integer progressStep) + { + this.progressStep = progressStep; + } + public ThreadedOperationUpdateArgs(Integer progressOperation,Integer progressStep) + { + this.progressOperation = progressOperation; + this.progressStep = progressStep; + } + public ThreadedOperationUpdateArgs(Integer progressOperation,Integer progressStep,String statusText) + { + this.progressOperation = progressOperation; + this.progressStep = progressStep; + this.statusText = statusText; + } + public ThreadedOperationUpdateArgs(Integer progressOperation,Integer progressStep,String statusText,String stepLabel) + { + this.progressOperation = progressOperation; + this.progressStep = progressStep; + this.statusText = statusText; + this.stepLabel = stepLabel; + } + + public String getStepLabel() { + return stepLabel; + } + + public void setStepLabel(String stepLabel) { + this.stepLabel = stepLabel; + } + + public Integer getProgressStep() { + return progressStep; + } + + public void setProgressStep(Integer progressStep) { + this.progressStep = progressStep; + } + + public Integer getProgressOperation() { + return progressOperation; + } + + public void setProgressOperation(Integer progressOperation) { + this.progressOperation = progressOperation; + } + + public String getStatusText() { + return statusText; + } + + public void setStatusText(String statusText) { + this.statusText = statusText; + } + + public String getTitleText() { + return titleText; + } + + public void setTitleText(String titleText) { + this.titleText = titleText; + } + +} diff --git a/src/org/hwo/thread/ThreadedOperationUpdateListener.java b/src/org/hwo/thread/ThreadedOperationUpdateListener.java new file mode 100644 index 0000000..ff3225b --- /dev/null +++ b/src/org/hwo/thread/ThreadedOperationUpdateListener.java @@ -0,0 +1,6 @@ +package org.hwo.thread; + +public interface ThreadedOperationUpdateListener { + public void threadedOperationUpdate(ThreadedOperationUpdateArgs args); + public void threadedOperationFinished(int result); +} diff --git a/src/org/hwo/ui/CellEditor.java b/src/org/hwo/ui/CellEditor.java new file mode 100644 index 0000000..b3d5329 --- /dev/null +++ b/src/org/hwo/ui/CellEditor.java @@ -0,0 +1,16 @@ +package org.hwo.ui; + +import java.awt.Rectangle; + +import org.hwo.ui.treetable.TreeTable; + +public interface CellEditor { + + public void addCellEditorListener(CellEditorListener listener); + public void removeCellEditorListener(CellEditorListener listener); + + public boolean editBegin(TreeTable treeTable,Rectangle rect,Object value); + public void editCancel(); + public void editFinish(); + +} diff --git a/src/org/hwo/ui/CellEditorArgs.java b/src/org/hwo/ui/CellEditorArgs.java new file mode 100644 index 0000000..96a9f70 --- /dev/null +++ b/src/org/hwo/ui/CellEditorArgs.java @@ -0,0 +1,40 @@ +package org.hwo.ui; + +import org.hwo.ui.treetable.TreeTable; + +public class CellEditorArgs { + + private CellEditor cellEditor; + private Object value; + private TreeTable treeTable; + + public CellEditorArgs(CellEditor cellEditor,Object value,TreeTable treeTable) + { + this.cellEditor = cellEditor; + this.value = value; + this.treeTable = treeTable; + } + + public CellEditor getCellEditor() { + return cellEditor; + } + public void setCellEditor(CellEditor cellEditor) { + this.cellEditor = cellEditor; + } + public Object getValue() { + return value; + } + public void setValue(Object value) { + this.value = value; + } + public TreeTable getTreeTable() { + return treeTable; + } + public void setTreeTable(TreeTable treeTable) { + this.treeTable = treeTable; + } + + + + +} diff --git a/src/org/hwo/ui/CellEditorListener.java b/src/org/hwo/ui/CellEditorListener.java new file mode 100644 index 0000000..e7e230b --- /dev/null +++ b/src/org/hwo/ui/CellEditorListener.java @@ -0,0 +1,9 @@ +package org.hwo.ui; + +public interface CellEditorListener { + + public void editBegin(CellEditorArgs args); + public void editCanceled(CellEditorArgs args); + public void editFinished(CellEditorArgs args); + +} diff --git a/src/org/hwo/ui/CellRenderer.java b/src/org/hwo/ui/CellRenderer.java new file mode 100644 index 0000000..9f2bd38 --- /dev/null +++ b/src/org/hwo/ui/CellRenderer.java @@ -0,0 +1,11 @@ +package org.hwo.ui; + +import java.awt.Graphics; +import java.awt.Rectangle; + +public interface CellRenderer { + + public void renderCell(Graphics g,int row,int column,Rectangle cellRect,Object value,Object rowObject); + + +} diff --git a/src/org/hwo/ui/DefaultCellEditor.java b/src/org/hwo/ui/DefaultCellEditor.java new file mode 100644 index 0000000..90bb186 --- /dev/null +++ b/src/org/hwo/ui/DefaultCellEditor.java @@ -0,0 +1,108 @@ +package org.hwo.ui; + +import java.awt.Container; +import java.awt.Rectangle; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JTextField; + +import org.hwo.ui.treetable.TreeTable; + +public class DefaultCellEditor implements CellEditor { + + private List editorListeners; + + private JTextField textField; + private TreeTable treeTable; + private Object value; + + public DefaultCellEditor() + { + editorListeners = new LinkedList(); + } + + @Override + public void addCellEditorListener(CellEditorListener listener) { + editorListeners.add(listener); + } + + @Override + public void removeCellEditorListener(CellEditorListener listener) { + editorListeners.remove(listener); + } + + private void fireEditBegin() + { + CellEditorArgs args = new CellEditorArgs(this, value, treeTable); + for (CellEditorListener listener: editorListeners) + listener.editBegin(args); + } + private void fireEditFinish() + { + CellEditorArgs args = new CellEditorArgs(this, value, treeTable); + for (CellEditorListener listener: editorListeners) + listener.editFinished(args); + } + private void fireEditCancel() + { + CellEditorArgs args = new CellEditorArgs(this, value, treeTable); + for (CellEditorListener listener: editorListeners) + listener.editCanceled(args); + } + + private void destroyTextField() + { + textField.setVisible(false); + Container parent = textField.getParent(); + + parent.remove(textField); + + textField = null; + } + + @Override + public boolean editBegin(TreeTable treeTable, Rectangle rect, Object value) { + if (textField != null) + editCancel(); + + this.treeTable = treeTable; + this.value = value; + + this.textField = new JTextField(); + treeTable.add(textField); + + textField.setBounds(rect); + textField.requestFocusInWindow(); + textField.repaint(); + + fireEditBegin(); + + return true; + } + + @Override + public void editCancel() { + if (textField != null) + { + destroyTextField(); + + fireEditCancel(); + } + + } + + @Override + public void editFinish() { + if (this.textField != null) + { + this.value = this.textField.getText(); + destroyTextField(); + + fireEditFinish(); + } + } + + + +} diff --git a/src/org/hwo/ui/DefaultCellRenderer.java b/src/org/hwo/ui/DefaultCellRenderer.java new file mode 100644 index 0000000..4818ed4 --- /dev/null +++ b/src/org/hwo/ui/DefaultCellRenderer.java @@ -0,0 +1,23 @@ +package org.hwo.ui; + +import java.awt.Graphics; +import java.awt.Rectangle; + +public class DefaultCellRenderer implements CellRenderer{ + + @Override + public void renderCell(Graphics g,int row,int column, Rectangle cellRect, Object value,Object rowObject) + { + if (value != null) + { + g.drawString( value.toString(), + cellRect.x + 2, + cellRect.y + cellRect.height - 4 + ); + }; + + } + + + +} diff --git a/src/org/hwo/ui/FlexibleJTable.java b/src/org/hwo/ui/FlexibleJTable.java new file mode 100644 index 0000000..aa87b83 --- /dev/null +++ b/src/org/hwo/ui/FlexibleJTable.java @@ -0,0 +1,66 @@ +package org.hwo.ui; + +import java.util.List; + +import javax.swing.JTable; +import javax.swing.event.ListSelectionListener; + +import org.hwo.models.FlexibleObjectTableModel; + +public class FlexibleJTable extends JTable { + private FlexibleObjectTableModel model; + + public FlexibleJTable(Class class_t) + { + this.model = new FlexibleObjectTableModel(class_t); + this.setModel(this.model); + } + + public FlexibleObjectTableModel getModel() + { + return this.model; + } + + public T getSelectedObject() + { + if (this.getSelectedRow()==-1) + return null; + return this.model.getRows().get(this.getSelectedRow()); + } + + public void addListSelectionListener(ListSelectionListener listener) + { + this.getSelectionModel().addListSelectionListener(listener); + } + + public void removeListSelectionListener(ListSelectionListener listener) + { + this.getSelectionModel().removeListSelectionListener(listener); + } + + public void addColumn(String column) + { + this.addColumn(column, true); + } + + public void addColumn(String column,boolean readonly) + { + this.model.addColumn(column,readonly); + } + + public void setRows(List rows) + { + this.model.setRows(rows); + } + + public void addRow(T o) + { + this.model.addRow(o); + } + + public int getRowCount() + { + return this.model.getRowCount(); + } + +} diff --git a/src/org/hwo/ui/InteractiveObjectListView.java b/src/org/hwo/ui/InteractiveObjectListView.java new file mode 100644 index 0000000..2644f47 --- /dev/null +++ b/src/org/hwo/ui/InteractiveObjectListView.java @@ -0,0 +1,75 @@ +package org.hwo.ui; + +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.List; + +import javax.swing.DefaultListModel; +import javax.swing.JList; + +import org.hwo.interactiveobjects.IInteractiveObjectEditor; +import org.hwo.interactiveobjects.InteractiveObjectHelper; + +public class InteractiveObjectListView extends JList { + + DefaultListModel pModel; + + public InteractiveObjectListView() + { + this.addMouseListener(new MouseListener() { + + @Override + public void mouseReleased(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mousePressed(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseExited(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent arg0) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseClicked(MouseEvent arg0) { + if (arg0.getClickCount()==2) + openEditor(); + } + }); + pModel = new DefaultListModel(); + setModel(pModel); + } + + private void openEditor() + { + if (getSelectedIndex() != -1) + { + IInteractiveObjectEditor oe = InteractiveObjectHelper.getEditor(getSelectedValue()); + if (oe != null) + oe.setVisible(true); + + } + } + + public void setItems(List items) + { + pModel.clear(); + for (Object o:items) + { + pModel.addElement(o); + } + } + +} diff --git a/src/org/hwo/ui/JCalendar.java b/src/org/hwo/ui/JCalendar.java new file mode 100644 index 0000000..b558887 --- /dev/null +++ b/src/org/hwo/ui/JCalendar.java @@ -0,0 +1,93 @@ +package org.hwo.ui; + +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JButton; + +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; +import java.awt.Insets; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.util.Date; +import java.awt.Dimension; + +public class JCalendar extends JPanel { + private JTextField tfDate; + + private Date date; + private JButton btnLookup; + private boolean nullable; + + public JCalendar() { + setMaximumSize(new Dimension(32767, 30)); + GridBagLayout gridBagLayout = new GridBagLayout(); + gridBagLayout.columnWidths = new int[]{100, 134, 0}; + gridBagLayout.rowHeights = new int[]{29, 0}; + gridBagLayout.columnWeights = new double[]{1.0, 0.0, Double.MIN_VALUE}; + gridBagLayout.rowWeights = new double[]{1.0, Double.MIN_VALUE}; + setLayout(gridBagLayout); + + tfDate = new JTextField(); + GridBagConstraints gbc_tfDate = new GridBagConstraints(); + gbc_tfDate.fill = GridBagConstraints.BOTH; + gbc_tfDate.insets = new Insets(0, 0, 0, 5); + gbc_tfDate.gridx = 0; + gbc_tfDate.gridy = 0; + add(tfDate, gbc_tfDate); + tfDate.setColumns(10); + + btnLookup = new JButton("X"); + btnLookup.setMaximumSize(new Dimension(25, 29)); + btnLookup.setPreferredSize(new Dimension(25, 29)); + btnLookup.setMinimumSize(new Dimension(25, 29)); + GridBagConstraints gbc_btnLookup = new GridBagConstraints(); + gbc_btnLookup.fill = GridBagConstraints.BOTH; + gbc_btnLookup.gridx = 1; + gbc_btnLookup.gridy = 0; + add(btnLookup, gbc_btnLookup); + } + + private void updateView() + { + tfDate.setEnabled(false); + + if (date != null) + { + btnLookup.setEnabled(false); + tfDate.setText( SimpleDateFormat.getInstance().format(date)); + } else + { + btnLookup.setEnabled(false); + tfDate.setText(""); + } + } + + + public Date getDate() { + return date; + } + + public void setDate(Date date) { + this.date = date; + updateView(); + } + + public void setValue(Object value) + { + setDate((Date)value); + } + public Object getValue() + { + return this.getDate(); + } + + public boolean isNullable() { + return nullable; + } + + public void setNullable(boolean nullable) { + this.nullable = nullable; + } + +} diff --git a/src/org/hwo/ui/JComboBoxEx.java b/src/org/hwo/ui/JComboBoxEx.java new file mode 100644 index 0000000..e715c75 --- /dev/null +++ b/src/org/hwo/ui/JComboBoxEx.java @@ -0,0 +1,19 @@ +package org.hwo.ui; + +import javax.swing.JComboBox; + +public class JComboBoxEx extends JComboBox { + + + public void selectEqualItem(Object o) + { + for (int i=0;i= 0) + { + return checkBoxes[no].isSelected(); + } + return false; + } + + public void selectOption(String option) + { + int no = getOptionIndex(option); + if (no >= 0) + { + checkBoxes[no].setSelected(true); + } + } + + public void unselectOption(String option) + { + int no = getOptionIndex(option); + if (no >= 0) + { + checkBoxes[no].setSelected(false); + } + } + + public String[] getSelectedOptions() + { + ArrayList ol = new ArrayList(); + for (int n=0; n < options.length; n++) + { + if (checkBoxes[n].isSelected()) + ol.add(options[n]); + } + return ol.toArray(new String[0]); + } + public void setSelectedOptions(String[] selectedOptions) + { + this.selectedOptions = selectedOptions; + + for (int n=0; n < options.length; n++) + checkBoxes[n].setSelected(false); + + for (String option:selectedOptions) + selectOption(option); + + } + + + +} diff --git a/src/org/hwo/ui/JSearchTextField.java b/src/org/hwo/ui/JSearchTextField.java new file mode 100644 index 0000000..d32f280 --- /dev/null +++ b/src/org/hwo/ui/JSearchTextField.java @@ -0,0 +1,323 @@ +package org.hwo.ui; + +import java.awt.Dimension; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.FocusEvent; +import java.awt.event.FocusListener; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPopupMenu; +import javax.swing.JScrollPane; +import javax.swing.JTable; +import javax.swing.JTextField; +import javax.swing.KeyStroke; +import javax.swing.SingleSelectionModel; +import javax.swing.Timer; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import org.hwo.datetime.JTimeOfDay; +import org.hwo.models.TableMapper.TableMapper; +import org.hwo.ui.wellknown.WellKnown; +import org.hwo.ui.wellknown.WellKnownClass; +import org.hwo.ui.wellknown.WellKnownSearch; + +public class JSearchTextField extends JTextField implements FocusListener { + + private Class searchClazz; + private JTable tResults; + private TableMapper tmResults; + + private JPopupMenu popupList; + + private Timer searchTimer; + + private WellKnownClass wellKnownClass; + private WellKnownSearch wellKnownSearch; + + private Object selectedObject; + + private List actionListeners; + + public JSearchTextField() + { + actionListeners = new LinkedList(); + + setPreferredSize(new Dimension(120, 24)); + + searchClazz = null; + + popupList = new JPopupMenu(); + popupList.setFocusable(false); + + JScrollPane scrollPane = new JScrollPane(); + tResults = new JTable(); + + tResults.setCellSelectionEnabled(false); + tResults.setColumnSelectionAllowed(false); + tResults.setRowSelectionAllowed(true); + + scrollPane.setViewportView(tResults); + popupList.add(scrollPane); + + addFocusListener(this); + + getDocument().addDocumentListener(new DocumentListener() { + + @Override + public void removeUpdate(DocumentEvent arg0) { + } + + @Override + public void insertUpdate(DocumentEvent arg0) { + searchTimer.stop(); + searchTimer.start(); + showPopup(); + } + + @Override + public void changedUpdate(DocumentEvent arg0) { + //showPopup(); + } + }); + + KeyStrokeHelper helper = new KeyStrokeHelper(this); + helper.registerKeyStrokeListener(new KeyStrokeListener() { + + @Override + public void keyStroke(KeyStrokeParameters parameters) { + switch (parameters.getKeyCode()) + { + case KeyEvent.VK_ESCAPE: + popupList.setVisible(false); + break; + case KeyEvent.VK_UP: + selectionUp(); + break; + case KeyEvent.VK_DOWN: + selectionDown(); + break; + case KeyEvent.VK_ENTER: + selectObject(); + break; + } + + } + }); + helper.addKeyCode(KeyEvent.VK_ESCAPE) + .addKeyCode(KeyEvent.VK_UP) + .addKeyCode(KeyEvent.VK_DOWN) + .addKeyCode(KeyEvent.VK_ENTER); + + + searchTimer = new Timer(250, new ActionListener() { + + @Override + public void actionPerformed(ActionEvent arg0) { + search(); + } + }); + searchTimer.setRepeats(false); + + + } + + @Override + public synchronized void addActionListener(ActionListener l) { + actionListeners.add(l); + } + + @Override + public synchronized void removeActionListener(ActionListener l) { + actionListeners.remove(l); + } + + protected void fireNewActionPerformed() + { + for (ActionListener l:actionListeners) + l.actionPerformed(new ActionEvent(this, 0, "")); + } + + private void selectObject() + { + if (!popupList.isVisible()) + return; + + Object o = tmResults.getSelectedRow(); + if (o != null) + { + setSelectedObject(o); + fireNewActionPerformed(); + transferFocus(); + } + + } + + private void search() + { + System.err.println("searching..."); + if (wellKnownSearch != null) + { + List l = wellKnownSearch.keywordSearch(searchClazz, getText()); + tmResults.setRows(l); + } + } + + private void selectionDown() + { + if (!popupList.isVisible()) + showPopup(); + + if (tResults.getSelectedRow()!=-1) + { + if (tResults.getSelectedRow() < tmResults.getRowCount() - 1) + { + tResults.setRowSelectionInterval(tResults.getSelectedRow() + 1,tResults.getSelectedRow() + 1); + System.err.println("down"); + } + } else + { + System.err.println("Select first"); + tResults.setRowSelectionInterval(0, 0); + } + + selectedObject = null; + + } + + private void selectionUp() + { + if (!popupList.isVisible()) + return; + + if (tResults.getSelectedRow()!=-1) + { + if (tResults.getSelectedRow() > 0) + { + tResults.setRowSelectionInterval(tResults.getSelectedRow()-1,tResults.getSelectedRow()-1); + System.err.println("up"); + } + } else + { + System.err.println("Select last"); + tResults.setRowSelectionInterval(tmResults.getRowCount() - 1, tmResults.getRowCount() - 1); + } + + selectedObject = null; + + } + + private void showPopup() + { + if (searchClazz == null) + return; + + if (!popupList.isVisible()) + { + popupList.show(this, 0, getHeight()); + popupList.setVisible(true); + grabFocus(); + } + } + + + @Override + public void focusGained(FocusEvent arg0) { + if (selectedObject != null) + selectAll(); + + } + + + + @Override + public void focusLost(FocusEvent arg0) { + if (popupList.isVisible()) + popupList.setVisible(false); + + } + + public Class getSearchClazz() { + return searchClazz; + } + + public void setSearchClazz(Class searchClazz) { + this.searchClazz = searchClazz; + + tmResults = new TableMapper(searchClazz, tResults); + tmResults.setReadOnly(true); + tmResults.setEditorEnabled(false); + + tResults.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if ((e.getButton() == MouseEvent.BUTTON1) && (e.getClickCount() == 2)) + { + Object so = tmResults.getSelectedRow(); + if (so != null) + { + setSelectedObject(so); + fireNewActionPerformed(); + } + } + } + }); + + wellKnownClass = WellKnown.getWellKnownClass(searchClazz); + if (wellKnownClass != null) + { + if (wellKnownClass.search() != null) + { + Class clazz = wellKnownClass.search(); + try { + wellKnownSearch = clazz.newInstance(); + wellKnownSearch.setClazz(searchClazz); + } catch (InstantiationException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } + } + } + + } + + public void setMaxPopupHeight(int maxPopupHeight) + { + Dimension dim = popupList.getMaximumSize(); + dim.height = maxPopupHeight; + popupList.setMaximumSize(dim); + } + public int getMaxPopupHeight() + { + return (int)popupList.getMaximumSize().getHeight(); + } + + public Object getSelectedObject() { + return selectedObject; + } + + public void setSelectedObject(Object selectedObject) { + this.selectedObject = selectedObject; + + if (selectedObject == null) + { + setText(""); + } else + { + setText(WellKnown.getDisplayLabel(selectedObject)); + } + + popupList.setVisible(false); + } + + + +} diff --git a/src/org/hwo/ui/KeyStrokeHelper.java b/src/org/hwo/ui/KeyStrokeHelper.java new file mode 100644 index 0000000..a3b7a90 --- /dev/null +++ b/src/org/hwo/ui/KeyStrokeHelper.java @@ -0,0 +1,82 @@ +package org.hwo.ui; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.util.ArrayList; + +import javax.swing.JComponent; +import javax.swing.JFrame; +import javax.swing.KeyStroke; + +public class KeyStrokeHelper { + + private class KeyStrokeActionListener implements ActionListener + { + int keycode; + + public KeyStrokeActionListener(int keycode) + { + this.keycode = keycode; + } + + @Override + public void actionPerformed(ActionEvent e) { + fireKeyStroke(keycode); + } + + } + + ArrayList keystrokeListeners; + JComponent component; + JFrame frame; + boolean focusedWindow; + + public KeyStrokeHelper(JComponent component) + { + keystrokeListeners = new ArrayList(); + this.component = component; + focusedWindow = false; + } + + public KeyStrokeHelper(JFrame frame) + { + keystrokeListeners = new ArrayList(); + this.frame = frame; + this.focusedWindow = true; + } + + public KeyStrokeHelper addKeyCode(int keyCode) + { + if (focusedWindow) + frame.getRootPane().registerKeyboardAction(new KeyStrokeActionListener(keyCode), KeyStroke.getKeyStroke(keyCode, 0), JComponent.WHEN_IN_FOCUSED_WINDOW ); + else + component.registerKeyboardAction(new KeyStrokeActionListener(keyCode), KeyStroke.getKeyStroke(keyCode, 0), JComponent.WHEN_FOCUSED); + return this; + } + + public void removeKey(int keyCode) + { + if (focusedWindow) + frame.getRootPane().unregisterKeyboardAction(KeyStroke.getKeyStroke(keyCode, 0)); + else + component.unregisterKeyboardAction(KeyStroke.getKeyStroke(keyCode, 0)); + } + + public void registerKeyStrokeListener(KeyStrokeListener listener) + { + keystrokeListeners.add(listener); + } + + public void removeKeyStrokeListener(KeyStrokeListener listener) + { + keystrokeListeners.remove(listener); + } + + + private void fireKeyStroke(int keyCode) + { + for (KeyStrokeListener listener:keystrokeListeners) + listener.keyStroke(new KeyStrokeParameters(keyCode)); + } + +} diff --git a/src/org/hwo/ui/KeyStrokeListener.java b/src/org/hwo/ui/KeyStrokeListener.java new file mode 100644 index 0000000..7ae211f --- /dev/null +++ b/src/org/hwo/ui/KeyStrokeListener.java @@ -0,0 +1,6 @@ +package org.hwo.ui; + +public abstract class KeyStrokeListener { + + public abstract void keyStroke(KeyStrokeParameters parameters); +} diff --git a/src/org/hwo/ui/KeyStrokeParameters.java b/src/org/hwo/ui/KeyStrokeParameters.java new file mode 100644 index 0000000..4a90557 --- /dev/null +++ b/src/org/hwo/ui/KeyStrokeParameters.java @@ -0,0 +1,22 @@ +package org.hwo.ui; + +public class KeyStrokeParameters { + + private int keyCode; + + public KeyStrokeParameters(int keyCode) + { + this.keyCode = keyCode; + } + + public int getKeyCode() { + return keyCode; + } + + public void setKeyCode(int keyCode) { + this.keyCode = keyCode; + } + + + +} diff --git a/src/org/hwo/ui/MousePopupListener.java b/src/org/hwo/ui/MousePopupListener.java new file mode 100644 index 0000000..6c1ee6c --- /dev/null +++ b/src/org/hwo/ui/MousePopupListener.java @@ -0,0 +1,29 @@ +package org.hwo.ui; + +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +public abstract class MousePopupListener extends MouseAdapter { + + public void mouseClicked(MouseEvent arg0) { + checkPopup(arg0); + } + @Override + public void mousePressed(MouseEvent arg0) { + checkPopup(arg0); + } + @Override + public void mouseReleased(MouseEvent arg0) { + checkPopup(arg0); + } + + public void checkPopup(MouseEvent e) + { + if (e.isPopupTrigger()) + popupTriggered(e.getX(),e.getY()); + } + + public abstract void popupTriggered(int x,int y); + + +} diff --git a/src/org/hwo/ui/ProgressDialog.java b/src/org/hwo/ui/ProgressDialog.java new file mode 100644 index 0000000..40a728b --- /dev/null +++ b/src/org/hwo/ui/ProgressDialog.java @@ -0,0 +1,183 @@ +package org.hwo.ui; + +import java.awt.BorderLayout; +import java.awt.FlowLayout; + +import javax.swing.JButton; +import javax.swing.JDialog; +import javax.swing.JPanel; +import javax.swing.border.EmptyBorder; + +import java.awt.GridBagLayout; + +import javax.swing.JLabel; + +import java.awt.GridBagConstraints; +import java.awt.Insets; +import java.awt.Font; + +import javax.swing.JProgressBar; +import javax.swing.border.TitledBorder; +import javax.swing.JTextArea; + +import org.hwo.thread.ThreadedOperation; +import org.hwo.thread.ThreadedOperationUpdateArgs; +import org.hwo.thread.ThreadedOperationUpdateListener; + +import java.awt.Dialog.ModalExclusionType; +import java.awt.Dialog.ModalityType; +import java.awt.event.WindowAdapter; +import java.awt.event.WindowEvent; + +public class ProgressDialog extends JDialog implements ThreadedOperationUpdateListener{ + + private final JPanel contentPanel = new JPanel(); + private JProgressBar pSchritt; + private JProgressBar pGesamt; + private JTextArea taStatus; + private JLabel lblSchritt; + + private int operationResult; + private boolean operationFinished; + + + public static int executeOperation(ThreadedOperation operation) + { + ProgressDialog dialog = new ProgressDialog(); + operation.addThreadedOperationUpdateListener(dialog); + dialog.setTitle(operation.getName()); + operation.start(); + dialog.setVisible(true); + operation.removeThreadedOperationUpdateListener(dialog); + return dialog.getOperationResult(); + } + + + /** + * Create the dialog. + */ + protected ProgressDialog() { + addWindowListener(new WindowAdapter() { + @Override + public void windowClosing(WindowEvent arg0) { + if (!operationFinished) + setVisible(true); + } + @Override + public void windowOpened(WindowEvent e) { + } + }); + setModalityType(ModalityType.APPLICATION_MODAL); + setModalExclusionType(ModalExclusionType.APPLICATION_EXCLUDE); + setBounds(100, 100, 691, 270); + getContentPane().setLayout(new BorderLayout()); + contentPanel.setBorder(new EmptyBorder(5, 5, 5, 5)); + getContentPane().add(contentPanel, BorderLayout.CENTER); + GridBagLayout gbl_contentPanel = new GridBagLayout(); + gbl_contentPanel.columnWidths = new int[] {0}; + gbl_contentPanel.rowHeights = new int[]{0, 0, 0, 0, 0, 0, 0}; + gbl_contentPanel.columnWeights = new double[]{1.0}; + gbl_contentPanel.rowWeights = new double[]{0.0, 0.0, 0.0, 0.0, 0.0, 1.0, Double.MIN_VALUE}; + contentPanel.setLayout(gbl_contentPanel); + { + JLabel lblBitteWarten = new JLabel("Bitte warten..."); + lblBitteWarten.setFont(new Font("Lucida Grande", Font.PLAIN, 32)); + GridBagConstraints gbc_lblBitteWarten = new GridBagConstraints(); + gbc_lblBitteWarten.insets = new Insets(0, 0, 5, 0); + gbc_lblBitteWarten.gridx = 0; + gbc_lblBitteWarten.gridy = 0; + contentPanel.add(lblBitteWarten, gbc_lblBitteWarten); + } + { + JLabel lblGesamtfortschritt = new JLabel("Gesamtfortschritt:"); + GridBagConstraints gbc_lblGesamtfortschritt = new GridBagConstraints(); + gbc_lblGesamtfortschritt.insets = new Insets(0, 0, 5, 0); + gbc_lblGesamtfortschritt.gridx = 0; + gbc_lblGesamtfortschritt.gridy = 1; + contentPanel.add(lblGesamtfortschritt, gbc_lblGesamtfortschritt); + } + { + pGesamt = new JProgressBar(); + GridBagConstraints gbc_pGesamt = new GridBagConstraints(); + gbc_pGesamt.insets = new Insets(0, 0, 5, 0); + gbc_pGesamt.fill = GridBagConstraints.HORIZONTAL; + gbc_pGesamt.gridx = 0; + gbc_pGesamt.gridy = 2; + contentPanel.add(pGesamt, gbc_pGesamt); + } + { + lblSchritt = new JLabel("Arbeitsschritt:"); + GridBagConstraints gbc_lblSchritt = new GridBagConstraints(); + gbc_lblSchritt.insets = new Insets(0, 0, 5, 0); + gbc_lblSchritt.gridx = 0; + gbc_lblSchritt.gridy = 3; + contentPanel.add(lblSchritt, gbc_lblSchritt); + } + { + pSchritt = new JProgressBar(); + GridBagConstraints gbc_pSchritt = new GridBagConstraints(); + gbc_pSchritt.insets = new Insets(0, 0, 5, 0); + gbc_pSchritt.fill = GridBagConstraints.HORIZONTAL; + gbc_pSchritt.gridx = 0; + gbc_pSchritt.gridy = 4; + contentPanel.add(pSchritt, gbc_pSchritt); + } + { + JPanel panel = new JPanel(); + panel.setBorder(new TitledBorder(null, "Status", TitledBorder.LEADING, TitledBorder.TOP, null, null)); + GridBagConstraints gbc_panel = new GridBagConstraints(); + gbc_panel.fill = GridBagConstraints.BOTH; + gbc_panel.gridx = 0; + gbc_panel.gridy = 5; + contentPanel.add(panel, gbc_panel); + GridBagLayout gbl_panel = new GridBagLayout(); + gbl_panel.columnWidths = new int[]{0, 0}; + gbl_panel.rowHeights = new int[]{0, 0}; + gbl_panel.columnWeights = new double[]{1.0, Double.MIN_VALUE}; + gbl_panel.rowWeights = new double[]{1.0, Double.MIN_VALUE}; + panel.setLayout(gbl_panel); + { + taStatus = new JTextArea(); + GridBagConstraints gbc_taStatus = new GridBagConstraints(); + gbc_taStatus.fill = GridBagConstraints.BOTH; + gbc_taStatus.gridx = 0; + gbc_taStatus.gridy = 0; + panel.add(taStatus, gbc_taStatus); + } + } + } + + + public int getOperationResult() { + return operationResult; + } + + + public void setOperationResult(int operationResult) { + this.operationResult = operationResult; + } + + + @Override + public void threadedOperationUpdate(ThreadedOperationUpdateArgs args) { + if (args.getProgressOperation()!=null) + pGesamt.setValue(args.getProgressOperation()); + if (args.getProgressStep()!=null) + pSchritt.setValue(args.getProgressStep()); + if (args.getStepLabel()!=null) + lblSchritt.setText(args.getStepLabel()); + if (args.getStatusText()!=null) + taStatus.setText(args.getStatusText()); + if (args.getTitleText()!=null) + setTitle(args.getTitleText()); + } + + + @Override + public void threadedOperationFinished(int result) { + operationResult = result; + operationFinished = true; + setVisible(false); + } + +} diff --git a/src/org/hwo/ui/SelectionMode.java b/src/org/hwo/ui/SelectionMode.java new file mode 100644 index 0000000..98ad7ec --- /dev/null +++ b/src/org/hwo/ui/SelectionMode.java @@ -0,0 +1,8 @@ +package org.hwo.ui; + +public enum SelectionMode { + NONE, + CELL, + ROW, + COLUMN +} diff --git a/src/org/hwo/ui/shapes/Rectangle.java b/src/org/hwo/ui/shapes/Rectangle.java new file mode 100644 index 0000000..23fa86a --- /dev/null +++ b/src/org/hwo/ui/shapes/Rectangle.java @@ -0,0 +1,13 @@ +package org.hwo.ui.shapes; + +import java.awt.Polygon; + +public class Rectangle extends Polygon { + + public Rectangle(int left,int top,int width,int height) + { + super(new int[]{left,left + width - 1,left + width - 1,left},new int[]{ top,top,top + height - 1,top + height - 1 },4); + } + + +} diff --git a/src/org/hwo/ui/shapes/Triangle.java b/src/org/hwo/ui/shapes/Triangle.java new file mode 100644 index 0000000..af9bb15 --- /dev/null +++ b/src/org/hwo/ui/shapes/Triangle.java @@ -0,0 +1,12 @@ +package org.hwo.ui.shapes; + +import java.awt.Polygon; + +public class Triangle extends Polygon { + + public Triangle(int x1,int y1,int x2,int y2,int x3,int y3) + { + super(new int[]{x1,x2,x3},new int[]{y1,y2,y3},3); + } + +} diff --git a/src/org/hwo/ui/treetable/DefaultTreeTableColumnModel.java b/src/org/hwo/ui/treetable/DefaultTreeTableColumnModel.java new file mode 100644 index 0000000..b687b35 --- /dev/null +++ b/src/org/hwo/ui/treetable/DefaultTreeTableColumnModel.java @@ -0,0 +1,198 @@ +package org.hwo.ui.treetable; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; + +import org.hwo.ui.CellRenderer; + +public class DefaultTreeTableColumnModel implements TreeTableColumnModel { + + public class Column + { + private String label; + private int width; + private int modelColumn; + private CellRenderer + cellRenderer; + private TreeTablePopupListener + popupListener; + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + fireColumnsChanged(); + } + public int getWidth() { + return width; + } + public Column setWidth(int width) { + this.width = width; + fireColumnsChanged(); + + return this; + } + public int getModelColumn() { + return modelColumn; + } + public Column setModelColumn(int modelColumn) { + this.modelColumn = modelColumn; + fireColumnsChanged(); + + return this; } + public CellRenderer getCellRenderer() { + return cellRenderer; + } + public Column setCellRenderer(CellRenderer cellRenderer) { + this.cellRenderer = cellRenderer; + + return this; + } + public TreeTablePopupListener getPopupListener() { + return popupListener; + } + public Column setPopupListener(TreeTablePopupListener popupListener) { + this.popupListener = popupListener; + return this; + } + } + + private List columns; + private List treeTableModelListener; + + public DefaultTreeTableColumnModel() + { + treeTableModelListener = new LinkedList(); + + columns = new ArrayList(); + Column column = new Column(); + column.label = ""; + column.width = 280; + columns.add(column); + } + + public Column addColumn(String label) + { + return addColumn(label,100); + } + + public Column addColumn(String label,int width) + { + return addColumn(label, width, -1); + } + + public Column addColumn(String label,int width,int modelColumn) + { + Column column = new Column(); + column.label = label; + column.width = width; + columns.add(column); + + if (modelColumn == -1) + column.modelColumn = columns.indexOf(column); + else + column.modelColumn = modelColumn; + + fireColumnsChanged(); + return column; + } + + public void removeColumn(int column) + { + columns.remove(column); + fireColumnsChanged(); + } + + public Column getColumn(int column) + { + return columns.get(column); + } + + public int indexOfColumn(Column column) + { + return columns.indexOf(column); + } + + @Override + public int getColumnCount() { + return columns.size(); + } + + @Override + public String getColumnLabel(int column) { + return columns.get(column).getLabel(); + } + + @Override + public int getColumnWidth(int column) { + return columns.get(column).getWidth(); + } + + @Override + public int getColumnPos(int column) { + int x = 0; + for (int i=0;i treeTableModelListener; + + public DefaultTreeTableModel() + { + treeTableModelListener = new LinkedList(); + } + + @Override + public Object getParent(Object node) { + return ((TreeTableElement)node).getParent(); + } + + @Override + public int getChildCount(Object parent) { + return ((TreeTableElement)parent).getChildCount(); + } + + @Override + public Object getChild(Object parent, int index) { + return ((TreeTableElement)parent).getChild(index); + } + + @Override + public Object getRoot() { + return getRootNode(); + } + + + @Override + public boolean isLeaf(Object node) { + if (((TreeTableElement)node).getChildCount()==0) + return true; + else + return false; + } + + @Override + public Object getValue(Object node, int column) { + return ((TreeTableElement)node).getValue(column); + } + + + public TreeTableElement getRootNode() { + return rootNode; + } + + public void setRootNode(TreeTableElement rootNode) { + this.rootNode = rootNode; + fireRowsChanged(); + } + + @Override + public TreeTableColumnModel getDefaultColumnModel() { + return new DefaultTreeTableColumnModel(); + } + + @Override + public void addTreeTableModelListener(TreeTableModelListener listener) { + treeTableModelListener.add(listener); + } + + @Override + public void removeTreeTableModelListener(TreeTableModelListener listener) { + treeTableModelListener.remove(listener); + } + + private void fireRowsChanged() + { + for (TreeTableModelListener listener:treeTableModelListener) + listener.rowsChanged(); + } + + +} diff --git a/src/org/hwo/ui/treetable/TreeTable.java b/src/org/hwo/ui/treetable/TreeTable.java new file mode 100644 index 0000000..42b82b1 --- /dev/null +++ b/src/org/hwo/ui/treetable/TreeTable.java @@ -0,0 +1,661 @@ +package org.hwo.ui.treetable; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.GridLayout; +import java.awt.Point; +import java.awt.Polygon; +import java.awt.Rectangle; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.awt.event.MouseListener; +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.LinkedList; +import java.util.List; + +import javax.swing.JComponent; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JViewport; +import javax.swing.Scrollable; +import javax.swing.SwingConstants; + +import org.hwo.ui.CellEditor; +import org.hwo.ui.CellEditorArgs; +import org.hwo.ui.CellEditorListener; +import org.hwo.ui.CellRenderer; +import org.hwo.ui.DefaultCellEditor; +import org.hwo.ui.DefaultCellRenderer; +import org.hwo.ui.SelectionMode; +import org.hwo.ui.shapes.Triangle; +import org.hwo.ui.treetable.DefaultTreeTableColumnModel.Column; + +public class TreeTable extends JComponent implements Scrollable, TreeTableModelListener, CellEditorListener { + + class NodeState + { + private boolean opened; + + public int indentation; + + public boolean isOpened() { + return opened; + } + + public void setOpened(boolean opened) { + this.opened = opened; + } + } + public class HeaderView extends JComponent + { + + @Override + public void paint(Graphics g) { + + g.drawLine(0, getHeight()-1, TreeTable.this.preferredSize.width - 1, getHeight()-1); + + for (int i=0;i rowObjects; + private Hashtable + nodeStates; + + private Hashtable, CellRenderer> cellRendererList; + private Hashtable, CellEditor> cellEditorList; + + private JViewport headerViewport; + private Dimension preferredSize; + + private List popupListener; + private List mouseListener; + + private CellEditor activeEditor; + + private SelectionMode selectionMode; + private int selectedRow; + + + public TreeTable() + { + popupListener = new LinkedList(); + mouseListener = new LinkedList(); + + preferredSize = new Dimension(1,1); + + rowHeight = 20; + setBackground(Color.WHITE); + + cellRendererList = new Hashtable, CellRenderer>(); + cellRendererList.put(Object.class, new DefaultCellRenderer()); + + cellEditorList = new Hashtable, CellEditor>(); + addCellEditor(Object.class, new DefaultCellEditor()); + + rowObjects = new ArrayList(); + nodeStates = new Hashtable(); + setModel(new DefaultTreeTableModel()); + + addMouseListener(new MouseListener() { + + @Override + public void mouseReleased(MouseEvent e) { + if (e.isPopupTrigger()) + firePopupRequestedFromMouseEvent(e); + } + + @Override + public void mousePressed(MouseEvent e) { + if (e.isPopupTrigger()) + firePopupRequestedFromMouseEvent(e); + + } + + @Override + public void mouseExited(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseEntered(MouseEvent e) { + // TODO Auto-generated method stub + + } + + @Override + public void mouseClicked(MouseEvent e) { + int row,column; + + row = e.getY() / rowHeight; + column = columnModel.getColumnAtX(e.getX()); + + TreeTable.this.mouseClicked(e.getX(), e.getY(), e.getClickCount(), row, column); + + if (e.isPopupTrigger()) + firePopupRequestedFromMouseEvent(e); + else + fireMouseClicked(e); + + } + }); + + prepareWidth(); + prepareHeight(); + + selectedRow = -1; + } + + public Point mouseToCell(int x,int y) + { + Point p = new Point(); + p.x = columnModel.getColumnAtX(x); + p.y = y / rowHeight; + + if ((p.x >= columnModel.getColumnCount()) || (p.y >= rowObjects.size())) + return null; + + return p; + } + + public Object getRowObject(int row) + { + return this.rowObjects.get(row); + } + + private CellRenderer findCellRenderer(Class clazz) + { + if (clazz == null) + return new DefaultCellRenderer(); + if (cellRendererList.containsKey(clazz)) + return cellRendererList.get(clazz); + if (clazz.getSuperclass()!=null) + return findCellRenderer(clazz.getSuperclass()); + return new DefaultCellRenderer(); + } + + public void addCellEditor(Class clazz,CellEditor editor) + { + editor.addCellEditorListener(this); + cellEditorList.put(clazz,editor); + } + + private CellEditor findCellEditor(Class clazz) + { + if (clazz == null) + return null; + if (cellEditorList.containsKey(clazz)) + return cellEditorList.get(clazz); + + return cellEditorList.get(Object.class); + + } + + private void mouseClicked(int x,int y,int clickCount,int row,int column) + { + System.err.println("Click: " + x + "/" + y + " ( " + row + " : " + column + " )"); + if (clickCount == 1) + { + if (column == 0) + { + if (x < rowHeight) + { + NodeState state = getState(rowObjects.get(row)); + setOpened(rowObjects.get(row), !state.opened); + } else if (selectionMode == SelectionMode.ROW) + { + selectedRow = row; + repaint(); + } + } + } + } + + private void prepareWidth() + { + preferredSize.width = columnModel.getColumnPos(columnModel.getColumnCount()); + } + + private void prepareHeight() + { + prepareRows(); + preferredSize.height = rowHeight * rowObjects.size(); + } + + private void prepareRow(Object row) + { + if (row!=null) + { + int ind = getState(row).indentation; + + rowObjects.add(row); + if (model.getChildCount(row)>0) + { + if (getState(row).isOpened()) + { + for (int i=0;i0) + { + if (!state.isOpened()) + { + g.drawPolygon(new Triangle(left + a, top + a, left + b, top + b, left + a, bottom - a)); + } else + { + g.drawPolygon(new Triangle(left + a, top + b, left + a + b, top + b, left + b, bottom - a )); + } + } + + left += rowHeight; + } + + g.setColor(getForeground()); + + Object value = model.getValue(ro, columnModel.getColumnModelColumn(column)); + CellRenderer renderer = columnModel.getColumnCellRenderer(column); + + if (renderer == null) + if (value != null) + renderer = findCellRenderer(value.getClass()); + else + renderer = findCellRenderer(null); + + Rectangle rect = new Rectangle(left, top, width, rowHeight); + + Rectangle clipRestore = g.getClipBounds(); + + if (clipRestore.intersects(rect)) + { + Rectangle rectClip = clipRestore.intersection(rect); + + g.setClip(rectClip); + renderer.renderCell(g, row, column, rect, value, ro); + g.setClip(clipRestore); + } + + } + } + + + @Override + public void paint(Graphics g) { + prepareRows(); + + g.setColor(getBackground()); + g.fillRect(0, 0, getWidth(), getHeight()); + + for (int i=0;i clazz) + { + WellKnownClass wk = clazz.getAnnotation(WellKnownClass.class); + if (wk != null) + return wk; + if (clazz.getSuperclass() != null) + return getWellKnownClass(clazz.getSuperclass()); + return null; + } + + static public Method findAnnotatedMethod(Class clazz,Class annotationClass) + { + for (Method method:clazz.getDeclaredMethods()) + { + Object anno = method.getAnnotation(annotationClass); + if (anno != null) + return method; + } + if (clazz.getSuperclass() != null) + return findAnnotatedMethod(clazz.getSuperclass(), annotationClass); + return null; + } + + + + static public String getDisplayLabel(Object o) + { + Method m = findAnnotatedMethod(o.getClass(), WellKnownDisplayLabel.class); + if (m != null) + { + m.setAccessible(true); + try { + Object result = m.invoke(o, null); + return result.toString(); + + } catch (IllegalArgumentException e) { + e.printStackTrace(); + } catch (IllegalAccessException e) { + e.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } + } + return o.toString(); + } + + +} diff --git a/src/org/hwo/ui/wellknown/WellKnownClass.java b/src/org/hwo/ui/wellknown/WellKnownClass.java new file mode 100644 index 0000000..8ef82ca --- /dev/null +++ b/src/org/hwo/ui/wellknown/WellKnownClass.java @@ -0,0 +1,58 @@ +package org.hwo.ui.wellknown; + +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.util.ArrayList; +import java.util.List; + +@Retention(RetentionPolicy.RUNTIME) +public @interface WellKnownClass { + + class DefaultWellKnownSearch implements WellKnownSearch + { + @Override + public List keywordSearch(Class clazz, String keyword) { + return new ArrayList(); + } + @Override + public void setClazz(Class clazz) { + } + } + + class DefaultWellKnownEditor implements WellKnownEditor + { + @Override + public void getValue() { + } + @Override + public void setValue(Object value) { + } + @Override + public void show(boolean modal) { + } + } + + class DefaultWellKnownIdentity implements WellKnownIdentity + { + + @Override + public Object getIdentity(Object o) { + return null; + } + + @Override + public Object loadWithIdentity(Class clazz, Object identity) { + return null; + } + + @Override + public void save(Object o) { + } + + } + + public Class search() default DefaultWellKnownSearch.class; + public Class editor() default DefaultWellKnownEditor.class; + public Class identity() default DefaultWellKnownIdentity.class; + +} diff --git a/src/org/hwo/ui/wellknown/WellKnownDisplayLabel.java b/src/org/hwo/ui/wellknown/WellKnownDisplayLabel.java new file mode 100644 index 0000000..66ec4c1 --- /dev/null +++ b/src/org/hwo/ui/wellknown/WellKnownDisplayLabel.java @@ -0,0 +1,5 @@ +package org.hwo.ui.wellknown; + +public @interface WellKnownDisplayLabel { + +} diff --git a/src/org/hwo/ui/wellknown/WellKnownEditor.java b/src/org/hwo/ui/wellknown/WellKnownEditor.java new file mode 100644 index 0000000..f403fc2 --- /dev/null +++ b/src/org/hwo/ui/wellknown/WellKnownEditor.java @@ -0,0 +1,10 @@ +package org.hwo.ui.wellknown; + +public interface WellKnownEditor { + + public void setValue(Object value); + public void getValue(); + + public void show(boolean modal); + +} diff --git a/src/org/hwo/ui/wellknown/WellKnownIdentity.java b/src/org/hwo/ui/wellknown/WellKnownIdentity.java new file mode 100644 index 0000000..bb88774 --- /dev/null +++ b/src/org/hwo/ui/wellknown/WellKnownIdentity.java @@ -0,0 +1,9 @@ +package org.hwo.ui.wellknown; + +public interface WellKnownIdentity { + + public Object getIdentity(Object o); + public Object loadWithIdentity(Class clazz,Object identity); + public void save(Object o); + +} diff --git a/src/org/hwo/ui/wellknown/WellKnownSearch.java b/src/org/hwo/ui/wellknown/WellKnownSearch.java new file mode 100644 index 0000000..2057fc8 --- /dev/null +++ b/src/org/hwo/ui/wellknown/WellKnownSearch.java @@ -0,0 +1,10 @@ +package org.hwo.ui.wellknown; + +import java.util.List; + +public interface WellKnownSearch { + + public List keywordSearch(Class clazz,String keyword); + public void setClazz(Class clazz); + +}