Building a Text Editor in Scala

I think the default project for learning a language these days is building your own blog software, but I wanted to go the classic route for Scala: I'm building a text editor. I haven't done a lot of GUI development, and I wanted more experience with it, plus I already like my blogging software.

I encountered a ton of frustration on my first try, mainly because I don't know Java well, I know Swing even less, and Scala's got some big holes in documentation. The API is well documented for the most part, but practical tutorials are missing. I hope posting this code and describing my issues help someone.

Programming in Scala from Artima Press showed me the basics of Swing in Scala, up until when I wanted to pop up a file chooser dialog. If you know Java, this is probably obvious, but for me, it was baffling. You don't create a file chooser when you need it, but during app construction, and then call showOpenDialog(parent) and showSaveDialog(parent) to pop up the dialogs. (Looking now, it seems I could have made them when I needed them.) The parent in this situation has to be a Component that the dialog will pop up over, and not every graphical element in your app is a Component. After looking through plenty of docs and following inheritance chains, I found that Panes are Components, and I had to put a ScrollPane around my TextArea to allow it to have scrollbars. This is not intuitive, this passing of an element meant to enable scrolling in order to have a file dialog. Beating my head against this took at least half an hour. My code for this looked like:

val editor = new TextArea {
  font = new Font("Monaco", Font.PLAIN, 12)
  columns = 80
  rows = 40
}
val editPane = new ScrollPane { contents = editor }

val open = new Button { text = "Open" }
val fileChooser = new FileChooser

// lots elided

reactions += {
  case ButtonClicked(`open`) => {
    if (fileChooser.showOpenDialog(editPane) == FileChooser.Result.Approve) {
      currentFile = fileChooser.selectedFile
      fileLabel.text = currentFile.getAbsolutePath

      editor.text = new String
      for (line <- Source.fromFile(currentFile).getLines)
        editor.append(line)
    }
  }
}

You'll note another issue in the code above: the way I'm reading the file and putting it into the text area is bound to be inefficient on larger files. Explaining IO isn't a strong suit of the Scala book either, so I'm a little stuck on the best way to load a file in chunks. The book is great, but I find it focuses on what makes Scala special over how to build applications in it. I should read the last chapter closer, though: there may be some gems in there.

This was a fun, very simple project, but I've got higher ambitions for it. I'd like to be able to actually use it as my editor some day, which is overly ambitious, especially for someone who loves Emacs. My interest might wane, but until it does, you can find the code at "http://github.com/crnixon/calliope":http://github.com/crnixon/calliope.

Published: 03 Dec 2008