IntelliJ IDEA 14: How to stop stripping of trailing spaces

I’ve recently been using Markdown in conjunction with Metalsmith to create some new static content web sites (more on this in a future post). IntelliJ IDEA, IMHO the world’s best IDE for Java/web/Python/PHP (and many more languages/technologies) supports all the popular web technologies and is a joy to use most of the time.

However, I came across an annoying little problem recently when I noticed that line breaks were missing from my Markdown generated content. Markdown uses 2 trailing spaces on a line to signify that a line break is required, and it transpired that IDEA was stripping these trailing spaces from lines when the Markdown file was saved!

After a bit of a search through the IDEA Editor settings I finally found the offending option buried deep in the Editor / General section:

idea-14-settings

The default setting is set to strip trailing spaces so simply select “None” here and your Markdown line breaks will remain intact!

A month of using my MacBook Pro

It’s been over a month since I got my new MacBook Pro so I thought I’d post a few thoughts on my experience with it so far.

First, I’ve got to say I love it!

It exudes quality in nearly every area.

On the hardware side, the things I love most are:

  • the aluminium unibody construction is rock solid, yet still light
  • the quad core Intel Core i7 processor, 16GB RAM and 512GB flash storage make it fly!
  • the Retina 15″ screen is very high quality and provides plenty of screen real estate to work with. I was concerned about dropping down from a 17″ screen to 15″ but that’s not proved to be a problem at all
  • the trackpad is the best I’ve ever used… very accurate and responsive and when combined with multi-touch gestures takes it to another level
  • battery life has been very good so far (I get home from my 4 hour commute to London and back with around 80% battery left which is fantastic compared with the 20% remaining I used to get from my old HP laptop!)
  • the sleep and instant-on behaviour when closing and opening the lid is great
  • the Magsafe 2 power connector is so quick and easy to connect with its magnetic connection and useful indicator LED showing charging state

On the OS / software side I’ve found working with OS X on a daily, development-oriented basis quite refreshing. The multiple Spaces (desktops) works very well and intuitively with multi-finger trackpad swipes to switch between them. I’m also using the Mission Control (formerly Exposé) feature a lot to see a birds eye view of all applications I have open, and the App Exposé feature to see all windows opened by the current application.

The recent Mac OS X 10.10 Yosemite upgrade looks really nice and makes it even more pleasant to use.

When I’m travelling, I rely on the mobile network connection from my Nexus 5 phone for internet access. With my old Windows laptop I used to use a wifi hotspot on the phone to connect, but on the MacBook I’m using the Bluetooth connection which seems easier and very stable.

The only minor problem I’ve had is that the Moshi iGlaze transparent hard case I fitted for some extra protection started to crack in the corners of the lid cover. This happened just over a month after getting it but Amazon replaced it free of charge when I reported the problem to them. It is a nice case and definitely adds  some valuable protection without detracting from it’s appearance – in fact most people don’t even realise there’s a case on it! – but I think the cracking is a basic design flaw so I’m expecting it to happen again 🙁

 

 

Creating Java Swing components – the List Index Bar

In what may turn out to be a regular feature, I wanted to start talking about some of the work I do involving the creation of custom Java Swing components. As anyone who has seen the GUIs I create will know, I quite often create custom components for a variety of purposes. It’s not difficult to write custom Swing components, but there are a few hints and tips which can make this easier and result in well performing components. Hopefully this series will be interesting to those readers who are using Java Swing and inspire them to create their own interesting custom components.

So… let’s get started!

For one of the Java Swing GUI projects I’m working on there’s a requirement to display a visual representation of the index of a list of items with particular items in this index highlighted according to certain criteria. Think along the lines of the margin shown in intelligent code editors used to highlight warnings and errors in the code (such as the right hand margin in IntelliJ IDEA), and you’re not too far from the mark.

This is quite a specialised component so obviously doesn’t exist in the standard Swing set, but it’s a nice little component to write so I thought I’d share with you how I created it. To show you exactly what this component will look like when finished there’s a screenshot of it in action on the right.

Getting started

This will be a fairly simple component in terms of graphical content and behaviour, and there are no existing Swing components which are similar to it, so we will derive our new component from the base Swing component class, JComponent.

public class ListIndexBar extends JComponent {

}

Breaking the design down into the key aspects, we need to consider:

  • keeping track of how many items there are in the list this component represents
  • keeping track of the indices of all items which need to be highlighted
  • calculating the vertical pixel position and height of each item marker based on the current height and the total number of items in the associated list
  • painting the item markers
  • handling mouse events to change the cursor when hovering over item markers and to handle mouse clicks on item markers

So let’s start with the first couple of items.

private int itemCount;

// set of list indices associated with items to be marked
private Set<Integer> markerSet = new HashSet<Integer>();

public int getItemCount() {
  return itemCount;
}
public void setItemCount(int itemCount) {
  this.itemCount = itemCount;
  recalc();  // more on this later
  repaint();  // we've made changes which affect appearance so trigger a repaint
}

public Set<Integer> getMarkerSet() {
  return markerSet;
}

