メモの日々


2013年11月02日(土) [長年日記]

[hard] 無線LANルータを買った

無線LANはたまに使うだけなのだけれど、そのときは3年前に買ったUSBに刺す小型の機械を親機モードで使っていた。が、これが「Windows 7(64bit)では親機モードはご利用いただけません」とのことで使えなくなってしまった。

ウェブで検索すると使えるようにする手順が紹介されており試してみたのだけれど、うまく接続できなかったので諦めて新しい機械を買うことにした。

買ったのはI-O DATAのWN-G300Rという無線LANルータ。ヨドバシカメラで一番安い無線LANルータを選んだらこれになった。3190円。 B007MSEUU4

ルータの機能は不要なのでアクセスポイントモードで運用し、無事接続できた。


2013年11月07日(木) [長年日記]

[life] 健康診断を受けた2013

今年も受診。去年と変わりなかったかな。あ、採血する人が毎年同じおじさんだったのだけれど、女の人に代わってたや。

大腸がん検査は色々面倒なので断ってしまった。300円。


2013年11月11日(月) [長年日記]

[python][java] JythonをScriptEngine経由で使うとdatetimeモジュールが正しく動かない

Javaのスプリクティング機能Jython 2.5.3を使ってJavaから次のPythonスクリプト

import datetime

d = datetime.date.today()
print d
print d.year
print d.min

を実行すると、

2013-11-11
113
AttributeError: 'java.sql.Date' object has no attribute 'min' in <script> at line number 6

と出力される(Java側のコードは省略)。'java.sql.Date' だと?!

試しにスプリクティング機能を使わず、

% java -jar jython-standalone-2.5.3.jar script.py

のようにスクリプトを実行すると、

2013-11-11
2013
0001-01-01

と正しく動作した。

検索すると、

というJythonのissueが見つかった。2年以上前に報告されているけれど未だに直らないみたい。

このissueにあるように「del datetime.date.__tojava__」という行をPythonスクリプトに追加してからJavaのスクリプティング機能を使って実行すると、

datetime.date(2013, 11, 11)
2013
datetime.date(1, 1, 1)

と出力されるようになった。


2013年11月12日(火) [長年日記]

[python][java] JythonをScriptEngine経由で使うときにマジックコメントを書くとエラーになる

以前も調べたのに今日また調べてしまったのでメモしておく。

Pythonスクリプト内でエンコード宣言を書いたものをJavaのスクリプティング機能から呼び出すと、例外が投げられてしまう。

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

public class JythonRunner {
    public static void main(String[] args) throws ScriptException {
        ScriptEngineManager sem = new ScriptEngineManager();
        ScriptEngine engine = sem.getEngineByName("python");
        engine.eval(
            "# coding: utf-8\n" +
            "print 'hello'\n");
    }
}
Exception in thread "main" javax.script.ScriptException: org.python.antlr.ParseException: org.python.antlr.ParseException: encoding declaration in Unicode string
	at org.python.jsr223.PyScriptEngine.scriptException(PyScriptEngine.java:196)
	at org.python.jsr223.PyScriptEngine.compileScript(PyScriptEngine.java:75)
	at org.python.jsr223.PyScriptEngine.eval(PyScriptEngine.java:31)
	at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
	at JythonRunner.main(JythonRunner.java:9)
Caused by: org.python.antlr.ParseException: encoding declaration in Unicode string


org.python.antlr.ParseException: org.python.antlr.ParseException: encoding declaration in Unicode string

	at org.python.core.Py.JavaError(Py.java:481)
	at org.python.core.ParserFacade.parseExpressionOrModule(ParserFacade.java:124)
	at org.python.util.PythonInterpreter.compile(PythonInterpreter.java:259)
	at org.python.util.PythonInterpreter.compile(PythonInterpreter.java:256)
	at org.python.util.PythonInterpreter.compile(PythonInterpreter.java:250)
	at org.python.jsr223.PyScriptEngine.compileScript(PyScriptEngine.java:70)
	... 3 more
Caused by: org.python.antlr.ParseException: encoding declaration in Unicode string
	at org.python.core.ParserFacade.prepBufReader(ParserFacade.java:277)
	at org.python.core.ParserFacade.parseExpressionOrModule(ParserFacade.java:119)
	... 7 more

Javaを使わずJython上で直接実行する場合はエラーにならない。

例外を投げているParserFacade#prepBufReader()のソースコードを見ると、

        if (findEncoding(bufferedReader) != null)
            throw new ParseException("encoding declaration in Unicode string");

となっていて、意図的に例外を投げているみたい。エンコーディングはJava側で決めてスクリプトを読み込んでいるからだと思うけど、不便。


2013年11月25日(月) [長年日記]

[java] JInternalFrameの大きさ変更中はフレームのGlassPaneが可視になる

JInternalFrameを使っていて、

  • 内部フレームの縁をドラッグして大きさを変えようとするとフレームのGlassPaneが表示される

