質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.32%

  • Java

    14434questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Swing

    232questions

    SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

[JAVA]Swingでファイル保存時に枝番を付けたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 1,106

junn

score 59

以下のツールを使ってファイルを保存しているのですが、同じファイル名があると
自動的に上書き保存されてしまいます。同じファイル名があるときに上書き保存せずにファイル名の後ろに(1),(2)といった風に枝番を自動的につけるようには
どうすればようでしょうか?実際に追加するソースコード等も教えていただけると
助かります。
※回答者様のソースを記入したら「ローカル変数mは使用されていません」
と出たのでその解決策も教えていただけると助かります。

public class MainInit implements ActionListener , WindowListener {        //impriments(組み込む)
    private JFrame mainFrame;
    private Container contentPane;
    private JPanel itemPanel;
    private JPanel textPanel;
    private JPanel buttonPanel;
    private JTextField textField;
    private JButton dirButton;
    private JButton addButton;
    private ScreenShot screenShot;
    private String  folderpath;
    private JLabel  folderlabel;

    private SettingWindow settingwindow;

    private ItemBox itemboxtest1;
    private ItemBox itemboxtest2;
    private ItemBox itemboxtest3;
    private ItemBox itemboxtest4;

    //private Thumbnail DrawPanel;




    public MainInit(){
        mainFrame = new JFrame("エビデンスキャプチャ");
        mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //終了方法
        mainFrame.setSize(500, 300);                //ウィンドウのサイズ
        mainFrame.setLocationRelativeTo(null);        //ウィンドウを画面の中央に表示
        contentPane = mainFrame.getContentPane();   //要素、成分 メインフレームのパネルを取得


        contentPane.setLayout(null);


        dirButton   = new JButton("Dir");        //Dirボタンの作成 クラス名( ) = コンストラクタ
        dirButton.setBounds(20, 0, 80, 30);
        contentPane.add(dirButton);                //コンパネにボタンを追加

        addButton   = new JButton("Capture");
        addButton.setBounds(400, 0, 90, 60);
        contentPane.add(addButton);





        JMenuBar menubar = new JMenuBar();
        JMenu menu1 = new JMenu("設定");            //メニューの生成
        JMenu menu2 = new JMenu("ヘルプ");
        JMenuItem menuitem1 = new JMenuItem("設定");

        menubar.add(menu1);
        menubar.add(menu2);
        menu1.add(menuitem1);

        mainFrame.getRootPane().setJMenuBar(menubar);        //メインフレームに対してメニューバーを追加

        folderlabel = new JLabel();
        textField   = new JTextField();            //オブジェクトの作成
        //dirButton   = new JButton("Dir");        //Dirボタンの作成
        //addButton   = new JButton("Capture");    //Captureボタンの作成


        //「追加」ボタンとアクション・リスナーの関連付け
        dirButton.addActionListener(this);
        dirButton.setActionCommand("Dir"); // イベントに対するコマンド文字列登録
        addButton.addActionListener(this);
        addButton.setActionCommand("Capture"); // イベントに対するコマンド文字列登録


        menuitem1.addActionListener(this);
        menuitem1.setActionCommand("settingwindow"); // イベントに対するコマンド文字列登録


        itemPanel    = new JPanel();                                //上下
        itemPanel.setBounds(0, 0, 500, 100);
        contentPane.add(itemPanel);
        //itemPanel.setBackground(Color.RED);

        textPanel    = new JPanel();                                //directryfield dir add
        textPanel.setLayout(null);
        contentPane.add(textPanel);
        textPanel.setBounds(0,80, 500, 100);
        //textPanel.setBackground(Color.GREEN);

        buttonPanel = new JPanel();

        buttonPanel.setLayout(null);
        contentPane.add(buttonPanel);
        buttonPanel.setBounds(0,180,500,200);
        //buttonPanel.setBackground(Color.ORANGE);


        itemboxtest1 = new ItemBox();                            //□↑↓
        itemPanel.add(itemboxtest1);


        itemboxtest2 = new ItemBox();
        itemPanel.add(itemboxtest2);

        itemboxtest3 = new ItemBox();
        itemPanel.add(itemboxtest3);

        itemboxtest4 = new ItemBox();
        itemPanel.add(itemboxtest4);


        //DrawPanel = new Thumbnail();
        //DrawPanel.add(addButton);



        textPanel.add(folderlabel);
        folderlabel.setBounds(0, 30, 200, 30);

        textPanel.add(textField);
        textField.setBounds(320, 30, 150, 30);

        buttonPanel.add(dirButton);
        buttonPanel.add(addButton);




        // フォルダパス初期値
        folderpath = "C:\\tmp";
        // folderlabel,textFieldを初期値設定
        folderlabel.setText(folderpath);

        textField.setText("UT_EOM_%d-%d-%d-%d.jpg");        //初期表示フォルダパス


        mainFrame.setVisible(true);
        screenShot = new ScreenShot();

    }