public void addMarkers(Collection<Integer> markers) {
  markerSet.addAll(markers);
  repaint();
}

public void removeMarkers(Collection<Integer> markers) {
  markerSet.removeAll(markers);
  repaint();
}

public void clearMarkers() {
  markerSet.clear();
  repaint();
}

Calculating item marker sizes

Now let’s do the simple calculations associated with working out where each item marker needs to be painted.

We know the height of the component and the total number of items in the associated list so we can calculate the vertical size each item marker needs to be. From this we can work out the vertical pixel position that each item marker needs to be painted at. Note, this calculation needs to be done whenever there is a change in the component size or when the total number of associated list items changes. Accordingly, we call recalc() in the setItemCount method and we also override the two setBounds methods to call recalc() after calling their superclass method.

private double scaleFactor;
private int markerHeight;

private void recalc() {
  scaleFactor = getHeight() / (double) itemCount;
  markerHeight = Math.max(2, (int) scaleFactor);  // markers have min height of 2
}

@Override
public void setBounds(Dimension dimension) {
  super.setBounds(dimension);
  recalc();
}

@Override
public void setBounds(int x, int y, int width, int height) {
  super.setBounds(x, y, width, height);
  recalc();
}

Painting

So now we get to the guts of the component – the painting code. Hopefully this should be self explanatory – there’s nothing too complex going on here.

@Override
protected void paintComponent(Graphics g) {
  // cast to a Graphics2D so we can do more with it
  Graphics2D g2 = (Graphics2D) g;

  // paint or clear the background depending on whether this component is opaque
  // or not. store the current composite so we can restore it later
  Composite composite = g2.getComposite();
  g2.setColor(getBackground());
  if (!isOpaque()) {
    // if not opaque, set the alpha composite to clear the background
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.DST));
  }
  g2.fillRect(0, 0, getWidth(), getHeight());
  g2.setComposite(composite);  // restore the previous composite

  // markers will be drawn with the foreground colour
  g2.setColor(getForeground());

  int pos;
  for (Integer marker : markerSet) {
    // for each marker, calculate the appropriate Y position
    // and paint a marker of required size
    pos = (int) (marker * scaleFactor);
    g2.fillRect(0, pos, getWidth(), markerHeight);
  }
}

Handling mouse events and finishing off

We’re nearly finished now – the only thing left is to add the code to handle mouse events and initialise the object in its constructor.

We need to handle three types of mouse event:

  • motion events so that we can change the cursor when hovering over an item marker to give a visual cue to the user that the item can be clicked on
  • mouse exit events so we can clear the highlighted index and reset the cursor when the pointer leaves the component
  • mouse click events when hovering over item markers

We also need to keep track of the index of the last highlighted index so it can be included in the selection notification event. If there is no currently highlighted index we set this to -1. We are re-using the existing Swing ListSelectionListener and associated ListSelectionEvent classes here for our notifications for convenience as they are a close match to what we need. We could quite easily enough have used our own custom listener and event classes which are more tailored to this particular situation – but it doesn’t make much difference.

And finally, we do the last bit of initialisation in the constructor, including setting the initial number of items and setting an initial minimum and preferred size so that the component appears with a sensible size when first created. Oh, and we provide an alternative no-arg constructor which uses a default item count of 1!

// the index of the currently highlighted marker index
// gets set when the pointer hovers over a marker and cleared when the mouse is moved off a marker
// or the pointer leaves the component completely
private int highlightedIndex = -1;

// keep track of listeners interested in marker selection events
private List<ListSelectionListener> listeners = new ArrayList<ListSelectionListener>();

public ListIndexBar(int itemCount) {
  this.itemCount = itemCount;
  recalc();

  // add a mouse motion listener to track the current highlighted marker
  addMouseMotionListener(new MouseMotionAdapter() {
    @Override
    public void mouseMoved(MouseEvent e) {
      // calculate the list index which is under the mouse pointer
      int pos = (int) (ListIndexBar.this.itemCount * (e.getPoint().getY() / getHeight()));
      if (markerSet.contains(pos)) {
        // we're over one of the markers so record the index and change the cursor
        highlightedIndex = pos;
        setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
      } else {
        // we're not over any marker so clear the highlighted index
        // and reset the cursor
        highlightedIndex = -1;
        setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
      }
    }
  });

  // add a mouse listener to handle mouse clicks on markers
  addMouseListener(new MouseAdapter() {
    @Override
    public void mousePressed(MouseEvent e) {
      if (highlightedIndex != -1) {
        ListSelectionEvent event = new ListSelectionEvent(ListIndexBar.this, highlightedIndex, highlightedIndex, false);
        for (ListSelectionListener listener : listeners) {
          listener.valueChanged(event);
        }
      }
    }

    @Override
    public void mouseExited(MouseEvent e) {
      // clear the highlighted index when we leave this component
      highlightedIndex = -1;
      setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
    }
  });

  // give the component a min and preferred size
  setMinimumSize(new Dimension(16, 60));
  setPreferredSize(new Dimension(16, 60));
}

public ListIndexBar() {
  this(1);
}

public void addSelectionListener(ListSelectionListener listener) {
  listeners.add(listener);
}

