• ベストアンサー

文字をドラッグし配列にいれたい

テキストボックスに文字を打ち込み、表示させ、その後文字をドラッグし、ドラッグされた文字を配列に格納するプログラムを考えています。 ですが普通に表示させるだけですとドラックできません。 ウェブで調べているのですが画像のドラッグして移動するプログラムばかりで参考にしづらかったです。 参考になるページがあれば教えていただけると助かります。お願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • zozy
  • ベストアンサー率60% (20/33)
回答No.5

> str[strIndex]には文字列が入っていますから文字列の後に種類を追加するという形になるのでしょうか? 具体例を書いてなかったのよくなかったです。 まだ未熟故、最善のアドバイスができないことをお許しください。。。 わかりづらくなってて申し訳ない。。。 質問者さんの解釈で正しいです。 例.small,carと入力し、それぞれ,形容詞,品詞であるという意味づけをしたい 例えば、処理の前の前提として フォントサイズは20,一文字の幅は10とする 1)smallを描画する位置をマウスクリックで指定 x=100,y=100の位置でクリック 2)"small"と入力 画面上のx=100,y=100の地点からsmallと描画される このときstr[0]に"small"が入る 3)形容詞ボタンを押す このときstr[0]="small"に",形"が追加され str[0]="small,形"となる。 smallを描画し、配列にも格納できたので要素番号を1個後([1])にする これによって、smallが形容詞であることがひとつの文字列で関連付けられる。 4)同じ手順を繰り返して"car"も入力すると str[0]="small,形",strX[0]=100,strY[0]=100 smallの高さは20,幅は50 str[1]="car,品",strX[1]=150,strY[1]=170 carの高さは20,幅は30 となった。 5)最後にsmallとcarを線で結びましょう GUI上の動作ではsmall~carへマウスドラッグで線をひく まず当たり判定という分かりづらい表現でなくどういった処理を行っているかソースを記述します。(普段ゲーム作ってるのでつい;) たとえば、smallの上にマウスがあるかを判定するために public void mousePressed(MouseEvent e){ //マウスポインタが100,100~120,150の中にあるか判定 if(e.getX()>strX[0]&&e.getX()<strX[0]+str[0].length()*10 &&e.getY()>strY[0]&&e.getY()<strY[0]+20){ //concatは文字列の追加 //StringBufferのappendはソースが長くなる //追加のたびインスタンス生成するため処理が重くなる //つまり、appendよりconcatのほうが優秀 str[0]=str[0].concat("→"); link[0]=str[0]; } } ここでなぜ,マウスプレスイベントなのかというとイベント処理が"一度だけ"呼ばれるからです。 出発点は点です。当然呼ばれる処理は1回でなければなりません。 終着点に関しても同じことが言えます。 ですが、内部処理と描画処理をわけるという基本的なことを忘れてました。。。 そこで考え直しました。 ・内部処理(配列への格納)はマウスプレス&リリース ・描画処理はマウスプレス(出発点)&マウスドラッグ(現在のマウスの座標) これによって線が描かれていくように描画できる。

hiro0825
質問者

お礼

返事が遅れてすみません。 もっと表現しやすくするにはと考えたところ少し変わったところもでてきました。 またその際は質問しますのでよろしくお願いします。

その他の回答 (4)

  • zozy
  • ベストアンサー率60% (20/33)
回答No.4

やっと理解ができました。 どうやら、自分自身いろいろ勘違いをしていたようです。 では、設計について考えましょう そこで俺の案としては マウスクリックで文字列を書き始める位置を指定する //strXはdrawString()でのx座標 int[] strX=new int[Short.MAX_VALUE]; int[] strY=new int[Short.MAX_VALUE]; public void マウスクリックイベント{ strX[strIndex]=クリック時のx座標; strY[strIndex]=クリック時のy座標; } 次に文字列を入力し、主語ボタン・述語ボタン・形容詞ボタン・品詞ボタンなどのいずれかを押す。 //現在配列strで参照している要素番号 strIndex=0; //入力した文字列と文字列の種類を格納する String[] str=new String[]; public void キータイプイベント{ if(キー==エンター){ str[strIndex]="入力した文字列"; }else if(キー==文字キー){ 文字の入力; } } public void ボタンのアクションパーフォームイベント{ str[strIndex]に",文字列の種類"を追加 strIndex++; } こうすることで入力された文字列が主語,述語,形容詞,品詞のどれにあたるか判断できます。 同時に配列への格納も出来ます。 次に線を繋ぐ際ですが、線の出発点にある文字列が終着点の文字列にかかっているということにすれば形→品などの関係が表現できます。 同時に配列にも修飾関係を格納できる。 small-----------→car ....↑出発点.....↑終着点 //現在linkで参照している要素番号 int linkIndex=0; //文字列のつながりをあらわす配列 String[] link=new String[Short.MAX_VALUE]; //出発点の座標 int[] startX=new int[Short.MAX_VALUE]; int[] startY=new int[Short.MAX_VALUE]; //終着点の座標 int[] endX=new int[Short.MAX_VALUE]; int[] endY=new int[Short.MAX_VALUE]; //線の描画 for(iは0~linkIndexまで){ drawLine(startX[i],startY[i],endX[i],endY[i]); } public void マウスプレスイベント{ startX[linkIndex]=プレス時のx座標; startY[linkIndex]=プレス時のy座標; for(iを0~strIndexまで){ if(startX[linkIndex],startY[linkIndex]がstrX[i]+文字列の幅,strY[i]+文字列の高さのなかに入っているか(俗に言うアタリ判定)){ link[linkIndex]にstr[i]に"→"を追加した文字列を格納 } } } public void マウスリリースイベント{ endX[linkIndex]=リリース時のx座標; endY[linkIndex]=リリース時のy座標; for(iを0~strIndexまで){ if(マウスプレスイベントの時のように当たり判定を判定){ link[linkIndex]にstr[i]を追加 linkIndex++; } } } 線の種類に関しては出発点と終着点で線の種類を特定します if(出.equals("形")&&終.equals("品"))線の色は青; if(出.equals("主")&&終.equals("述"))線の色は赤; これで必要な区別は全てできるかと思いますがどうでしょう?

hiro0825
質問者

お礼

何度も本当にありがとうございます。 私自身あまり詳しくないので調べながらzozyさんが書いてくださったことを理解しようとしていますがなかなか難しいようです。 //public void ボタンのアクションパーフォームイベント{ //str[strIndex]に",文字列の種類"を追加 //strIndex++;} の部分ですがstr[strIndex]には文字列が入っていますから文字列の後に種類を追加するという形になるのでしょうか? //if(startX[linkIndex],startY[linkIndex]がstrX[i]+文字列の幅,strY[i]+文字列の高さのなかに入っているか(俗に言うアタリ判定)) アタリ判定というのは見た目上文字列の上に線が引かれているようにみせるためですよね? //{link[linkIndex]にstr[i]に"→"を追加した文字列を格納} これはどういうことでしょうか? 線の描写は線を引くごとでなく引き終わった後になるのでしょうか?

  • zozy
  • ベストアンサー率60% (20/33)
回答No.3

文字列同士を線で結ぶことの必要性がわかりません。 もし、文字列が1万個あったらどうするのですか? 配列に格納するというのなら文字列を箱のようなものにドラッグ&ドロップではいけないのですか? そして分類のしかたについてですが、単純に配列名+要素番号で分類できないでしょうか? 一言で言ってGUIを実装したデータベースということでよろしいのでしょうか?

hiro0825
質問者

お礼

解答ありがとうございます。 線で結ぶ必要性はプログラムの動作だけ見れば必要ないです。 使用される想定シーンはユーザーが構文解析するような感じと言えば伝わりませんか?英語で言えば主語述語の関係、ある形容詞がどの品詞にかかっているかを示す為に線で結ぶようなものです。ユーザーは文章を書いてどの形容詞が品詞にかかっているかを書くときは「形→品」のようなボタンを押して文字列を選択すれば結ばれた単語を配列に格納します。 This is a small car.という文章の場合は 形容詞(small)→品詞(car) の形で書き出せるようなことができる。というものをまずしようと思っています。書き出す形はこれだけでないのでいくつかの種類の線(見た目の上では)で区別したいと考えました。 無数に文字列があった場合も考えられますが、想定シーンでは指定できる可能な数と考えています。ドラッグすれば格納される形でも構いません。ですがその文字列同士に見た目上の線が結びたいのです。 GUIを実装したデータベースというのがどういうものか今の私の知識でははっきりイメージできませんが、文字を書いて線を引く等が一番の目的でなく、書かれた文字列から別のテキストファイルに書き出すのが目的です。 これでいかがでしょうか。とりあえずしようと思っていることがかけたと思います。

  • zozy
  • ベストアンサー率60% (20/33)
回答No.2

支障のない程度にソースを載せてもらえると回答しやすいです。 どういった基準で言葉の意味を判定しているのかがサッパリなので。。。 そもそも、ここでいう"意味","線"はどういったものなのでしょうか? 概念等説明していただけるとなお回答しやすくなりますので。

hiro0825
質問者

補足

度々すみません。 言葉の意味付けですが基準はないです。 http://kissho.xii.jp/1/src/1jyou60583.gif.html (DLキーはtest) に簡単なイメージ図を書きました。 [A]で文字を入力します。 その後、[LINE1]もしくは[LINE2]を押し複数の文字列をドラッグします。そうすると線で結ばれます。ドラッグの後ボタンを押すのでも構いません。 文字をドラッグでなくてもとにかく指定できれば構いません。複数の文字列を選択しそれを線で結びます。 最終的に配列に入れた言葉から、新たにファイルを出力する予定です。その為に指定された言葉を意味を持たして抜き出す必要があります。 ですので線が同じ線で結ばれては全て同じ文字とされてしまいますので、ファイル出力する際に理想のファイルに変換できなくなります。 つまり線自体に意味を持たすというより文字列を分類するのが目的です。しかし見た目の問題でどの意味か区別ができれば問題ないです。 まだ難しいですが何度も補足しますのでよろしくお願いします。

  • zozy
  • ベストアンサー率60% (20/33)
回答No.1

AWT,swingにテキストボックスというコンポーネント(ボタンなどの部品)は存在しません。 最低限調べてから質問しましょう↓ http://java.sun.com/javase/ja/6/docs/ja/api/index.html そもそも、なんの言語を使うのかすら不明です。 そして、文字を配列に格納してからどうしたいのでしょうか? コンボボックスに選択された文字を挿入し、表示選択できるものをswingで作ったので参考にしてください。 //importを一個ずつ宣言してるのはメモリ節約のため import java.awt.BorderLayout; import java.awt.Font; import javax.swing.DefaultComboBoxModel; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.WindowConstants; import javax.swing.event.CaretEvent; import javax.swing.event.CaretListener; public class DraggedString extends JFrame{ JTextArea textArea=new JTextArea(); JScrollPane scroll=new JScrollPane(); JComboBox comboBox=new JComboBox(); //ドラッグ&ドロップで取り出した文字を格納する String[] log=new String[Short.MAX_VALUE]; //logの現在の要素番号 int index=0; public DraggedString(){ //これがないと×ボタンを押してもアプリケーション自体は終了しない setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //テキストエリアの表示サイズを確保(10文字*10行分) textArea.setColumns(10); textArea.setRows(10); //textAreaで使用するフォントの指定 textArea.setFont(new Font("MS UI Gothic",1,24)); //このようにすると抽象メソッドを全てよばなくてもよく //コンポーネントごとにイベント処理を独立させることができる textArea.addCaretListener(new CaretListener(){ //テキストに変化があったらイベント発生 public void caretUpdate(CaretEvent evt){ textAreaCaretUpdate(evt); } }); //コンポーネントを指定してビューポートを作成 //textAreaはscrollの下位コンポーネントになる scroll.setViewportView(textArea); //ボーダーレイアウトでコンポーネントを配置 getContentPane().add(comboBox,BorderLayout.PAGE_START); getContentPane().add(scroll,BorderLayout.CENTER); //コンポーネントの位置をみて推奨サイズに設定してくれます pack(); } private void textAreaCaretUpdate(CaretEvent evt){ //ドラッグ&ドロップで指定した文字列が空でなかったら if(textArea.getSelectedText()!=null){ //logに指定した文字列を格納 log[index]=textArea.getSelectedText(); //次の要素を参照する index++; //コンボボックスのアイテムをlogに設定する comboBox.setModel(new DefaultComboBoxModel(log)); } } public static void main(String args[]){ new DraggedString().setVisible(true); } }

hiro0825
質問者

お礼

解答ありがとうございます。 焦って質問してしまいました。 javaで作ります。 最終的に作ろうとしているものは文章を入力し、表示し、入力指定した文章から指定した文字列同士を意味を持たせて線で結びます(AとBは同じ意味等、判別できればよい)。さらに指定した文字列を線で引かれた意味別に配列に格納します。 その後格納された配列から別の文字列操作する予定です。そこまでをどうするか悩んでいます。 文字の入力や意味を持たせて線をもたせる等の操作は作れるのですが、同一画面でとなるとどうすればよいか全く思いつきません。

関連するQ&A