@NASKAA

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

ワープロのような動きを再現

解決したいこと

ArrayListの中でStringBuilderを用いてワープロのような動きをシミュレーションしたい
そこで次の命令をキーボードの入力で受け付ける

そこで次の命令を受け付けることとする
left・・・カーソルを左に動かす
right・・・カーソルを右に動かす
insert 文字列・・・カーソルの左側に文字列を挿入する
backspace・・・カーソルの左側の文字を削除する
quit・・・プログラムを終了する
up・・・カーソルを上に動かす
down・・・カーソルを下に動かす
insertline・・・カーソルの上側に空文字列の行が挿入される
addline・・・カーソルの下側に空文字列が挿入される
deleteline・・・カーソルがある行を消す

該当するソースコード

package prog2;
import java.util.ArrayList;
import java.util.Scanner;
public class MultiLineEditor {
    ArrayList<StringBuilder> line ;
    int cursorRow;
    int cursorPos;
    public MultiLineEditor() {
        line = new ArrayList<StringBuilder>();
        line.add(new StringBuilder());
        cursorRow = 0;
        cursorPos = 0;
    }
    void run() {
        Scanner sc = new Scanner(System.in);
        while(true) {
            String inline = sc.nextLine();
            String [] input = inline.split("[ ]+");
            int i=0;
            if(input[i].equals("left")) {
                left();
                print();
            }else if(input[i].equals("right")) {
                right();
                print();
            }else if(input[i].equals("insert")) {
                insert(input[i+1]);
                print();
            }else if(input[i].equals("backspace")) {
                backspace();
                print();
            }else if(input[i].equals("quit")) {
                break;
            }
        }
    }
    void left() {
        if(0<cursorPos) {
            cursorPos=cursorPos-1;
        }else {
            System.out.println("カーソルは既に左端にあります");
        }
    }
    void right() {
        if(cursorPos<line.size()) {
            cursorPos=cursorPos+1;
        }else {
            System.out.println("カーソルは既に右端にあります");
        }
    }
    void backspace() {
        if(0<cursorPos) {
            line.remove(cursorPos-1);
            cursorPos=cursorPos-1;
        }else{
            System.out.println("左側に文字はありません");
        }
    }
    void insert(String str) {
        line.add(cursorPos,str);//ここはエラーが出てます
        cursorPos=cursorPos+str.length();
    }
    void print() {
    System.out.println(cursorRow+" "+cursorPos + " " + line);
    }
    void up() {
        if(cursorRow>0) {
            cursorRow=cursorRow-1;
        }else {
            System.out.println("カーソルは一番上にあります");
        }
    }
    void down() {
        if(cursorRow>line.size()) {
            cursorRow=cursorRow+1;
        }else {
            System.out.println("カーソルは一番下にあります");
        }
    }
    void insertline() {

    }
    void addline() {

    }
    void deleteline() {

    }
    public static void main(String[] args) {
    new MultiLineEditor().run();
    }
}

ここまでは組むことができたのですが、ここから先の進め方がわからなくなってしまいました。教えていただけると幸いです。

0 likes

1Answer

少し触ってみました(触ったところにコメント入れてます)

何か書籍を見られながらプログラムされているのでしょうか。もしくは何かの授業のプログラムとかでしょうか。なのでしたら、Listの動きやStringBuilderをなぜ使っているか等を学びなおしてみることをおすすめします。(•̀ᴗ•́)و ̑̑ ガンバッテ

import java.util.ArrayList;
import java.util.Scanner;

public class MultiLineEditor {
	//データの格納先
	ArrayList<StringBuilder> line;

	//[コメント] 変数命名に関して
	// わかりやすい命名にしたほうが良いです
	// row -> 行
	// column -> 列
	// position -> 位置
	// rowって調べたら行も列も出てきた。英語ムズカシイ...

	//列の位置
	// int cursorRow;
	//行の位置(ポジション?)
	// int cursorPos;

	//[コメント]
	// javadocのコメントの書き方[/** コメント~~~ */]で書くと
	// eclipseとかで変数追いかけるとき見やすい(カーソルあてるとコメントが出る)
	/**	カーソル位置(行/上下 用) */
	int cursorPosRow;
	/**	カーソル位置(列/左右 用) */
	int cursorPosCol;