    // 利用者の操作に応じた処理を実装
    public void actionPerformed(ActionEvent event){
        // コマンド文字列を取得
        String cmd = event.getActionCommand();

        if(cmd.equals("Capture")){
            int x = mainFrame.getX();
            int y = mainFrame.getY();
            // 画面キャプチャー
            try{
                String filepath = FilePathCreate();
                // 自分を消す(見えない位置に移動)
                mainFrame.setLocation(-1000,-1000);
                // 画面キャプチャ
                screenShot.screenCapture(filepath);

                // 自分を表示(元の位置に移動)
                mainFrame.setLocation(x, y);

                //new Thumbnail(filepath);            //サムネイルの表示


            } catch (AWTException e){
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            } catch (IOException e){
                // TODO 自動生成された catch ブロック
                e.printStackTrace();
            }
        }
        else if(cmd.equals("Dir")) {


            //folderpath = settingwindow.getfolderpath();        //folderpath()を取得する。
            //folderlabel.setText(folderpath);                //folderlabelにfolderpathをセットする。


        JFileChooser filechooser = new JFileChooser(folderpath);        //上二行と相互関係

                 filechooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);

                 int selected = filechooser.showSaveDialog(this.contentPane);
                 if (selected == JFileChooser.APPROVE_OPTION){
                     File file = filechooser.getSelectedFile();
                     folderpath = file.getAbsolutePath();
                     folderlabel.setText(folderpath);


                 }

        else if(cmd.equals("settingwindow")){


            settingwindow = new SettingWindow();
        }
                 }


    }







    // ファイルのパスを生成
    public String FilePathCreate() {
        String filepath;
        String filename;
        filepath = folderpath;

        filename = FileNameCreate();
        filepath = filepath + "\\" + filename;
        return filepath;
    }


    // 数値リストからファイル名を生成
    public String FileNameCreate() {
        String filename;
        String[] itemNumbers = new String[4];
        filename = textField.getText();
        int i=0;
        int found = 0;

        itemNumbers[0] = itemboxtest1.getText();
        itemNumbers[1] = itemboxtest2.getText();
        itemNumbers[2] = itemboxtest3.getText();
        itemNumbers[3] = itemboxtest4.getText();

        for(i=0; i<4; i++){
            found = filename.indexOf("%d",found);
            if( found != 0 ){
                filename = filename.replaceFirst("%d",itemNumbers[i]);
            }
        }
        return filename;
    }

    // アプリケーションの起動
    public static void main(String[] args) {
        new MainInit();
    }
}
public class ItemBox extends JPanel  implements ActionListener{        //ItemBoxはJPanelというオブジェクトクラスを継承
                                                                    //ActionListnerというインタフェースを実装
    private JButton upButton;
    private JButton downButton;
    private JTextField itemField;
    private Container contentPane;
    private JPanel itemPanel;

    GridBagLayout gbl = new GridBagLayout();



    void addButton(Object itemobject, int x, int y, int w, int h) {
        GridBagConstraints gbc = new GridBagConstraints();
        gbc.fill = GridBagConstraints.BOTH;
        gbc.gridx = x;
        gbc.gridy = y;
        gbc.gridwidth = w;
        gbc.gridheight = h;
        gbl.setConstraints((Component) itemobject, gbc);
        add((Component) itemobject);
    }

