Thứ Bảy, 7 tháng 1, 2012

Java Back in the OSCON 2012 Fold

By all accounts I have read and others have expressed, OSCON Java 2011 was a tremendous success. OSCON Java 2011 was O'Reilly's Java-specific conference held in conjunction with OSCON 2011 and the post Why OSCON Java? explains some of the reasons for the Java-specific conference being held last year. In 2012, it appears that the separate Data and Java conferences of 2011 are being brought back into the main OSCON 2012 conference. The page states, "Those who attended last year's OSCON Data and OSCON Java told us that they wanted to be part of the 'main' OSCON, so we're bringing Data and Java back into fold in 2012."

The About OSCON page explains OSCON: "Now in its 14th year, OSCON is the best place on the planet to prepare for what comes next ... OSCON is a unique gathering of all things open source." One example of praise for the OSCON conference is available in the post Why I Won’t Be At OSCON This Year.

According to the main OSCON 2012 page, "roughly 400 people will be presenting" and speaker proposals are due 12 January 2012. OSCON 2012 is to be held July 16-20, 2012, in Portland, Oregon, with registration opening in March.

NetBeans 7.1 Released

Perhaps the biggest news in all of Javadom this past week was the release of NetBeans 7.1.

JavaFX 2.0 [specifically JavaFX 2.0.2 SDK support (release notes), which is downloaded separately] is the featured attraction for NetBeans 7.1. The Oracle press release (5 January 2012) announcing NetBeans 7.1 refers to it as the "first IDE to Support JavaFX 2.0" and the NetBeans 7.1 Release Notes list "Support for JavaFX 2.0" first on the list of new features. In NetBeans 7.1 geared for building better user interfaces, Joab Jackson states that this release "adds full support for Swing, JSF, and JavaFX 2."

The title of Charles Humble's post is "NetBeans 7.1 Shipped with JavaFX 2.0 and CSS3 Support" and talks about NetBeans "active users" exceeding one million last summer. As that post's title suggests, improved CSS3 support (including for JavaFX) is also featured in NetBeans 7.1. The NetBeans for PHP blog features a post on NetBeans 7.1 and its improved PHP features.

NetBeans 7.1 offers other new features and improvements such as more hints (see my post Seven Indispensable NetBeans Java Hints for more information on NetBeans hints). Improvements and new features related to Maven are offered as are C/C++ improvements. The new Visual Debugger and profiler improvements are also welcome.

No product is perfect, especially when first released, and NetBeans 7.1 has some known issues. The post Netbeans 7.1 is out but watch out before you grab that hot cake! references some of these.

Not only has the release of NetBeans 7.1 generated significant press and blogosphere coverage, but adoption seems robust as well. Although still in its very early stages, a new Java.net poll asking "How soon do you plan to start using the just-released NetBeans 7.1?" currently shows 33% of the respondents stating they are already using NetBeans 1.7 and another 15% stating they intend to upgrade within the month. Given that almost 1/3 of the respondents are saying "Never, since I don't use NetBeans," that's a large percentage of the NetBeans users who have or soon will be upgrading.

Thứ Năm, 5 tháng 1, 2012

Pair Class Coming to Java via JavaFX?

The pair class is familiar to those of us who have used C++ for any considerable length of time. Although there has been talk of adding it to Java as a standard part of the SDK, it is a somewhat controversial topic. Several folks have formally requested it and bugs have even been filed (4947273, 4983155, and 6229146) to get it in Java. In a post asking the question Do we want a java.util.Pair?, Alex Miller does a nice job of covering both sides of the issue.

There are already implementations of Pair or a Pair-like equivalent out there for Java. Besides the unknown number of custom ones in local code bases, there are publicly available examples such as those provided by the post Java Pair Class, examples provided in a StackOverflow thread, Ideograph's Generic Pair, and (no surprise) Java Tuples's Pair. The Android SDK also features a Pair class. The one that has surprised me the most is the existence of JavaFX 2.0's javafx.util.Pair class.

The package and class name most often proposed for an SDK version of the Pair class has been java.util.Pair and the JavaFX version is similar in package name: javafx.util.Pair. Running javap against this class in the JavaFX SDK, leads to the following output.


Compiled from "Pair.java"
public class javafx.util.Pair<K, V> {
public K getKey();
public V getValue();
public javafx.util.Pair(K, V);
public java.lang.String toString();
public int hashCode();
public boolean equals(java.lang.Object);
}

As the above javap output indicates, this is a relatively simple class with a basic parameterized constructor, "get" methods for the key and value portions of the Pair, and "common" methods toString(), equals(Object), and hashCode(). The next code listing demonstrates using the parameterized constructor to provide the key and value to each instance of Pair that is instantiated.


