Saturday, June 29, 2013

Java 7 Swing: Creating Translucent and Shaped Windows

Java 7 Swing supports windows with transparency and non-rectangular shapes.

The following screenshot shows a circular window created with 75% opacity.

You can create a translucent window by altering its opacity using the setOpacity method on a JFrame. Note that you can only create translucent windows if the underlying operating system supports them. Also, ensure that the window is undecorated by calling setUndecorated(true).

To change the shape of the window, call the setShape method inside the componentResized method, so that if the window is resized, the shape is recalculated as well.

Sample code to create a translucent, circular window is shown below:

import java.awt.Color;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.geom.Ellipse2D;

import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;

public class TranslucentCircularFrame extends JFrame {

  /**
   * Creates a frame containing a text area and a button. The frame has a
   * circular shape and a 75% opacity.
   */
  public TranslucentCircularFrame() {
    super("Translucent Circular Frame");
    setLayout(new GridBagLayout());
    final JTextArea textArea = new JTextArea(3, 50);
    textArea.setBackground(Color.GREEN);
    add(textArea);
    setUndecorated(true);

    // set the window's shape in the componentResized method, so
    // that if the window is resized, the shape will be recalculated
    addComponentListener(new ComponentAdapter() {
      @Override
      public void componentResized(ComponentEvent e) {
        setShape(new Ellipse2D.Double(0, 0, getWidth(), getHeight()));
      }
    });

    // make the window translucent
    setOpacity(0.75f);

    setLocationRelativeTo(null);
    setSize(250, 250);
    setDefaultCloseOperation(EXIT_ON_CLOSE);
    setVisible(true);
  }

  public static void main(String[] args) {

    // Create the GUI on the event-dispatching thread
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        GraphicsEnvironment ge = GraphicsEnvironment
            .getLocalGraphicsEnvironment();

        // check if the OS supports translucency
        if (ge.getDefaultScreenDevice().isWindowTranslucencySupported(
            GraphicsDevice.WindowTranslucency.TRANSLUCENT)) {
          new TranslucentCircularFrame();
        }
      }
    });
  }
}

Sunday, May 26, 2013

Guava Joiner: Converting an Iterable into a String

Guava's Joiner makes it really easy to convert an Iterable into a String, so you no longer have to iterate over it and build the String manually. Here is an example:
// joining a list
final List<String> fruits = Lists.newArrayList("apple", "banana", null, "cherry");
System.out.println(Joiner.on(", ").skipNulls().join(fruits));

// joining a map
final Map<String, Integer> people = ImmutableMap.of("Alice", 21, "Bob", 19);
System.out.println(Joiner.on("\n").withKeyValueSeparator(": ").join(people));
prints:
apple, banana, cherry
Alice: 21
Bob: 19

Saturday, May 25, 2013

JAXB: Marshalling/Unmarshalling Example

This post shows how you can marshal a JAXB object into XML and unmarshal XML into a JAXB object.

Consider the following JAXB class:

import javax.xml.bind.annotation.*;

@XmlRootElement
public class Book {

  @XmlElement
  private String author;

  @XmlElement
  private String title;
}
Unmarshalling:
To convert an XML string into an object of class Book:
public static Book unmarshal(final String xml) throws JAXBException {
  return (Book) JAXBContext.newInstance(Book.class)
                           .createUnmarshaller()
                           .unmarshal(new StringReader(xml));
}
Marshalling:
To convert a Book object into an XML string:
public static String marshal(Book book) throws JAXBException {
  final Marshaller m = JAXBContext.newInstance(Book.class)
                                  .createMarshaller();
  m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, true);
  final StringWriter w = new StringWriter();
  m.marshal(book, w);
  return w.toString();
}

Sunday, April 28, 2013

Useless Use of Grep

Most of us are familiar with the infamous Useless Use of Cat Award which is awarded for unnecessary use of the cat command. A while back, I also wrote about Useless Use of Echo in which I advised using here-strings and here-docs instead of the echo command. In a similar vein, this post is about the useless use of the grep command.

Useless use of grep | awk
awk can match patterns, so there is no need to pipe the output of grep to awk. For example, the following:

grep pattern file | awk '{commands}'
can be re-written as:
awk '/pattern/{commands}' file
Similarly:
grep -v pattern file | awk '{commands}'
can be re-written as:
awk '!/pattern/{commands}' file

Useless use of grep | sed
sed can match patterns, so you don't need to pipe the output of grep to sed. For example, the following:

grep pattern file | sed 's/foo/bar/g'
can be re-written as:
sed -n '/pattern/{s/foo/bar/p}' file
Similarly:
grep -v pattern file | sed 's/foo/bar/g'
can be re-written as:
sed -n '/pattern/!{s/foo/bar/p}' file

Useless use of grep in conditions
If you find yourself using grep in conditional statements to check if a string variable matches a certain pattern, consider using bash's in-built string matching instead. For example, the following:

if grep -q pattern <<< "$var"; then
    # do something
fi
can be re-written as:
if [[ $var == *pattern* ]]; then
    # do something
fi
or, if your pattern is a regex, rather than a fixed string, use:
if [[ $var =~ pattern ]]; then
    # do something
fi

Saturday, April 27, 2013

Adding Java System Properties from a Properties File

Apache Commons Configuration provides a very easy way to load a properties file into the system properties:
try {
  final PropertiesConfiguration propsConfig = new PropertiesConfiguration(
                                              Foo.class.getResource("foo.properties"));
  SystemConfiguration.setSystemProperties(propsConfig);
} catch (Exception e) {
  throw new RuntimeException("Failed to load config file: " + propsFile, e);
}
If you are unable to use this library, then you will have to use the longer, more tedious approach of loading the properties file, iterating over the properties and setting each one into the system properties. This is shown below:
final Properties props = new Properties();
final InputStream in = Foo.class.getResourceAsStream("foo.properties");
try {
  props.load(in);
  for (final Entry<Object, Object> entry : props.entrySet()) {
    System.setProperty(entry.getKey().toString(), entry.getValue().toString());
  }
} catch (IOException e) {
  throw new RuntimeException("Failed to load properties", e);
}
finally {
  try {
    in.close();
  } catch (IOException e) {
    // don't care
  }
}