Skip to main content

Posts

Showing posts from 2016

Git Recover One Deleted File Among Many

Git can include many files in a single commit. You can modify, add, or delete multiple files, then commit the new state of the working directory. What if we deleted multiple files, and now we need to recover in Git some but not all of what has been deleted? Since Git tracks the state of our repository as a series of snapshots (aka Commits) in time, we can recover the file by looking at a past snapshot / commit and “checking out” the resource(s) we must recover. For example: Let's say that a few days ago I deleted several files from the Git repository. I deleted them on my local, committed the change, and pushed to the server. Other developers have done many other commits since then. Now, it turns out one of the files is needed after all, but the others should remain deleted. How to get the one file back? I will show some Git command-line steps to retrieve it. There are other ways, using your IDE, File Explorer, Tortoise or your UI of choice. But the command-l

Reflections on an ATM's User Interface Sequence

While at my local bank today, I had an unpleasant end-user experience with the user interface for their automated teller machine. My goal was to deposit 10 cash bills into my account, an action I have performed many times before. This series of lived-out Use-Cases started out well: a blinking light prompted me to begin by inserting my bank card in the adjacent slot. Very nice and clear. I entered my PIN on the large-button key pad and successfully and easily logged in. Next, I used the touch-screen to select my action (Deposit), my account (Savings), and the deposit format (Cash). The ATM promised to count the stack of bills and determine the exact amount of the deposit. That's where the problems began.

Java Generics Return type refactoring exercise

One of my more interesting tasks of the past few weeks was to refactor an existing method to use Generics in a method's return type and simplify the readability of code that calls the method. The starting point was this method: public static Object getHandler(Class<?> aClass) throws HandlerException  {    if (handlerFactory == null)       handlerFactory = new HandlerFactory();    return handlerFactory.getHandler(aClass); }

Java 8: Rewrite For-loops using Stream API

Java 8 Tip: Anytime you write a Java For-loop, ask yourself if you can rewrite it with the Streams API. Now that I have moved to Java 8 in my work and home development, whenever I want to use a For-loop, I write it and then see if I can rewrite it using the Stream API. For example: I have an object called myThing, some Collection-like data structure which contains an arbitrary number of Fields. Something has happened, and I want to set all of the fields to some common state, in my case "Hidden"

Unit Testing Tip: Break steps into separate methods