/**
* Provide a collection of famous pairs.
*
* @return Collection of famous pairs.
*/
private static Collection<Pair<String,String>> createFamousPairs()
{
final Collection<Pair<String,String>> pairs =
new ArrayList<Pair<String,String>>();
pairs.add(new Pair("Yin", "Yang"));
pairs.add(new Pair("Action", "Reaction"));
pairs.add(new Pair("Salt", "Pepper"));
pairs.add(new Pair("Starsky", "Hutch"));
pairs.add(new Pair("Fox", "Mulder"));
pairs.add(new Pair("Batman", "Robin"));
pairs.add(new Pair("Fred Astaire", "Ginger Rogers"));
pairs.add(new Pair("Flotsam", "Jetsam"));
pairs.add(new Pair("Brutus", "Nero"));
pairs.add(new Pair("Tom", "Jerry"));
pairs.add(new Pair("Jekyll", "Hyde"));
pairs.add(new Pair("Holmes", "Watson"));
pairs.add(new Pair("Mario", "Luigi"));
pairs.add(new Pair("Pinky", "The Brain"));
pairs.add(new Pair("Wallace", "Gromit"));
return pairs;
}

Accessing the key and value of each Pair is also easy as shown in the next code sample.


/**
* Write provided collection of pairs to standard output.
*
* @param title Title for output written to standard output.
* @param pairsToPrint Pairs to be written to standard output.
*/
private static void writeCollectionOfPairs(
final String title,
final Collection<Pair<String,String>> pairsToPrint)
{
out.println(title + ":");
for (final Pair<String,String> pair : pairsToPrint)
{
out.println("\t" + pair.getKey() + " and " + pair.getValue());
}
}

The above example is relatively contrived, but could be argued to be a most effective use of Pair because, in that particular example, it really is a "pair" concept being represented. One of the biggest complaints about adding Pair to the SDK or using it in general is that it is not named specific enough to cover the business purpose for an object's existence. I actually had thought about using the JavaFX Pair class when I wrote my Christmas Tree example for the post JavaFX 2.0 Christmas Tree (JavaFX 2.0 Shapes). I ended up deciding against this and used a more appropriately-named nested Coordinate class. However, I could have easily used Pair in that example. The next code listing contains that very example with the nested Coordinate class removed and references to it replaced by Pair.


package dustin.examples;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.Glow;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.scene.paint.Paint;
import javafx.scene.shape.*;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.stage.Stage;
import javafx.util.Pair;

