Monday, March 23, 2009

JavaFX Text Component

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


At the Roundup a few weeks ago we rewrote the old Swing JFlubber application to JavaFX. We had a brand new graphical design done in PhotoShop, and we hooked up the functionality with some swanky effects. I might get into that in another blog entry.



But one challenge we ran into was that of displaying text. In the Flubber application we need to have an editable text area where flub times are automatically inserted and the user can add additional comments. JavaFX makes it easy to throw some simple text in a design, but edit, scroll, and so on? Not yet.



Proper GUI components for JavaFX is coming. But in the mean time, there are some tricks you can use. Put simply, you can use a Swing text area, but without looking like Swing. Here's how. First, create a JavaFX scenegraph node for the Swing text component:


var textPane = new JTextPane();
var scrollPane = new JScrollPane(textPane);
var text: SwingComponent = SwingComponent.wrap(scrollPane);

Let's see how that looks:




Ugh!! Not what we want. Obviously, we don't want the text area to look like Swing... we have a nice background as part of the PhotoShop design that we want to use under below the text. But that's not hard to fix. Java colors have an alpha channel, for opacity. We can use a completely transparent background on the text area to make it just pass through its background (and we have to make the scroll pane nonopaque as well):

textPane.setBackground(new java.awt.Color(0,0,0,0)); // 0 opacity => 100% transparent!
textPane.setForeground(java.awt.Color.WHITE);
textPane.setCaretColor(java.awt.Color.WHITE);
scrollPane.setOpaque(false);

Let's try again:




Much better! But there is still a gray rectangle on top of the graphics, placed there by the border of the scrollpane. We can get rid of that too:

scrollPane.setBorder(new EmptyBorder(new Insets(0,0,0,0)));





Now we're talking! But the font is too small. Dick told me he wants to use a Courier font. So let's try this one:

textPane.setFont(new java.awt.Font("American Typewriter", 0, 14));

Here's what we get:




Ewwwwww! The font is not antialiased. I tried a bunch of things to fix this -- for example setting antialias rendering hints on the component itself, setting the aa system property, etc. It looks like there is a bug here in that the rendering hints aren't picked up properly for the wrapped Swing components. But I did find a workaround that works: We can set the antialiasing rendering hints directly on the graphics object ourselves. That means we need to get involved in the painting of the component itself, but luckily that's trivial. Instead of creating a new JTextPane, we'll create a simple subclass of it where we override the paint method to add the rendering hints:


import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JTextPane;

public class AntiAliasedTextArea extends JTextPane
{
@Override
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
super.paint(g);
}
}


Now we can just change

var textPane = new JTextPane();

to

var textPane = new AntiAliasedTextPane();


and we get this:




Ta-da!



But there is one more problem... What if we add a lot of text:




Scrollbars! We don't want those. This text pane won't be used for much text, so you can just move the caret around like in a text field to navigate the overflow content. So let's turn off the scrollbars:


scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);


and with that, the text pane behaves exactly the way we want. Now you can manipulate text in the usual way: textPane.setText(string), textPane.getText(), etc.



While we're at it, let's fix the selection colors as well such that when you select text you don't get the telltale Swing light blue:


textPane.setSelectionColor(new Color(255, 255, 255, 50));
textPane.setSelectedTextColor(new Color(255, 255, 255, 255));

Note again how we can use transparency on this colors to give a nice glass effect on the selection (I also bumped up the font size):



Hopefully these tricks will help you with your text needs until we have real JavaFX components...



Monday, March 16, 2009

NetBeans Screenshot of the Week 42: JavaScript Native Interface

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


At the Roundup last week I talked to
Robert Cooper, who's doing a lot of interesting work with GWT (Google Web Toolkit). In GWT (which compiles Java to JavaScript), you can embed JavaScript directly within the Java files inside comments with special markers. Robert mentioned that IntelliJ has a nice feature for GWT programmers where your native JavaScript snippets get JavaScript highlighting etc.



I figured that would be a trivial thing to add to NetBeans with our language embedding infrastructure. Sure enough, the patch just adds 13 lines of code. Here's a screenshot - showing JavaScript (regular expressions etc) inside Java code (with packages etc) - it's inside comments that start and end with -{ and }-:




If you want this functionality in your own 7.0 build, just download this module nbm, or apply the patch to your own build.


Thursday, March 12, 2009