という現象に遭遇したのでメモ。Javaのバージョンは1.7.0_45。

javax.swing.plaf.basic.BasicInternalFrameUI.BorderListener のソースに、

                if (c instanceof RootPaneContainer) {
                    Component glassPane = ((RootPaneContainer)c).getGlassPane();
                    glassPane.setCursor(Cursor.getPredefinedCursor(
                        Cursor.DEFAULT_CURSOR));
                    glassPane.setVisible(false);
                }
                if (c instanceof RootPaneContainer) {
                    Component glassPane = ((RootPaneContainer)c).getGlassPane();
                    glassPane.setVisible(true);
                    glassPane.setCursor(s);
                }

というコードがあって、このせいみたい。マウスカーソルの形状を変更しようとしているのかな。

動作確認用のコードを示しておく。

import java.awt.BorderLayout;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;

public class IFrame {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                showFrame();
            }
        });
    }

    public static void showFrame() {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

        // GlassPaneに不透明なコンポーネントを設定
        JLabel glass = new JLabel("GlassPane");
        glass.setOpaque(true);
        frame.setGlassPane(glass);

        final JDesktopPane desktop = buildDesktop();
        frame.add(desktop, BorderLayout.CENTER);

        frame.setSize(400, 300);
        frame.setVisible(true);
    }

    public static JDesktopPane buildDesktop() {
        JDesktopPane desktop = new JDesktopPane();

        JInternalFrame iframe = new JInternalFrame("hello", true);
        iframe.setSize(100, 100);
        iframe.setVisible(true);

        desktop.add(iframe);

        return desktop;
    }
}
  • 通常の画面

通常の画面

  • 内部フレームリサイズ中の画面

内部フレームのリサイズ中


2013年11月26日(火) [長年日記]

[java] JOptionPaneが閉じる前に処理をしたい

JOptionPaneで表示できるダイアログはボタンを押すと必ず閉じてしまうので、閉じる前にテキストフィールドの値をチェックしたりすることができない。

ダイアログが閉じる前に処理をする方法を調べていて、

が参考になったのでメモ。

  • JDialog.html#setContentPane()でJOptionPaneのインスタンスを設定すると、JOptionPaneが作るのとほぼ同じダイアログを作れる。
  • JOptionPaneのインスタンスにPropertyChangeListenerをセットすると、ダイアログ上のどのボタンが押されたのかを調べることができる。JOptionPaneのドキュメントに「 選択が変更されると、setValue が呼び出され、PropertyChangeEvent が生成されます。JOptionPane がすべての入力 setWantsInput に設定されている場合、バウンドプロパティーの JOptionPane.INPUT_VALUE_PROPERTY を待機することによっても、ユーザーが値を入力または選択した時点を判定することができます。 」とあるのがその説明だと思う。

2013年11月27日(水) [長年日記]

[java] try-with-resource文での処理順序

次のプログラムがどういう出力をするのか。

public class TryWithResoruce implements AutoCloseable {
    public TryWithResoruce() {
        System.out.println("TryWithResoruce");
    }

    @Override
    public void close() {
        System.out.println("close");
    }

    public static void main(String[] args) {
        try (TryWithResoruce twr = new TryWithResoruce()) {
            throw new RuntimeException();
        } catch (RuntimeException ex) {
            System.out.println("catch");
        } finally {
            System.out.println("finally");
        }
    }
}

注: 通常の try 文と同様に、try-with-resources 文には catch ブロックと finally ブロックを含めることができます。try-with-resources 文内の catch または finally ブロックは、宣言されているリソースが閉じられたあとで実行されます。

とある通り、

TryWithResoruce
close
catch
finally

となったことをメモ。先にクローズされちゃうのかー。

[life] 再検査を受けに行った

健康診断の結果が出て、肝機能のALT(GTP)という検査項目の値が基準値を超えていた。再検査が必要とのこと。健診で再検査になるのって初めて。肝臓に問題があるなんて考えたこともなかった。酒飲まないのに。

それで、病院を予約して今日行ってみた。内科を受診する。先生の部屋の入口に今何時予約の人を診察しているかという情報が表示されていて、1時間前に予約した人が受診中だった。というわけで、1時間近く待たされた。

やっと自分の番。座るといくつか質問される。先生は答えを聞くとPCに文章を打ち込んでいた。今日は採血をして、超音波検査の予約を取るとのこと。超音波の検査は後日になっちゃうのか。最後に思い出したようにお腹を診ると言われ、ベッドに横になって腹を押された。それで問診終了で、部屋の外で待つように言われる。まだ採血はしていない。

部屋の外で随分待つ。40分くらいか。やっと呼ばれて、超音波検査の予約の手続きをした。超音波の予約は混んでいるとのことで、受けるのは来週になった。それが終わったら採血室に行って採血。これはほとんど待たずにできた。会計をして終了。全部で2時間くらいかかった。