/**
* Simple example of using JavaFX 2.0's Path to create a simple Christmas tree.
*
* @author Dustin
*/
public class ChristmasTreePathWithPair extends Application
{
/** Number of branches on Christmas tree. */
private final static int NUMBER_BRANCHES = 4;
/** X-coordinate of very top of Christmas tree. */
private final static int TOP_CENTER_X = 400;
/** Y-coordinate of very top of Christmas tree. */
private final static int TOP_CENTER_Y = 25;
/** Horizontal distance to end of each branch. */
private final static int DELTA_X = 125;
/** Vertical distance to end of each branch. */
private final static int DELTA_Y = 100;
/** Length of each branch as measured on bottom of branch. */
private final static int BRANCH_LENGTH = 75;
/** Width of tree stump. */
private final static int STUMP_WIDTH = 100;
/** Height of tree stump. */
private final static int STUMP_HEIGHT = 150;
/** X-coordinate of top left corner of tree stump. */
private final static int LEFT_STUMP_X = TOP_CENTER_X - STUMP_WIDTH/2;
/** Y-coordinate of top left corner of tree stump. */
private final static int LEFT_STUMP_Y = TOP_CENTER_Y + DELTA_Y * NUMBER_BRANCHES;
/** Width of Christmas tree bottom. */
private final static int TREE_BOTTOM_WIDTH = (DELTA_X-BRANCH_LENGTH) * NUMBER_BRANCHES * 2;

/**
* Draw left side of the Christmas tree from top to bottom.
*
* @param path Path for left side of Christmas tree to be added to.
* @param startingX X portion of the starting coordinate.
* @param startingY Y portion of the starting coordinate.
* @return Coordinate with x and y values.
*/
private Pair<Integer, Integer> drawLeftSide(
final Path path, final int startingX, final int startingY)
{
int coordX = startingX - DELTA_X;
int coordY = startingY + DELTA_Y;
final LineTo topLeft = new LineTo(coordX, coordY);
path.getElements().add(topLeft);

coordX += BRANCH_LENGTH;
final LineTo topLeftHorizontal = new LineTo(coordX, coordY);
path.getElements().add(topLeftHorizontal);

coordX -= DELTA_X;
coordY += DELTA_Y;
final LineTo secondLeft = new LineTo(coordX, coordY);
path.getElements().add(secondLeft);

coordX += BRANCH_LENGTH;
final LineTo secondLeftHorizontal = new LineTo(coordX, coordY);
path.getElements().add(secondLeftHorizontal);

coordX -= DELTA_X;
coordY += DELTA_Y;
final LineTo thirdLeft = new LineTo(coordX, coordY);
path.getElements().add(thirdLeft);

coordX += BRANCH_LENGTH;
final LineTo thirdLeftHorizontal = new LineTo(coordX, coordY);
path.getElements().add(thirdLeftHorizontal);

coordX -= DELTA_X;
coordY += DELTA_Y;
final LineTo fourthLeft = new LineTo(coordX, coordY);
path.getElements().add(fourthLeft);

coordX += BRANCH_LENGTH;
final LineTo fourthLeftHorizontal = new LineTo(coordX, coordY);
path.getElements().add(fourthLeftHorizontal);

return new Pair(coordX, coordY);
}

/**
* Draw right side of the Christmas tree from bottom to top.
*
* @param path Path for right side of Christmas tree to be added to.
* @param startingX X portion of the starting coordinate.
* @param startingY Y portion of the starting coordinate.
* @return Coordinate with x and y values.
*/
private Pair<Integer, Integer> drawRightSide(
final Path path, final int startingX, final int startingY)
{
int coordX = startingX + BRANCH_LENGTH;
int coordY = startingY;
final LineTo bottomHorizontal = new LineTo(coordX, coordY);
path.getElements().add(bottomHorizontal);

coordX -= DELTA_X;
coordY -= DELTA_Y;
final LineTo bottomBranch = new LineTo(coordX, coordY);
path.getElements().add(bottomBranch);

coordX += BRANCH_LENGTH;
final LineTo secondHorizontal = new LineTo(coordX, coordY);
path.getElements().add(secondHorizontal);

coordX -= DELTA_X;
coordY -= DELTA_Y;
final LineTo secondBottomBranch = new LineTo(coordX, coordY);
path.getElements().add(secondBottomBranch);

coordX += BRANCH_LENGTH;
final LineTo thirdHorizontal = new LineTo(coordX, coordY);
path.getElements().add(thirdHorizontal);

coordX -= DELTA_X;
coordY -= DELTA_Y;
final LineTo thirdBottomBranch = new LineTo(coordX, coordY);
path.getElements().add(thirdBottomBranch);

coordX += BRANCH_LENGTH;
final LineTo fourthHorizontal = new LineTo(coordX, coordY);
path.getElements().add(fourthHorizontal);

coordX -= DELTA_X;
coordY -= DELTA_Y;
final LineTo fourthBottomBranch = new LineTo(coordX, coordY);
path.getElements().add(fourthBottomBranch);

return new Pair(coordX, coordY);
}

/**
* Draw stump of tree.
*
* @return Path representing Christmas tree stump.
*/
private Path buildStumpPath()
{
final Path path = new Path();

int coordX = LEFT_STUMP_X;
int coordY = LEFT_STUMP_Y;
final MoveTo startingPoint = new MoveTo(coordX, coordY);
path.getElements().add(startingPoint);

coordY += STUMP_HEIGHT;
final LineTo leftStumpSide = new LineTo(coordX, coordY);
path.getElements().add(leftStumpSide);

coordX += STUMP_WIDTH;
final LineTo stumpBottom = new LineTo(coordX, coordY);
path.getElements().add(stumpBottom);

coordY -= STUMP_HEIGHT;
final LineTo rightStumpSide = new LineTo(coordX, coordY);
path.getElements().add(rightStumpSide);

coordX -= STUMP_WIDTH;
final LineTo topStump = new LineTo(coordX, coordY);
path.getElements().add(topStump);

path.setFill(Color.BROWN);

return path;
}

/**
* Build the exterior path of a Christmas Tree.
*
* @return Path representing the exterior of a simple Christmas tree drawing.
*/
private Path buildChristmasTreePath()
{
int coordX = TOP_CENTER_X;
int coordY = TOP_CENTER_Y;
final Path path = new Path();
final MoveTo startingPoint = new MoveTo(coordX, coordY);
path.getElements().add(startingPoint);

final Pair<Integer, Integer> bottomLeft = drawLeftSide(path, coordX, coordY);
coordX = bottomLeft.getKey() + TREE_BOTTOM_WIDTH;
coordY = bottomLeft.getValue();

final LineTo treeBottom = new LineTo(coordX, coordY);
path.getElements().add(treeBottom);

drawRightSide(path, coordX, coordY);

path.setFill(Color.GREEN);

return path;
}

/**
* Create a bulb based on provided parameters and associate a MouseEvent to
* it such that clicking on a bulb will increase its size and enable the glow
* effect.
*
* @param centerX X-coordinate of center of bulb.
* @param centerY Y-coordinate of center of bulb.
* @param radius Radius of bulb.
* @param paint Paint/color instance to be used for bulb.
* @return Christmas tree bulb with interactive support.
*/
private Circle createInteractiveBulb(
final int centerX, final int centerY, final int radius, final Paint paint)
{
final Circle bulb = new Circle(centerX, centerY, radius, paint);
bulb.setOnMouseClicked(
new EventHandler<MouseEvent>()
{
@Override
public void handle(MouseEvent mouseEvent)
{
bulb.setEffect(new Glow(1.0));
bulb.setRadius(bulb.getRadius() + 5);
}
});
return bulb;
}

/**
* Add colored circles (bulbs) to the provided Group.
*
* @param group Group to which 'bulbs' are to be added.
*/
private void addBulbs(final Group group)
{
final Circle bulbOne = createInteractiveBulb(350,100,10, Color.RED);
group.getChildren().add(bulbOne);
final Circle bulbTwo = createInteractiveBulb(285,210,10, Color.YELLOW);
group.getChildren().add(bulbTwo);
final Circle bulbThree = createInteractiveBulb(325,300,10, Color.WHITE);
group.getChildren().add(bulbThree);
final Circle bulbFour = createInteractiveBulb(475,290,10, Color.BLUE);
group.getChildren().add(bulbFour);
final Circle bulbFive = createInteractiveBulb(380,150,10, Color.CADETBLUE);
group.getChildren().add(bulbFive);
final Circle bulbSix = createInteractiveBulb(550,390,10, Color.VIOLET);
group.getChildren().add(bulbSix);
final Circle bulbSeven = createInteractiveBulb(375,400,10, Color.GOLD);
group.getChildren().add(bulbSeven);
final Circle bulbEight = createInteractiveBulb(445,195,10, Color.SILVER);
group.getChildren().add(bulbEight);
final Circle bulbNine = createInteractiveBulb(220,385,10, Color.DARKSALMON);
group.getChildren().add(bulbNine);
}

/**
* Add text portions to Christmas Tree group.
*
* @param group Group for text to be added to.
*/
private void addText(final Group group)
{
final Text text1 = new Text(25, 125, "Merry\nChristmas!");
text1.setFill(Color.RED);
text1.setFont(Font.font(java.awt.Font.SERIF, 50));
group.getChildren().add(text1);

final Text text2 = new Text(600, 150, "2011");
text2.setFill(Color.DARKGREEN);
text2.setFont(Font.font(java.awt.Font.SERIF, 75));
group.getChildren().add(text2);
}

/**
* Starting method of JavaFX application.
*
* @param stage Primary stage.
* @throws Exception Thrown for exceptional circumstances.
*/
@Override
public void start(final Stage stage) throws Exception
{
stage.setTitle("JavaFX 2.0: Christmas Tree 2011 (Pair)");
final Group rootGroup = new Group();
final Scene scene = new Scene(rootGroup, 800, 600, Color.WHITE);
stage.setScene(scene);
rootGroup.getChildren().add(buildChristmasTreePath());
rootGroup.getChildren().add(buildStumpPath());
addBulbs(rootGroup);
addText(rootGroup);
stage.show();
}

/**
* Main function that kicks off this JavaFX demonstrative application.
*
* @param arguments Command-line arguments; none expected.
*/
public static void main(final String[] arguments)
{
Application.launch(arguments);
}
}

