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

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

新規登録して質問してみよう
ただいま回答率
86.12%
JTable

JTableとは二次元的なセルの表を表示し編集するJava Swing用のコンポーネントです。

Java

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

受付中

tableのデータを更新したいが表示が変わらない

suteaka
suteaka

総合スコア13

JTable

JTableとは二次元的なセルの表を表示し編集するJava Swing用のコンポーネントです。

Java

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

2回答

0グッド

1クリップ

965閲覧

投稿2022/02/04 12:07

前提・実現したいこと

javaを独学で勉強しています。
表についての質問で、表のデータを初期値から変更し、反映させたいと思っています。

プログラムを起動し情報タブを開くと写真のようになります。
イメージ説明
仮に機械1のワット数「100」を「500」に変えたい場合、表の該当セル(または行)をクリックすることでマウスイベントが発生し、新規ウィンドウ(DetailFrame)を表示させます(写真参照)
イメージ説明
ここで100の数字を500に変更し「OK」を押したときに、配列 tabledata1[][]の値を500変更し、表についても500と表示されるようにしたいです。

発生している問題・エラーメッセージ

System.out.println によって変える前後の状態を確認し、値は変わっているようなのですが、フレームで表示させているほうに反映されません。
加えて、新規ウィンドウ(DetailFrame)で100を500に変えてOKを押し、プログラムを終了せずに再度変更しようと表をクリックし200にしたとするとき、System.out.printlnの1回目(100→500)は問題ないですが、2回目(500→200)のときはbeforeのほうが100に戻っています(新規ウィンドウの方は100で問題ないですが、System.out.printlnで表示させている方はtablemodelないしtabledataで本来は1回目で500に変えたので500が表示されるはず)。

該当のソースコード

java

