Saturday, April 15, 2017

Linux Mint 17 and scroll bar arrows

A while ago I did a complete reinstall of my desktop machine using Linux Mint 17. One of the first things I noticed after doing this was that the arrow bars that normally appear in conjunction with the scroll bar had disappeared. I deemed this a minor irritation and didn't do anything about it. But more recently I investigated why this was and what to do about it and found various blogs etc where people were complaining of the same thing and offering various solutions. I only found one solution that actually worked and give details on it below:

* Ensure that your changes are made to the Mint-X theme. You need access to the theme selector. Click on the Linux button (bottom left hand corner) and click on Settings. In the right hand menu pane click on Appearance (with the jacket and tie icon). This shows the theme selector when you pick the first tab, Style (which is the default tab). When you click on a theme it is immediately selected. There is no need to logout, reboot, or anything else. On selecting a theme the theme config files are read and processed. Therefore when you edit the theme files, use the selector to pick any theme *other* than Mint-X, then click on Mint-X again to pick up your changes.

* As root, edit the theme files. These are found under /usr/share/themes, so for Mint-X the directory is /usr/share/themes/Mint-X. There are sub-directories for gtk-2.0 and gtk-3.0. My edits were done to gtk-2.0. The file there is called gtkrc. Make a backup copy of the file first. Ensure your file contains the following:

GtkScrollbar::has-backward-stepper = 1
GtkScrollbar::has-forward-stepper = 1
GtkScrollbar::stepper_size = 18
GtkScrollbar::min-slider-length = 30
GtkScrollbar::slider-width = 18
GtkScrollbar::trough-border = 1
GtkScrollbar::activate-slider = 1

The crucial line turns out to be:

GtkScrollbar::stepper-size = 18

Without that line, no scroll bar arrows.
I found this tip on Linux Questions at http://www.linuxquestions.org/questions/linux-mint-84/question-how-to-enable-scrollbar-arrow-buttons-in-linux-mint-v17-3-a-4175580868/.

Sunday, February 26, 2017

Using Joda time to handle date+time+timezone

I have been working on a client-server system where the client and server are in different timezones. The client is on London time, the server is in Los Angeles, a difference of 8 hours. This means that at the end of the business day in LA it already the next day in London. The API that I have to use contains functions with parameters of type Calendar. As we know, Calendar is a date+time+timezone triple, and the timezone defaults. This means that if the timezone is not explicitly specified then it will change its meaning as it goes over the wire.

I have been using the Joda datetime package to help me and after a bit of struggling eventually came up with the example program below which shows the construction of Joda DateTime objects for a specific date+time+timezone which is displayed correctly in both timezones. The program also shows how to construct Calendar objects from them for the correct timezone.

       
package jodaexample;

import java.text.SimpleDateFormat;
import java.util.Calendar;

import org.joda.time.DateTime;
import org.joda.time.DateTimeZone;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;

/**
 * 
 * @author marlowa
 * This example shows a time of 18:30 PST which is 8 hours behind UTC.
 * This means the date+time+timezone is 01:30 the previous day in UTC,
 * or 02:30 in BST.
 */
public class example {

    public static void main(String[] args) {
        System.out.println("Joda timezone example program.");
        DateTimeZone mytimezone = DateTimeZone.forID("America/Los_Angeles");
        DateTime mydatetime = new DateTime(2017, 3, 31, 18, 30, 0, mytimezone);
        String formatString = "yyyy-MM-dd HH:mm:ss z '('Z')'";
        DateTimeFormatter dtf = DateTimeFormat.forPattern(formatString);
        System.out.println("DateTime (local, i.e. behind UTC) = "+dtf.print(mydatetime));
        Calendar datetimeInAmerica = mydatetime.toGregorianCalendar();
        SimpleDateFormat sdfInAmerica = new SimpleDateFormat(formatString);
        sdfInAmerica.setCalendar(datetimeInAmerica); // to set the timezone.
        System.out.println("Calendar inAmerica                = "+sdfInAmerica.format(datetimeInAmerica.getTime()));
  
        long dateTimeMilliseconds = mydatetime.getMillis(); 
        int millisecondsOffset = mytimezone.getOffset(dateTimeMilliseconds);
        System.out.println(String.format("Milliseconds = %d, offset = %d", dateTimeMilliseconds, millisecondsOffset));
  
        long millisecondsInTimezone = dateTimeMilliseconds+millisecondsOffset;
        System.out.println("millisecondsInTimezone            = "+millisecondsInTimezone);
        long millisecondsInUTC = mytimezone.convertLocalToUTC(millisecondsInTimezone, false);
        DateTime dateTimeUTC = new DateTime(millisecondsInUTC, DateTimeZone.UTC);
        System.out.println("DateTime (UTC)                    = "+dtf.print(dateTimeUTC));
        Calendar datetimeInLondon = dateTimeUTC.toGregorianCalendar();
  SimpleDateFormat sdfInLondon = new SimpleDateFormat(formatString);
  sdfInAmerica.setCalendar(datetimeInLondon); // to set the timezone.
  System.out.println("Calendar inLondon                 = "+sdfInLondon.format(datetimeInAmerica.getTime()));
 }
}