goo blog サービス終了のお知らせ 

職業JAVAらーの憂鬱

職業JAVAらーの、世のため人のため以前に、自分のための覚え書き。

標準の動き

2009-05-06 23:02:55 | Weblog
たとえばIEの標準の動作として、テキストボックスでリターンキーを押下しても何の反応もない。
(デフォルトボタンが設定されている場合等は別として)

で、ユーザ側の要望でリターンキーを押下すると、次の入力フィールドにフォーカスを移動してほしいという要望があったとする。

ここ最近思うのは、HTML+JavaScriptにしてもWPFやSilverlightにしても、対象のソフトが提供しているコントロールの標準動作を変えるような動きにするのはよろしくないのではないか?と言うこと。

とりあえずIEに限定するとして、そもそもリターンキークリック時にフォーカス移動を行わないというIEの動きそのものに意味があるんじゃなかろーか?
事実、SilverlightやWPFでフォーカス移動時に何らかの処理をする場合、イベントの処理順序等、製造自体色々と面倒なことが多い。
特にフォーカス移動で入力チェックもやるしフォーカス移動もやるし・・・とやることが色々あればなおさら。

そもそもIE標準の動きを変えることを想定していないのではないのか?
意味があるからIE標準の動作にフォーカス移動などというのが組み込まれていないのでは?

最近特に「○○標準の動き」を拡張することに抵抗がある。

WPF ListViewの内容をコンテナのインデックスで取得する場合

2009-04-10 13:42:27 | Weblog

listView1というListViewが画面にあったとして。
画面表示後に何らかのイベントを発生させて

for (int i = 0; i <listView1.Items.Count; i++)<br>
{
    ListViewItem listViewItem = (ListViewItem)listView1.ItemContainerGenerator.ContainerFromIndex(i);
}


こんなコードを書いてみる。


listView1に表示しているデータ件数く、縦スクロールバーが表示されてる場合に
listViewItemがnullになることがある。
画面の縦のサイズを広げて、縦スクロールバーがでないようにすると、同じデータ量でもnullが返ることはなかった。


画面に表示されていない部分を
ItemContainerGenerator.ContainerFormIndex
で取得しようとすると、
その部分にはContainerがまだ生成されていないからなのかなんなのか、
Indexは間違ってないのにnullで返されるらしい。


参考:
ttp://pro.art55.jp/?eid=1092685
ttp://pro.art55.jp/?eid=1093019


SQLerの憂鬱?

2007-10-30 11:05:39 | Weblog
SQLの基礎。

テーブルA
GROUPCD,GROUP
------------
01,motenaiTeam

テーブルB
GROUPCD,ID,NAME
------------
01,AA,javaler
02,BB,sqler

上記テーブルがあって、テーブルAのレコード1件を取得したい場合。

1)
select A.*
from A

ではテーブルAのレコードが正しく抽出される。
しかし、

2)
select A
from A, B

こういう、テーブルBが全く意味をなさないSQLを流したときの話。
予想では1)と同様にAのレコードが1件だけ正しく取得できると思ってたんだけど・・・。
結果として、同一レコードが複数抽出された。

GROUPCD,GROUP
---------------
01,motenaiTeam
01,motenaiTeam

その秘密はテーブルBの使い方にあった。

2)のSQLは、テーブルBは何も使用されていないように見えるが、
実は「inner join」でテーブルAに結合されているらしい!

inner joinをしているが結合条件がないために、
テーブルAのレコード1件に対して、テーブルBの全レコードが結合される。

試しに
select A.*, B.*
from A, B
を流してみると

01,motenaiTeam,01,AA,javaler
01,motenaiTeam,02,BB,sql

こんな感じで、テーブルAの1件にBのレコードが全てくっついて、別レコードとして抽出されてしまうのが確認できる。

2)で同一レコードが複数出てくるように見えたのは、
テーブルAの内容しか表示していなかったからなのだ。

逆にテーブルBのレコードを0件にすると、
1)では1件が正しく取得できたのに対して、
2)では正しく取得できない(該当0件となってしまう)

これは「inner join」の特性を考えると自然なことだった。
inner joinは結合しようとするテーブル(この場合はテーブルB)に、
結合条件に該当するレコードが存在しない場合は、テーブルAのレコードは抽出しないという特性がある。

よって、テーブルBが0件の場合は、当然テーブルAに結合できるデータがないので、該当件数0となってしまう。

☆結論☆
下手なSQLは休日出勤の元。
よ~く考えよ~。
ご利用は計画的に。。。