1public class Hyouji_sample{ 2 public static void main(String[] args) { 3 MyFrameSample mainframe = new MyFrameSample("表示", 800, 600); 4 mainframe.setLocationRelativeTo(null); 5 mainframe.setVisible(true); 6 } 7} 8 9class MyFrameSample extends JFrame { 10 11 MyFrameSample(String title, int width, int height){ 12 setTitle(title); 13 setSize(width, height); 14 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 15 16 JTabbedPane tabbedpane = new JTabbedPane(); 17 18 Machine1 machine1 = new Machine1(); 19 Info info = new Info(); 20 21 tabbedpane.addTab("機械1", machine1); 22 tabbedpane.addTab("情報", info); 23 24 getContentPane().add(tabbedpane, BorderLayout.NORTH); 25 } 26} 27 28class Machine1 extends JPanel{ 29 Machine1(){ 30 JLabel label = new JLabel(); 31 LineBorder border = new LineBorder(Color.RED, 2, true); 32 33 label.setText("sanpuru"); 34 35 add(label); 36 setPreferredSize(new Dimension(720, 240)); 37 setBorder(border); 38 } 39 40} 41 42class Info extends JPanel implements MouseListener{ 43 private String[][] tabledata1 = { 44 {"機械1", "100", "ABC", "50"}, 45 {"機械2", "200", "FRE", "10"}, 46 }; 47 private String[] columnNames1 = {"", "ワット数", "油の種類", "油残量"}; 48 DefaultTableModel tableModel1 = new DefaultTableModel(tabledata1, columnNames1); 49 JTextField textfield = new JTextField(); 50 JTable table = new JTable(tableModel1); 51 52 public Info(){ 53 JScrollPane sp = new JScrollPane(table); 54 JPanel panel = new JPanel(); 55 JLabel label = new JLabel("テロップ内容"); 56 textfield.setText("残量確認のこと"); 57 textfield.addMouseListener(this); 58 table.addMouseListener(this); 59 panel.add(label); 60 panel.add(textfield); 61 sp.setPreferredSize(new Dimension(600, 200)); 62 add(sp, BorderLayout.NORTH); 63 add(panel, BorderLayout.SOUTH); 64 } 65 public void mouseClicked(MouseEvent e){ 66 if (e.getSource()==textfield) { 67 68 }else { 69 int i; 70 i = table.getSelectedRow(); 71 DetailHyouji frame = new DetailHyouji(i); 72 } 73 } 74 public void mouseEntered(MouseEvent e){ 75 } 76 public void mouseExited(MouseEvent e){ 77 } 78 public void mousePressed(MouseEvent e){ 79 } 80 public void mouseReleased(MouseEvent e){ 81 } 82 public void Renew(int row, int column, String str){ 83 System.out.println("before "+ tableModel1.getValueAt(row, column)); 84 System.out.println("before "+ tabledata1[row][column]); 85 tableModel1.setValueAt(str, row, column); 86 tabledata1[row][column] = str; 87 tableModel1.fireTableCellUpdated(row, column); 88 System.out.println("after "+ tableModel1.getValueAt(row, column)); 89 System.out.println("after "+ tabledata1[row][column]); 90 System.out.println(""); 91 } 92} 93 94class DetailHyouji { 95 public DetailHyouji(int i) { 96 DetailFrame mainframe = new DetailFrame("詳細入力", 300, 200, i); 97 mainframe.setLocationRelativeTo(null); 98 mainframe.setVisible(true); 99 } 100} 101 102class DetailFrame extends JFrame implements MouseListener{ 103 JButton ok = new JButton("OK"); 104 JButton cancel = new JButton("キャンセル"); 105 JTextField textfield_wat = new JTextField("100"); 106 JTextField textfield_syurui = new JTextField("ABC"); 107 JTextField textfield_zanryou = new JTextField("50"); 108 int j; 109 110 DetailFrame(String title, int width, int height, int i){ 111 j = i; 112 setTitle(title); 113 setSize(width, height); 114 setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 115 116 JPanel panel = new JPanel(); 117 JPanel panel2 = new JPanel(); 118 JLabel wat = new JLabel("ワット数"); 119 JLabel syurui = new JLabel("油の種類"); 120 JLabel zanryou = new JLabel("油残量"); 121 wat.setHorizontalAlignment(JLabel.CENTER); 122 syurui.setHorizontalAlignment(JLabel.CENTER); 123 zanryou.setHorizontalAlignment(JLabel.CENTER); 124 ok.addMouseListener(this); 125 cancel.addMouseListener(this); 126 127 panel.setLayout(new GridLayout(5, 2)); 128 panel.add(wat); 129 panel.add(textfield_wat); 130 panel.add(syurui); 131 panel.add(textfield_syurui); 132 panel.add(zanryou); 133 panel.add(textfield_zanryou); 134 135 panel2.add(ok); 136 panel2.add(cancel); 137 138 getContentPane().add(panel, BorderLayout.CENTER); 139 getContentPane().add(panel2, BorderLayout.SOUTH); 140 } 141 142 public void mouseClicked(MouseEvent e) { 143 Info info = new Info(); 144 if (e.getSource()==cancel) { 145 setVisible(false); 146 dispose(); 147 }else { 148 String str_wat = textfield_wat.getText(); 149 info.Renew(j, 1, str_wat); 150 String str_syurui = textfield_syurui.getText(); 151 info.Renew(j, 2, str_syurui); 152 String str_zanryou = textfield_zanryou.getText(); 153 info.Renew(j, 3, str_zanryou); 154 155 setVisible(false); 156 dispose(); 157 } 158 } 159 public void mouseEntered(MouseEvent e){ 160 } 161 public void mouseExited(MouseEvent e){ 162 } 163 public void mousePressed(MouseEvent e){ 164 } 165 public void mouseReleased(MouseEvent e){ 166 } 167}

試したこと

ここに問題に対して試したことを記載してください。

補足情報(FW/ツールのバージョンなど)

独学で学んでいることもありコードはスマートでないと思われるかもしれませんが、ご了承ください。

以下のような質問にはグッドを送りましょう

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

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

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

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

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

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

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

適切な質問に修正を依頼しましょう。

2022/03/06 11:56

こちらの質問が他のユーザーから「過去の低評価」という指摘を受けました。

回答2

0

スマートかどうかは分かりませんが、独学中とのことですので他人が書いたらどうなるかの比較になれば。
(全体の仕様が分からないのでテキトウな所もあります)

java

