Monday March 23, 2009 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:
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:
scrollPane.setBorder(new EmptyBorder(new Insets(0,0,0,0)));
textPane.setFont(new java.awt.Font("American Typewriter", 0, 14));Here's what we get:
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:
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):
i really dont like to see swing components in javafx, they just look ugly. we need skinnable ui controls as soon as possible
Posted by jorgemania on March 23, 2009 at 11:17 AM PDT #
Agreed - we need skinnable UI controls as soon as possible. But the point of this blog entry was that they don't -have- to look ugly! A proper FX text component would be better, but if you -need- text, the above tricks will hopefully be an okay temporary solution - if you look at the last screenshot it's not obvious that it's Swing!
Posted by Tor Norbye on March 23, 2009 at 11:32 AM PDT #
You did an excellent job of hiding the ugliness of Swing from the end user, but the hackery required at so many different levels of abstraction shows that the ugliness faced by the developer is as bad as it ever was. It will be interesting to see if JavaFX manages to get this right in the end.
Posted by Jim Elliott on March 23, 2009 at 01:01 PM PDT #
Hopefully the SwingComponent.wrap memory leak will be fixed by v1.1.1 :)
Posted by Jean Louis Bonneton on March 23, 2009 at 01:32 PM PDT #
real skinnable Swing components in JavaFX -
http://jfxstudio.wordpress.com/2009/02/18/something-usefull/
Posted by surikov on March 27, 2009 at 12:33 PM PDT #
About the font aa. I found on windows if i pass the jvm argument
-Dawt.useSystemAAFontSettings="gasp"
all fonts will have aa turned on. (that is all the fonts i've tested)
ant
Posted by Antoine Kurukchi on March 28, 2009 at 02:57 AM PDT #
Off topic..
I had a blog request and didn't know how to get it to ya.
Tor would you consider a 'how to optimize my netbeans usage' series of blog posts? I have heard many allusions over the years to your ability to use netbeans in a an optimal way. It would be really kewl if you could share a bunch of those.
Thanx,
LES
Posted by Les Stroud on March 28, 2009 at 09:30 AM PDT #
BTW, this link : http://net.tutsplus.com/videos/screencasts/how-i-can-code-twice-as-fast-as-you/ made me think of it. Obviously, we can be far more sophisticated in nb.
Posted by Les Stroud on March 28, 2009 at 09:32 AM PDT #