2012年6月6日水曜日

AndroidでSilverlightのWrapPanel風のViewGroupが欲しい

AndroidでSilverlightのWrapPanelのように自動で折り返すViewGroupが欲しいです。
デフォルトじゃないみたいなので、いろいろ漁ってると以下の記事を発見。

・Androidでボタンを横に並べて自動で折り返す

ほほー。RelativeLayoutでござるか。

使 っ た こ と な い ん で す よ ね 。

上記の記事を使いまわしが効くようにコントロール化してみました。
かなり適当。
public class WrapLayout extends RelativeLayout {

    public WrapLayout(Context context) {
        super(context);
    }

    public WrapLayout(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    public WrapLayout(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
    }

    @Override
    public void addView(View child) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child);
    }

    @Override
    public void addView(View child, int width, int height) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, width, height);
    }

    @Override
    public void addView(View child, ViewGroup.LayoutParams params) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, params);
    }

    @Override
    public void addView(View child, int index) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, index);
    }

    @Override
    public void addView(View child, int index, ViewGroup.LayoutParams params) {
        // idが未設定の場合は乱数でどうにかする。
        if (child.getId() == -1) { child.setId(new Random(System.currentTimeMillis()).nextInt(Integer.MAX_VALUE)); }

        super.addView(child, index, params);
      }

    @Override
    public void onWindowFocusChanged(boolean hasWindowFocus) {

        super.onWindowFocusChanged(hasWindowFocus);

        // 子供の数を取得
        int l = this.getChildCount();
        // 無いなら何もしない
        if (l == 0) {
          return;
        }

        // ディスプレイの横幅を取得
        WindowManager wm = (WindowManager) this.getContext().getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();

        // 1行最大長
        int max = display.getWidth();

        // 一番最初は基点となるので何もしない
        View pline = this.getChildAt(0);
        // 現在の1行の長さ
        int currentTotal = pline.getWidth();
        for (int i = 1; i < l; i++) {
            int w = this.getChildAt(i).getWidth();
            RelativeLayout.LayoutParams layoutParams =
                    (RelativeLayout.LayoutParams) this.getChildAt(i).getLayoutParams();

            // 横幅を超えないなら前のボタンの右に出す
            if (max > currentTotal + w) {
                // 現在長に処理対象コントロール長を加算
                currentTotal += w;
                layoutParams.addRule(RelativeLayout.ALIGN_TOP, this.getChildAt(i - 1).getId());
                layoutParams.addRule(RelativeLayout.RIGHT_OF, this.getChildAt(i - 1).getId());
            } else {
                // 横最大長を超過した場合は折り返す
                layoutParams.addRule(RelativeLayout.BELOW, pline.getId());

                // 基点を変更
                pline = this.getChildAt(i);

                // 長さをリセット
                currentTotal = pline.getWidth();
            }
        }
    }
}


わかってます。onWindowFocusChangedにaddViewしたらダメじゃね?ってのはわかってます。
とりあえずです。
[[Activity]]
public class MainActivity extends Activity {
    /** Called when the activity is first created. */

    String[] strings = { "てst1", "てst2", "てst3", "てst4", "てst5", "てst6", "てst7", "てst8", "てst9", "てst10", "てst111111a", "てst111", "てst234"};
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        WrapLayout layout = (WrapLayout)this.findViewById(R.id.FixedGridLayout);
        for (String string : strings) {
            Button btn = new Button(this);
            btn.setText(string);
            //btn.setId(random.nextInt(Integer.MAX_VALUE));
            layout.addView(btn);
        }
    }
}
[[出力結果]]

良い感じ。

2012年6月5日火曜日

[Silverlight] UIスレッド上で処理を実行する。

System.Windows.Deployment.Current.Dispatcher.BeginInvoke(() =>{ .... });

Triggerでシーケンス値を自動採番


以下のようなテーブルが存在したとする。
テーブル名 : [MST_Magazine]
フィールド

項目名型備考
ID数値PK 連番でデータを格納
Publisher_ID数値
Name文字列



このようなテーブルではIDはシーケンスでの採番となる。
しかし、OracleではSQLServerのように、型として自動採番の型が存在しない。

そこで、トリガを用いて自動採番を行う。

CREATE OR REPLACE TRIGGER TRG_MST_Magazine_ID
BEFORE Insert
ON MST_Magazine
FOR EACH ROW
BEGIN
    IF :NEW.ID  IS NULL THEN
        SELECT SEQ_Magazine_ID.NEXTVAL INTO :NEW.ID FROM DUAL;
    END IF;
END;