Removing the nested Coordinate class reduces the overall lines of code for the application, but argument against this is that Pair is not as readable or specific as Coordinate was. This example exemplifies what I typically do: make simple custom classes rather than using a generic Pair.

What's perhaps most interesting to me about JavaFX having a Pair class is the implication of this when one considers that JavaFX will likely be standardized and made part of Java SE. This Pair class could very well end up in the Java SDK as-is. Other options would be to include a standard java.util.Pair class as a replacement for the JavaFX version, to have both in the SDK (having more than one in the SDK itself), or to not add the new one and remove the JavaFX version. There are ramifications on maintenance of existing applications either way. Several people have commented that it is a code smell or feels dirty to use a Pair rather than a custom object pairing two attributes. It would probably only make things feel even dirtier to use an implied JavaFX-specific class (javafx.util.Pair) in code that has nothing to do with JavaFX or even with presentation or user interface.

Thứ Tư, 4 tháng 1, 2012

JavaFX 2's Tri-State CheckBox

JavaFX 2.0 provides the CheckBox (notice capital 'B' versus AWT's Checkbox's lowercase 'b') control that supports three states ("undefined", "checked", and "unchecked"). The AWT Checkbox only supports two states (on/true or off/false), but JavaFX's CheckBox can optionally support three states. If one desires the JavaFX version to support three states (the third being indeterminate), this is done by invoking allowIndeterminateProperty() on the CheckBox instance. Alternatively, setAllowIndeterminate(boolean) can be used to enable three states (passing it true) or only two states (passing it false).

The next code listing provides the source code for a simple JavaFX application that demonstrates the tri-state JavaFX CheckBox control. All the application does is to change the text associated with the CheckBox to indicate what state that CheckBox is in. As described in the CheckBox's Javadoc documentation, the three states of the CheckBox consist of "undefined" (indeterminate), "checked" (determinate and selected), or "unchecked" (determinate and not selected). This simple example boils these three states down to "determinate", "selected", and "unselected" and uses nested conditional ternary operators to set that String.