1package teratail_java.q_ma9cgl882hfegi; 2 3import java.awt.*; 4import java.awt.event.*; 5import java.util.*; 6import java.util.List; 7 8import javax.swing.*; 9import javax.swing.border.LineBorder; 10import javax.swing.table.AbstractTableModel; 11 12public class MachineFrame extends JFrame { 13 public static void main(String[] args) { 14 new MachineFrame().setVisible(true); 15 } 16 17 MachineFrame() { 18 super("表示"); 19 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 20 setSize(800, 600); 21 setLocationRelativeTo(null); 22 23 MachineModel model = new MachineModel(); 24 model.put(new Machine("機械1", 100, "ABC", 50)); //テストデータ1 25 model.put(new Machine("機械2", 200, "FRE", 10)); //テストデータ2 26 27 JTabbedPane tabbedPane = new JTabbedPane(); 28 for(int i=0; i<model.size(); i++) { 29 MachinePanel panel = new MachinePanel(model.get(i).name, model); 30 tabbedPane.addTab(panel.name, panel); 31 } 32 tabbedPane.addTab("情報", new InfoPanel(this, model)); 33 34 getContentPane().add(tabbedPane); 35 } 36} 37//"機械n"タブ 38class MachinePanel extends JPanel { 39 final String name; 40 private MachineModel model; 41 private JLabel label; 42 43 MachinePanel(String name, MachineModel model) { 44 super(); 45 setPreferredSize(new Dimension(720, 240)); 46 setBorder(new LineBorder(Color.RED, 2, true)); 47 48 this.name = name; 49 this.model = model; 50 51 model.addChangeListener((e) -> setLabels()); 52 53 label = new JLabel("sanpuru"); 54 add(label); 55 56 setLabels(); 57 } 58 59 private void setLabels() { 60 label.setText(""+model.get(name)); 61 } 62} 63//"情報"タブ 64class InfoPanel extends JPanel { 65 private interface RowClickListener { 66 void rowClicked(int rowIndex); 67 } 68 69 public InfoPanel(Frame frame, MachineModel model){ 70 super(); 71 72 InfoTableModel tableModel = new InfoTableModel(model); 73 JComponent tableComponent = createTablePanel(tableModel, (rowIndex) -> { 74 //行クリック 75 Machine machine = tableModel.get(rowIndex); 76 MachineDialog dialog = new MachineDialog(frame, machine, (m)->model.put(m)); 77 dialog.setLocationRelativeTo(null); 78 dialog.setVisible(true); 79 }); 80 add(tableComponent, BorderLayout.NORTH); 81 82 add(createSouthPanel(), BorderLayout.SOUTH); 83 } 84 85 private JComponent createTablePanel(InfoTableModel tableModel, RowClickListener listener) { 86 JTable table = new JTable(tableModel); 87 table.setRowSelectionAllowed(true); 88 table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 89 table.setColumnSelectionAllowed(false); 90 table.addMouseListener(new MouseAdapter() { 91 public void mouseClicked(MouseEvent e) { 92 int rowIndex = table.getSelectedRow(); 93 if(rowIndex >= 0) listener.rowClicked(rowIndex); 94 } 95 }); 96 97 JScrollPane scrollPane = new JScrollPane(table); 98 scrollPane.setPreferredSize(new Dimension(600, 200)); 99 return scrollPane; 100 } 101 102 private JPanel createSouthPanel() { 103 JPanel panel = new JPanel(); 104 panel.add(new JLabel("テロップ内容")); 105 106 JTextField textfield = new JTextField(); 107 textfield.setText("残量確認のこと"); 108 panel.add(textfield); 109 110 return panel; 111 } 112} 113//機械 114class Machine { 115 final String name; 116 final int output; //ワット 117 final String oilType; 118 final int oilAmount; 119 120 Machine(String name, int output, String oilType, int oilAmount) { 121 this.name = name; 122 this.output = output; 123 this.oilType = oilType; 124 this.oilAmount = oilAmount; 125 } 126 127 @Override 128 public String toString() { 129 return "name="+name+", output="+output+", oilType="+oilType+", oilAmount="+oilAmount; 130 } 131} 132//機械モデル 133class MachineModel { 134 interface DataChangeListener extends EventListener { 135 public void dataChanged(DataChangeEvent e); 136 } 137 138 static class DataChangeEvent extends EventObject { 139 public DataChangeEvent(Object source) { 140 super(source); 141 } 142 } 143 144 private List<Machine> machineList = new ArrayList<>(); 145 private final Set<DataChangeListener> listenerList = new HashSet<>(); 146 147 int size() { 148 return machineList.size(); 149 } 150 151 Machine get(int index) { 152 return machineList.get(index); 153 } 154 155 Machine get(String name) { 156 for(Machine m : machineList) if(m.name.equals(name)) return m; 157 return null; 158 } 159 160 public void put(Machine machine) { 161 for(int i=0; i<machineList.size(); i++) { 162 if(machineList.get(i).name.equals(machine.name)) { 163 machineList.set(i, machine); 164 fireDataChangeEvent(); 165 return; 166 } 167 } 168 machineList.add(machine); 169 fireDataChangeEvent(); 170 } 171 172 synchronized void addChangeListener(DataChangeListener l) { 173 if(!listenerList.contains(l)) { 174 listenerList.add(l); 175 } 176 } 177 178 synchronized void removeChangeListener(DataChangeListener l) { 179 listenerList.remove(l); 180 } 181 182 synchronized protected void fireDataChangeEvent() { 183 DataChangeEvent evt = new DataChangeEvent(this); 184 for(DataChangeListener listener : listenerList) listener.dataChanged(evt); 185 } 186} 187//機械情報テーブルモデル 188class InfoTableModel extends AbstractTableModel { 189 private static final String[] COLUMN_NAMES = {"", "ワット数", "油の種類", "油残量"}; 190 191 private MachineModel model; 192 193 InfoTableModel(MachineModel model) { 194 this.model = model; 195 model.addChangeListener((e) -> fireTableDataChanged()); 196 } 197 198 Machine get(int index) { 199 return model.get(index); 200 } 201 202 @Override 203 public String getColumnName(int columnIndex) { 204 return COLUMN_NAMES[columnIndex]; 205 } 206 207 @Override 208 public Class<?> getColumnClass(int columnIndex) { 209 if(columnIndex == 1 || columnIndex == 3) return Integer.class; 210 return String.class; 211 } 212 213 @Override 214 public int getRowCount() { 215 return model.size(); 216 } 217 218 @Override 219 public int getColumnCount() { 220 return 4; 221 } 222 223 @Override 224 public Object getValueAt(int rowIndex, int columnIndex) { 225 Machine machine = model.get(rowIndex); 226 switch(columnIndex) { 227 case 0: return machine.name; 228 case 1: return machine.output; 229 case 2: return machine.oilType; 230 case 3: return machine.oilAmount; 231 } 232 return null; 233 } 234} 235//機械情報入力ダイアログ 236class MachineDialog extends JDialog { 237 interface MachineManager { 238 void put(Machine machine); 239 } 240 241 MachineDialog(Frame frame, Machine machine, MachineManager manager) { 242 super(frame, "詳細入力", true); 243 setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE); 244 setSize(300, 200); 245 246 JPanel inputPanel = new JPanel(new GridLayout(5, 2)); 247 appendLabelAndTextField(inputPanel, "名称", ""+machine.name, false); 248 JTextField outputText = appendLabelAndTextField(inputPanel, "ワット数", ""+machine.output); 249 JTextField oilTypeText = appendLabelAndTextField(inputPanel, "油の種類", machine.oilType); 250 JTextField oilAmountText = appendLabelAndTextField(inputPanel, "油残量", ""+machine.oilAmount); 251 getContentPane().add(inputPanel, BorderLayout.CENTER); 252 253 ActionListener okActionListener = new ActionListener() { 254 @Override 255 public void actionPerformed(ActionEvent ae) { 256 try { 257 int output = Integer.parseInt(outputText.getText()); 258 String oilType = oilTypeText.getText(); 259 int oilAmount = Integer.parseInt(oilAmountText.getText()); 260 manager.put(new Machine(machine.name, output, oilType, oilAmount)); 261 262 dispose(); 263 } catch(NumberFormatException e) { 264 JOptionPane.showMessageDialog(frame, "数値に変換できません", "エラー", JOptionPane.ERROR_MESSAGE); 265 } 266 } 267 }; 268 getContentPane().add(createButtonPanel(okActionListener), BorderLayout.SOUTH); 269 } 270 271 private JTextField appendLabelAndTextField(JPanel panel, String text, String value) { 272 return appendLabelAndTextField(panel, text, value, true); 273 } 274 private JTextField appendLabelAndTextField(JPanel panel, String labelText, String initValue, boolean editable) { 275 JLabel label = new JLabel(labelText); 276 label.setHorizontalAlignment(JLabel.CENTER); 277 panel.add(label); 278 279 JTextField textfield = new JTextField(initValue); 280 textfield.setEditable(editable); 281 panel.add(textfield); 282 283 return textfield; 284 } 285 286 private JPanel createButtonPanel(ActionListener okActionListener) { 287 JPanel panel = new JPanel(); 288 289 JButton okButton = new JButton("OK"); 290 okButton.addActionListener(okActionListener); 291 panel.add(okButton); 292 293 JButton cancelButton = new JButton("キャンセル"); 294 cancelButton.addActionListener(new ActionListener() { 295 @Override 296 public void actionPerformed(ActionEvent e) { 297 dispose(); 298 } 299 }); 300 panel.add(cancelButton); 301 302 return panel; 303 } 304}

投稿2022/02/04 17:15

編集2022/02/05 06:25
jimbe

総合スコア10755

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

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

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

このような回答には修正を依頼しましょう。

0

直接の原因はInfo info = new Info();が2か所にあるためです。
それぞれのinfoは全く別のインスタンスですので、2個目のinfoをいくらいじっても1個目のinfoには何もおきません。

JTableは標準で編集機能(セルをダブルクリック)がありますが、別ウィンドウで編集はマストでしょうか?(特定の列だけ編集不可とかのほうがはるかに楽ですが)


以下本題以外で気になったところ

  • JButtonには通常ActionListenerを使用します(MouseListenerは使いません)
  • こういった(詳細入力のような)ウィンドウは通常モーダルで出します(JDialog
    現状詳細入力ウィンドウはモードレスなので、何個も出せてしまいます。

追記

例えば油の種類は普通決められているのでラジオボタンなどで選択式にして変更できるようにと考えています。

JTableでコンボボックスも使えます(が、マストのことですので今回はスルーで結構です^^;
How to Use Tables (The Java™ Tutorials > Creating a GUI With Swing > Using Swing Components)

駅のホーム天井からぶら下がってるのりば案内とかのディスプレイが機械1のタブ、情報タブは時刻表のように情報の格納場所というイメージです

わかるような、わからないような?^^;
情報は一覧用途で、主に個別タブを見るって感じなんですかね?

タブ(=TableModelの行)は動的に増減するんでしょうか?(つまり「機械追加」ボタンのようなものがあるのかどうか)

そのため表の値を変更したときにイベントを発生させてラベルの値を変えてあげる必要があります

まあいろいろなアプローチがあるとは思いますが、TableModelListenerを使えば値の変更は検知できます。
How to Use Tables (The Java™ Tutorials > Creating a GUI With Swing > Using Swing Components)

結局すべてのデータはTableModelが持っているわけですから、それを渡せばいいんじゃないですかね?

パネル(ウィンドウ)間であれこれちょっかいを出そうとすると、コードがすぐスパゲッティ化します。
相互に依存したりせず、できるだけシンプルなつくりにするように心がけましょう。

Java

1import javax.swing.JButton; 2import javax.swing.JComboBox; 3import javax.swing.JDialog; 4import javax.swing.JFrame; 5import javax.swing.JLabel; 6import javax.swing.JPanel; 7import javax.swing.JScrollPane; 8import javax.swing.JSpinner; 9import javax.swing.JTabbedPane; 10import javax.swing.JTable; 11import javax.swing.SpinnerNumberModel; 12import javax.swing.SwingUtilities; 13import javax.swing.event.TableModelEvent; 14import javax.swing.event.TableModelListener; 15import javax.swing.table.DefaultTableModel; 16import javax.swing.table.TableModel; 17import java.awt.BorderLayout; 18import java.awt.GridLayout; 19import java.awt.event.ActionEvent; 20import java.awt.event.ActionListener; 21import java.awt.event.MouseEvent; 22import java.awt.event.MouseListener; 23 24 25public class MyFrame extends JFrame { 26 public static void main(String[] args) { 27 new MyFrame().setVisible(true); 28 } 29 30 private final DefaultTableModel tableModel; 31 32 MyFrame() { 33 setSize(800, 600); 34 setLocationRelativeTo(null); 35 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 36 37 var tabbedPane = new JTabbedPane(); 38 39 // csvファイルかなんかで読み込むテイで 40 var csv = ",ワット数,油の種類,油残量\n" + 41 "機械1,100,ABC,50\n" + 42 "機械2,200,FRE,10"; 43 var lines = csv.split("\n"); 44 tableModel = new DefaultTableModel(lines[0].split(","), 0); 45 46 for (var i = 1; i < lines.length; i++) { 47 var row = lines[i].split(","); 48 tableModel.addRow(row); 49 50 var machine = new MachinePanel(tableModel, i - 1); 51 tabbedPane.addTab(row[0], machine); 52 } 53 54 tabbedPane.addTab("情報", new InfoPanel(tableModel)); 55 add(tabbedPane); 56 } 57} 58 59class MachinePanel extends JPanel implements TableModelListener { 60 private final TableModel tableModel; 61 private final int row; 62 63 private final JLabel watLabel; 64 private final JLabel oilTypeLabel; 65 private final JLabel oilLevelLabel; 66 67 MachinePanel(TableModel tableModel, int row) { 68 setLayout(new BorderLayout()); 69 this.tableModel = tableModel; 70 tableModel.addTableModelListener(this); 71 this.row = row; 72 73 var panel = new JPanel(new GridLayout(3, 2)); 74 panel.add(new JLabel("ワット数", JLabel.CENTER)); 75 watLabel = new JLabel(); 76 panel.add(watLabel); 77 78 panel.add(new JLabel("油の種類", JLabel.CENTER)); 79 oilTypeLabel = new JLabel(); 80 panel.add(oilTypeLabel); 81 82 panel.add(new JLabel("油残量", JLabel.CENTER)); 83 oilLevelLabel = new JLabel(); 84 panel.add(oilLevelLabel); 85 add(panel, BorderLayout.NORTH); 86 87 tableChanged(null); // 雑いw 88 } 89 90 @Override public void tableChanged(TableModelEvent e) { 91 // 本来はいろいろ情報が来るが、面倒なのでノーチェック&全更新^^; 92 var wat = (String) tableModel.getValueAt(row, 1); 93 var oilType = (String) tableModel.getValueAt(row, 2); 94 var oilLevel = (String) tableModel.getValueAt(row, 3); 95 96 watLabel.setText(wat); 97 oilTypeLabel.setText(oilType); 98 oilLevelLabel.setText(oilLevel); 99 } 100} 101 102class InfoPanel extends JPanel implements MouseListener { 103 private final DefaultTableModel tableModel; 104 105 private final JTable table; 106 107 public InfoPanel(DefaultTableModel tableModel) { 108 setLayout(new BorderLayout()); 109 this.tableModel = tableModel; 110 111 table = new JTable(tableModel); 112 table.addMouseListener(this); 113 add(new JScrollPane(table)); 114 } 115 116 @Override public void mouseClicked(MouseEvent e) { 117 var frame = (JFrame) SwingUtilities.getWindowAncestor(this); 118 var row = table.getSelectedRow(); 119 120 // モーダルなので閉じるまで帰ってこない 121 new DetailEditDialog(frame, tableModel, row).setVisible(true); 122 123 printTable(); 124 } 125 126 @Override public void mouseEntered(MouseEvent e) {} 127 128 @Override public void mouseExited(MouseEvent e) {} 129 130 @Override public void mousePressed(MouseEvent e) {} 131 132 @Override public void mouseReleased(MouseEvent e) {} 133 134 private void printTable() { 135 for (var row = 0; row < tableModel.getRowCount(); row++) { 136 for (var col = 0; col < tableModel.getColumnCount(); col++) { 137 var s = (String) (tableModel.getValueAt(row, col)); 138 System.out.print(s + "\t"); 139 } 140 System.out.println(); 141 } 142 System.out.println(); 143 } 144} 145 146class DetailEditDialog extends JDialog implements ActionListener { 147 private final DefaultTableModel tableModel; 148 private final int row; 149 150 private final JButton okButton = new JButton("OK"); 151 private final JSpinner watSpinner; 152 private final JComboBox<String> oilTypeComboBox; 153 private final JSpinner oilLevelSpinner; 154 155 DetailEditDialog(JFrame owner, DefaultTableModel tableModel, int row) { 156 super(owner, "詳細入力 - " + tableModel.getValueAt(row, 0), true); 157 setSize(300, 200); 158 setLocationRelativeTo(owner); 159 160 this.tableModel = tableModel; 161 this.row = row; 162 var wat = Integer.parseInt((String) tableModel.getValueAt(row, 1)); 163 var oilType = (String) tableModel.getValueAt(row, 2); 164 var oilLevel = Integer.parseInt((String) tableModel.getValueAt(row, 3)); 165 166 var panel = new JPanel(new GridLayout(3, 2)); 167 panel.add(new JLabel("ワット数", JLabel.CENTER)); 168 watSpinner = new JSpinner(new SpinnerNumberModel(wat, 0, 1000, 1)); 169 panel.add(watSpinner); 170 171 panel.add(new JLabel("油の種類", JLabel.CENTER)); 172 oilTypeComboBox = new JComboBox<>(new String[]{"ABC", "FRE", "XYZ"}); 173 oilTypeComboBox.setSelectedItem(oilType); 174 panel.add(oilTypeComboBox); 175 176 panel.add(new JLabel("油残量", JLabel.CENTER)); 177 oilLevelSpinner = new JSpinner(new SpinnerNumberModel(oilLevel, 0, 100, 1)); 178 panel.add(oilLevelSpinner); 179 add(panel, BorderLayout.NORTH); 180 181 var panel2 = new JPanel(); 182 okButton.addActionListener(this); 183 var cancel = new JButton("キャンセル"); 184 cancel.addActionListener(this); 185 panel2.add(okButton); 186 panel2.add(cancel); 187 add(panel2, BorderLayout.SOUTH); 188 } 189 190 @Override public void actionPerformed(ActionEvent e) { 191 if (e.getSource() == okButton) { 192 // 面倒なので文字列に戻したが、jimbeさんの回答のように専用のTableModelを作ったほうがいいんでしょうね 193 tableModel.setValueAt(String.valueOf(watSpinner.getValue()), row, 1); 194 tableModel.setValueAt(oilTypeComboBox.getSelectedItem(), row, 2); 195 tableModel.setValueAt(String.valueOf(oilLevelSpinner.getValue()), row, 3); 196 } 197 dispose(); 198 } 199}
  • エラーチェック全くなし
  • 動的な追加削除は無考慮

追加はいいとしても、削除はremoveTableModelListenerrowの振り直し等必要になりますね。

投稿2022/02/04 14:21

編集2022/02/04 21:36
TN8001

総合スコア8046

良いと思った回答にはグッドを送りましょう。
グッドが多くついた回答ほどページの上位に表示されるので、他の人が素晴らしい回答を見つけやすくなります。

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

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

このような回答には修正を依頼しましょう。

回答へのコメント

suteaka

2022/02/04 16:56

回答ありがとうございます。 "それぞれのinfoは全く別のインスタンスですので、2個目のinfoをいくらいじっても1個目のinfoには何もおきません。" 納得しました。確かに別物になっているので変化しないのは当然ですね。 "JTableは標準で編集機能(セルをダブルクリック)がありますが、別ウィンドウで編集はマストでしょうか?(特定の列だけ編集不可とかのほうがはるかに楽ですが)" 別ウィンドウでの編集をマストにしたいと考えています。まだ実装していませんが、例えば油の種類は普通決められているのでラジオボタンなどで選択式にして変更できるようにと考えています。ただ選択肢がすべて見える状態は見づらいですし、実際には列数ももう少し増える予定なのでスクロールしたりしなくて済むよう別ウィンドウで表示させたいです。(JDialogの存在を知りませんでした。こちらを利用してウィンドウを出したいと思います。) 加えて、今回の質問とは別事項なので省略していましたが、表の値はタブ「機械1」の方でラベルなどを使って表示させたいと思っています(駅のホーム天井からぶら下がってるのりば案内とかのディスプレイが機械1のタブ、情報タブは時刻表のように情報の格納場所というイメージです)。そのため表の値を変更したときにイベントを発生させてラベルの値を変えてあげる必要がありますが、Tableに対するイベントは無いようでしたので、別ウィンドウで表示させてOKボタンに対してイベントを行えば対応できると考えました。 この方法だと必然的にワット数、種類、残量の3つの値をInfoクラスへ渡してあげる必要が出てきますが、3つの値をreturnで返すことはできないですし、どのようにして値をInfoクラスへ渡せばよいのでしょうか。
TN8001

2022/02/04 21:38

回答に追記しました。 teratailの不具合で全然通知が来ないですね^^;

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
86.12%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問

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

JTable

JTableとは二次元的なセルの表を表示し編集するJava Swing用のコンポーネントです。

Java

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