Here are the components I used. I bought them all from amazon.de.
Corsair CC-9011023-WW Carbide 200R PC-Gehäuse (midi-ATX, 4x 3,5 HDD, 7x PCI-e, 1x USB 3.0) schwarz

Corsair RM Series 650Watt Voll Modular 80 PLUS Gold ATX/EPS Netzteil (CP-9020054-EU)

Intel Core i7 4770K Prozessor (3,5GHz, Sockel LGA1150, 8MB Cache) boxed

Crucial Ballistix Sport Arbeitsspeicher 16GB (1600MHz, 240-polig, CL9, 2x 8GB) DDR3-RAM Kit

MSI N760 TF 4GD5/OC 4096MB GDDR5 PCI-E 256 bits DV

I can say that I am quite happy with the new system. Windows 8.1 installed without a problem. The drivers provided by MSI work quite well and the overclocking tools are very nice. All in all, the system is very quite even though the case is not sound isolated at all.
]]>
The new system will be a browser based system with a backend running in our company. The browser UI will consist of two parts built with different technologies.
The management side allows maintenance of core data like available projects and work packages, users, billing information etc. It also allows company management to generate reports and bills etc. This part of the UI will use a classical round trip approach and will only be available on company premises.
The UI for employees on the other hand will allow booking of work time and project/work package times and is based on AngularJS which is an ideal framework for the purpose. It will provide an offline mode which stores entered data in browser local storage and an online mode which keeps the data in sync with the server on premises.
The picture below shows my prototype for the employee UI.
The red rows in the left hand table are weekends and German hollidays. The golden row is the selected day, for which details are shown on the right.
The Start Stop and Break columns allow the user to enter the working times for a given day. Those times then have to be allotted to projects (or rather work packages which are organized into projects). Various validations highlight different kinds of errors (time > 24:00, illegal time format, Stop Time < Start Time etc.)
Over the next weeks I plan to post a few articles on the gritty details of how this all works and especially how AngularJS can be used effectively to build applications like this.
In the meantime, please play around with the prototype. The link will always take you to the current version. Feel free to View Source and have a look at the JavaScript. It’s not minified. Also if you are interested in tests, have a look at the unit tests and the e2e tests.
]]>
]]>So what will I do with my Bitcoins now? Well I think I’ll keep them and dream a bit. Lets assume, the world at large embraces the advantages of Bitcoins over the current currencies we have and in a few years all currencies are traded into Bitcoins. Today the amount of $ (M2) floating around is around 10 000 Billion $, The amount of € (M2) is around 85 000 Billion €. Let’s assume the total amount of money in the world is somewhere around 40 000 Billion $.
The total amount of Bitcoins is limited by the system to asymptotically approach 21 Million BTC (it is currently around 6.4 Million BTC).
So, if the world economy completely converts to Bitcoin (21 Million available) and I still have my 68.28 BTC, I will have about 0.000325% of the global money supply. Translated to the current money supply that would come out to be around 130 Million $. Not too shabby.
Of course you could argue that this outcome isn’t very likely. I completely agree. However, I have invested only 500€ in this little dream and so far it is living up to its promise. Today my Bitcoins are worth around 800€ and I can’t wait to check again tomorrow.
]]>
I finally found out why!
Android has a low level property system that lives in the init process. A good writeup of how it works can be found at
http://rxwen.blogspot.com/2010/01/android-property-system.html
The important part is that the property system only has space for 247 system properties. The properties are filled from the following files:
/default.prop
/system/build.prop
/system/default.prop
/data/local.prop
Additional properties are created by scripts with the setprop utility and by various processes (wifi manager, vpn manager etc.)
Since Android 2.1, Motorola has filled the above files with lots of properties so that the property service is almost filled up by the time the phone has finished booting. When opening a WiFi connection, additional properties have to be set. If no more properties are available, things start to fail.
I have commented out quite a few of the properties from above files to make some space and now everything works smoothly again. I am not sure yet, which properties are important and which not, once I have done some more research, I will post the changes I have made.
I hope this helps Milestone users with similar problems.
Here is my modified /system/build.prop:
# begin build properties
# autogenerated by buildinfo.sh
ro.build.id=SHOLS_U2_02.36.0
ro.build.display.id=SHOLS_U2_02.36.0
ro.build.version.incremental=8985865
ro.build.version.sdk=7
ro.build.version.codename=REL
ro.build.version.release=2.1-update1
##ro.build.svn=24
##ro.build.date=Thu Jun 3 12:47:57 CDT 2010
##ro.build.date.utc=1275587277
##ro.build.type=user
##ro.build.user=milestcm
##ro.build.host=il93lnxebld02
##ro.build.tags=rel-keys
ro.product.model=Milestone
ro.product.brand=MOTO_VFDE
ro.product.name=umts_sholes
ro.product.device=umts_sholes
ro.product.board=sholes
ro.product.cpu.abi=armeabi-v7a
ro.product.cpu.abi2=armeabi
ro.product.manufacturer=motorola
ro.product.locale.language=de
ro.product.locale.region=DE
ro.wifi.channels=
ro.board.platform=omap3
# ro.build.product is obsolete; use ro.product.device
ro.build.product=umts_sholes
# Do not try to parse ro.build.description or .fingerprint
ro.build.description=umts_sholes-user 2.1-update1 SHOLS_U2_02.36.0 8985865 rel-keys
ro.build.fingerprint=MOTO_VFDE/umts_sholes/umts_sholes/sholes:2.1-update1/SHOLS_U2_02.36.0/8985865:user/rel-keys
# end build properties
#
# system.prop for UMTS Sholes
#
rild.libpath=/system/lib/libril-moto-umts-1.so
rild.libargs=-d /dev/ttyS0
ro.sf.lcd_density=240
ro.default_usb_mode=0
# Default network type.
# 3 -> GSM/WCDMA (auto mode, according to PRL)
# AVAILABLE Application Settings menu
ro.telephony.default_network=3
wifi.interface = tiwlan0
# Time between scans in seconds. Keep it high to minimize battery drain.
# This only affects the case in which there are remembered access points,
# but none are in range.
wifi.supplicant_scan_interval = 15
# The OpenGL ES API level that is natively supported by this device.
# This is a 16.16 fixed point number
ro.opengles.version = 131072
# This is a high density device with more memory, so larger vm heaps for it.
dalvik.vm.heapsize=24m
#proximit sensor screen off delay
mot.proximity.delay=450
#proximit sensor disable touch distance
mot.proximity.distance=60
#
# ADDITIONAL_BUILD_PROPERTIES
#
ro.product.multi_touch_enabled=true
ro.product.max_num_touch=2
ro.product.tfdt_string=com.motorola.android.app.tfdt.START
dalvik.vm.jniopts=warnonly
ro.com.motorola.smartsensor=true
ro.config.notification_sound=F1_New_SMS.ogg
ro.config.alarm_alert=Alarm_Classic.ogg
ro.telephony.call_ring.multiple=false
ro.telephony.call_ring.delay=3000
##ro.url.safetylegal=http://www.motorola.com/staticfiles/Support/legal/?model=A855
ro.setupwizard.enable_bypass=1
ro.media.enc.hprof.file.format=mp4
ro.media.enc.hprof.codec.vid=h264
ro.media.enc.hprof.codec.aud=aac
ro.media.enc.hprof.vid.width=720
ro.media.enc.hprof.vid.height=480
ro.media.enc.hprof.vid.fps=25
ro.media.enc.hprof.vid.bps=3000000
ro.media.enc.hprof.aud.bps=96000
ro.media.enc.hprof.aud.hz=16000
ro.media.enc.hprof.aud.ch=1
ro.media.enc.hprof.duration=60
##ro.media.enc.lprof.file.format=mp4
##ro.media.enc.lprof.codec.vid=m4v
##ro.media.enc.lprof.codec.aud=amrnb
##ro.media.enc.lprof.vid.width=320
##ro.media.enc.lprof.vid.height=240
##ro.media.enc.lprof.vid.fps=15
##ro.media.enc.lprof.vid.bps=200000
##ro.media.enc.lprof.aud.bps=12200
##ro.media.enc.lprof.aud.hz=8000
##ro.media.enc.lprof.aud.ch=1
##ro.media.enc.lprof.duration=30
ro.media.enc.file.format=3gp,mp4
ro.media.enc.vid.codec=h264,m4v,h263
ro.media.enc.aud.codec=aac,amrnb
ro.media.enc.vid.h264.width=176,720
ro.media.enc.vid.h264.height=144,480
ro.media.enc.vid.h264.bps=64000,8000000
ro.media.enc.vid.h264.fps=1,30
ro.media.enc.vid.h263.width=176,720
ro.media.enc.vid.h263.height=144,480
ro.media.enc.vid.h263.bps=64000,8000000
ro.media.enc.vid.h263.fps=1,30
ro.media.enc.vid.m4v.width=176,720
ro.media.enc.vid.m4v.height=144,480
ro.media.enc.vid.m4v.bps=64000,8000000
ro.media.enc.vid.m4v.fps=1,30
ro.media.enc.aud.amrnb.bps=5525,12200
ro.media.enc.aud.amrnb.hz=8000,8000
ro.media.enc.aud.amrnb.ch=1,1
ro.media.enc.aud.aac.bps=8192,96000
ro.media.enc.aud.aac.hz=16000,16000
ro.media.enc.aud.aac.ch=1,1
ro.media.dec.aud.wma.enabled=1
ro.media.dec.vid.wmv.enabled=1
ro.media.cam.preview.fps=0
ro.com.google.clientid=android-motorola
##ro.url.legal=http://www.google.com/intl/%s/mobile/android/basic/phone-legal.html
##ro.url.legal.android_privacy=http://www.google.com/intl/%s/mobile/android/basic/privacy.html
ro.config.vc_call_vol_steps=7
dalvik.vm.dexopt-flags=m=y
net.bt.name=Android
ro.config.sync=yes
dalvik.vm.stack-trace-file=/data/anr/traces.txt
ro.config.ringtone=Red_Beats.ogg
ro.com.google.gmsversion=2.1_r1
ro.com.google.clientidbase.am=android-vf-{country}
ro.com.google.clientidbase=android-hms-vf-{country}
ro.setupwizard.mode=OPTIONAL
ro.com.google.clientidbase.gmm=android-motorola
ro.com.google.clientidbase.yt=android-motorola
ro.com.google.locationfeatures=1
The entries starting with ## have been commented out by me.
And here is my modified /system/default.prop
ro.com.google.clientidbase.vs=android-motorola ro.build.config.version=GAS_EMEA_USASHLS00VFDE_P035 ro.build.config.date=Mon Jul 12 20:51:05 -0500 2010 ##ro.bidi.Hebrew=Off ro.keyboard.type=qwertz ro.bidi.enabled=false ##ro.bidi.Arabic=Off persist.sys.timezone=Europe/Berlin ro.fota.enable=1 sms.convert.char.for.latam=0 ##ro.bidi.Russian=Off
bidi seems to stand for “bidirectional input”. Since ro.bidi.enabled is false, I assume that the other ro.bidi.* properties are irrelevant anyway.
After thinning out the property files, is have 245 properties after using WiFi, 3G-data and VPN. Two properties left in reserve 
Examples for properties that are created dynamically are:
[dhcp.tiwlan0.result]: [ok] [init.svc.dhcpcd]: [running] [dhcp.tiwlan0.pid]: [3986] [dhcp.tiwlan0.reason]: [RENEW] [dhcp.tiwlan0.dns1]: [192.168.1.6] [dhcp.tiwlan0.dns2]: [] [dhcp.tiwlan0.dns3]: [] [dhcp.tiwlan0.dns4]: [] [dhcp.tiwlan0.ipaddress]: [192.168.1.61] [dhcp.tiwlan0.gateway]: [192.168.1.6] [dhcp.tiwlan0.mask]: [255.255.255.0] [dhcp.tiwlan0.leasetime]: [14400] [dhcp.tiwlan0.server]: [192.168.1.6] [net.dns1]: [192.168.1.6]
If these properties can not be created when activating WiFi, WiFi does not work.
]]>Resource deallocation in Java is no problem since Java has automatic garbage collection.
Right! …? …?? …Wrong!
Since Java has automatic garbage collection, resource deallocation is often taken care of for you,
but when it is not, it becomes a real pain.
Since the language relies so heavily on garbage collection, it seems the language
designers forgot to include good mechanisms for the cases where garbage collection does
not solve the problem (releasing external resources) or just does not happen automatically.
A common scenario for memory leaks in Java is Listener registration and de-registration.
When you want one component to react to events in another component you usually use a listener
pattern. The listening component registers itself as a callback client to an observable component.
Finding the right place to register the listener usually is not a problem.
Often it is done in the constructor of the listening component or in some setup
method.
Unregistering however is often not so obvious since there is no canonical tear down
mechanism in Java. You are often left with listeners staying registered in their
observables and therefore not eligable for garbage collection.
The Netbeans developers have addressed this problem by providing a class called
WeakListener. It works by inserting a WeakListener object between the listener
and the observable. The listener is only referenced weakly (with a WeakReference)
and therefore is automatically collected, when other references to the listener
go away. The WeakListener class also unregisters itself automagically when it
notices that its concrete listener has been collected. Unregistering the WeakListener
is only possible, if the observable conforms to certain conventions.
This solution is great, when you have a given model and want to make sure, that
your listeners do not remain referenced indefinitely.
My solution works the other way around. The observable has support for weak listeners
built in. It keeps its list of listeners in a WeakListener support class. Listeners
can register themselves in the usual way. They may unregister themselves explicitly
or just count on being disconnected automatically.
This solution is great, when you are designing a model (observable) and want to
make life easier for your clients (listeners).
public class NumberModel {
private WeakNumberChangedListeners listeners =
new WeakNumberChangedListeners();
private int theNumber = 0;
private String name;
public NumberModel(String name)
{
this.name = name;
}
public synchronized void inc()
{
int oldNumber = theNumber;
theNumber++;
listeners.fire (new NumberChangedEvent(this, oldNumber, theNumber));
}
public synchronized void dec()
{
int oldNumber = theNumber;
theNumber--;
listeners.fire (new NumberChangedEvent(this, oldNumber, theNumber));
}
public synchronized int getNumber ( )
{
return theNumber;
}
public String getName()
{
return name;
}
public void addNumberChangedLisener (NumberChangedListener listener)
{
listeners.add (listener);
}
public void removeNumberChangedListener (NumberChangedListener listener)
{
listeners.remove (listener);
}
}
public interface NumberChangedListener {
void numberChanged (NumberChangedEvent event);
}
public class WeakNumberChangedListeners
extends WeakListeners<NumberChangedListener, NumberChangedEvent>
{
@Override
protected void fireOne(NumberChangedListener listener, NumberChangedEvent event)
{
listener.numberChanged (event);
}
}
}
package com.bininda.weaklistener;
import java.lang.ref.WeakReference;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import java.util.WeakHashMap;
/**
* A list of listeners that are only referenced weakly.
* Listeners are registered using the add method. They may be deregistered
* using the remove method, however if the listener is garbage collected, because
* it is not hard referenced any more, it is automatically removed.
* The method fireOne must be overwritten in a derived class.
* @param I The listener interface
* @param E The event type
* @author bininda
*/
public abstract class WeakListeners<I, E> {
/**
* Weak map of references to listeners.
* WeakHashMap has the nice feature of automatically getting rid of
* stale entries.
*/
private Set<I> wSet = Collections.newSetFromMap(new WeakHashMap<I, Boolean>());
/**
* Create an empty weak listener list.
*/
public WeakListeners()
{
}
/**
* Add a new listener to the list of registered listeners.
* If the listener has already been added, the only effect is diagnostic
* output.
* @param listener The new listener
*/
public synchronized void add (I listener)
{
wSet.add (listener);
}
/**
* Remove a registered listener from the list.
* If the listener has already been removed, output diagnostics.
* Note that automatic removal can not happen as long as someone still has
* a hard reference to the listener and is therefore able to call this method.
* @param listener
*/
public synchronized void remove (I listener)
{
wSet.remove (listener);
}
/**
* Fire one event to one registered listener.
* @param listener The listener to fire to
* @param event The event to pass to the listener.
*/
abstract protected void fireOne(I listener, E event);
/**
* Fire an event to all registered listeners.
* If diagnostics are enabled, listeners that have been collected automatically
* are printed out.
* @param event The event to fire to the listeners.
*/
public synchronized void fire(E event)
{
{
List<I> lcp = new LinkedList<I>(wSet);
for (I l: lcp)
{
try
{
fireOne (l, event);
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
}
]]>Distributed hypermedia method and system for automatically invoking external application providing interaction and display of embedded objects within a hypermedia document
As I understand the patents, they are (among other things) about browser plug-in. If you follow the links to the patents (either US-Patent 5,838,906 or US-Patent 7,599,985), you come to pages on the United States Patent and Trademark Office. At the top of the page there are a couple of red buttons, one of them is labeled “Images”. If you click on that button, you come to a page that requires an Apple QuickTime plug-in.
Apple of course is one of the companies being sued by Eolas Technologies for violating the patent.
I found this quite amusing.
]]>
The file chooser does not filter files. It allows the user to select any file but if it can be opened as an image, the preview is shown.
I created a component based on JPanel for the preview which overrides the paintComponent method:
package x.y.z.util;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JPanel;
public class ImagePanel extends JPanel
{
private Image image;
private Image scaledCache;
public ImagePanel()
{
setBorder(javax.swing.BorderFactory.createEtchedBorder());
}
public void setImage (Image image)
{
this.image = image;
scaledCache = null;
repaint();
}
private Image getScaled()
{
int iw = image.getWidth(this);
int ih = image.getHeight(this);
int pw = getWidth();
int ph = getHeight();
double scale;
if (1.0 * pw / iw < 1.0 * ph / ih)
{
scale = 1.0 * pw / iw;
}
else
{
scale = 1.0 * ph / ih;
}
int scaledw = (int) (iw * scale);
int scaledh = (int) (ih * scale);
if (scaledCache != null)
{
if (scaledCache.getWidth(this) == scaledw &&
scaledCache.getHeight(this) == scaledh)
{
return scaledCache;
}
}
scaledCache = image.getScaledInstance(scaledw, scaledh, Image.SCALE_DEFAULT);
return scaledCache;
}
@Override
public void paintComponent(Graphics g)
{
if (g != null)
{
Graphics scratch = g.create();
scratch.setColor(getBackground());
scratch.fillRect(0, 0, getWidth(), getHeight());
if (image != null)
{
Image scaled = getScaled();
scratch.drawImage(scaled, getWidth() / 2 - scaled.getWidth(this) / 2,
getHeight() / 2 - scaled.getHeight(this) / 2, this);
}
}
}
}
Then I created a the class ImageFileChooser derived from JFileChooser:
package x.y.z.util;
import java.awt.Dimension;
import java.awt.Image;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import javax.swing.ImageIcon;
import javax.swing.JFileChooser;
public class ImageFileChooser extends JFileChooser {
public ImageFileChooser()
{
final ImagePanel preview = new ImagePanel();
preview.setPreferredSize(new Dimension (150, 150));
setAccessory(preview);
addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent e)
{
String propertyName = e.getPropertyName();
if (propertyName.equals(JFileChooser.SELECTED_FILE_CHANGED_PROPERTY))
{
File selection = (File) e.getNewValue();
String name;
if (selection == null)
{
return;
}
else
{
name = selection.getAbsolutePath();
}
ImageIcon icon = new ImageIcon(name);
Image newImage = icon.getImage();
preview.setImage (newImage);
}
}
});
}
}
Works great.
]]>Update:
Chris tried updating to Update 16 first. This didn’t help. Updating to Netbeans 6.8 Milestone 1 solved the problem though.
A new requirement came up which essentially defined a new type of additional resource files. These resource files contain Lua scripts and have to be editable in the configuration tool.
When the configuration tool opens a configuration, it receives a zip file from the persistence component and extracts the zip file into a memory file system.
The lua scripts can be opened in the standard Netbeans editor component and are handled by a lua editing module. When the configuration is saved, the xml file is saved and the memory file system is zipped and passed to the persistence module.
Two of the challenges where:
First of all, I implemented a method that finds out if any modified DataObjects exist that are part of a given configuration DataObject.
public Set<DataObject> getModifiedLuaDataObjects()
{
Set<DataObject> modified =
DataObject.getRegistry().getModifiedSet();
final Map<FileObject, DataObject> modifiedFiles =
new HashMap<FileObject, DataObject>();
final Set<DataObject> modifiedDataObjects =
new HashSet<DataObject>();
for (DataObject d: modified)
{
modifiedFiles.put (d.getPrimaryFile(), d);
}
getConfiguration().walk(new IModelWalker() {
public boolean visit(StructureItem item) {
try {
URL configFile = item.getConfigurationFile();
if (configFile != null)
{
FileObject fo =
URLMapper.findFileObject(configFile);
if (modifiedFiles.containsKey(fo))
{
modifiedDataObjects.add (modifiedFiles.get(fo));
}
}
return false;
} catch (Exception e) {
Exceptions.printStackTrace(e);
return false;
}
}
});
return modifiedDataObjects;
}
Then I registered a listener in the DataObject Registry, that gets called, whenever a DataObject changes its modifcation status
public ConfigurationDataObjectBase
(final FileObject pf, UniFileLoader loader)
throws DataObjectExistsException, IOException
{
super (pf, loader);
//...
DataObject.getRegistry().
addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e)
{
Set<DataObject> modified = getModifiedLuaDataObjects();
if (!modified.isEmpty())
{
setModified(true);
}
}
});
}
When saving a configuration, the following piece of code gets called:
//...
Set<DataObject> dataObjects = getModifiedLuaDataObjects();
for (DataObject dao: dataObjects)
{
SaveCookie sc = dao.getCookie(SaveCookie.class);
if (sc != null)
{
try
{
sc.save();
} catch (IOException ex)
{
Exceptions.printStackTrace(ex);
}
}
}
//...
When a configuration is close, all the open editors for the lua scripts have to be closed as well
private void closeLuaEditors()
{
Set<TopComponent> comps =
new HashSet<TopComponent>
(TopComponent.getRegistry().getOpened());
FileObject directory = getPrimaryFile().getParent();
if (comps != null)
{
for (TopComponent tc: comps) {
Node[] arr = tc.getActivatedNodes();
if (arr != null)
{
for (Node n: arr)
{
if (n instanceof DataNode)
{
DataNode dn = (DataNode) n;
FileObject luaFile =
dn.getDataObject().getPrimaryFile();
if (luaFile.getParent() == directory)
{
// in same directory as our primary file
EditorCookie ec =
n.getCookie(EditorCookie.class);
if (ec != null) {
ec.close();
}
}
}
}
}
}
}
}
]]>