CheckboxExample.java

package dustin.examples;

import javafx.application.Application;
import javafx.event.EventHandler;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.CheckBox;
import javafx.scene.control.CheckBoxBuilder;
import javafx.scene.input.MouseEvent;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
* Simple example of JavaFX 2.0 Checkbox control.
*
* @author Dustin
*/
public class CheckboxExample extends Application
{
/**
* Provides a checkbox instance with specified String and supporting three
* states (supporting indeterminate state).
*
* @param checkboxText Text to go with checkbox.
* @return Checkbox with text.
*/
private CheckBox buildTriStateCheckbox(final String checkboxText)
{
// Note that AWT's Checkbox does not have capital 'b'
final CheckBox checkbox =
CheckBoxBuilder.create()
.allowIndeterminate(true)
.indeterminate(true)
.prefHeight(50)
.prefWidth(300)
.text(checkboxText)
.build();

checkbox.setOnMouseClicked(
new EventHandler<MouseEvent>()
{
@Override
public void handle(final MouseEvent mouseEvent)
{
final String newText =
checkbox.isIndeterminate()
? "Indeterminate!"
: checkbox.isSelected() ? "Selected!": "Unselected!";
checkbox.setText(newText);
}
}
);
return checkbox;
}

/**
* Overridden method defined in parent class and used in JavaFX application
* lifecycle.
*
* @param stage
* @throws Exception Exception during JavaFX sample application.
*/
@Override
public void start(final Stage stage) throws Exception
{
stage.setTitle("JavaFX 2 Checkbox Demo");
final Group rootGroup = new Group();
rootGroup.getChildren().add(buildTriStateCheckbox("Tri-State CheckBox"));
final Scene scene = new Scene(rootGroup, 300, 50, Color.CADETBLUE);
stage.setScene(scene);
stage.show();
}

/**
* Main function for running demonstration of JavaFX 2 Checkbox example.
*
* @param arguments Command-line arguments: none expected;
*/
public static void main(final String[] arguments)
{
Application.launch(arguments);
}
}

This is another all-Java example of JavaFX and it can be compiled with the normal Java compiler (assuming JavaFX on the classpath) and executed with the normal Java application launcher (again assuming JavaFX on the classpath). When executed it behaves as demonstrated in the following series of static snapshots. The first screen snapshot is its initial appearance with initially set text and the three images following that one indicate the changing of the state of the CheckBox as it is clicked on.

The JavaFX 2 CheckBox class, like other JavaFX controls, provides significant more styling flexibility than the defaults I've shown here. The CheckBox is easy to use and can support two or three states as needed.

Thứ Ba, 3 tháng 1, 2012

JavaFX 2's Ensemble and other Sample Applications

There are several places within the JavaFX 2 documentation that the sample application Ensemble is referenced. Ensemble is the largest JavaFX sample application provided in the JavaFX 2.0 samples. Acquiring the JavaFX 2 samples, using the JavaFX 2 samples, and learning from the JavaFX 2 samples are the subjects of this post.

The JavaFX Developer Downloads page currently features "JavaFX 2.0.2 General Availability Download" and includes a link for downloading JavaFX Samples [only for "Microsoft Windows (x86 and x64)" as of this writing]. The downloaded file, javafx_samples-2_0_2.zip, is about 18 MB in size. The contents of this ZIP file, when extracted are shown in the next screen snapshot.

Once the samples ZIP has been downloaded and its contents extracted, the Ensemble sample application can be executed. One way to do this is to take advantage of the executable JAR in the main unzipped samples directory as shown in the next screen snapshot (java -jar Ensemble.jar).

The JavaFX 2 Ensemble sample application starts up and appears as shown in the next screen snapshot.

There are numerous items that can be clicked on in the Ensemble application to learn more details about what it is and how it is implemented. For example, clicking on "Adv Candle Stick Chart" opens up the "Custom Candle Stick Chart" as shown in the next screen snapshot.

The above screen snapshot shows Ensemble with the "Sample" tab for this specific example. Clicking on the "Source Code" tab displays the source code for the same sample. As shown in the next screen snapshot, this tab includes a button for copying the JavaFX 2 source code that built that sample.

The combination of the source code with what it produces in the Ensemble sample application can help developers to learn what's available and how to use various parts of JavaFX. Sections currently included in Ensemble include Animation, Charts, Controls, Graphics, Language, Layout, Media, Scene Graph, and Web.

The downloadable JavaFX 2 samples also include Brick Breaker (BrickBreaker.jar) and the next screen snapshot was taken of it in action.

Running the executable JAR SwingInterop.jar demonstrates the "JavaFX 2.0 in Swing" sample application (screen snapshot shown next).

The JavaFX 2 samples ZIP also includes FXML-LoginDemo, which is a simple login sample that includes an FXML file (profile.fxml) in its source. It's shown in the next screen snapshot.

