- ベストアンサー
JDK1.4でのフォーカス遷移
- JDK1.4でのフォーカス遷移について質問があります。
- JComboboxでsetEditableがtrueの部品だけ、tabを2回押さないとフォーカスが移ってくれません。
- 解決法をご存知の方はいますか?
- みんなの回答 (4)
- 専門家の回答
質問者が選んだベストアンサー
問題が絞り込めたようで、よかったですね。(^^) JComboBoxというのはなかなか厄介で、Editableかどうかで挙動が変わってしまうようです。 JComboBoxのEditableをtrueにすると、JComboBoxにComboBoxEditorというものがくっついてきます。これが(編集可能な)テキスト部分です。 この状態のComboBoxの時はComboBoxではなく、ComboBoxEditorにフォーカスがいくようです。 前の例で、▽部分にしかフォーカスが当たらないのは、ComboBoxEditorではなく、ComboBoxにフォーカスを当てていたのだからだと思います。 それと前の例では、ContainerOrderFocusTraversalPolicyを継承していましたが、 swingならLayoutFocusTraversalPolicyの方が正常な動作をしました。 (ごめんなさい) 長々と言い訳してしまいましたが、要するに 前に示したサンプルをこんな感じで修正してみました。 ・LayoutFocusTraversalPolicyを継承する。 ・フォーカスがいくべきコンポーネントがJComboBoxで、かつEditableの場合は、ComboBoxEditorを対象にする。 ・ComboBoxEditorから遷移する際には、それの親であるComboBoxからの遷移とみなす。 あと、JComboBoxのFocusまわりはなにかと不具合が多いみたいです。 そのへんは、Bugパレードを見ると、かなり参考になりますよ。 同じ現象で悩んでいる人がいたりすると、助かります。 英語ですけど、なんとなくわかると思います。
その他の回答 (3)
- sasadora
- ベストアンサー率68% (59/86)
>フォーカス完璧に遷移するようになりました。 完璧ですか。よかったですね(^^) >この一個前の質問の回答で、"LayoutFocusTraversalPolicyを継承してHashtableを用いる。" >と言う考えはどこから来たのですか? >sunのAPIを読めば普通分かるものなのでしょうか? LayoutFocusTraversalPolicyに至ったのは、いちばんはじめに紹介したサイトに書いてあったからです。 (http://www-6.ibm.com/jp/developerworks/java/020308/j_j-awtfocus.html) 新しいトラバース・ポリシー・クラス Hashtableを使った部分は、私がてきとーに作っただけなんです。。。 あるコンポーネントから次を検索するのに、あらかじめHashtableに格納してあればいいかな?と。 これは、もともとHashtableを使った経験があるから思いつくのだと思います。 逆に、もっといい方法があるが、私がその存在を知らなくて思いつかないものもあると思います。 今回、私が作ったサンプルがベストとはとても思えないので、気をつけてください。(^^; うまくできたのであれば、tomokkoさんには興味のない話かもしれませんが、 SortingFocusTraversalPolicyと、Comparatorを使えば、もっときれいに書けるかもしれません。 んではまた今度。
お礼
助かります、とても(TT) どしどし質問するので答えてください(笑) しかし私はもう少し自分でがんばるってことをしなくちゃいかんなー。 あの最初のサイトに書いてあったとは・・・。 読み飛ばしてソースに集中してたのがまずかったのでしょう。 shift+tabができたらお知らせしますので、あそこにのっけてくださいね~♪ 本当にありがとうございました!!
- sasadora
- ベストアンサー率68% (59/86)
そうですか。シンプルな例でもそうなるんですかぁ…。 私の環境では問題ないです。No.1で私が書いたサンプルでも、 同様の症状になるんでしょうか? だとしたら、まずは再現させたいですね。 お使いのJavaの環境はJDK1.4とのことですが、細かいバージョンはいくつでしょう? 私は >java -version を実行すると、 java version "1.4.0_01" Java(TM) 2 Runtime Environment, Standard Edition (build 1.4.0_01-b03) Java HotSpot(TM) Client VM (build 1.4.0_01-b03, mixed mode) と出てきます。 ところで、 >右端の▽のところにフォーカスが移って、2回目でコンボボックスのテキスト部… これは、ちょっと気になります。前に私が示したFocusTraversalPolicyを使うと、Editable=TrueのJComboBoxにフォーカスを当てると、▽部分にしか当たりませんでした。でも、もう一度TABすると、テキスト部ではなく次のコンポーネントに移りました。 できれば再現するサンプルを提示してもらいたいです。 >嫌になったらいつでも捨て置いちゃってください じゃあ、手詰まりになったら見捨てます。(^^; 冗談です。 私は暇ができたときに回答していますし、自分的にもわからないで放っておくのは、 気になってしょうがないので好きでやってます。 #40画面とかなんで仕事なんでしょうね。 #私もそうなんで、胸中お察しします…。(TT) #なんかこう、胃が痛くなってきません?(他人事発言)
お礼
こんにちは、すばやいお返事ありがとうございます! では早速・・・ private class FocusTestTraversalPolisy extends ContainerOrderFocusTraversalPolicy { private Hashtable focusMap; private FocusTestTraversalPolisy(){ focusMap = new Hashtable(); } public void setNextFocusableComponent(Component src, Component dest){ focusMap.put(src, dest); } /* public Component getComponentAfter(Container focusCycleRoot, Component aComponent){ //Hashtableから次のコンポーネントを取得 Component next = (Component)focusMap.get(aComponent); if(next == null){ //nullだったらデフォルトの動作 return super.getComponentAfter(focusCycleRoot, aComponent); } if(!accept(next)){ //遷移不可の場合は、さらにその次。(再帰) return getComponentAfter(focusCycleRoot, next); } return next; }*/ } カスタマイズしたFocusTraversalPolisyの一部を、コメントにしてました。 実際に使う画面ではこの部分があるとフォーカスがさーっぱり動かなかったからです。 ここがないと2回でフォーカス遷移する。 ためしにコメントを取ってみたところ、シンプルな例では動きました! と言うことは、やっぱりカスタマイズした部品に問題があるんですねー。 でも、もう一つ問題が・・・。 ▽部ではなくテキスト部にフォーカスが行くように。と主任に言われてしまいました。 (そう、仕事なんです、お察しの通り・・・) 道は遠く険しいようです。 しかし時間はまだまだあるのでめげずにがんばります! ちなみにバージョンは 1.4.0-b92 のようです。
補足
ごめんなさい! 下のお礼で、コメントにしないとさっぱり遷移しなかった。とありますが、遷移してました。 ▽部に行ってました!シンプルな例と一緒で。 ただ、カスタマイズしたせいで▽部にフォーカスが移っても色とか何も変わらず気づかなかっただけみたいです、すみません。(←言い訳) てことで問題は一つになりました。 "コンボボックスのフォーカスがテキスト部に行かない" うーむ、うーむ。
- sasadora
- ベストアンサー率68% (59/86)
こんにちはsasadoraです。(昨日から引き続きで。) 前の話ですと、JComboBoxや、JTextFieldはカスタマイズしたものだとおっしゃっていましたが、その辺は疑ったのでしょうか? ためしに、やってみましたが1度のTABで遷移しました。 まずは原因がどこにあるかを特定しましょう。 JFrameにJComboBoxを配置し、setEditableを変更しただけのシンプルな例でも、 やはりそういった動作をするのでしょうか? これが問題なければ、少しずつ現在のプログラムに近づけて、正常→異常になったタイミングで何をしたかを特定しちゃいましょう。 <試しプログラム> import javax.swing.*; public class FocusTest2 extends JFrame{ public static void main(String args[]){ new FocusTest2().show(); } public FocusTest2(){ setSize(400, 200); JComboBox cmb1 = new JComboBox(); JComboBox cmb2 = new JComboBox(); JComboBox cmb3 = new JComboBox(); getContentPane().setLayout(new java.awt.FlowLayout()); getContentPane().add(cmb1); getContentPane().add(cmb2); getContentPane().add(cmb3); cmb2.setEditable(true); cmb1.addItem("combo1"); cmb2.addItem("combo2"); cmb3.addItem("combo3"); addWindowListener(new java.awt.event.WindowAdapter(){ public void windowClosing(java.awt.event.WindowEvent e){ System.exit(0); } }); } } それではまた。
お礼
sasadoraさん、ホントに何度も何度もすみません(TT) 嫌になったらいつでも捨て置いちゃってください。 回答を読んで、なるほど!と思い、早速JFrameの上にJTextFieldとJComboBoxを何個か置いて、JComboBoxをsetEditable(true)とsetEditable(false)でごちゃまぜにしたところ、やはりtureの時はtab2回押さないとだめなんですー。 一回目でコンボボックスの右端の▽のところにフォーカスが移って、2回目でコンボボックスのテキスト部(?)に来ます。 なぜだーっ!? 力尽きそうです。 Googleで検索の鬼になって、資料がないか午後から探す予定です。 これは締め切らないのでsasadoraさん(は無視するのもありです、辛いけど)、その他でなにか情報をお持ちの方、助けてください! よろしくお願いします。。。
お礼
お返事が遅れましたが、sasadoraさん、ありがとうございました! 苦節1週間、長かった・・・。 shift+tabはまだこれからですけど、がんばります! 最後に一つ質問。 この一個前の質問の回答で、"LayoutFocusTraversalPolicyを継承してHashtableを用いる。" と言う考えはどこから来たのですか? sunのAPIを読めば普通分かるものなのでしょうか? 参考文献等ありましたら教えてください。 しつこくてすみません。。。