VS古いコード

2007-09-25 00:15:51 | Weblog
ユーザ主導のパッケージ開発に途中からアサインすることがある。
もう何度もバージョンアップリリースして、そこそこのボリュームがあるパッケージ。

途中から製造メンバーとしてアサインされたときに難しいこと。

バージョンアップ時に自分が修正を行うとき。
長い間使われ続けている既存のコードをどこまで修正していいのか?
このメソッドのI/Fを変更していいのか?
色々考えると、どうしても既存のI/Fは極力そのままに、当たり障りの無い修正をしてしまう。
特に、曰く「共通部分」ならなおさら。
当たり障りの無いっていうことは、この場合要はツジツマあわせ。ツジツマあわせをするってことは、
I/Fはあまり変わらないけどフラグが大量発生ってことになりかねない。
というか、ほぼなる。

今後も長くそのコードと付き合っていく正社員なら・・・とも思う。
けど、それは言い訳だろうなぁ。

I/F部分を変えたら影響が大きいからとは言っても、
結局中身が読みにくければ後々修正が大変になる。
特に仕様書がないような環境だと。

実際にコードの変更を行う前に、
修正対象となる箇所を実際に何度も動かして、
コードを何度も読んで、
修正方法を色んなパターン考えて、
その時点でよりベターがI/Fを変えることなのであれば、潔く行動に移すべし。
既存のわからない箇所は聞けばいい。

既存の作りを変えることに怖がるな。
あれこれ理由を作って逃げるな。
作り変えた分、しっかりテストをすればいいんだ。

逃げたところで作り直す恐怖はいずれ出てくる。
その時のコードはもっと難解になっていて、もっと怖くなってる。

betwixtのOutOfMemory

2007-06-05 18:26:47 | Weblog
jakarta commons betwixt0.7を使ってみた・・・けど・・・

public class Parent {
private List children;
}

public class Child {
// 20項目くらい
}

こんな作りでChildのインスタンスを1万強、childrenに格納して
StringWriter outputWriter = new StringWriter();
outputWriter.write("XMLの先頭行 エンコードとかのやつを記述");
BeanWriter beanWriter = new BeanWriter(outputWriter);
beanWriter.write(parent)
でメモリリーク発生。

googleで調べて見た結果、
複雑なXMLを短時間に何度も生成した場合、
使われなくなったヒープが開放されていないケースがあったらしい。
今回の事象とはケースが異なってはいるけど、試してみたら多少改善!
DefaultIdStoringStrategyで
private Map idByBeanMap;
private Map beanByIdMap;
これらにはHashMapが入るんだけど、そこをWeakHashMapを使うんだそうな。
WeakHashMapは弱参照
(HashMapと違い、使用されなくなったらすぐGC対象となる・・・だったはず)
なので、メモリリークが緩和される。

betwixt自体を使った感想としては、
細かい設定ができないから不要なタグが勝手に出力されちゃったりして、
ほんとに簡単なXMLの読み書きなら良いけど、複雑になると結構使いづらい気がする。
ファイル数も増えるし、管理も大変orz

でも、簡単なものならDOMなんかでゴリゴリ書くよりはすごい楽だし、
まだ0.7っていうこともあわせて、より柔軟性が高くなるのを今後に期待かな。

byte配列同士の結合

2007-06-02 13:41:45 | Weblog
byte配列同士の結合。
オブジェクトの配列同士の結合方法は数あれど、
プリミティブ型の配列同士の結合方法はなかなかヒットしないんざます。

今回はbyte配列同士の結合の必要にせまられたので、いろいろ調べてみた。
結果・・・
よーわからん。

byte[] a = {1, 2, 3};
byte[] b = {4, 5, 6};
これを結合して
byte[] c = {1, 2, 3, 4, 5, 6}という配列を作りたい。

たどり着いた先はByteBufferというクラス。
ByteBuffer byteBuf = ByteBuffer.allocate(6);
byteBuf.put(a);
byteBuf.put(b);
byte[] c = byteBuf.array();

これでaとbが結合されたcのbyte配列が完成・・・するらしい。動作未確認。
(2007/06/01 動作確認)

byte配列はこれでどうにかなるけど、他のプリミティブ型配列はやっぱり未解決。

余談。
jakarta commons primitivesがそれっぽいものを提供していそうな雰囲気だったけど、
javadocを見てみたら・・・
ListIteratorListIteratorクラス?なんだそりゃ。
javadoc読む前に一気に使う気が失せちゃった