The Ensemble application is by far the largest of the sample applications that are included in the JavaFX 2 samples ZIP file and is the "flagship" sample application. Brick Breaker is relatively large for a single application. All of the samples have value in showing what JavaFX is capable of and in providing source code to demonstrate how to accomplish these very feats with JavaFX.

Thứ Hai, 2 tháng 1, 2012

Scala for 2012? Deciding Whether to Invest In a Programming Language

I have found it both interesting and rewarding to learn a new programming language or major framework on a roughly yearly basis. If forced to self-identify with any single programming language, it would be Java. However, over the years, I've used C and C++ fairly extensively and have used and learned enough to be dangerous about several other languages including shell scripting languages, Perl, JavaScript, Pascal, C#, Ruby, JRuby, Groovy, PHP, and Python. Of the latter group of languages (Ruby, JRuby, Groovy, PHP, and Python), Groovy has had the most practical benefit for me, but I have learned valuable idioms, best practices, and different ways of thinking from using the other languages.

In some years, I've not been as quick to learn a language in a year in which I've been learning either a major framework for that language or in a year in which a language I am familiar with undergoes significant changes. For example, Struts and the Spring Framework dominated my time as I learned each of them. JavaFX has similarly dominated my interest in recent weeks. When not working with a new language, I tend to focus on libraries and frameworks of the languages I am comfortable with. I have spent more time on Guava this year, for example.

Learning a new language does provide many benefits. However, these benefits don't come for free. There is always an opportunity cost associated with learning anything new. If a programming language is particularly different than what one is used to, this opportunity cost can be great. The opportunity cost can be manifest as many different things. It might be lower productivity than could be had using a known language. It might be missing out on learning a new framework, library, or approach in the more familiar language. The opportunity cost might be having to settle on fewer or choosing different features that better fit the new language. The opportunity cost may be as simple as not being able to do other things one would want to do and might have time to do if using a familiar language.

Because there are so many potential opportunity costs associated with learning a new programming language, I try to be careful about which I invest my time in. I typically have a compelling reason for learning a new language. Compelling reasons might include specific advantages of a language (such as PHP for many Web 2.0-centric projects) or widespread use and "employability" of that language. Other reasons might be to learn new techniques that can be adapted to more familiar languages. Perhaps the most compelling reason I've learned a new language has been to read and maintain code or scripts that I have handed to me and am assigned responsibility for.

For several years now, I've been somewhat curious about Scala, but have not yet committed myself to using it and learning it because other languages, frameworks, and tools have grabbed my attention. Typically, I've had some motivation that has made these tools, languages, or frameworks seem most worth my investment of time and energy. For example, the need to have a nice scripting language that meshes well in my Java development environment led me to Groovy. My attendance at JavaOne 2010 and JavaOne 2011, coupled with my interest in a modern GUI technology, has led to my interest in JavaFX. I spent time with Python after being in a position where I needed to read and modify Python scripts.

I recently welcomed the opportunity to pose some questions to Scala creator Martin Odersky related to what is in Scala that might motivate me (and others) to invest time and energy into learning Scala. As I articulated the questions I had for Martin, I realized that these are really the things that I informally look at when investigating a new language. I typically spend an hour to two finding a language's highest-level motivations first and only invest more time in that language if it seems to be a good potential fit for me. Martin has agreed to me posting my questions and his answers and they are shown next (I have added hyperlinks).

Question: What is the most compelling/motivating reason or reasons that one might want to invest time in learning Scala as opposed to continuing use of Java (mostly for applications in my case) + Groovy (mostly for development environment scripting in my case)? For example, Groovy appealed to me at a high level as a way to script with libraries, idioms, and syntax that I was comfortable with from Java application development experience.
There are actually quite a few different facets of Scala that individuals attach to for different reasons. Some are attracted by the succinct syntax and resulting productivity. Others gravitate to the stability of the JVM and runtime performance of a compiled language (versus an interpreted language, like Groovy), or the ability of a sophisticated type system to help programmers avoid errors that would otherwise crop up at runtime. Others find the functional style of programming to be a more natural way to reason about their application logic.

One of the strongest attractors, from a practical point of view, is that Scala (and the rest of the Typesafe Stack -- including Akka and Play) are designed to provide better tools to address the dual challenges of parallel and concurrent programming. With the advent of mainstream multicore/manycore hardware, and the increasing scale of applications that developers are charged to build, many industry developers are looking for higher level abstractions than threads and locks for building at this next scale. Many find that the functional style, immutable state, actor concurrency model, and other concepts at the heart of Scala make it simpler to build parallel and concurrent applications.

Question: What are Scala's biggest strengths, advantages, and innovative features?
At a high level, Scala seeks to be a pragmatic language that scales from the smallest scripts to the largest distributed systems.

One major thread of innovation in Scala is its unique blend of object-oriented Java with functional programming concepts. Scala's libraries build on this foundation to provide outstanding support for concurrency and parallelism, for example through the actor programming model and the built-in parallel collections introduced in Scala 2.9.