public void removeSelectionListener(ListSelectionListener listener) {
  listeners.remove(listener);
}

And that’s it!

Wrapping up

This is not a particularly complex custom component so hopefully the code has been easily understandable and I hope it’s given you an insight into how you can create effective custom components without having to write too much code.

I’ve attached a complete copy of the component code together with an example class making use of the component below.

ListIndexBar component code and example

New Android dev tools – visual UI designer

I watched a video of one of the Google I/O 2011 talks last night by Xavier Ducrohet and Tor Norbye about the new Android development tools and was particularly interested in the new visual UI designer in ADT 11. I was very impressed with what I saw but one downside is that I believe it is only currently provided as an Eclipse plugin whereas I am 100% an IntelliJ IDEA man. Hopefully an equivalent IDEA plugin will appear before too long.

On Apache SSL and name based virtual hosts

Background

I run several services from my home Linux server to support the home software development I do. This includes services such as Subversion source control, Nexus Maven repository, JIRA issue tracking, Jenkins continuous integration build server to name a few. To provide a clean and consistent entry point into each service, I use separate vhosts in my Apache 2 server, each with its own dedicated sub-domain e.g. nexus.server.com, jira.server.com etc. These vhosts then proxy onto the underlying service using a mixture of HTTP, DAV and AJP13 proxying. [NOTE: I’m using server.com instead of my real domain here simply as an example]

As I want all of these services to be available securely externally I also ensure that they are all served over an SSL connection. Apache is responsible for the SSL handling – SSL is terminated at Apache and then plaintext proxying is used to the underlying service (SVN, Nexus etc.)

The use of SSL necessitates SSL certificates for each vhost, which is pretty straightfoward to implement. I have my own CA certificate which I use to issue certs for each of my services and by adding this CA cert to the truststores on client machines, the certification trust chain can be completed and the SSL connection is verified as valid.

I’ve recently gone through a process of renewing the various SSL certs for my services and moving them to their own dedicated sub-domains (previously they were simply sub-contexts from my main www.server.com domain e.g. www.server.com/nexus, www.server.com/jira etc. rather than having their own sub-domains e.g. nexus.server.com, jira.server.com etc.) Configuring the vhosts in Apache was trivial and on the face of it everything appeared to be working just fine after the changes. Accessing each service from a browser, the SSL certificates were being verified as valid and the web applications were completely functional. It wasn’t until I tried to access my Nexus Maven repository from a Maven command line build that I noticed there was a problem…

Where is that SSL cert coming from?!

On attempting to establish an SSL connection with my Nexus server, the connection was being rejected with a the following exception:

java.security.cert.CertificateException: No name matching nexus.server.com found

I knew that the SSL cert configured in my Nexus vhost was correctly issued for that sub-domain so I couldn’t understand why it was complaining. To investigate further I invoked mvn with the extremely useful Java network debugging property:

-Djavax.net.debug=ssl

This results in the full SSL handshake being logged which can be invaluable when investigating SSL problems. Alternatively, if you’re not using a Java based client and have openssl installed you can use the following command to inspect details of the SSL handshake:

openssl s_client -connect nexus.server.com:443 -status

By doing this I could see that the subject (and specifically the CN element) of the cert being returned by Apache was www.server.com instead of nexus.server.com! Woah – what was going on here…?

The only place that the www.server.com SSL cert was mentioned in my Apache configuration was in the www.server.com vhost – but it couldn’t be using that, could it? As a simple test I tried changing this vhost configuration to use the nexus.server.com cert and then restarted Apache. The next time I ran my mvn command it verified the SSL connection to nexus.server.com with no problems i.e. the SSL server cert now being returned was nexus.server.com! This was very strange I thought… until I started to think more about how Apache name based vhosts actually work…

Limitations of Apache name based virtual hosts

I started Googling on this subject and came across this very interesting Wiki article. This article explains the problem very well, but to summarise… it’s all to do with the way that name based hosts work in Apache: It relies on the Host: header in the HTTP request to determine which vhost this request should be serviced by. In the case of an HTTPS request, this only takes place after the initial SSL connection has been established. Therefore, there isn’t enough information available to Apache in that initial connection establishing phase in order to determine which SSL server cert to return in the SSL handshake. As a result, Apache uses the first SSL cert it finds in the ordered list of vhost configurations. In my case, this was for my www.server.com vhost which explains why it was using the www.server.com SSL cert!

But how could I get round this problem if Apache will only ever use one SSL cert in its SSL handshake?

Introducing wildcard SSL certs

The referenced article mentions the use of wildcard SSL certs i.e. those with a subject name of the form *.server.com. This will only work if all of the subsequent vhosts use genuine server.com sub-domains, but in my case that is true.

To be honest, I’d not really heard of wildcard SSL certs before so after a bit more reading I tried creating one for my domain – with a subject CN of *.server.com. After configuring this in each of my Apache vhosts and a bit of testing everything seems to work just fine. The only difference between now and my previous configuration is that the SSL certs associated with each vhost as less specific than before but I can’t see any problem with that at all.

So, wildcard SSL certs it is from now on!