inamenaiの日記 RSSフィード

2010年10月22日

私的Swingメモ

  • JFrameを継承したクラスを作成しそこにmainメソッドを定義する。主な初期処理はこのクラスのコンストラクタで行う。
public class BaseFrame extends JFrame {
    public static void main(String[] args) {
        BaseFrame base = new BaseFrame();
        base.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        base.setVisible(true);
    }
    public BaseFrame() {
        // コンポーネントの作成・配置など。
    }
}
  • JFrame.setDefaultCloseOperation() メソッドで「閉じる」を押したときの挙動を設定する。何もしてない状態だと「閉じる」を押してもウィンドウは閉じるがアプリケーションは終了しない(デフォルトは JFrame.EXIT_ON_CLOSE が良かったんじゃないだろうか…)。
  • JFrame.setVisible() は実行するタイミングによって挙動が変わる場合がある…気がする(単に可視状態になるタイミングの問題だけでなくコンポーネントの配置が崩れたりする)。main()の最後に実行するのが安全そう。
  • JEditorPaneをHTML形式で使うとデフォルトの行間がなぜかとても広くなっていて、line-heihtスタイルでの調整も効かないために使いづらい…(何か対応策はあるのかな?)
    (2010/11/05追記:少なくともWindowsの場合は下記の方法で通常のフォントや行間にできることを確認。)
try {
    // WindowsのLook&Feelを使用
    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
}
JEditorPane editorPane = new JEditorPane();
editorPane.putClientProperty(JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
  • JLabelは1つのラベルにテキストと画像を同時に設定できたり、HTMLも使える何かと便利な子。
  • (Swingに限った話ではないが)イベント処理でaddXXXListenerするときは無名クラスを使って実装するのが便利。またXXXListenerに定義されている全てのメソッドを実装する必要がないときはXXXXAdapterを継承させるとよい。
hoge.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent e) {
        // ここに処理を記述
    }
});

hoge.addKeyListener(new KeyAdapter() {
    @Override
    public void keyPressed(KeyEvent e) {
        // ここに処理を記述
    }
    // keyReleased()とkeyTyped()はいらない。
});

  • JList(など)はデータとその表示を分離しつつ連動させることができる。表示をカスタマイズしたい場合は、ListCellRendererを実装したクラスを用意し、ListModelにそのインスタンスを追加していく。
// JLabelを表示させたい場合
public class CustomJLabel extends JLabel implements ListCellRenderer {
    @Override
    public Component getListCellRendererComponent(
            JList list, Object obj, int index, boolean isSelected, boolean hasFocus) {
        // thisに対して表示内容を設定
        return this;
    }
}

何かあれば適宜追加していく。

2009年03月28日

指定したURLに一致するリンクテキストをハイライト表示するGreasemonkeyスクリプト

正規表現でURLを指定(複数可)しておくとそれに合致するリンクがあった場合にそのテキストをハイライト表示するスクリプト。リンク先がTinyURLの場合は本来のURLに変換してからチェックします。(2009/11/27:リンク展開APIが使えなくなってるみたいなので変換機能は消しました。)冒頭の正規表現の配列の中身を書き換えて使ってください。→インストール

自分の運営するサイトやブログのURLを指定しておくと、思わぬところで言及されていたときなどに気づきやすくなってよいんじゃないでしょうか。まあ個人運営のサイトなら数が知れているので大した効果はないかもしれませんが、僕の場合は自分の会社が関わったサイトを片っ端から登録して情報を拾っているので、そういう大量のサイトをチェックするニーズがあるときは便利かと思います。

// ==UserScript==
// @name        link highlighter
// @namespace   http://inasphere.net/
// @description 指定したURLに一致するリンクテキストをハイライト表示する
// @include     *
// @author      inamenai
// @license     MIT License
// @version     0.2
// ==/UserScript==

// 配布場所
//     http://d.hatena.ne.jp/inamenai/20090328/p1
// 変更履歴
//     2009/11/27 0.2 TinyURL展開機能削除
//     2009/03/28 0.1 リリース

