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

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

ただいまの
回答率

87.61%

JAVA リストボックスの文字色の設定について

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 1,037

score 15

public class TEST1 extends JFrame implements ListSelectionListener {

    JList lst0;

    public TEST1() throws Exception {

        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        setSize(1300, 750);
        setLayout(null);

        // ボタンの設置
        button_sakusei();

        // 画面作成
        gamen_sakusei();

        // 空のリストボックスの作成
        list_sakusei();

        // 表示する
        setVisible(true);

    }


    //空のリストボックス作成
    public void list_sakusei() {

        lst0 = new JList(file_name2);
        lst0.addListSelectionListener(this);
        lst0.setCellRenderer(new StripedListCellRenderer());
        JScrollPane lst1 = new JScrollPane(lst0);
        lst1.setBounds(240, 150, 470,400);
        getContentPane().add(lst1);
        setVisible(true);

    }


    public void valueChanged(ListSelectionEvent e) {

        // 初期化
        for(int i=0;i<5000;i++) {
            new_flag[i]=0;
        }

        JList lst0 = (JList)e.getSource();

        if(lst0.getSelectedValue()!="") {
            if(lst0.getSelectedValue()!=null) {

                Object lst = lst0.getSelectedValue() ;
                sentaku_str = lst.toString();

                //フォルダの一覧を抽出する
                File file2 = new File(str_saki2);
                if(!file2.isDirectory()) return;
                File files[] = file2.listFiles();
                file_name = new String[files.length];
                for (int i=0; i<files.length; i++) {
                    file_name[i] = files[i].getName();
                    File item = files[i];
                    if(item.isDirectory()) {
                        folder[i] = item.getName();
                        //System.out.println("folder[i]:" + folder[i]);
                    }
                    if (item.isFile()) {
                        name[i] = item.getName();
                      }
                }
                //lst0.setListData(file_name);


                for (int i=0; i<files.length; i++) {
                    // フォルダだったら下位フォルダを表示する
                    //ファイルだったら開く                    
                }

                //フォルダの一覧を抽出する
                File file22 = new File(str_saki2);
                if(!file22.isDirectory()) return;
                File files23[] = file22.listFiles();
                file_name = new String[files23.length];
                for (int i=0; i<files23.length; i++) {
                    file_name[i] = files23[i].getName();
                    File item = files23[i];
                    if(item.isDirectory()) {
                        folder[i] = item.getName();
                        //System.out.println("folder[i]:" + folder[i]);
                    }
                    if (item.isFile()) {
                        name[i] = item.getName();
                        //System.out.println("name[i]:" + name[i]);
                    }
                }
                lst0.setListData(file_name);

                try {
                    folder_new_check();
                } catch (Exception e2) {
                    e2.printStackTrace();
                }
            }
        }
        lst0.clearSelection();
        lst0.getSelectionModel().setAnchorSelectionIndex(-1);
        lst0.getSelectionModel().setLeadSelectionIndex(-1);
    }


    // 画面作成メソッド
    public void gamen_sakusei() {
    //背景色の設定
}



    //  リストボックスのNEWファイルを赤で表示する
    public class StripedListCellRenderer extends DefaultListCellRenderer {
        public Component getListCellRendererComponent(JList list, Object value,
            int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label = (JLabel) super.getListCellRendererComponent(list, value,index, isSelected, cellHasFocus);
            if (new_flag[index] == 1) {
                label.setForeground(Color.red);
            }
            return label;
        }
    }


      public void folder_new_check() throws Exception {

          //フォルダの一覧を抽出する
        File file22 = new File(str_pass[1]);
        File files23[] = file22.listFiles();
        file_name = new String[files23.length];
        for (int i=0; i<files23.length; i++) {
            file_name[i] = files23[i].getName();
            File item = files23[i];
            if(item.isDirectory()) {
            folder[i] = item.getName();
            //System.out.println("folder[i]:" + folder[i]);
        }
        if (item.isFile()) {
            name[i] = item.getName();
            //System.out.println("name[i]:" + name[i]);
        }
        }

          for(int i=0;i<new_cou[0];i++) {
              file_name3[i] = new_file[i].substring(5);
              String sarch2 = "\\";
                int result = file_name3[i].indexOf(sarch2);
                if (result != -1) {
                    kiridashi = file_name3[i].substring(0,result);
                }
                for(int j=0;j<files23.length; j++) {
                    if(folder[j].equals(kiridashi)) {
                        new_flag[j]=1;
                    }
                }
          }
      }

      // 初期化
      public static void initialaize() {
    }


      public static void main(String[] args) throws Exception {

        NEW_FILE_SEARCH.new_file_search(new_file,koushinbi,new_cou,cou_folde,cou_file,str_pass,folde_name_new,file_name_new);
        new DMSZUMEN();
    }

}