Testing in the Trenches (TinT) is a series of posts adapted from real-world discussions and advice I have given to teams and individuals struggling to adopt Unit Testing habits and best-practices. The Method is an important basic unit of unit-testing. If you have a tendency to write entire processes or algorithms as single, large methods, you will find a lot of benefits to breaking them into smaller steps in separate methods. Unit tests for these smaller methods are easier to write, and are key for proving the validity of each step in the larger process. For example: We have an Enhancement Specification that says the program should behave one way if a given Rule has never yet been applied, and behave another way if the Rule has already been applied one or more times. This distinction of "already used or not" is a key condition that appears many times in this spec. We can check for the condition with something like this: if (myrecord.getAsString(lastPledgeDate

Multiple Remote Git Repositories and Branches in Eclipse

Sometimes, when using Git repositories and the Eclipse IDE, we want to access other remote repositories within the one we are currently using. One example, which I will use as the scenario for the steps below: a team converted existing code and its history to Git from another source-control management tool, with separate repositories for closely related but distinct release points. When they need to make a fix to a past release, on the past release's "hotfix" branch, they want to do as little work as possible to bring that fix into the current cutting-edge "dev" branch of their main repository. Other writers have offered How-To's for the git command-line steps to do so. What I will do is to show how the setup and configuration can be done within the Eclipse IDE (I used Mars for the screen-shots).

Git Reset in Eclipse

Using Git and the Eclipse IDE, you have a series of commits in your branch history, but need to back up to an earlier version. The Git Reset feature is a powerful tool with just a whiff of danger, and is accessible with just a couple clicks in Eclipse. In Eclipse, switch to the History view. In my example it shows a series of 3 changes, 3 separate committed versions of the Person file. After commit 6d5ef3e, the HEAD (shown), Index, and Working Directory all have the same version, Person 3.0.

How to do Git Rebase in Eclipse

This is an abbreviated version of a fuller post about Git Rebase in Eclipse. See the longer one here : One side-effect of merging Git branches is that it leaves a Merge commit. This can create a history view something like: The clutter of parallel lines shows the life spans of those local branches, and extra commits (nine in the above screen-shot, marked by the green arrows icon). Check out this extreme-case history:  http://agentdero.cachefly.net/unethicalblogger.com/images/branch_madness.jpeg Merge Commits show all the gory details of how the code base evolved. For some teams, that’s what they want or need, all the time. Others may find it unnecessarily long and cluttered. They prefer the history to tell the bigger story, and not dwell on tiny details like every trivial Merge-commit. Git Rebase offers us 2 benefits over Git Merge: First, Rebase allows us to clean up a set of local commits before pushing them to the shared, central repository. For this

Git Rebase in Eclipse

Note: I led the project to convert a team's Source Control Management tool and processes from Microsoft Visual SourceSafe to Git. This is an edited version of a How-To document I wrote and distributed in response to some questions about Merge vs Rebase in Eclipse. As you know, I’ve been recommending using local Git branches to separate your projects. By that, I mean create a branch from the Dev branch, make your changes and commit them as often as necessary to your local branch, switch branches when you need to switch projects, etc. One side-effect of using local branches is that when you bring your work into the main Dev branch, it leaves a new commit, a Merge commit. This means that, even though we do not have feature branches on the server, we can still wind up with a history that looks like this on the server: We wind up with the clutter of parallel lines showing the life spans of our local branches, and extra commits (nine in the above screen-shot, marked by the

Unit Test Benefits, Goals and Stories

I recently came across an old entry on a Blog that outlined the stories that a consultant was using in introducing Unit Testing concepts and practices to a group of developers. What a great idea! They are a concise list of driving principles, guiding his activities. They could be easily turned into some measurable benchmarks, milestones that indicate how far the team has come and how much more work the consultant still has. I am envious. I began doing something similar - introducing Unit Testing to a group of developers - a couple years ago. I became the team's Unit Test Evangelist, championing the practice. I had some benefits of unit testing that I wanted them to grasp and run with. But I did not take the time at the outset to clarify to myself or articulate to the team's management, exactly what we hoped to achieve. And of course without knowing what you want to achieve, it becomes harder to know if you succeeded. How will you know you are there when you don't

TinT: Controlling Application Licenses in Unit Tests

Testing in the Trenches (TinT) is an occasional series recounting some of the situations I encountered and advice I gave real people and real teams on real projects to help them buy into and improve at applying the concepts of Unit Testing. Any identifying data has been changed to protect them.  Not so very long ago, I worked with a software team whose application had some core functionality that the clients would purchase and install on their own machines (we did not host the system). This core functionality could then be expanded through about a dozen separate "Licenses" that the clients could purchase in whatever combination suited their needs. If the client wanted a web interface to the core desktop system, they could purchase one or more of the web-functionality licenses. Or if they needed more powerful tools for the financial processing side of the core application, they could buy the license that would allow access to those expanded features. The state of the Licen

Shout-out for Good Customer Service: Abstrakti

Let me give a shout-out to Abstrakti Software for a job well done and excellent customer service. My small team recently completed a project to move all of our development work from Visual Source Safe to Git source control management. Our code base was very large, with hundreds of thousands of source files across dozens of VSS projects spanning more than 17 years of history. Preserving the VSS History was one of the project's top priorities, and for that we looked into a handful of tools that were designed for just that purpose.

Object-Oriented Trinity - Part 3

I currently make a living as a Software Engineer, and I am also an ordained Anglican priest. In seminary, one assignment was to write a letter to a fictional friend, explaining the Trinity in some creative imagery.  My paper sought to use Object-Oriented concepts to shed light on this great mystery of faith. This is third in a 3-part series of posts that somewhat adapts that 2005 paper to the different medium of a Blog, and to refine with my understanding as it stands now of both the Trinity and Object-Oriented programming and design. The first part is HERE . The second part is  HERE . Hey Christian, I'm glad to hear that you are dazzling your new company with your brilliance. So you think something is incomplete in our discussion so far about the Trinity and Object-Oriented design? You're right. The doctrine of the Trinity says that God Almighty is both One and Three, at the same time, and we have left a third out completely so far. The Trinity's third Person is t

Object-Oriented Trinity - Part 2

If you have read my limited Bio information, you may have noticed that I am a Software Engineer and also an ordained Anglican priest. In seminary, one assignment was to write a letter to a fictional friend, explaining the Trinity in some creative imagery. The doctrine of the Holy Trinity is and to some extent has always been one of the more numinous and abstruse in Christianity. My paper sought to use Object-Oriented concepts to shed light on this great mystery of faith. This is second in a series of posts that somewhat adapts that paper to this different forum, and to my understanding as it stands now of both the Trinity and Object-Oriented programming and design. The first part is found here. Hi Christian! The last time I wrote, I used the Object-Oriented design pattern of the Singleton to look at the Trinity and its claim that God is One. But as you rightly point out in your reply, that barely scratched the surface of the doctrine of the Trinity. Let's go deeper.

Reusing UI Sections in FXML and Scene Builder

If the DRY principle (Don't Repeat Yourself) is a core Best Practice in Object-Oriented Programming and software development, is there any way to define common user interface sections of an application in FXML? Can we avoid repeating the work that goes into laying out and controlling sections that are common across across many or even all screens? It would be beneficial and more consistent if their layout could be defined once and reused wherever necessary. Rather than redefine a menu bar or a collection of buttons on multiple screens, create them once and apply them as needed. Of course, this approach is nothing new. But as I explored JavaFX as a User Interface toolkit, it was straight-forward how to do this in code, but it was less clear how to do so using FXML. To speed up user interface development, we want to use the JavaFX layout manager Scene Builder. I am using v8.2 from Gluon - thank you Gluon for backing this important tool!

Object-Oriented Trinity - Part 1

If you have read any of my limited Bio information, you may have noticed that I am a Software Engineer. It was my first career, from which I took a hiatus for about a decade to do other things. One of those other things was becoming an ordained Anglican priest. I was recently reminded of a somewhat whimsical paper I wrote in seminary, while working on my MDiv and preparing for the priesthood. Our assignment was to write a letter to a fictional friend, explaining the Trinity in some creative imagery. The doctrine of the Holy Trinity is and to some extent has always been one of the more gnarley in Christianity. Drawing on my first career of software development, my paper sought to use Object-Oriented concepts to shed light on this great mystery of faith. In a series of posts (Three would be the right number, no?), I will somewhat adapt that paper to this different forum, and to my ever-growing and evolving understanding of both the Trinity and Object-Oriented programming and design

Adding Items to a ListView using Scala, ScalaFX and FXML

I have been playing with writing an application using Scala, with its API defined in ScalaFX, which wraps the powerful JavaFX library. For simple exercises, coding the UI by hand was enough. But for more complex forms, I began using the JavaFX Scene Builder tool. Fortunately, others have blazed this trail, and there are fairly stable ScalaFX and ScalaFXML libraries available. Using the Scene Builder tool, I laid out my form and included a ListBox to hold possible gender selections. The Scene Builder tool generated fxml code such as: <AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="208.0" prefWidth="275.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">    <children>       <Label layoutX="14.0" layoutY="30.0" text="Name" />       <Label layoutX="14.0" l

TinT: Metaphors for Test Types

Testing in the Trenches (TinT) is an occasional series recounting some of the experiences I have had as a Unit Testing evangelist on various projects. Where appropriate, any references to actual details have been sanitized to protect the participants. This post is adapted from a regular email that I sent to the team, to promote and educate about testing. I secretly called these my Unit Test Propaganda Messages. For a while now, I have been promoting among the team the idea of automated testing, especially Unit Testing, as a means to improve both our lives as developers and our software for our clients. Recently, I was listening to a Software Engineering Radio podcast , and the speaker mentioned seven different kinds of automated testing that they do in his organization. The speaker was Mike Barker, talking about his work on the LMAX architecture, and the seven kinds of automated testing he named (around the 50-minute mark) were: Unit Tests,  Integration Tests,  Acceptance Tes

Fixing "resource modena.css not found" in SBT

I have a project that is building a system in Scala. Its GUI is being defined using the ScalaFX system, which is a thin layer that delegates to the underlying JavaFX tools, components and features. The application was running with a fine-looking GUI in early testing, but all the builds were being driven by the IDE. For various reasons, we wanted to migrate the build to the SBT system. But upon launching with $ sbt run we would get entries like this in the console: [info] Running StartHere May 21, 2016 8:50:28 PM com.sun.javafx.css.StyleManager loadStylesheetUnPrivileged WARNING: Resource "com/sun/javafx/scene/control/skin/modena/modena.css" not found. The application would compile without issue and would run correctly, but looked terrible. For instance there would be no edges visible for buttons or for text box input fields. Obviously, a dependency was missing from the build.sbt file. It was easy enough to add, with a line like the following: unmanagedJars in Co

TinT: Composition vs Inheritance vs Unit Testing

This episode of  Testing in the Trenches  describes, with appropriate modifications to protect the parties involved, a unit-testing situation I encountered on a client's project. One question I was asked in a job interview some number of years ago was: "For code reusability, which is better: Inheritance or Composition?" As I recall from the interview, I chose one - in my case, Inheritance - and defended my choice: there is conceptual power in defining higher-level, common traits and behaviors higher up the hierarchy, and re-using it in its sub-classes, or overriding and refining it when more specific behavior is required. Or something like that. It was obvious from my interviewer's reaction that he was not impressed with my answer. And I have occasionally wondered, in hindsight, if I should have not chosen either, but talked about both and shown my grasp of both concepts. That might have been the better interview technique. After all, a couple years later, wit

Windows .BAT Script to launch task, then loop until done

My last post described my discovery of the Windows Schtasks.exe utility to trigger via the command-line a scheduled task on a local or - more relevant to the challenges I was facing - on a remote server. I described its ability to query the state of the task, and to launch it. Of course, since my whole purpose was to automate a tedious manual section of our build process, Schtasks.exe is helpful but hardly the end of the story. To benefit from that new knowledge, I now need to create a Windows shell script that our Continuous-Integration tool Jenkins can launch. This post is almost a stream-of-consciousness blog as I play with this problem. The requirements are that the script launch the remote scheduled task, poll its status until it is complete, and end with an appropriate result code. Some minimal logging of activity would also be nice. To begin, I created a .BAT file and created a labelled section to trigger the remote task: :LaunchBuild REM  QUESTION: What if it is alr

Trigger Windows Scheduled Task from Remote Computer via Jenkins

One thing I love about working in Information Technology is the opportunity - the NEED - to constantly learn new things. If a week goes by in which I have not looked up something on StackOverflow or other message boards, I start lobbying my team for more challenges. This week, I learned the power of running " SCHTASKS.exe " from a command-line script for a remote server in a Microsoft Windows environment. If you don't know Schtasks, you can read up on it here: https://msdn.microsoft.com/en-us/library/windows/desktop/bb736357(v=vs.85).aspx In a nutshell, it is the command-line interface for the Windows Task Scheduler, and allows you (or a system administrator) to create, change, run, query, terminate, and delete scheduled tasks on a work-station, either the local one or a remote one. Not all of the features are available in older versions. In my scenario below, this was relevant as the local computer will be a Windows 8 machine, and the remote server is, shall we

TinT: Avoiding User Interactions

This episode of Testing in the Trenches describes, with appropriate modifications to protect the parties involved, a situation I encountered on a client's project that challenged our efforts to create a suite of automated unit tests and what we did about it. It is adapted from one of the internal Tips that I regularly sent to the team. One of the key goals in unit testing is that we can run the suites of tests quickly. When the tests run in just a handful of seconds, we get fast feedback when issues arise. It is easier and safer to resolve those issues when the developer's mind is still on the problem they were working on. And tests that run quickly are less of a perceived interruption to the work of a test-averse developer. This increases the odds that the developer will adopt the practice of running the test suite before committing their code. But a run of tests comes to a complete halt when user interaction is required. For example, a path through the code that create

Comparison Operators and Between in Relational Databases

Sometimes our techie-brains convert a concept clearly articulated in plain English into unnecessarily mathematically expressed code. For example, "I want all records with an amount between 1000 and 1999" can become "x >= 1000 AND x <= 1999" But modern RDBMS database systems give us an English equivalent that saves translating the concept "between" into "greater than or equal to this, and less than or equal to that." It's the BETWEEN function, and it is the same across SQL Server, PostgreSQL, MySQL, and Oracle. Maybe others, too, but those are the ones that I have used in the past. BETWEEN is of the form: MyTestValue BETWEEN StartValue AND EndValue It is an inclusive comparison, equivalent to using >= and <= So these generate the same results: SELECT * FROM MyTable WHERE MyValue BETWEEN 100 AND 1000 vs SELECT * FROM MyTable WHERE MyValue >= 100 AND MyValue <= 1000 What are the advantages of BETWEEN? It's a

Using Java 8 to Refactor an Iteration over a Collection

On a recent project, I came across an ideal algorithm to (re-)write using Java 8's Streams API and Lambda expressions. Here is the original code, modified to protect the client: public String extractAllToAccountsAsCSV(List<AccountPair> collectionOfPairedAccounts) { String result = ""; for (AccountPair pair : collectionOfPairedAccounts) { if (result.length() > 0) result += ","; result += String.valueOf(pair.getToAccount()); } return result; } This simple algorithm iterates over a collection of AccountPairs, which are objects of a data structure that associates two accounts. Its goal is to produce a comma-separated String output of all values of one kind of account in the AccountPair, a CSV that the calling class will consume in some way. The description sounds right in the wheelhouse of Java 8. It would not be a refactoring that alters the structure of the class, per se , but it does change the detailed design inside the publi

How to do a Case-Sensitive SQL Server Query

When selecting data in SQL Server, the WHERE-clause has, in my experience, ignored the case and done a case-insensitive comparison. For example, my Individuals table may have a mix of upper and lower cases, depending on how people entered their names: SELECT firstname, lastname  FROM Individuals WHERE lastname = 'Timmins' firstname lastname --------- -------- Tammy TIMMINS Tellie timmins Tommy TimMinS Tubby Timmins My query selected all four people with the last name "Timmins" without caring if it was all capitals, all lower case, or a mixture. I rely on that behavior all the time. But once in a while, we need to do a case-sensitive query. How can we, for example, find Tommy TimMinS and correct it to Tommy Timmins?

Testing-in-the-Trenches: Spin-off a New Class

Testing in the Trenches (TinT) is an occasional series based on my experiences promoting and coaching Unit Testing on real projects, ones where the team or management do not always embrace the philosophy or practices of Unit-Testing. Technique: Spinning-off a New Class Imagine you believe in the principles of automated unit testing. You want to write tests to prove the correctness of your code. But imagine that you are working in a code base with pockets, sections, even whole packages of code that has no tests, possibly even code whose design is hostile to being put into a test harness. Imagine that the enhancement or bug fix on your plate involves changing existing code that has no current test coverage, or not very much, or maybe some tests but they are poor quality. Maybe they have a lot of dependencies, or it takes a lot of work to set them up, or they do too many things on construction. This imaginary scenario is very common on some projects. Faced with such a scenario, as

Exploring Scala foldLeft and foldRight

Scala collections let you "fold" the data in the collection into a single result. In the Scaladoc, it says that it "Folds the elements of this traversable or iterator using the specified associative binary operator." Let's play with this concept. Since fold() is the most flexible and powerful, let's warm up by looking at the simpler foldLeft and foldRight methods. These fold* operations will apply to a collection, so let's create a simple one: scala> val a = List(1,2,3) a: List[Int] = List(1, 2, 3) scala> a.foldLeft(7)(_+_) res1: Int = 13 What just happened? We created a List of integers, and called foldLeft on the List. We provided two parameters. The first is the start value, in this case 7. The second is a binary operation, in this case an addition. Since foldLeft applies the binary operation to the start value and each of the elements in the collection, going left to right, the steps to the result are: 7 + 1 = 8 8 + 2 = 10 10 + 3

Scala Collections: A Group of groupBy() Examples

Scala provides a rich Collections API. Let's look at the useful groupBy() function. What does groupBy() do? It takes a collection, assesses each item in that collection against a discriminator function, and returns a Map data structure. Each key in the returned map is a distinct result of the discriminator function, and the key's corresponding value is another collection which contains all elements of the original one that evaluate the same way against the discriminator function. So, for example, here is a collection of Strings: val sports = Seq ("baseball", "ice hockey", "football", "basketball", "110m hurdles", "field hockey") Running it through the Scala interpreter produces this output showing our value's definition: sports: Seq[String] = List(baseball, ice hockey, football, basketball, 110m hurdles, field hockey) We can group those sports names by, say, their first letter. To do so, we need a disc

Moving a Collection Task to Java 8 Lambdas and Streams

On a recent project, I encountered a function that had been copy-pasted to a dozen places in the code base. That in itself is a classic Code Smell , and I determined to extract it to a common, reusable function. The block of lines also repeated an action over several elements in a larger collection. Since this team had recently moved to Java 8, I decided to rewrite this code using Lambdas and the Stream API. The project's code base used a class called DBRecord as a very flexible extended Collection, representing the data in a single row from a relational database. It was designed to contain one Collection of the various field values for the row of data, and another Collection of meta-data defining the traits of the fields themselves. Another wrinkle was the state of denormalization of their underlying data model. The team has traditionally not been interested in following Third-Normal-Form design patterns, resulting in as much duplicated and repeated data in their table struc

How to Disable Windows Rotate Screen Keyboard Shortcut

I love keyboard shortcuts and hot-keys. I learn and use as many of them as I can. Sometimes, however, the same short-cut can get defined by multiple parts of a system and can create surprising results. For example: when working in Eclipse IDE, a very useful one is CTRL-ALT-UP (or DOWN) arrow. It takes whatever line the cursor is currently on and duplicates it above or below the current line. It also works on highlighted blocks of lines. I use it all the time to preserve the original form of a line or block. For example, when I am writing unit-tests that are all related, I take the one I just wrote and CTRL-ALT-DOWN to copy it, then I modify the duplicated code for my next test. Saves retying the boiler-plate. I may also use it when modifying some code. I duplicate it with CTRL-ALT-DOWN keyboard short cut and then while the line(s) are highlighted still, I do a CTRL-ForwardSlash which in Eclipse comments out the line. This preserves the original line while I tinker and experiment.

ScalaFX MenuBars: Can I Right-align one Menu?

A question arose recently: can we move the Help menu item to the right edge of the active window? In an earlier post, I looked at some basics of Menu-related controls in ScalaFX, and wrote some simple code for ScalaFX to create a basic menu bar that looked like this: Our three Menus are all left-aligned, which is pretty standard in the realm of desktop applications. So: does ScalaFX give us the controls and hooks that we need in order to adjust the alignment and push the last menu to be Right-aligned?

An Occasional Unit Test Failure Caused by Dates

In honor of the Leap Day of February 29th, let me tell a story about an unusual date problem I encountered while unit-testing. One project I worked on had made a small effort at writing unit tests, using Java and jUnit. Unfortunately, the team culture was not to run the test suite frequently while developing. Rather, developers were sort of willing to run their own tests, but let the nightly job run the full suite. When a test would fail, someone would track down and lean on whoever had broken it. Once in a blue moon, a certain couple of Unit tests would fail. This is the story of why they were breaking, why it was hard to duplicate the issue, and how I fixed it once I found it. These tests failed one night in the spring, and again one night in the summer. But next morning, no one could reproduce the failure. So they were chalked up to disturbances in the Force or cosmic rays, one of "those things" that happen "sometimes" and nothing was done.

ScalaFX Menu Basics

I am working on an application for a personal project, and learning ScalaFX in the process. Since Menu bars are important parts of the user interface, with easy access to a range of application functionality, I plan to build a menu bar into my product. This post explores some of what I am discovering about Menu-related features of ScalaFX. First, let me set up a basic framework for my exploration, a scala object extending JFXApp. I also import the scene, layout and control packages, since I will need them for the Scene, MenuBar and VBox classes. import scalafx.application.JFXApp import scalafx.scene.layout._ import scalafx.scene._ import scalafx.scene.control._ /**  * Exploring Menu-related classes in ScalaFX  */ object SfxMenuExplore extends JFXApp {   // We will define the menu object here.      val wholeLayout = new VBox {     children = List(menu)   }   val myScene = new Scene(wholeLayout, 300, 200)   stage = new JFXApp.PrimaryStage {     scene = myScene  

ScalaFX: Button positioning with HBox

I'm working on an application, as an excuse to practice my Scala and learn ScalaFX in the process. The application will have several input forms. Most will have action buttons, such as Save and Cancel. While the mobile world is going more and more vertical in its layout, the program I am working on is targeting Windows and Mac platforms. In them, buttons are usually laid out side by side. The ScalaFX HBox layout does exactly that: draws its components in a horizontal sequence. As I work through the different aspects of HBox, I will use this Scala object structure:

Introducing: ME

Hello. I'm Steven Page, the maker of SJGP Software. I started this blog several years ago, to show off the software I was creating out of my personal interests. It became a mini online user manual for two programs in particular. Most of the blog's past activity occurred while I worked outside the Information Technology industry. When I returned to IT professionally in 2012, the blog's activity dropped off. Time to resurrect it, with a different focus: me and what I am learning and discovering in the world of software development, instead of just tips for using the software I wrote several years ago. Right now I am brushing up on my |Scala, exploring ScalaFX UI, promoting unit testing and continuous integration at my work, and learning Git. Stay tuned for more.