	//コンストラクタ
	public MultiLineEditor() {
		line = new ArrayList<StringBuilder>();
		// 0行目のStringBuilder
		line.add(new StringBuilder());
		// カーソル位置を初期化
		cursorPosRow = 0;
		cursorPosCol = 0;
	}

	void run() {
		Scanner sc = new Scanner(System.in);
		while (true) {
			String inline = sc.nextLine();
			//[コメント]
			// この条件んで分割すると空白が混入すると空白の位置で文字が途切れる
			// (元ソース)String[] input = inline.split("[ ]+");
			//
			// splitメソッドの第2引数に上限値を当てあると分割数が制限されるため、
			// こっちの実相のほうが良いかもしれない
			//
			// 例:入力)insert aaa bbbb cccc
			//  -> [0]insert
			//  -> [1]aaa bbbb cccc
			String[] input = inline.split("[ ]+",2);

			//[コメント]
			// 入力の1要素目がコマンドとなるためiは0固定となるので
			// 固定値として定義するか、input[0].equals(...
			// みたいな書き方のほうが良いかもしれないです。
			int i = 0;

			//[コメント]
			// 動作を確認したくてdown、up、insertlineを
			// 追加しちゃいましたゴメンナサイ...
			if (input[i].equals("left")) {
				left();
				print();
			} else if (input[i].equals("right")) {
				right();
				print();
			} else if (input[i].equals("insert")) {
				insert(input[i + 1]);
				print();
			} else if (input[i].equals("backspace")) {
				backspace();
				print();
			} else if (input[i].equals("down")) {//追記しました
				down();
				print();
			} else if (input[i].equals("up")) {//追記しました
				up();
				print();
			} else if (input[i].equals("insertline")) {//追記しました
				insertline();
				print();
			} else if (input[i].equals("quit")) {
				break;
			}
		}
		//while後、後続処理がないので
		//Scannerを閉じる
		sc.close();
	}

	void left() {
		if (0 < cursorPosCol) {
			cursorPosCol = cursorPosCol - 1;
		} else {
			System.out.println("カーソルは既に左端にあります");
		}
	}

	void right() {
		if (cursorPosCol < line.size()) {
			cursorPosCol = cursorPosCol + 1;
		} else {
			System.out.println("カーソルは既に右端にあります");
		}
	}

	void backspace() {
		//カーソルが0文字目に来た時に左側は消せないので制御
		if (0 < cursorPosCol) {

			//lineは行を格納している配列なのでこの消し方をすると、行ごと消える
			//(元ソース)line.remove(cursorPosCol - 1);

			//カーソル位置の左を消すのでインデックス-1
			line.get(cursorPosRow).deleteCharAt(cursorPosCol - 1);
			cursorPosCol = cursorPosCol - 1;
		} else {
			System.out.println("左側に文字はありません");
		}
	}

	void insert(String str) {
		//編集中の行に格納されているStringBuilderに文字列を追加(挿入)する
		line.get(cursorPosRow).insert(cursorPosCol, str);
		//(元ソース)line.add(cursorPos,str);//ここはエラーが出てます
		cursorPosCol = cursorPosCol + str.length();
	}

	void print() {
		//表示が見づらかったので少し手を入れました
		//内容表示
		System.out.println("********************");
		for (int i = 0; i < line.size(); i++) {
			System.out.println(i + ":" + line.get(i).toString());
		}
		System.out.println("********************");
		System.out.println("[カーソル位置 -> "
				+ cursorPosRow + "行目 "
				+ cursorPosCol + "文字目 ]");
	}

	void up() {
		if (cursorPosRow > 0) {
			cursorPosRow = cursorPosRow - 1;
			//カーソル位置を上下移動時の位置を考慮して
			// 調整しないとIndexOutOfBoundsになる
		} else {
			System.out.println("カーソルは一番上にあります");
		}
	}

	void down() {
		if (cursorPosRow > line.size()) {
			cursorPosRow = cursorPosRow + 1;
			//カーソル位置を上下移動時の位置を考慮して
			// 調整しないとIndexOutOfBoundsになる
		} else {
			System.out.println("カーソルは一番下にあります");
		}
	}

	void insertline() {
		//カーソル位置に挿入すると配列要素が後ろにずれるので
		//上に行挿入が起こったように見える
		line.add(cursorPosRow, new StringBuilder());
		cursorPosRow++;
	}

	void addline() {

	}

	void deleteline() {

	}

	public static void main(String[] args) {
		new MultiLineEditor().run();
	}

}
0Like

Your answer might help someone💌