    public ItemBox(){

        //setLayout(null);
        //setBackground(Color.blue);

        itemField = new JTextField("0");
        itemField.setPreferredSize(new Dimension(20, 10));        //アイテムフィールドの大きさ指定
        itemField.setFocusable(false);            //入力制限

        upButton   = new JButton("↑");            //upButtonオブジェクトを作成し、↑を代入する。
        downButton = new JButton("↓");            //downButtonオブジェクトを作成し、↓を代入する。

       

        upButton.setActionCommand("upButton");
        upButton.addActionListener(this);        //アクションイベントを受け取れるようになる。
        downButton.setActionCommand("downButton");
        downButton.addActionListener(this);

        setLayout(gbl);
        addButton(itemField, 0, 0, 1, 2);   // (0, 0) 幅=1, 高さ=3
        addButton(upButton, 1, 0, 1, 1);   // (1, 0) 幅=1, 高さ=1
        addButton(downButton, 1, 1, 1, 1);   // (1, 1) 幅=1, 高さ=1



     }



    public String getText(){


        return itemField.getText();


    }


    //操作に応じた処理の実装
    public void actionPerformed(ActionEvent event){        //イベントが発生するとここが処理される
        //ユーザーの操作e対象の判断                        //このクラスでのアクションリスナー
        String cmd = event.getActionCommand();

        if(cmd.equals("upButton")) {
            int i = Integer.parseInt(itemField.getText());
            i++;
            if(i>99)i=0;
            //itemField.setText(String.format("%1$02d",i));        //0埋め
            itemField.setText(String.valueOf(i));

        }
        else if(cmd.equals("downButton")){
                int i = Integer.parseInt(itemField.getText());
                i--;
            if(i<0)i=99;
            //itemField.setText(String.format("%1$02d",i));        //0埋め
            itemField.setText(String.valueOf(i));

        }
    }



}
public class ScreenShot {

    public void screenCapture(String filepath) throws AWTException, IOException {
        Robot robot = new Robot();
        Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
        BufferedImage image = robot.createScreenCapture(
            new Rectangle(0, 0, screenSize.width, screenSize.height));
        ImageIO.write(image, "PNG", new File(filepath));        //PNGファイルの保存
    }
}
  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

+3

Fileクラスのexistsメソッドが使えると思います。
作成したいパスのファイルが存在するかどうかを調べるメソッドです。
これでファイルが存在したときに、枝番をつければよいわけです。

具体的には、FilePathCreateメソッドに、以下のようなファイルの存在確認を追加すればよいと思います。

    File save = new File(filepath);//ファイルパスを示すファイルオブジェクト。
    String hogepath //括弧をつけた仮のパス。
    int m = 1;//カッコ内の数字の初期値
    if(save.exists()){//指定したパスが存在する限り、後ろに(数字)をつけていく。
            hogepath = filepath+ " (m)";//このとき、括弧は元のファイルパスの後につけること。
            save = new File(hogepath);
    m++;
    }
念のため、この行程の追加場所は、以下の位置と思われます。
    public String FilePathCreate() {
        String filepath;
        String filename;
        filepath = folderpath;

        filename = FileNameCreate();
        filepath = filepath + "\\" + filename;
   //この位置に、上記の行程を追記すると良い。
        return filepath;
    }

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/08 23:09

    mottyさん回答ありがとうございます。
    hogepath = filepath+ " (m)";//このとき、括弧は元のファイルパスの後につけること。
    はどういうことでしょうか?
    ローカル変数mは未定義と言われました。

    キャンセル

  • 2015/07/09 11:58

    横から失礼します。
    「ローカル変数mが未定義」は、おそらくmが全角文字になっているためと思われます。mを半角にしてみてください。

    キャンセル

  • 2015/07/09 13:03

    argiusさん
    解答ありがとうございます。
    半角にしたが直りませんでした。解答のコードを入れるだけでなくほかも
    変えなくてはいけないのですかね?

    キャンセル

  • 2015/07/09 13:31

    すみません。ブラウザに直接書き込んだのでコードが間違いだらけでした。
    未定義の理由は、おそらくm=1の部分が、1も全角だからだと思います。
    argiusさんのコードで正しいと思います。

    キャンセル

  • 2015/07/09 14:11

    mottyさん
    全角直してもだめでしたありがとうございました。

    キャンセル

checkベストアンサー

+1