上記のトリガは、MST_MagazineテーブルへのInsert時に起動し、
InsertされたMST_Magazine.ID項目がNULLの場合、SEQ_Magazine_ID.Nextvalの値を使用する。

これにより、IDを指定せずMST_MagazineテーブルへのInsertを行った場合は自動で数値が採番される。

HtmlPage.Window.Navigate で cookie を使用する。




Silverlightなんかで、画面を切り替えるときに HtmlPage.Window.Navigate で遷移させたりしますけども、
その時にCookieを使用したいと思いました。

System.Net.Cookieとかあるからこれを使うのかと思ったけども、どうやら違う。
こいつはHttpWebRequestの時に使うみたい。
それじゃあ、こまります。
ええ、困りますとも。
だって画面遷移をさせたいんだから。

さてどうするかと言うと、System.Windows.Browser.HtmlPageのDocumentプロパティのSetPropertyで設定してあげればいいんでがす。

[[サンプル]]
HtmlPage.Document.SetProperty( "cookie", "Key1=Value1" );
        HtmlPage.Document.SetProperty( "cookie", "Key2=Value2" );
        HtmlPage.Window.Navigate
        (
            new Uri( "http://....", UriKind.RelativeOrAbsolute),
            "_self"
        );



で、Cookie情報を取得するには HtmlPage.Document.Cookies プロパティに格納される。
これは文字列でドバーっと入ってるので、いいように加工して使うしか無いんでしょうか。
めんどくさい。

LINQで配列


// AからZまでのchar型の配列を生成 var az = new (List<char>)(System.Linq.Enumerable.Range('A', 'Z' - 'A' + 1).Select(i => (char)i).ToArray());

2010年6月10日木曜日

Windows7にOracle10g R2 を入れてみた


以前Windows7にOracle10gR1を入れようとして発狂したエントリ を書きましたが、
R2ならいけるよーとのコメントをいただいたので、今更やってみました。


とりあえずそのままインストールしようとして、
Versionが対応外なんですけ?的なエラー
じゃあ、Varsionをごまかせ☆と、setup.exeのプロパティから互換性タブの値をチョロッと編集。
ここはR1での作業と一緒。
さてさてどうなることか。



あれ?なんかインストールできましたけど?
あれ?DBにも接続できましたけど?

わおwwwwwwwwww

あの苦労は一体・・・
oracle10g用のSQLをSQLServer2005用にコンバージョンした苦労って・・・

とりあえず、select * from PRODUCT_COMPONENT_VERSIONして取得した結果

Oracle Database 10g Enterprise Edition
10.2.0.3.0
Prod

うん入ってるね。
これで幸せ。

2009年12月3日木曜日

Windows7 + oracle 10g R1 試行手順

!!! これは10g R1に関するエントリです。10g R2はこちら !!!


アクセス解析見てると、「oracle10g」を「Windows7」にぶち込みたい方が結構いるみたいですね。
俺が試したインストール手順をとりあえず書いときます。
まぁ失敗したんだけどねwwwwwww
書いてたら、詳しい人が解決策を教えてくれるかもという、淡い期待です。


「setup.exe」をそのまま起動すると、
「お前のWindowsのVerは対応してないんですけどwwww」
っていってきます。

じゃ、誤魔化しちゃいましょう。

「setup.exe」のプロパティを開きます。
「互換性」ってタブが存在するかと思います。
「互換モード」の「互換モードでこのプログラムを実行する」にチェックつけてやってください。

とりあえずこれでOk

あとは、「setup.exe」を起動するとちゃんとインストーラが動くはず。

こっから先のインストール手順に関しては他のサイトで、
山のように解説してくださってるんで割愛します。

で、問題が発生するのは、一番最後。
「Oracle Database Configuration Assistant」とやらのインストール時です。
これが「アクセス権ナスwwwwwww涙目wwwwww」(12546[アクセス権なし])ってエラーをはきます。

ここで積む。

続行すると、
「「Oracle Database Configuration Assistant」のインストールに失敗したけど、必須じゃないからよくね?」
的な文章がむにゅっとポップアップで出てきます。

あれ?そうなの?びっくりさせないでよねwwwww
とか思って、とりあえずSQL*Plus起動すっかなーと、
コマンドプロンプトで[sqlplus]って打ち込むと、
「アクセス権ナスwwwwwww涙目wwwwww」(12546[アクセス権なし])ってエラーをはきます。

だめじゃねーかwwwwwwwwwwwww俺涙目wwwwwwwwwwww
ってなるかと思います。

エラーコードは同一なことから見ても、おそらく原因は同じと思われます。
アクセス権がどのアクセス権なのかもサッパリです。
詳しい人ボスケテ