Moble Manufacturers argee to use Micro USB interface to connect to new mobile phones. So what is Mirco USB? Well the answer to that was not so simple to find. One of the pictures on Wikipedia that first claimed to show a Micro USB does not look like it...
I downloaded the USB 2.0 specfication and found this picture:
There is also a micro-A plug. An USB A-type plug are often found at places that gives power (for example your computer). A B plug can most often be found at place that draw power (for example your mobile phone).
To confuse things a bit more the connectors in the USB 3.0 specifications looks "half" different. And in the USB 3.0 specification there is also a AB-plug that can take both a A and B. But the USB 3.0 specification uses more wires so it is a completely different story.
Whats the lesson here? First of all don't always trust Wikipedia! Second, the mist behind an article on a new site can take some time to disperse.
29 June 2009
27 June 2009
My Compaq Mini
I've bought a Compaq Mini 700 series (730eo) netbook computer. The price was 3000 Swedish kronor (SEK). I've used it for 2 weeks now and gotten myself an opinion of how it is so here is my review.
Pros:
Cons:
Here is a picture of the keyboard layout (Swedish):
One thing I really like with a netbook is that I can move it around my apartment so easy. I read websites at the kitchen table, use it at the couch when I watch tv and can have it in my lap when I sit at the balcony.
Update: Here is how I fixed the fan control: http://blog.lesc.se/2009/10/how-to-improve-fan-control-on-hpcompaq.html
Pros:
- Small and light. I put my computer on my kitchen scale and it was 1066 grams. The trend now is bigger netbooks but this is still in the smaller range.
- Good keyboard. I've tested a bunch of netbooks at my local store and this had one of the best keyboards
- Good value for money.
Cons:
- Noisy fan and bad fan control. The fan really makes some noise and the fan control is not that good at adapting the speed of the fan. I have solved this problem and I'll post another blog post about it later
- Slow hard drive (4200 RPM). But it is good enough for me. I can even develop Java programs in Eclipse with it. So it does not bug me that much.
- Only a 3 cell battery that lasts 2 hours (3 max). I guess that is a compromise for its small wiegth
- Low quality web cam. Other netbooks have much better (I tried these in the store as well). But that does not bother me that much.
Here is a picture of the keyboard layout (Swedish):
One thing I really like with a netbook is that I can move it around my apartment so easy. I read websites at the kitchen table, use it at the couch when I watch tv and can have it in my lap when I sit at the balcony.
Update: Here is how I fixed the fan control: http://blog.lesc.se/2009/10/how-to-improve-fan-control-on-hpcompaq.html
26 June 2009
Resize a dialog with a multi line text field that has fixed width
stackoverflow.com is a great forum to ask questions. Sometimes an answer to a question you ask there will trigger yourself to think in new ways so you can answer you own question. This happened to me in the problem with the dialog with the multi line text field with fixed width: http://stackoverflow.com/questions/1048224/get-height-of-multi-line-text-with-fixed-width-to-make-dialog-resize-properly
Base class for ChangeEvent/ChangeListener mangament
If you have written a data model you often want to be able to notify others about the change in the model by using some kind of listener. The Java swing ChangeListener interface is one choice of listener to choose. But the management of a listener list (adding, removing and notification of listeners) is a bit of a hazel to write code for each time you have a model. I searched the Java API but could not find any base class of helper class to solve this. The closest I got was the EventListenerList class. By using this class I've written my own base/helper class:
An example of how to use this class:
import javax.swing.event.*;
/**
* Convenience class to notify others of changes
* Can be used as a base class or as an aggregate/helper
*/
public class ChangeEventDispatcher {
protected EventListenerList listenerList = new EventListenerList();
protected ChangeEvent changeEvent = null;
public void addChangeListener(ChangeListener l) {
listenerList.add(ChangeListener.class, l);
}
public void removeFooListener(ChangeListener l) {
listenerList.remove(ChangeListener.class, l);
}
/**
* Called by by child/wrapper class to dispatch a Change event
*
* Code is copied from EventListenerList documentation and adapted to ChangeEvent
*/
public void fireChangeEvent() {
// Guaranteed to return a non-null array
Object[] listeners = listenerList.getListenerList();
// Process the listeners last to first, notifying
// those that are interested in this event
for (int i = listeners.length-2; i>=0; i-=2) {
if (listeners[i]==ChangeListener.class) {
// Lazily create the event:
if (changeEvent == null)
changeEvent = new ChangeEvent(this);
((ChangeListener)listeners[i+1]).stateChanged(changeEvent);
}
}
}
}
An example of how to use this class:
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
@SuppressWarnings("serial")
public class ChangeTester extends JFrame {
private JButton increaseButton = new JButton("Increase");
private JLabel valueLabel = new JLabel();
private ValueModel model = new ValueModel();
public ChangeTester() {
setLayout(new FlowLayout());
add(increaseButton);
add(valueLabel);
//Change the model when pressing the button
increaseButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
model.increaseValue();
}
});
//The label should be updated when the model is changed
model.addChangeListener(new ChangeListener() {
public void stateChanged(ChangeEvent e) {
updateLabelValue();
}
});
updateLabelValue();
pack();
}
private void updateLabelValue() {
valueLabel.setText(Integer.toString(model.getValue()));
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame frame = new ChangeTester();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
});
}
/**
* Simple model that extends the ChangeEventDispatcher
* to get listener list handling
*/
public static class ValueModel extends ChangeEventDispatcher {
private int value;
public void increaseValue() {
this.value++;
fireChangeEvent(); //Notify listeners
}
public int getValue() {
return value;
}
}
}
Quick close a dialog by escape key
I Windows there is a convention that a dialog is closed (and canceled) if the user pressed the Esc key. There is also a convention that pressing Enter closes (and confirms) the dialog. In Java there is no default implementation of this.
So we need to implement this ourself. A naive approach would be to add a KeyListener to the dialog. This will not work if the keyboard focus is in a nested component (for example a text field). So how about to add a key listener to both the dialog and all its subcomponents? Well this would work, and I have successfully implemented this using a ContainerListener in the dialog so any components added in the dialog also gets a key listener. But there is a simpler way: the key bindings way!
With a key binding you don't have to care where the keyboard focus is.
Update: My solution is probably not thread safe, this alternative solution is: http://stackoverflow.com/questions/642925/swing-how-do-i-close-a-dialog-when-the-esc-key-is-pressed
So we need to implement this ourself. A naive approach would be to add a KeyListener to the dialog. This will not work if the keyboard focus is in a nested component (for example a text field). So how about to add a key listener to both the dialog and all its subcomponents? Well this would work, and I have successfully implemented this using a ContainerListener in the dialog so any components added in the dialog also gets a key listener. But there is a simpler way: the key bindings way!
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
@SuppressWarnings("serial")
public class QuickCloseDialog extends JDialog {
public QuickCloseDialog() {
initCloseListener();
add(new JTextField("A text field"));
pack();
}
private void initCloseListener() {
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE , 0), "close");
getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), "close");
getRootPane().getActionMap().put("close", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JDialog dialog = new QuickCloseDialog();
dialog.setVisible(true);
}
});
}
}
With a key binding you don't have to care where the keyboard focus is.
Update: My solution is probably not thread safe, this alternative solution is: http://stackoverflow.com/questions/642925/swing-how-do-i-close-a-dialog-when-the-esc-key-is-pressed
25 June 2009
Static import and GroupLayout tip for Eclipse
I you like GroupLayout and use Eclipse this might be a good tip:
Eclipse is not that good with static imports but it is possible to make the content assist suggest and automatically add static imports. Go to Preferences -> Java -> Editor -> Content Assist -> Favorites and add the types
It is now possible to use the Content Assist (Ctrl + Space) to get help when writing the GroupLayout properties:
Eclipse is not that good with static imports but it is possible to make the content assist suggest and automatically add static imports. Go to Preferences -> Java -> Editor -> Content Assist -> Favorites and add the types
javax.swing.GroupLayout.*
, javax.swing.GroupLayout.Alignment.*
and javax.swing.LayoutStyle.ComponentPlacement.*
:It is now possible to use the Content Assist (Ctrl + Space) to get help when writing the GroupLayout properties:
Eclipse 3.5 Galileo - a first impression
I installed Eclipse 3.5 (or Galileo as it is called) today.
My first impression is that it is similar to 3.4. One thing that i noticed is that cancellation of building a Java project is working better in 3.5. The Java editor is updated and writing code is a bit different. For instance I got a bit annoyed by how parenthesis are inserted. But I guess that I'll quickly get used to it.
The "editor" for Team Synchronizing compare view is updated so it now is more like a Java editor. I'm note sure I will edit code in a compare view just now. I still miss the Ctrl + Shift + T shortcut in Team Synchronizing.
24 June 2009
Key bindings is sometimes to prefer over KeyListener
In Java (Swing) there are KeyListener:s and key bindins. KeyListerner is the classical way of catching events from the keyboard. But inn some situations the key bindings feature is preferred:
For example if you are developing a tetris game this code can be used to get the Left arrow key:
To catch the control key use
More information at http://java.sun.com/docs/books/tutorial/uiswing/misc/keybinding.html
- If you want to catch (only) the CTRL key
- If you want to catch keys regardles of where the user has focus
For example if you are developing a tetris game this code can be used to get the Left arrow key:
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
getActionMap().put("left", new AbstractAction() {
public void actionPerformed(ActionEvent e) {
engine.moveBrickLeft();
}
});
To catch the control key use
KeyStroke.getKeyStroke("ctrl pressed CONTROL")
and KeyStroke.getKeyStroke("released CONTROL")
More information at http://java.sun.com/docs/books/tutorial/uiswing/misc/keybinding.html
04 June 2009
Hint: Set a good comment on your ssh key
Using a ssh key to login into a ssh account is really good. You don't have to know the passwords of the accounts you are logging into, only the password on the ssh key (if any). If you use a password on the key the password can be cached (for example using Pageant).
When creating a ssh key I really recommend that you set a good comment. For example using puttygen enter a "Key comment":
This should be included in the key:
This way it will be so much easier when someone should clean up the keys from
When creating a ssh key I really recommend that you set a good comment. For example using puttygen enter a "Key comment":
This should be included in the key:
- The identity of you (for example your e-mail)
- The computer you used to create it on (for example your Windows computer name)
- The date you created the key
This way it will be so much easier when someone should clean up the keys from
.ssh/authorized_keys
. The identity is good if there are many users for the same ssh account (common in some corporations). The computer name and date is useful when you know that you have lost the key (for example because of hard drive crash), of when a security exploit has been published and the key is considered unsafe.
03 June 2009
Clean your laptop from dust periodically
A colleague of mine had some problems with very high temperatures in a laptop. The temperatures was about 71 degrees Celsius at idle and 91 degrees Celsius a full load. (It was a HP laptop with some kind of dual core). I opened the laptop up and took out the fan. In the space between the outlet of the fan and the heat pipe there was a rather thick layer of dust. I cleaned it and now the temperatures where about 5 degrees lower.
I my colleague's case there is probably something else wrong with the fan (or computer), but it is clear that a little bit of dust defensively can have an effect on the temperature (and sound level).
I my colleague's case there is probably something else wrong with the fan (or computer), but it is clear that a little bit of dust defensively can have an effect on the temperature (and sound level).
02 June 2009
Breakpoint problem with Eclipse 3.4 and JDK 1.6 update 14
I had problems that some break points did not take in my Eclipse 3.4.1 when I updated from JDK 1.6 update 12 to JDK 1.6. update 14. Well some breakpoints took, but none in the AWT thread. It could be a coincidence, I don't know.
I updated to Eclipse 3.4.2 but that did not solve the problem.
I had to downgrade to JDK 1.6 update 13 to solve the problem. It was enough to choose another JDK for my specific project. Eclipse itself could run update 14.
I searched the Internet but could not find any official bug either in Java or Eclipse. Anybody out there got more information?
Update: the problem is now fixed: http://blog.lesc.se/2009/09/jdk-breakpoint-problem-fixed-in-update.html
I updated to Eclipse 3.4.2 but that did not solve the problem.
I had to downgrade to JDK 1.6 update 13 to solve the problem. It was enough to choose another JDK for my specific project. Eclipse itself could run update 14.
I searched the Internet but could not find any official bug either in Java or Eclipse. Anybody out there got more information?
Update: the problem is now fixed: http://blog.lesc.se/2009/09/jdk-breakpoint-problem-fixed-in-update.html
01 June 2009
Java VisualVM, a better JConsole
A new tool is available for Java developers: VisualVM. JDK 1.6 update 7 and later comes bundled with this new tool. The executable (jvisualvm) can be found in bin or the tools directory.
The first thing I recommend doing is to install the MBean plugin. With this plugin VisualVM gets the mbean feature found in JConsole. In fact I never uses JConsole anymore since VisualVM has all the features, and more.
To install the plugin select Tools -> Plugins -> Available Plugins. Check the VisualVM-MBeans and press install:
Now attach to a process by clicking on it in the list. If the process is on another computer use the Remote-node.
This is how the MBeans tab looks like:
This is how the monitor tab looks like:
The first thing I recommend doing is to install the MBean plugin. With this plugin VisualVM gets the mbean feature found in JConsole. In fact I never uses JConsole anymore since VisualVM has all the features, and more.
To install the plugin select Tools -> Plugins -> Available Plugins. Check the VisualVM-MBeans and press install:
Now attach to a process by clicking on it in the list. If the process is on another computer use the Remote-node.
This is how the MBeans tab looks like:
This is how the monitor tab looks like:
Btrace – a debugging tool with bugs
I tried Btrace (http://btrace.dev.java.net/) it is a debugging tool for Java. I have often been in the situation that a bug has been found in a production system. The production system must run even as I try to find the cause of the bug. That means the (java) program cannot be restarted to add some remote debugging ports or some other start-up options. This is where Btrace comes in. With Btrace you can write small script-like java code fragments so the program can be traced. Btrace accomplishes this by dynamically instrumenting the code.
Let’s take an example. Let’s say your production system tries to find numbers in the Fibonacci sequence:
When installed, right click on the process and select “Trace application…”.
Then paste (or write) the code fragment and press Start. When pressing Start it takes a few seconds for the code to be instrumented. The output is shown in the console below the code fragment.
A little bit more advanced fragment that will print the method arguments when the method nextFibonacci is called:
Everything is not good about Btrace:
Let’s take an example. Let’s say your production system tries to find numbers in the Fibonacci sequence:
import java.util.ArrayList;This Btrace code fragment will print out a trace string to the Btrace console every time the method calculateNext is entered:
import java.util.List;
public class FibonacciService {
private List<Integer> list = new ArrayList<Integer>();
public FibonacciService() {
//First two numbers in Fibonacci sequence.
list.add(0);
list.add(1);
new Thread(new Runnable() {
public void run() {
while (true) {
calculateNext();
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}, "calc-thread").start();
}
private void calculateNext() {
int oldOld = list.get(list.size() - 2);
int old = list.get(list.size() - 1);
int newNumber = nextFibonacci(oldOld, old);
list.add(newNumber);
System.out.println(newNumber);
}
private static int nextFibonacci(int oldOld, int old) {
return oldOld + old;
}
public static void main(String args[]) {
new FibonacciService();
}
}
@OnMethod(Btrace code fragments can be attached to running java processes in two ways. Either use the command line “btrace” command or use a plugin to Suns Java VisualVM. Java VisualVM is like a Jconsole on steroids. It s is included in the JDK bundle since 1.6 update 7 (or something like that). You will find it in the JDK installation directory (either in tools, or in bin). Follow these instructions to add Btrace capabilities to VisualVM: http://btrace.dev.java.net/visualvm_uc.html.
clazz="se.lesc.btrace_example1.FibonacciService",
method="calculateNext"
)
public static void onStartCalc() {
println("Starting to calculate new number...");
}
When installed, right click on the process and select “Trace application…”.
Then paste (or write) the code fragment and press Start. When pressing Start it takes a few seconds for the code to be instrumented. The output is shown in the console below the code fragment.
A little bit more advanced fragment that will print the method arguments when the method nextFibonacci is called:
@OnMethod(A fragment that prints out the return value when the nextFibonacci method is returned:
clazz="se.lesc.btrace_example1.FibonacciService",
method="nextFibonacci"
)
public static void onNextFibonacci(int oldOld, int old) {
print("Input values are ");
print(str(oldOld));
print(" and " );
print(str(old));
println();
}
@OnMethod(There are some restrictions on how advanced the fragments can be. Because the code must never get stuck loops are not allowed. Creating objects arbitrary is not allowed nor calling any methods (except from the BTraceUtils class).
clazz="se.lesc.btrace_example1.FibonacciService",
method="nextFibonacci",
location=@Location(Kind.RETURN)
)
public static void onNextFibonacci(int returnValue) {
print("Result is: ");
print(str(returnValue));
println();
}
Everything is not good about Btrace:
- Slow web page. Perhaps not Btrace fault. The entire *.dev.java.net servers are so slow that it is annoying.
- There is always a risk when instrumenting the code. Out of about 30 runs I had 3 unexpected crashes of the JVM that I can remember. It is with other words somewhat of a risk to run Btrace in a production environment.
- Some features don’t work. For example I tried to use a regular expression to match a method but every time I got java.lang.VerifyError (Edit: I've now submitted a bug report for it: https://btrace.dev.java.net/issues/show_bug.cgi?id=41). Another example is that I tried to get a reference to the current object in side a method, but it did not work.
- The documentation is need improvment. For example Btrace uses some kind of signature matching to find methods with arguments. How this matching is done is not documented. Such a central feature is really important to have documented.
- The project does not look to be actively developed. The last implemented ticket was submitted the 22th of February in 2009. Even critical and easy to fix problems is not fixed. For example in my opinion the bug about that Btrace cannot be run on Windows when there exist a space in the path should really be fixed. Edit: the project apparently has active development, based on the comments on this blog entry. :)