motty56psさんのとほとんど同じですが、一部だけ変えるのは難しかったので、FilePathCreateを全体的に書き直してみました。
戻り値はjava.io.Fileにします。

    public File FilePathCreate() {
        String filename = FileNameCreate();
        String name = filename;
        int m = 0;
        do {
            File f = new File(folderpath, name);
            if (!f.exists()) {
                return f;
            }
            ++m;
            name = filename + "_" + m;
        } while (m < 100); // 無限ループ防止
        throw new IllegalStateException("パス生成失敗");
    }

こうすると、Fileを外側で生成することになります。ScreenShot#screenCaptureでは結果的にFileを作るので、引数をFileにした方が良いです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/07/09 13:41

    argiusさん解答ありがとうございます。
    上記のソースコードで書き換えましたところ、actionlistenerの中の
    String filepath = FilePathCreate();
    がエラーとなり、String name = filename;の部分で
    filenameを変数に変換できませんとなってしまいました。
    何度もすみません。

    キャンセル

  • 2015/07/09 13:52

    すみません、FileNameCreateの呼び出しが抜けていました。メソッドの最初に追記しましたのでご確認ください。

    キャンセル

  • 2015/07/09 14:09

    追記ありがとうございます!変換の部分のエラー消えました。
    ただ、String filepath = FilePathCreate();のエラーが
    「型の不一致:FileからStringには変換できません」となりました。
    解決策にfilpathの型をFileに変換する、等の候補が挙がりましたが、
    変換したらよいでしょうか?宜しくお願いします。

    キャンセル

  • 2015/07/09 14:27

    Fileにするのがおすすめです。
    回答に書いたように、ScreenShot#screenCaptureの引数の型をFileに変えたうえで、filepath の型はFileにしてください。
    ScreenShot#screenCaptureの最後のnew File(filepath)は、filepathに書き直してください。

    キャンセル

  • 2015/07/09 16:28

    ありがとうございます。編集してみます。
    戻り値をjava.io.Fileにするというのは上記のソースコードに入っていますか?
    初心者なので申し訳ありません。

    キャンセル

  • 2015/07/09 16:30

    public File FilePathCreate() { ←この部分が、「戻り値をjava.io.Fileに」した箇所です。元はStringでした。

    キャンセル

  • 2015/07/10 08:44

    argiusさん
    わかりました。編集してみます!
    詳しくありがとうございます!

    キャンセル

  • 2015/07/10 09:21

    argiusさん
    上記のソースで実行したら無事できました。しかし今までキャプチャした画像が保存されましたがファイルとして保存されました。修復可能でしょうか?
    質問が悪かったですね。すみません。。。

    キャンセル

  • 2015/07/10 09:37

    今回の方式では、拡張子を無視して枝番付きにしています。
    画像ファイルとして保存したい場合は、枝番を拡張子の前につけてあげる必要があります。

    ただそれだと処理が少しだけ複雑になり、今すぐに書けません。
    とり急ぎ
    name = filename + "_" + m + ".png";
    とすれば、画像ファイルとして参照することはできるようになります。ただ、ファイル名は"aaa.png_1.png"のようになります。


    お話から推測すると、もしかすると拡張子を表示しない設定にしていますか? そうなると確認がちょっと難しいので、拡張子を表示する設定にするのをお勧めします。
    プログラミングの際には、拡張子が表示されていないといろいろと不便です。

    キャンセル

  • 2015/07/10 09:58

    お返事ありがとうございます。
    .jpgをつけたら画像となりました。(1)、(2)…といった枝番を付けたかったので
    name = filename + "(" + m + ")" + ".jpg";
    としたら無事できました。拡張子を表示する設定…見てみます!ありがとうございました。

    キャンセル

  • 2015/07/10 10:00

    あ、でも重複するファイル名が無い場合、ファイルになってしまいますね。

    キャンセル

  • 2015/07/10 10:45

    重複するファイルが無い場合の対応は、
    File f = new File(folderpath, name);
    のnameを重複時と同じように name + ".jpg" とすればOKだと思います。

    ところで、ScreenShotクラスではPNGで保存しているようですが、JPEGで良いのでしょうか?

    キャンセル

  • 2015/07/10 10:56

    解決しました。ありがとうございます!
    PNGになってましたね。修正しておきます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.32%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    14434questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Swing

    232questions

    SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。