2015年5月11日月曜日

Javaで文字列を表示した時の幅を取得する

FontオブジェクトとFontMetricsオブジェクトを使用して、簡単に取得できます。
簡単なのでいきなりサンプルプログラムです。
import java.awt.Font;
import java.awt.FontMetrics;
import sun.font.FontDesignMetrics;

public class Program {

    public static void main(String[] args) {
        // Fontオブジェクトをインスタンス化する
        // FontオブジェクトからFontMetricsオブジェクトを取得する
        // FontMetrics#stringWidthメソッドで文字列の幅を取得する
        Font font = new Font("Monospace", Font.PLAIN, 12);
        FontMetrics fontMetrics = FontDesignMetrics.getMetrics(font);
        String data = "Hello FontMetrics";
        int width = fontMetrics.stringWidth(data);
        System.out.println(width);
    }
}

※このプログラムをコンパイルすると警告が出ます。

2015年4月27日月曜日

JavaのExecutorServiceのサンプル

Javaでスレッドを使用するには、ExecutorService#invokeAllを呼ぶのが簡単です。ExecutorService#inokeAllは別スレッドで実行するCallableオブジェクトのコレクションを引数として受け取り、処理がすべて完了するまで現在のスレッドをブロックします。処理の結果はFutureのリストとして返ります。
サンプルとして、複数のホストに対してpingコマンドを発行するプログラムを作成しました。
import java.util.List;
import java.util.ArrayList;
import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Future;

public class Program {
    
    public static void main(String[] args) throws Exception {

        ExecutorService svc = Executors.newFixedThreadPool(3);

        try {
            List<Callable<Integer>> listCallable = new ArrayList<>();
            for (String ipAddress : args) {
                listCallable.add(new PingCommand(ipAddress));
            }
            List<Future<Integer>> listFuture = svc.invokeAll(listCallable);
            for (Future<Integer> future : listFuture) {
                System.out.println(future.get());
            }
        } finally {
            svc.shutdown();
        }
    }

    private static class PingCommand implements Callable<Integer> {
        private final String ipAddress;

        private PingCommand(String ipAddress) {
            this.ipAddress = ipAddress;
        }

        public Integer call() {
            try {
                String[] args = {"ping", ipAddress, "-c", "3"};
                Process proc = new ProcessBuilder(args).start();
                return proc.waitFor();
            } catch (Exception e) {
                e.printStackTrace();
                return -1;
            }
        }
    }
}

参考
ExecutorService
Callable
Future

2015年4月20日月曜日

Windows PowerShellでExcelが出力したCSVを読み込むには

先日、Excelで作成されたドキュメントを一括処理する作業をしていました。
最近「Windows PowerShellいいよ」という話をみかけたので、Windows PowerShellで自動化することにしました。

Windows PowerShellには、CSVを取り込むためのコマンドレットがあり、"Import-Csv"といいます。
ところがこのコマンドレット、Windows 7に標準でインストールされているバージョンでは、取り込む対象のエンコーディングを指定できないという致命的な欠点があります。Excelが出力するCSVのエンコーディングはShift-JIS。一方Import-CSVが対応しているのはUnicode。困りました。

解決策は2つあります。
1. Windows PowerShellをアップデートする
Windows PowerShell 3.0以降、Import-CSVに-Encodingパラメータが追加されました。"-Encoding Default"を指定すれば、Shift-JISのファイルにも対応できます。アップデートファイルは、下記参考の"Windows Management Framework 4.0"から取得してください。
Import-Csv -Path .\Book1.csv -Encoding Default

2. Get-ContentとConvertFrom-Csvを使用する
Get-ContentはShift-JISに対応していますので、Get-ContentとConvertFrom-Csvをパイプでつなぐことで読み込めます。
Get-Content .\Book1.csv | ConvertFrom-Csv

参考
Windows Management Framework 4.0
ConvertFrom-Csv
Get-Content
Import-Csv

2015年3月23日月曜日

Clojureでawtの画面を表示

ClojureからawtのWindowを表示するだけのサンプルプログラムです。
(ns myawt)

(import '(java.awt Frame)
        '(java.awt.event WindowListener))

(def window-width 600)
(def window-height 480)

(doto (Frame.)
    (.addWindowListener
        (proxy [WindowListener] []
            (windowActivated [e])
            (windowClosed [e] (System/exit 0))
            (windowClosing [e] (.dispose (.getWindow e)))
            (windowDeactivated [e])
            (windowDeiconified [e])
            (windowIconified [e])
            (windowOpened [e])))
     (.setSize window-width window-height)
     (.setVisible true))
windowClosedとwindowClosingのイベントハンドラを実装するのがポイントです。

参照
Frame
WindowListener

2014年9月29日月曜日

行指向ファイル処理フレームワーク

業務でファイルを一行ずつ読み込んで処理するプログラムをコーディングしているのですが、提供された設計書のフローチャートに従って実装を進めていたら、脳みそがぐちゃぐちゃにかき回されるようないらだちを覚えました。
"ファイルを一行ずつ読み込んで処理する"という要件は、あちこちで需要がありそうなので、モデルを考えてみました。 Process、FileFinder、FileHandler、LineHandlerの4つのクラスで構成します。

2014年9月22日月曜日

VB.NETを使い始めて戸惑ったこと3つ

最近VB.NETを使っているのですが、いくつか戸惑ったことがあったので紹介します。

Forループの終了条件
処理を10回繰り返そうとして次のようにFor文を記述します。
For i = 0 To 10
    Console.WriteLine(i)
Next
実行すると、11回実行されます。Toもループ変数の範囲に含むんですね。

charリテラル
VB.NETでは、charリテラルを次のように記述します。
Dim c As Char = "A"c
""c…。

抽象クラスの宣言
VB.NETでは、抽象クラスを次のように記述します。
Public MustInherit Class AbstractClass

End Class
MustInheritは「継承しないと使えないよ」という意味でしょうか。

2014年9月15日月曜日

JScriptからInternetExplorerを操作してYahoo!JAPANを検索する

JScriptからIEを操作し、Yahoo!JAPANで"ほどよくしっかり"を検索させてみました。











ちゃんと、このブログが先頭に表示されました。
JScriptからIEを操作できるということは、標準入力と標準出力を使ってIEを操作できるということで、諸々の自動化が捗るかもしれないということです。興味深い。

以下、コードです。