http://sdickinson.com/wordpress/wp-content/themes/HashOne
http://sdickinson.com/wordpress
Obox Signature Series Subscribe to my RSS feed

0 Comments Java Font issues

Article written by the brilliant Sam on the 27 Apr 2009 , in the Java category

An interesting problem I came across at work today (well, came across on Friday, solved today).  Basically I needed to get two fonts of different sizes (only containing numbers) to line up at the top on one side, and the bottom on another.

Problem is that the Java labels were taking into account the Ascenders and Descenders which were different heights due to the fonts being different sizes.

I’ve made a bit of a pic that describes all the info you can get from the Java FontMetrics class.

FontInfo

Basically, because I was only using numbers, they effectively were the ‘a’ in this picture (there were ascent’s above them)

So what I needed to do was calculate the difference between the top of the characters and the top of the area in both the sizes.  Problem is that you can’t easily just get the height of the font.  Ascent is given by FontMetrics.getAscent(), Decents similar, Leading same again.  So what I ended up having to do was get the actual glyph of the character, and subtract that from ascent size (which as you can see in the picture, comes from the baseline – shown in red).

Code follows (m_fntBig and m_fntSmall are the large and small font member variables):-

// Hack to get the font metrics
java.awt.image.BufferedImage image = new java.awt.image.BufferedImage(2,2,java.awt.image.BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = image.createGraphics();
FontMetrics fmBig = g2.getFontMetrics(m_fntBig);
FontMetrics fmSmall = g2.getFontMetrics(m_fntSmall);
 
// Get the size of a 0 (strangely enough you can't do this with Font Metrics)
GlyphVector gvSmall = m_fntSmall.createGlyphVector(fmSmall.getFontRenderContext(), "0");
int nGlyphSmallHeight = gvSmall.getGlyphPixelBounds(0, null, 0, 0).height;
GlyphVector gvBig = m_fntBig.createGlyphVector(fmSmall.getFontRenderContext(), "0");
int nGlyphBigHeight = gvBig.getGlyphPixelBounds(0, null, 0, 0).height;
 
int nTopOffset = (fmBig.getMaxAscent() - nGlyphBigHeight) - (fmSmall.getMaxAscent() - nGlyphSmallHeight);

So the code above basically gives us the offsets we need to use to line up the top.

Unfortunately, I did a stupid thing, and to line up the bottoms, I was just calculating the difference in the descenders, which as you can see in my picture above, is wrong. We need to include the leading space too (interestingly it’s pronounced Ledding and comes from the amount of Lead used between the lines in printing presses – Wikipedia has some great info on it).

So to calculate the bottom difference we get:-

int nBottomOffset =  (fmBig.getMaxDescent() + fmBig.getLeading()) - (fmSmall.getMaxDescent() + fmSmall.getLeading());

Now we have the offsets for both the top and bottom, and we can now move our labels around as needed (in my case, I had 3 labels within a SpringLayout) and will work with most fonts and sizes (as long as the numbers are all the same height, which is a reasonable assumption in a financial product).

Read More Add a Comment

0 Comments Stepping into Java source with Eclipse

Article written by the brilliant Sam on the 17 Dec 2008 , in the Uncategorized category

This will let you remotely debug an applet using Eclipse.  As far as I know, this will only work with Java 1.6 update 11 and above, but you can have old VM’s installed and only have them enabled (I’ll leave that as an exercise to the reader).

  1. You will need JDK 1.6 update 11 installed (which should install JRE update 11 along with it)
  2. Open your Java Control Panel, go to the Java Tab, and click the view button for Java Applet Runtime Settings
    Applet Settings Window

    Applet Settings Window

  3. Click Find and navigate to your JDK directory (in my case it was C:\Program Files (x86)\Java\jdk1.6.0_11\jre)
  4. Double click the Version field, add something like -debug to the string and disable the other VM’s

    Applet Settings after adding VM

    Applet Settings after adding VM

  5. Add your normal debug parameters in Java Runtime Parameters (in my case -Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,address=1235,suspend=n)
  6. Hit Ok/Apply on everything and close the Java Control Panel page
  7. In Eclipse make sure your default JDK is the one specified in the applet runtime settings (in your project properties)
  8. Open the Debug Configurations (under the Run menu), select your particular Remote Java Application, and go to the Source tab
  9. Click Add and select External Archive
  10. Select your src.zip in your JDK directory (in my case C:\Program Files (x86)\Java\jdk1.6.0_11\src.zip)

    Eclipse Debug Window

    Eclipse Debug Window

  11. Press Apply and you should now be able to debug your applet as normal, but with the added bonus of being able to step into the JDK code
Read More Add a Comment