Scala's expressive type system and syntax helps developers build more reliable code and greatly increase extensibility, especially for library developers and those building domain-specific languages (DSLs).

Finally, it's important not to overlook the fact that Scala is deeply integrated with Java, supporting blended Scala/Java projects and allowing developers to apply their skills and investments in Java immediately when they start working with Scala.

Question: What are Scala's biggest weaknesses, disadvantages, and plans for improvement?
One of the challenges for a relatively young language like Scala is the maturity of tools. In particular, the Scala IDE for Eclipse has had its rough edges in the past -- one of the reasons that Typesafe, as the leading commercial contributor to Scala, has invested substantial resources in overhauling the IDE with version 2.0 (just released in December 2011).

Another challenge for adoption is that Scala does introduce with functional programming a new mode of thinking about programs, which takes some time to learn. It makes the transition gentle, because one can start writing Scala code like more concise Java code. But as Scala's native library ecosystem grows chances are that newcomers to the language will come across to some of its more foreign features before they have developed a good understanding. To avoid culture shock, we need to develop a set of best practices and good tutorials that help the transition. "Programming in Scala", which I have co-authored, is a comprehensive tutorial of the object/functional style. Cay Horstmann's "Scala for the Impatient", available as a free preview on the Typesafe site, is a pragmatic, fast-paced introduction.

Question: What situations/scenarios/use cases is Scala best and worst suited for?
As described above, Scala and its frameworks like Akka and Play really shine for building systems that need to scale on multiple fronts -- across cores, across machines in a cloud environment, and across large software teams.

Traditionally, one area where Scala or other JVM-hosted languages would not be considered well suited would be lower-level systems programming. But interestingly, we see evidence of forward-looking systems developers increasingly embracing managed runtime languages like Scala because they face fundamental challenges in building reliable systems for the era of multicore hardware and distributed deployments.

Martin's responses validate some of my own conclusions about Scala from reading posts by Scala enthusiasts and even some of the detractors. In terms of motivation, I have a difficult time believing that learning Scala primarily as a scripting language will be very motivating because I'm pretty happy with Groovy for scripting. However, for development of applications, I tend to use Java and not Groovy and I wonder if it's in that area where I'd be most likely to benefit from learning and using Scala.

Once I determine that a language is worth investing in, the next step is deciding how to best learn it. Reading about it is a necessity, but using it is what really helps me learn it and also what helps me identify the things I don't like about it. The trick is to come up with a somewhat realistic example that is easy enough to implement, but interesting enough to prove out some concepts. A "Hello World" is okay to get one's feet wet, but doesn't really test how the language fares for a developer's specific needs. My favorite initial examples are ones that actually provide benefit in addition to being a mechanism for learning. For example, when I was learning Groovy, I developed several scripts early on that were helpful to me as scripts in their own right regardless of the language they were written in. In those cases, I gained familiarity with Groovy while also receiving other utilitarian benefits.

The JavaWorld article Learn Scala with Specs2 Spring describes how a Java developer who uses the Spring Framework can use the author's company's Specs2 Spring for integration testing and also benefit from "an efficient and safe way to learn the patterns of object-functional programming with Scala." The entire premise of this article is exactly the kind of thing I like to do when learning a new language: combine legitimate benefit with learning of the new language.

One other thing to think about when trying out a new language is to ensure that one is trying it out for the correct situations. This was easy for me with Groovy: I tried out Groovy first in situations in which I wanted the power of the JVM or the scope of the JDK, but wanted a scripting-friendly language. A developer can quickly decide a language is "not good" simply because the situation in which the language used is not a great fit for that language. Related to this, another issue I try to keep in mind when learning a new language is that it's not fair to compare a language I know well and have spent thousands of hours with to a language that I've spent a few hours with. Unless I encounter some real deal-breakers early in the process, I try to not let "little problems" or things I don't like about the new language prevent me from giving it a real chance. An excellent recent post on this is Rob Pike's Esmerelda's Imagination. All that being stated, there are times I run into a true deal-breaker that makes me realize I should not invest any more time in a particular language because it doesn't fit my needs. That doesn't necessarily mean there's anything wrong with the language, but simply that it doesn't fit my needs well. An example of this would be using Java for a real-time system in Java's early days.

I think I'm almost ready to commit to spending more time with Scala. I'm not the type to make new-year resolutions, but it just so happens that it seems like the right time to give Scala a closer look. If I really do start to invest more time in Scala, my plan is to first re-read Bruce Eckel's Scala: The Static Language that Feels Dynamic and then read the A1 chapters of Scala for the Impatient, trying out and adapting examples. If I'm still interested in Scala after that, I can invest more at that time.

