前提
https://ateraimemo.com/Swing/RowGroupInTable.html
このサイトの参考リンクのstackoverflowにある回答欄のソースコードについて
やりたいこと
コピペして何回か実行してみました。すると問題点が出てきました
すでに登録?保存?した値(例addMyData(model, new MyData("Tom", 17, "Book1"));
についてはレンダラーの機能で表現できていると思うのですが
新しいデータを追加してソートしたい場合には
新しい行を追加して空のセルの中に編集した値を入れるという風に考えると思います
しかしうまい方法が思い浮かびません
自分の頭の中
まず新しい行を追加するにはaddRowメソッドで追加するしかないので
model.addRow();
でも空の行を追加したいので
model.addRow(new Object[]);
と書くけどその行に新規のデータを手打ちしてソートしようにもモデルと紐づけられてないのでこれは無理
じゃあ、MyDataクラスのようにコンストラクタとゲッターを作ってそれを利用するか?いや待てよ
自分が編集したらこのコンストラクタは生成されないから意味ないだろ?
諦めきれない
一か月ほど前、似たような質問でベストアンサーの方に
「> 空っぽの行を追加して値を入力して保存する
コード的には逆のほうが分かり易いと思います。
つまり、追加ボタンを押したら ( 例えば ) 入力用のダイアログを出して日付や氏名等を入力し、 OK が押されたらそのデータで TableModel に addRow するということです。」
という回答をしてもらったんですが
その回答は確かにコードを作る側として簡単そうなんですけど
いざプログラムが完成したときに使う側としては一々ダイアログを出して入力する作業がめんどくさそうなんですよ
今ここで躓いています何か打開する方法を教えてください
追記
つまり何が言いたいのかというと
手打ちした値を何かに保存してそれをモデルと関連付けてソートしてさらにグループ化を表現したい(ダイアログの方法以外で
ということです
該当のソースコード
java
1import java.awt.*; 2import java.util.*; 3import java.util.List; 4import javax.swing.*; 5import javax.swing.table.*; 6 7public class RowGroupInTableTest { 8 private JComponent makeUI() { 9 String[] titles = new String[] {"Name", "Last job duration", "Book #"}; 10 DefaultTableModel model = new DefaultTableModel(null, titles) { 11 @Override public Class<?> getColumnClass(int column) { 12 return MyData.class; 13 } 14 }; 15 addMyData(model, new MyData("Tom", 17, "Book1")); 16 addMyData(model, new MyData("Tom", 23, "Book2")); 17 addMyData(model, new MyData("Tom", 25, "Book3")); 18 addMyData(model, new MyData("Polazzo", 41, "Book1")); 19 addMyData(model, new MyData("Polazzo", 45, "Book2")); 20 addMyData(model, new MyData("Polazzo", 12, "Book3")); 21 addMyData(model, new MyData("Anna", 1, "Book3")); 22 addMyData(model, new MyData("Anna", 33, "Book5")); 23 24 JTable table = new JTable(model); 25 table.setFillsViewportHeight(true); 26 table.setDefaultRenderer(MyData.class, new MyRenderer()); 27 28 TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(table.getModel()); 29 Comparator<MyData> c = Comparator.comparing(MyData::getName); 30 sorter.setComparator(0, c); 31 sorter.setComparator(1, c.thenComparing(Comparator.comparingInt(MyData::getDuration))); 32 sorter.setComparator(2, c.thenComparing(Comparator.comparing(MyData::getBook))); 33 table.setRowSorter(sorter); 34 35 return new JScrollPane(table); 36 } 37 private static void addMyData(DefaultTableModel model, MyData data) { 38 //Omission work... 39 model.addRow(Collections.nCopies(3, data).toArray()); 40 } 41 public static void main(String[] args) { 42 EventQueue.invokeLater(() -> { 43 JFrame f = new JFrame(); 44 f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 45 f.getContentPane().add(new RowGroupInTableTest().makeUI()); 46 f.setSize(320, 240); 47 f.setLocationRelativeTo(null); 48 f.setVisible(true); 49 }); 50 } 51} 52 53class MyData { 54 private final String name; 55 private final int duration; 56 private final String book; 57 protected MyData(String name, int duration, String book) { 58 this.name = name; 59 this.duration = duration; 60 this.book = book; 61 } 62 public String getName() { 63 return name; 64 } 65 public int getDuration() { 66 return duration; 67 } 68 public String getBook() { 69 return book; 70 } 71} 72 73class MyRenderer implements TableCellRenderer { 74 TableCellRenderer def = new DefaultTableCellRenderer(); 75 @Override public Component getTableCellRendererComponent( 76 JTable table, Object value, boolean isSelected, boolean hasFocus, 77 int row, int column) { 78 JLabel orig = (JLabel) def.getTableCellRendererComponent( 79 table, value, isSelected, hasFocus, row, column); 80 orig.setHorizontalAlignment(SwingConstants.LEFT); 81 MyData data = (MyData) value; 82 switch (table.convertColumnIndexToModel(column)) { 83 case 0: 84 String str = data.getName(); 85 if (row > 0) { 86 //if (table.getModel().getValueAt(row-1, column).equals(value)) { 87 //Since it compares with the value of the previous line on the display, 88 //table.getModel() is not needed 89 MyData prev = (MyData) table.getValueAt(row - 1, column); 90 if (Objects.equals(prev.getName(), str)) { 91 str = " "; 92 } 93 } 94 orig.setText(str); 95 break; 96 case 1: 97 orig.setHorizontalAlignment(SwingConstants.RIGHT); 98 orig.setText("" + data.getDuration()); 99 break; 100 case 2: 101 orig.setText(data.getBook()); 102 break; 103 default: 104 break; 105 } 106 return orig; 107 } 108}
補足情報(FW/ツールのバージョンなど)
All in One パッケージ Eclipse 2021
回答2件
あなたの回答
tips
プレビュー