public class NEW_FILE_SEARCH{


      public static void new_file_search(String new_file[],int koushinbi[],int new_cou[],int cou_folde[],int cou_file[],String str_pass[],String folde_name_new[][],String file_name_new[][]) throws Exception {

          String format2;
          String format3;

          // 初期化
          for(int i=1;i<=5;i++) {
              cou_folde[i] = 0;
              cou_file[i] = 0;
          }

          String strmoto = str_pass[2] + "\\";


          // 1階層目チェック
        File file_1 = new File(strmoto);
          File files_1[] = file_1.listFiles();
          for (int i=0; i<files_1.length; i++) {
              File item = files_1[i];
            // 階層のフォルダ名を取得
              if(item.isDirectory()) {
                  folde_name_new[1][cou_folde[1]] = item.getName();
                  //System.out.println("folde_name_new[1][cou_folde[1]]:" + folde_name_new[1][cou_folde[1]]);
                  cou_folde[1] = cou_folde[1] + 1;
              }
            // 階層のファイル名を取得
              if (item.isFile()) {
                  file_name_new[1][cou_file[1]] = item.getName();
                  cou_file[1] = cou_file[1] + 1;
              }
          }


        // 2階層目以降チェック
        for(int k=1;k<6;k++) {
            for (int i = 0;i<cou_folde[k];i++) {
                  File file_2 = new File(strmoto + folde_name_new[k][i]);
                  File files_2[] = file_2.listFiles();
                  for (int j=0; j<files_2.length; j++) {
                      File item = files_2[j];
                      // 階層のフォルダ名を取得
                      if(item.isDirectory()) {
                          folde_name_new[k+1][cou_folde[k+1]] = folde_name_new[k][i] + "\\" + item.getName();
                          //System.out.println("folde_name_new[k+1][cou_folde[k+1]]:" + folde_name_new[k+1][cou_folde[k+1]]);
                          cou_folde[k+1] = cou_folde[k+1] + 1;
                      }
                      // 階層のファイル名を取得
                      if (item.isFile()) {
                          file_name_new[k+1][cou_file[k+1]] = folde_name_new[k][i] + "\\" + item.getName();
                          //System.out.println("file_name_new[k+1][cou_file[k+1]]:" + file_name_new[k+1][cou_file[k+1]]);
                        cou_file[k+1] = cou_file[k+1] + 1;
                      }
                  }
              }
        } // 2階層目以降チェック終わり

        new_cou[0] = 0;

        for(int i=2;i<6;i++) {
              for(int j=0;j<cou_file[i];j++) {
                  File file200 = new File(strmoto + file_name_new[i][j]);
                long lastModified = file200.lastModified();
                  Date date = new Date(lastModified);
                  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
                format2 = sdf.format(date.getTime());
                Calendar calendar = Calendar.getInstance();
                calendar.setTime(date);
                calendar.add(Calendar.DAY_OF_MONTH, +koushinbi[0]);// 直近1ヶ月
                //calendar.add(Calendar.MONTH, +koushinbi[0]);// 直近1ヶ月
                Date d1 = calendar.getTime();
                Date date2 = new Date();
                SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd");
                format3 = sdf2.format(date2.getTime());
                Calendar calendar2 = Calendar.getInstance();
                calendar2.setTime(date2);
                if(d1.compareTo(date2) == -1){
                }else {
                      new_file[new_cou[0]] = file_name_new[i][j];
                    new_cou[0] = new_cou[0] + 1;
                }
              }
        }
      }ファイルの最終更新日確認処理

}

イメージ説明

社内のサーバーのファイルを閲覧し、リストボックスに表示するようにしました。
ファイルの更新日が直近30日以内のフォルダ/ファイルはリストボックスで赤字になるように設定しましたが、
「テスト2」フォルダが黒字になってしまいます。(テスト2はテストをそのままコピーしてます。)
文字数制限があるため、一部消去&他classのコードは入れておりませんが、今回の件とは関係ないと思います。

リストボックス上でクリックしたままだと赤字ですが、クリックを離すと黒字になるため、indexが上手く
操作出来ていないと思いますが、どのように修正すればよいか分かりません。

宜しくお願い致します。