Do I still have reservations about spending time on Scala? Of course. One of my biggest concerns is best articulated by someone who actually seems to have tried out Scala. Cédric Beust states, "In my experience with Scala, it's hard not to like the language in the first week and it's hard to still be in love with it after reading the 700+ pages of a book about it." On the other hand, Casper Bang articulates well why I think I maybe I should spend time with Scala despite any other obvious motivations: "So I guess my point is, even if I do find Scala hyperbolish and biting over a bit too much; the majority of identifiable alpha-geeks that I track, are moving this way and as a practicing professional, I can not afford to ignore this."

The post Offbeat: Scala by the end of 2011 – No Drama but Frustration is Growing and the feedback comments related to that post are insightful and seem to reiterate some of the issues that Martin pointed out that Scala must deal with. In particular, when I look at the issue most likely to deter me from spending time on Scala, it is the risk that Scala may never take hold in mainstream development. If that turns out to be the case, then the primary advantage of learning Scala would be to change my way of thinking about things and that's not always necessarily worth the opportunity cost and other costs. This post and the feedback comments contain multiple sides of the same issue and are another reminder that I probably need to do more with Scala to decide for myself how I feel about it.

My plan as of right now is to invest significant time and effort into learning basics of Scala and applying it to some "realistic" examples. I even have plans to blog on what I learn. But, I have had these types of plans before and been distracted by some other shiny thing that has come my way. I think this time will be different, but I should know for certain by the end of 2012.

Applying Sepia Effect to Loaded Images in JavaFX 2.0

In this blog post, I look at a very simple JavaFX 2.0 application that loads an image provided on the command-line and presents it in both normal form and with JavaFX 2.0's SepiaTone effect applied to it. The simple application presents the two images side-by-side for dramatic effect. To accomplish this, the simple example demonstrates loading images in JavaFX based on a URL, use of the HBox layout component, and accessing command-line parameters in a JavaFX application using Application's getParameters() method.

In general photography, use of sepia can make a photograph appear older or like an antique. The JavaFX SepiaTone Effect accomplishes this for JavaFX components, including loaded images. The following code snippet shows how this can be accomplished.

SepiaEffect.java

package dustin.examples;

import java.util.List;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.effect.SepiaTone;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.HBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

/**
* Simple demonstration of the SepiaTone Effect.
*
* @author Dustin
*/
public class SepiaEffect extends Application
{
/** Default width of displayed photographs/images. */
private final static int DEFAULT_WIDTH = 540;

/**
* Overridden (from parent Application class) method.
*
* @param stage Primary stage.
* @throws Exception JavaFX 2.0 application exception or file I/O exception.
*/
@Override
public void start(final Stage stage) throws Exception
{
// Get command-line parameters and access first argument as image URL.
final Parameters params = getParameters();
final List<String> parameters = params.getRaw();
final String imageUrl = !parameters.isEmpty() ? parameters.get(0) : "";

// The third-to-last 'true' preserves height/width ratio and the next
// 'true' argument indicates better quality (smooth) filtering should be
// used and the final 'true' indicates that background loading should be
// used. The imageUrl must really be a URL and begin with a protocol
// such as file:\\ or http:\\.
final Image loadedImage = new Image(imageUrl, DEFAULT_WIDTH, 405, true, true, true);
final ImageView originalView = new ImageView(loadedImage);
final ImageView sepiaView = new ImageView(loadedImage);
sepiaView.setEffect(new SepiaTone()); // default is full (1.0) effect

final HBox horizontalBox = new HBox();
horizontalBox.getChildren().add(originalView);
horizontalBox.getChildren().add(sepiaView);

stage.setTitle("Demonstration of JavaFX 2.0 Sepia Effect");
final Group rootGroup = new Group();
final Scene scene = new Scene(rootGroup, DEFAULT_WIDTH*2, 405, Color.WHITE);
rootGroup.getChildren().add(horizontalBox);
stage.setScene(scene);
stage.show();
}

/**
* Main function for running demonstration of JavaFX 2.0 SepiaTone Effect.
*
* @param arguments Command-line arguments: none expected.
*/
public static void main(final String[] arguments)
{
Application.launch(arguments);
}
}

The above example uses fewer than 70 lines, including white space and overly verbose comments in code intended for a blog post example. When run against a photograph I took in Juneau, the application looks like that shown in the next screen snapshot.

The source image was only loaded once into a single Image instance, but two different ImageView instances were used to present that single Image instance both in its original color scheme and with the sepia effect. The application of the sepia effect is only a single line. The level of "sepia-ness" can be specified, but I used the default in this case. The HBox layout component made it easy to place the images side-by-side.

As a comment in the code sample indicates, the String provided to the Image constructor needs to be a URL that includes a protocol such as http or file. For example, in my case the string I provided as the command-line argument to the sample application was "file:///C:/Users/Dustin/Pictures/P1010804-juneau.jpg". Without the "file://" prefix, the application is not able to find the image to load it.

This blog post has shown that loading images in JavaFX 2.0 and applying effects to them is straightforward.