(function() {

    // ハイライトする対象のURLを正規表現で指定した配列
    var urlRegExpArray = [
        /^http:\/\/www\.yahoo\.co\.jp/i,
        /^http:\/\/www\.google\.co\.jp/i,
        /^http:\/\/foo\.bar\.com/i
//      上記のようにここに正規表現を追加していく。行末のカンマの有無に注意。
    ];

    var anchorNodeArray = Array.slice(document.getElementsByTagName("a"));

    // アンカータグごとにループ
    for (var i = 0; i < anchorNodeArray.length; i++) {
        checkUrl(anchorNodeArray[i]);
    }
    // ハイライト用スタイルを追加
    GM_addStyle(
        "span.lh_highlight {font-weight: bold; color: #000000; background-color: #ffff66;}"
    );


    function checkUrl(anchorNode) {
        // 指定したURLごとにループ
        for (var i = 0; i < urlRegExpArray.length; i++) {

            // 現在のページがそもそもハイライト対象の場合はスキップ
            // (サイト内リンクが全部ハイライトされたりしてしまうので)
            if (urlRegExpArray[i].test(document.location.href)) {
                continue;
            }

            // アンカータグのURLが正規表現にマッチした場合はspanタグで囲う
            if (urlRegExpArray[i].test(anchorNode.getAttribute("href"))) {
                var spanNode = document.createElement("span");
                spanNode.setAttribute("class", "lh_highlight");
                anchorNode.parentNode.insertBefore(spanNode, anchorNode);
                spanNode.appendChild(anchorNode);
            }
        }
    }
})();

2009年03月24日

Google検索結果から未作成のはてな(などの)キーワードページを除去するGreasemonkeyスクリプト(11/27 追記)

何かググったときに「○○とは - はてなキーワード」のリンクをクリックして、「このキーワードはまだ作成されていません。」と言われたときのあのイライラをなくすためのスクリプト。→インストール

ところで、はてなが未作成のキーワードをnoindexにしないのは、(ダークサイド寄りな)SEOとしては有効かもしれないけどLPOとしては絶対に間違っている。未作成のキーワードのページは、検索エンジンから来訪したユーザにとってはほとんど何の価値もない(「○○を含むブログ」へのリンクとかもあるけどそんなのはGoogle先生が普通に補足してくれるのでノーサンキュー)。無闇にランディングページを量産するのではなくて、訪れたユーザが失望するだけのようなページにはむしろ「着地させない」ように配慮をすることこそが本当のLPOでしょう。

// ==UserScript==
// @name        hide uncreated Hatena Keyword on Google
// @namespace   http://inasphere.net/
// @description Google検索結果から未作成のキーワードページを除去する
// @include     http://www.google.co.jp/search*
// @author      inamenai
// @license     MIT License
// @version     0.3
// ==/UserScript==

// 配布場所
//     http://d.hatena.ne.jp/inamenai/20090324/p1
// 変更履歴
//     2009/11/27 0.3 ニコニコ大百科を除外
//     2009/03/25 0.2 複数サイト対応化、@PEDIA・ニコニコ大百科・FC2blogを追加
//     2009/03/24 0.1 リリース

(function() {

    var siteArray = [
        { url : /^http:\/\/d\.hatena\.ne\.jp\/keyword\/.+/i, text : /このキーワードはまだ作成されていません。/ },  // はてな
        { url : /^http:\/\/atpedia\.jp\/word\/.+/i, text: /はまだ編集されていません。/ },  // @PEDIA
        { url : /^http:\/\/blog\.fc2\.com\/tag\//i, text: /.*/ }  // FC2blog タグページ
    ];

    var result = document.evaluate('//a[@class="l"]', document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);

    for (var i = 0; i < result.snapshotLength; i++) {
        for (var j = 0; j < siteArray.length; j++) {

            if (!siteArray[j].url.test(result.snapshotItem(i).getAttribute("href"))) {
                continue;
            }

            (function(x, y) {
                GM_xmlhttpRequest({
                    method: "GET",
                    url: result.snapshotItem(x).getAttribute("href"),
                    onload: function(response) {
                        if (siteArray[y].text.test(response.responseText)) {
                            result.snapshotItem(x).parentNode.parentNode.setAttribute("style", "display: none;");
                        }
                    }
                });
            })(i, j);
        }
    }
})();

3/25追記:

複数サイトに対応できるようにして@PEDIAニコニコ大百科の同様のページも追加した。ついでに、FC2blogのタグページはキーワードについて何の説明も載せないくせに「○○とは」という悪質なタイトルをつけるので問答無用で除去する対象にした。

11/27追記:

サイト側で対応していただけたのでニコニコ大百科を除外。