```JAVAコード

  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • azuapricot

    2019/01/31 17:50

    マークダウンがきちんと適用されていません

    もう一度 <code>を押して、Javaコードではなく Javaと直して
    コードを貼りつけなおしてください。

    キャンセル

  • qwxpc243

    2019/02/01 09:04

    すみません。
    Javaで修正しました。
    宜しくお願い致します。

    キャンセル

  • stdio

    2019/02/01 09:26

    いやコードないけど...

    キャンセル

  • jimbe

    2019/02/01 18:12

    大分コードが煩雑になっています. ぱっと見て「フォルダの一覧を抽出する」というコメントが3つもあります. 修正をする前にコードの整理をされたほうが良いように思います.
    「そんなことより修正しないと…」と思われるかもしれませんが, このコードでは, どこに副作用が出るかもしれない状態です.

    処理毎にメソッドを分け, 名前を適切に付けて頂きたいです.
    変数名に番号が入っている時は, 変数名の付け方・スコープ(変数の使える範囲)が間違っているという客観的な印となります.
    テキトウにコードを書いていると, ここでは使えません的なことがあり, それが面倒だからとプログラム全体で見えるスコープにしてしまったりします. すると, 同じような機能が必要だけどもコピペすると既にあると言われるので, 名前に番号を付けてしまうようになります.
    また, ご質問のようにコードを提示する場合に, サイズ的な問題で一部だけの提示となってしまった場合に, 各変数が見えない所で変更されている可能性が捨てられず, 結局全部を見ないと分からないことになります.

    for(int i=0;i<5000;i++) {
    new_flag[i]=0;
    }
    というコードがありますが, この 5000 という数字は int new_flag[5000]; という宣言をしている所からと思います.
    ですが, この new_flag 配列は使われ方を見る限りフォルダ下のファイル/フォルダ数だけ必要なものであり, 一般にフォルダ下にファイル/フォルダ数が幾つあるのかは決まっておりません.
    file_name = new String[files23.length]; と同様, このような性質の変数は, 大きさが分かった時点で作成するようにしてください.

    キャンセル

回答 1

checkベストアンサー

0

ご提示されたコードだけでは実行には解読と修正がそれなりに必要な為, ご質問と画面から推測した機能のプログラムを書きました.
コンソールから実行する場合は, パラメータとしてHOMEとなるフォルダを指定してください.
パラメータ無しで実行すると, 内部で定義している DEFAULT_HOME_PATH = "T:\"(私の環境でのテンポラリ) が指定されたものとして動きますので, 必要に応じて DEFAULT_HOME_PATH を変えてください.

日付のチェックは getListCellRendererComponent 内で fileItem.lastModified.after(condition) として行っています.

lastModified = Calendar.getInstance();
lastModified.setTimeInMillis(file.lastModified());


としてファイルの lastModified から作った Calendar と, FolderFrame のコンストラクタで

Calendar conditions = Calendar.getInstance();
conditions.add(Calendar.DATE, -30);


として現在日時から 30日を引いた Calendar を比較しています.
このように表示の度にチェックしている為, フラグ等は要らなくなっています.

表示する名前やフラグ等を全て配列に準備して, 後は表示だけを行う形のほうが速いとお考えかも知れませんが, 速さはメモリの使用量とほぼトレードオフです. 巨大な配列等は好ましくないと思います.
また, 全ての動作が記述できていない状態で速度を考えるのは, 最近の開発ではしないほうが良いという認識が広まっていると思います.
機能が整い, コードを整理し, 後は性能の問題だけとなってから, 何処が遅いのかを計測して修正していく形です.
まぁ, これは理想論であって, 実際は時間や人員等の関係でそうも言っていられないとなってしまいますが.
逸れました.

ご提示のコードの中で問題視される new_flag の設定は, folder_new_check メソッドの二重 for ループの奥底で行われており, 一方日付の比較は NEW_FILE_SEARCH クラスの new_file_search メソッドの最期のほうの '直近1ヶ月' というコメントの辺りと思われますが...この二つのメソッドがどう関係しているのか, 省略されてコンパイルも大変なコードでは追いきれません.
下のコードでしたらご説明出来ますので, どこか意味が分からない箇所がありましたらコメントにてご質問ください.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;

public class FolderFrame extends JFrame {

    private static final String DEFAULT_HOME_PATH = "T:\\";

    public static void main(String[] args) {
        File homeFolder = null;
        if(args.length == 0) {
            homeFolder = new File(DEFAULT_HOME_PATH);
        } else if(args.length == 1) {
            homeFolder = new File(args[0]);
            if(!homeFolder.isDirectory()) {
                System.out.println("'"+args[0]+"' はフォルダではありません");
                printUsage();
                System.exit(2);
            }
        } else {
            printUsage();
            System.exit(1);
        }

        JFrame folderFrame = new FolderFrame(homeFolder);
        folderFrame.setSize(500, 500);
        folderFrame.setLocationRelativeTo(null);//画面の真ん中
        folderFrame.setVisible(true);
    }

    private static void printUsage() {
        System.out.println("Usage: java FolderView [HomeFolderPath]");
        System.out.println(" HomeFolderPath default '"+DEFAULT_HOME_PATH+"'");
    }

    FolderFrame(File homeFolder) {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        fileListModel = new DefaultListModel<FileItem>();

        //現在時刻から30日以内のファイル/フォルダを赤文字で表示するレンダラ
        Calendar conditions = Calendar.getInstance();
        conditions.add(Calendar.DATE, -30);
        DefaultListCellRenderer listCellRenderer = new StripedListCellRenderer(conditions, Color.RED);

        JList<FileItem> fileListView = new JList<FileItem>(fileListModel);
        fileListView.setPrototypeCellValue(new FileItem(new File("----+----1----+----2----+----3----+----4")));
        fileListView.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
        fileListView.setCellRenderer(listCellRenderer);
        fileListView.addListSelectionListener(new ListSelectionListener() {
            @Override
            public void valueChanged(ListSelectionEvent e) {
                if(e.getFirstIndex() != fileListView.getSelectedIndex()) return;//解除通知は無視
                FileItem selectedFileItem = fileListView.getSelectedValue();
                if(selectedFileItem.isDirectory()) {//フォルダなら
                    fileListView.clearSelection();
                    fileListView.ensureIndexIsVisible(0);//先頭を表示する位置に移動
                    setFolder(selectedFileItem.file);
                } else {    //ファイルなら
                    //表示(略)
                }
            }
        });

        add(createBreadcrumbsPane(), BorderLayout.NORTH);
        add(new JScrollPane(fileListView), BorderLayout.CENTER);
        add(createButtonsPane(homeFolder), BorderLayout.SOUTH);

        setFolder(homeFolder);
    }

    private Component createBreadcrumbsPane() {
        currentFolderView = new JTextField(30);//テキトウに30文字分
        currentFolderView.setEditable(false);
        return currentFolderView;
    }

    private Component createButtonsPane(File homeFolder) {
        JButton toHomeButton = new JButton("HOME");
        toHomeButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                setFolder(homeFolder);
            }
        });

        toParentButton = new JButton("戻る");
        toParentButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                File file = new File(currentFolderView.getText());
                setFolder(file.getParentFile());
            }
        });

        //BoxLayout で右寄せ
        JPanel panel = new JPanel(null);
        panel.setLayout(new BoxLayout(panel, BoxLayout.X_AXIS));
        panel.add(Box.createGlue());
        panel.add(toHomeButton);
        panel.add(toParentButton);

        return panel;
    }

    private DefaultListModel<FileItem> fileListModel;
    private JTextField currentFolderView;
    private JButton toParentButton;

    private void setFolder(File folder) {
        if(folder.listFiles() == null) return; //システム系の,中身を見せてもらえないフォルダ?
        currentFolderView.setText(folder.getAbsolutePath());
        fileListModel.removeAllElements();
        for(File file : folder.listFiles()) fileListModel.addElement(new FileItem(file));//フォルダ下のファイル/フォルダを収集
        toParentButton.setEnabled(folder.getParentFile() != null);
    }

    //JListのアイテム(データ)
    private class FileItem {
        final File file;
        final Calendar lastModified;
        FileItem(File file) {
            this.file = file;
            lastModified = Calendar.getInstance();
            lastModified.setTimeInMillis(file.lastModified());
        }
        boolean isDirectory() { return file.isDirectory(); }
        @Override
        public String toString() {
            SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd");
            String iconDummy = (isDirectory() ? "■" : " ");
            return iconDummy + " "+ file.getName() + " (" + dateFormat.format(new Date(file.lastModified())) + ")";
        }
    }

    //JListのレンダラ
    public class StripedListCellRenderer extends DefaultListCellRenderer {
        private Calendar condition;
        private Color foreground;
        StripedListCellRenderer(Calendar condition, Color foreground) {
            setCondition(condition, foreground);
        }
        public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
            JLabel label = (JLabel) super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
            FileItem fileItem = (FileItem)value;
            if(condition != null && fileItem.lastModified.after(condition)) {    //更新日チェック
                label.setForeground(foreground);
            }
            return label;
        }
        /**
         * 指定した conditions 以降の更新日付のファイル/フォルダーは文字色を foreground にする
         * @param conditions
         * @param foreground
         */
        void setCondition(Calendar condition, Color foreground) {
            if(condition == null || foreground == null) throw new NullPointerException();
            this.condition = condition;
            this.foreground = foreground;
        }
    }
}

投稿

編集

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2019/02/05 11:45

    jimbeさん
    作成していただいたコードを参考にして解決出来ました。
    (最初にご指摘頂いたとおりフラグの設定の仕方が悪かったです。)
    本当に助かりました。
    ありがとうございました。

    キャンセル

  • 2019/02/05 13:14

    全く違うコードとなってしまって, 逆に参考にするにも大変だったと思います. すみませんでした.

    キャンセル

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

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

関連した質問

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