Java Posse Roundup 2009

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


I just got back from the Java Posse Roundup 2009. It was our third year (blog entries from 2007, 2008), and therefore I can add "as usual" when I state that it was a wonderful time.



This year's topic was "developer productivity", which is obviously a passion of mine, so I found all the technical sessions thoroughly enjoyable. We recorded all of them so they will be released slowly through the regular podcast channel.



I was able to redeem myself from last year's skiing disaster but not falling doesn't make very compelling video...



Another highlight is the lightning talks. This year we had two hours of lightning talks every night. We'll be releasing those on a quicker schedule as YouTube videos in our
YouTube channel. I can recommend Barry Hawkins' talk as a starter. The nice thing about lightning talks are that they are short so go ahead, give it a try!



In order to enforce the 5 minute rule for lightning talks, we wrote a little timer app, as seen in this picture:




The laptop on the left is running our downcounter. It starts at 5 minutes, and when it gets down to 0 it plays a sound effect which politely asks the user to, ehm, stop. We wrote this app as a collaboration on the first day of the conference, during the language dojos. We had 3-4 sites where different people studied Scala, Groovy, Python, Fan and JavaFX, according to their interests. In the JavaFX group we played around with the language in the morning, and then decided to build something real - the countdown timer. We needed a sound effect to play when the timer expires, so we held up one of our conference audio recorders and all at once yelled "Shut Up!" into it. In the room next door Dick Wall had just started talking about Scala, and our brief recording session apparently caused some confusion...



P.S. There are a lot of pictures from the Roundup on flickr.
The below are by Joe Nuxoll.



Crested Butte, Colorado by night:



The first day of the Open Conference we held a languages-on-the-JVM dojo. This is a picture of those of us playing with JavaFX:



The lightning talks schedule for the Tuesday night:



On Thursday we had a progressive dinner where each household served one course for the other participants. Carl made Indian Style chicken wings and Ido is getting ready to serve:



Dick and Dianne talking during the progressive dinner.



Wednesday, March 11, 2009

New Job

WARNING: This blog entry was imported from my old blog on blogs.sun.com (which used different blogging software), so formatting and links may not be correct.


Apologies for the recent blog silence for me. It's not that I've been slacking off. Quite to the contrary!
The biggest news is that I've changed teams: I'm now working on JavaFX! And more specifically, the designer tool.




If you don't know what JavaFX is, you're probably reading my blog because you're interested in Ruby, Python or the various other languages for NetBeans I've been involved with. If so, fear not - NetBeans language support is in great hands - Erno just improved the Rails dynamic finders code completion for Ruby for example. Of course, as an open source project we can always use more contributors! I've received a bunch of patches for the Python support recently which I've been happy to apply immediately. Keep 'em coming!



Briefly, JavaFX is a new UI stack for Java which makes it trivial to build pretty, dynamic and interactive UIs. While Java has always made it easy to target multiple operating systems, JavaFX makes it easy to target the completely separate platforms of desktop, web and mobile. If you haven't looked into it, you should.



JavaFX has its own language, JavaFX Script. It has some language level features which makes it really suited to building UI applications - from something simple like a literal for durations (so you can write 2m or 5s or 250ms in your source code), to something advanced like variable bindings which give you all of the power of traditional property change listeners, but without the pain (and it's more powerful than that - you can for example bind the rotation angle of a clock hand to an expression which computes the angle from the current time, and whenever the time variable changes the clock hand rotation is updated.) As a Java developer (and a Ruby and Python and JavaScript coder as well) I can truly say I've seen some things in JavaFX Script that I would like to see in other languages. I might talk about that in an upcoming blog entry.



If you're one of the alternate-languages-on-the-JVM people, I think you should seriously look into adding a binding layer for the JavaFX platform to your language. Libraries like Groovy Swingbuilders (and similar libraries for Ruby etc) have made Swing more accessible, but at the end of the day you're still dealing with Swing. If you want to add drop shadows, transition animations etc. a JavaFX DSL would be a much better approach. And besides, we're firing on all 256 cylinders on the JavaFX platform -- from the base Java platform (adding modularity so we can provide a barebones FX runtime), to the graphics system, to components, to the language, and up to the designer tool! I think it's going to shake up the RIA space - which is why I wanted to be part of it.



I promise my next blog entry won't be long in waiting, I've got a bunch of things queued up!