前提・実現したいこと
Javaで住所録のデスクトップアプリを作成しています。
ファイルからデータを読みこんでJListに反映させたいのですが、うまく動作しません。
どこに問題があるのかご教示をお願い致します。
DefaultListModelを使い、読み込んだデータを動的に扱えるようにしたいです。
発生している問題・エラーメッセージ
DefaultListModelにデータを読み込むことはできたのですが、JListに表示されません。
該当のソースコード
質問用に簡略化しています。
Java
1import java.awt.Dimension; 2 3import java.io.BufferedInputStream; 4import java.io.FileInputStream; 5import java.io.IOException; 6import java.io.ObjectInputStream; 7 8import javax.swing.DefaultListModel; 9import javax.swing.JFrame; 10import javax.swing.JList; 11import javax.swing.JPanel; 12import javax.swing.JScrollPane; 13 14public class MainFrame extends JFrame { 15 JPanel panel; 16 static DefaultListModel<PersonalData> dataListModel; 17 JList<PersonalData> dataList; 18 19 MainFrame(){ 20 this.setSize(600,400); 21 this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 22 23 panel = new JPanel(); 24 dataListModel = new DefaultListModel<PersonalData>(); 25 dataList = new JList<PersonalData>(dataListModel); 26 JScrollPane sp = new JScrollPane(); 27 sp.setPreferredSize(new Dimension(500, 300)); 28 29 panel.add(sp); 30 this.add(panel); 31 } 32 33 34 35 public static void main(String[] args) { 36 MainFrame mainFrame = new MainFrame(); 37 mainFrame.setVisible(true); 38 fileRead("data.dat"); 39 } 40 41 public static void fileRead(String path) { 42 //ファイルの読み込み 43 try { 44 FileInputStream f = new FileInputStream(path); 45 BufferedInputStream b = new BufferedInputStream(f); 46 ObjectInputStream in = new ObjectInputStream(b); 47 DefaultListModel<PersonalData> list = (DefaultListModel<PersonalData>)in.readObject(); 48 System.out.println("list:" + list); 49 //読み込んだデータを配列にコピーし、dataListModelに追加する 50 PersonalData[] array = new PersonalData[list.size()]; 51 list.copyInto(array); 52 for(PersonalData data:array) { 53 dataListModel.addElement(data); 54 } 55 System.out.println("dataListModel:" + dataListModel); 56 57 } catch (ClassNotFoundException e) { 58 e.printStackTrace(); 59 } catch (IOException e) { 60 e.printStackTrace(); 61 } 62 63 } 64}
Java
1import java.io.Serializable; 2 3public class PersonalData implements Serializable { 4 String name,address,tel; 5 6 PersonalData(String n,String a,String t){ 7 this.name = n; 8 this.address = a; 9 this.tel = t; 10 } 11 12 @Override 13 public String toString() { 14 return this.name + this.address + this.tel; 15 16 } 17}
JScrollPane sp = new JScrollPane();
を
JScrollPane sp = new JScrollPane(dataList);
か
JScrollPane sp = new JScrollPane();
sp.getViewport().setView(dataList);
にすればなにかしらでませんか?
fileReadが不可解ですが本来はいろんな処理があるのかな?
ありがとうございます!
本来の方では
JScrollPane sp = new JScrollPane(dataList);
としていましたが、タイミングに問題があったようで、そちらを見直すことで無事に解決いたしました。
fileReadは基本的な処理の流れは同じです。
ファイルを暗号化しているためCipherInputStreamを挟む程度の差ですが、不可解なのはこちらでしょうか?
DefaultListModel<PersonalData> list = (DefaultListModel<PersonalData>)in.readObject();
//読み込んだデータを配列にコピーし、dataListModelに追加する
PersonalData[] array = new PersonalData[list.size()];
list.copyInto(array);
for(PersonalData data:array) {
dataListModel.addElement(data);
}
最初はDefaultListModelをnewせず、JListのインスタンス生成時の引数を空にして
dataListModel = (DefaultListModel<PersonalData>)in.readObject();
dataList.setModel(dataListModel)
とするとエラーが出たのでこのような形にしてしまいました。
質問内容部分の修正に伴い、setModelが使えるようになったのでこちらも修正いたしました。
その他の部分でおかしなところがあればご指摘いただければ幸いです。
解決されて何よりです^^
お手数ですが自己回答で解決済みにしてください。
> fileReadが不可解ですが
簡略化版で本来のコードとは違うのでしょうが、
1. static にする意味を感じない。そのせいでdataListModelまでstaticにせざるを得なくなっている。
2. 初期値で入ることが決まっているなら
dataList = (DefaultListModel<PersonalData>)in.readObject();
で十分では?(ここは改善されたようですね)
3. 何個か読むor後から読むような場合は
for (int i = 0; i < list.getSize(); i++) {
dataListModel.addElement(list.elementAt(i));
}
でいいのでは?
4. Streamのclose
あたりが気になりました。
追加でご回答いただき、ありがとうございます!
自己回答の件、承知いたしました。
1に関しては、再度見直してみます。
3は読み込みが最初だけなので2の状態でいこうと思いますが、今後の参考にさせていただきます。
4は単純に忘れておりました・・・ご指摘ありがとうございます。
入門書の読了後、初めてコードを書いているため、ご指摘いただいた内容が非常に参考になりました。
ご丁寧にありがとうございました。重ねてお礼申し上げます。
回答1件
あなたの回答
tips
プレビュー