29 October 2015

How to make a JTable a specific number of rows high

Java Swing is rather complex. You can do just about anything, but it can be hard to know how to do it. I have for a long time tried to adapt the visible (preferred) size of a JTable. I know how many rows I would like to display, but it is hard to know how to write the code for it.

I figured out this code today:
package se.lesc.blog;

import java.awt.Insets;

import javax.swing.GroupLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import static javax.swing.GroupLayout.DEFAULT_SIZE;

public class TableRowDemo extends JFrame {

    Object[][] data = { {"Kathy", "Smith", "Snowboarding", new Integer(5), new Boolean(false)},
        {"John", "Doe", "Rowing", new Integer(3), new Boolean(true)},
        {"Sue", "Black", "Knitting", new Integer(2), new Boolean(false)},
        {"Jane", "White", "Speed reading", new Integer(20), new Boolean(true)},
        {"Joe", "Brown", "Pool", new Integer(10), new Boolean(false)}
    String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
    public static void main(String [] args) {
        new TableRowDemo().setVisible(true);
    public TableRowDemo() {
        GroupLayout layout = new GroupLayout(getContentPane());
        JLabel label = new JLabel("My table:");
        JTable table = new JTable(data, columnNames);
        JScrollPane tableScrollPane = new JScrollPane(table);
        int numberOfRowsToDisplay = 3;
        //Fetch the border "padding"
        Insets insets = tableScrollPane.getBorder().getBorderInsets(table);
        //Compute the total height of the table
        int preferredTableHeight = insets.bottom + insets.top
                        + (int) table.getTableHeader().getPreferredSize().getHeight() +
                        numberOfRowsToDisplay * table.getRowHeight();
            .addComponent(tableScrollPane, DEFAULT_SIZE, preferredTableHeight, DEFAULT_SIZE)


15 September 2015

How Microsoft SmartScreen works and how it stores data in NTFS streams

Windows 10 (and 8) has a feature called Microsoft SmartScreen. It is split in two parts: one purely for the web and one for files downloaded for the web. I’ll try to explain how SmartScreen for downloaded files work. But first we need to know how streams works

ADS or just ”streams” is a feature in Microsoft NTFS file system feature that allows for ”hidden” data in a file. You can access the hidden data by using the colon separator.
Copy ftp.exe from C:\Windows\System32 to c:\temp\. I used ftp.exe because it is an unsigned executable that you probably can find on your hard drive. Use Windows PowerShell for these commands. Create an alternative stream by using notepad:
PS C:\temp> notepad ftp.exe:LennartStream
Answer yes in Notepad. Enter the content ”Hello World!”, save and close the file/stream. We can now open the file/stream by the same Notepad command again. No actual new file was created on the hard drive. It just created a new stream. You can list the streams by using Windows Sysinternals Streams program or just use PowerShell:
 PS C:\temp> Get-Item ftp.exe -Stream *

   FileName: C:\temp\ftp.exe

Stream                   Length
------                   ------
:$DATA                    55808
LennartStream.txt            12

As you can see my ”LennartStream” is there and it takes 12 bytes (the ”Hello World!” string). The main program for ftp takes 55808 bytes.

Microsoft SmartScreen
SmartScreen (https://en.wikipedia.org/wiki/Microsoft_SmartScreen) provides some protection for executing downloaded files from the internet. When a file is downloaded in the web browser (for example Firefox), a stream called “Zone.Identifier” is created. If the Zone is “dangerous” a warning dialog may be presented to the user when the file is run. In Windows 10 the settings for SmartScreen is in Control Panel\System and Security\Security and Maintenance.

Use notepad to edit the Zone.Identifier stream:
PS C:\temp> notepad ftp.exe:Zone.Identifier
Create a new stream and enter this content:

Now double click on ftp.exe to run it. You will now get a dialog like this:
“Windows protected your PC. Windows SmartScreen prevented an unrecognized app from starting. Running this app might put your PC at risk”

Press “More info”:

Choose “Run anyway” and then just close the ftp program. View the Zone.Identifier stream again:
PS C:\temp> notepad ftp.exe:Zone.Identifier
The content has now changed to:

As you can see SmartScreen has updated the stream data with respect to your answer in the dialog.

Please note that if the file is signed with a certificate and Microsoft can verify it (with some magical “reputation” system I don’t know the details on) the dialog may not be shown and the stream will not be changed.

23 April 2014

What to do when you get "Comparison method violates its general contract!"

Java 7 switched to a new sort algorithm - called ComparableTimSort. The old algorithm would silently ignore when you violate the Comparator/Comparable contract. The new one throws an exception "Comparison method violates its general contract!"

The contract is in the interface Comparable. The most common is to break the transitive contract. That is: If A < B and B < C, than A should be less than C. Stackoverflow.com has several posts on the issue.

I have made a small program that detects what elements that causes this issue. It only works for small lists but has helped me to debug compareTo()/compare() methods.

package se.lesc.blog;

import java.util.Comparator;

public class TransitivityTester {

    public static void transitivityTester(Object list[]) {
        transitivityTester(list, null);
    /** Check that a lists compareTo() method is correct with respect to transitivity */    
    public static void transitivityTester(Object list[], Comparator<Object> comparator) {

        //Cache all possible comparison (for speed)
        byte[][] compareTable = new byte[list.length][];
        for (int x = 0; x < list.length; x++) {
            byte[] column = new byte[list.length];
            compareTable[x] = column;
            for (int y = 0; y < list.length; y++) {
                int result;
                if (comparator != null) {
                    result = comparator.compare(list[x], list[y]);    
                } else {
                    Comparable<Object> comparableX = (Comparable<Object>)list[x];
                    result = comparableX.compareTo(list[y]);
                byte normalizedResult = normalize(result);
                column[y] = normalizedResult; 
        //Expensive O(n^3) iteration
        for (int a = 0; a < list.length; a++) {
            for (int b = 0; b < list.length; b++) {
                for (int c = 0; c < list.length; c++) {

                    if (compareTable[a][b] < 0 && compareTable[b][c] < 0) {
                        if (! (compareTable[a][c] < 0)) {
                            transitiveError("A < B && B < C but not A < C", a, b, c);
                    } else if (compareTable[a][b] > 0 && compareTable[b][c] > 0) {
                        if (! (compareTable[a][c] > 0)) {
                            transitiveError("A > B && B > C but not A > C", a, b, c);
                    } else if (compareTable[a][b] == 0 && compareTable[b][c] == 0) {
                        if (! (compareTable[a][c] == 0)) {
                            transitiveError("A == B && B == C but not A == C", a, b, c);
    private static void transitiveError(String transitiveRule, int a, int b, int c) {
        String errorMessage =
                        transitiveRule +
                        " (A = " + a + ", B= " + b + ", C = " + c + ") " + 
                        "Comparison method violates its general contract!";
        throw new IllegalArgumentException(errorMessage);

    private static byte normalize(int result) {
        byte normalizedResult;
        if (result > 0) {
            normalizedResult = 1;
        } else if (result < 0) {
            normalizedResult = -1;
        } else {
            normalizedResult = 0;
        return normalizedResult;

Here is some test code for the above class:
package se.lesc.blog;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

import org.junit.Before;
import org.junit.Test;

public class TransitivityTesterTest {

    private List<Integer> list;

    public void setUp() {
        list = new ArrayList<Integer>();

    public void testNormalIntegerListShouldWork() {
        TransitivityTester.transitivityTester(list.toArray(new Integer[0]));        
    public void testCrazyOneIsAlwaysMoreComparator() {
        TransitivityTester.transitivityTester(list.toArray(new Integer[0]), new CrazyOneIsAlwaysMoreComparator());        
    public void testCrazyAllIsOneComparator() {
        TransitivityTester.transitivityTester(list.toArray(new Integer[0]), new CrazyAllIsOneComparator());        
    public static class CrazyOneIsAlwaysMoreComparator implements Comparator<Object> {
        public int compare(Object o1, Object o2) {
            Integer i1 = (Integer) o1;
            Integer i2 = (Integer) o2;
            if (i1.intValue() == 1) {
                return 1; 
            } else {
                return i1.compareTo(i2);
    public static class CrazyAllIsOneComparator implements Comparator<Object> {
        public int compare(Object o1, Object o2) {
            Integer i1 = (Integer) o1;
            Integer i2 = (Integer) o2;
            if (i1.intValue() == 1 || i2.intValue() == 1) {
                return 0; 
            } else {
                return i1.compareTo(i2);

15 January 2014

More Btrace debugging

In the post http://blog.lesc.se/2009/06/btrace-debugging-tool-with-bugs.html I wrote about how it is possible to debug a running Java application. Here is some more magic.

Let say you have this simple program:

import javax.swing.JFrame;

public class SimpleApp {
  public static void main(String args[]) {
    JFrame frame = new JFrame("Simple application");
    frame.setSize(200, 100);

And this Btrace script:
import com.sun.btrace.annotations.*;
import static com.sun.btrace.BTraceUtils.*;
import java.awt.EventQueue;
import java.awt.AWTEvent;
import java.awt.event.MouseEvent;
import java.lang.reflect.Field;

public class SimpleAppMouseTracer {
  public static void onevent(@Self EventQueue queue, AWTEvent event) {
    if (event instanceof MouseEvent) {
      MouseEvent mouseEvent = (MouseEvent) event;
      Field idField = field("java.awt.AWTEvent", "id");
      Field xField = field("java.awt.event.MouseEvent", "x");
      Field yField = field("java.awt.event.MouseEvent", "y");
      if (getInt(idField, mouseEvent) == MouseEvent.MOUSE_CLICKED) {
          strcat("x = ", strcat(str(getInt(xField, mouseEvent)),
          strcat(", y = ", str(getInt(yField, mouseEvent))))));

I have installed the Btrace into Java VisualVM (I downloaded and installed all the visualvm plugins from https://kenai.com/projects/btrace/downloads).


Each time I click with the mouse inside the Window I get a printout with the mouse coordinates.

The Btrace code is Java, but with many restrictions. That is why the String creation code gets a bit large; because build in Btrace functions must be used. The same goes for accessing variables inside the MouseEvent object.

08 August 2013

A Java program that triggers the java.lang.OutOfMemoryError: GC overhead limit exceeded

I wanted to test how the -XX:+HeapDumpOnOutOfMemoryError JVM option worked when a JVM goes out of memory, but because of GC overheadlimit. This is my try:

import java.util.ArrayList;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class OutOfMemoryProvoker {
    private static final int MEMORY_BLOCK_MAX_SIZE = 1000000;
    private static final int REMOVE_BLOCK_FACTOR = 20000;

    public static void main(String[] args) throws Exception {
        final ArrayList<byte[]> list = new ArrayList<byte[]>();
        Random random = new Random(0);
        Timer timer = new Timer("reportTimer");
        timer.schedule(new TimerTask() {
            public void run() {
        }, 5000, 5000);
        while (true) {
            int memSize = random.nextInt(MEMORY_BLOCK_MAX_SIZE) + 1;
            byte[] memBlock = new byte[memSize];
            int removeBlockIndex = random.nextInt(REMOVE_BLOCK_FACTOR);
            if (list.size() > removeBlockIndex) {

    private static void report(ArrayList<byte[]> list) {

This works very nice. You have to modify the MEMORY_BLOCK_MAX_SIZE and REMOVE_BLOCK_FACTOR to match your memory settings. I used a 8 GB heap for my numbers.

Nice things to note:
  1. Java GC really dislikes different sizes of memory block. This is why I randomize the memory block sizes to provoke as much GC work as possible
  2. The REMOVE_BLOCK_FACTOR controls the chance that a memory block is dereferenced and eligible for GC. It simply removes an item from the list (if the list is big enough). This has the nice characteristic the the chance that a block is removed is higher the more the list is filled.

29 January 2013

Office/Word 2003 in Windows 8

So the Windows 8 Upgrade Assistant tells me that I cannot use Office 2003:
Well I upgraded my Windows 7 to Windows 8 (that is I did NOT perform a clean install). And how does for example Word 2003 work:
Well it turns out that it works just fine! I haven't tried every feature, but everything I have tried appears to work. That includes Excel 2003 and Visio 2003.

17 January 2013

The Eclipse foreach template

There are many "hidden" features in Eclipse that are really good. Today I discovered the foreach template.

It works like this: place your cursor just above a array or Iterable (List) declaration. Press Ctrl + Space and press Enter. Eclipse will now create a for loop that you can use. It will use the Iterable variable that is closest.