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

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

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

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

JFrame

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

JTable

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

Java

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

Q&A

解決済

2回答

907閲覧

DefaultTableModelのremoveRow()メソッドに関して

magmag123

総合スコア15

JavaFX

JavaFXとは、Java仮想マシン上で動作するリッチインターネットアプリケーション (RIA) のGUIライブラリです。Swingとは異なり、FXMLと呼ばれる XMLとCSSを併用してデザインを記述します。

JFrame

JFrameはJFC/Swingフレームワークのコンポーネントであり、トップレベルのコンテナです。

JTable

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

Java

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

0グッド

0クリップ

投稿2023/05/20 16:59

実現したいこと

  • JTableに表示されている表から行を選択して削除したい

前提

ここに質問の内容を詳しく書いてください。
Jframeでテーブルを表示させて操作させる簡単なシステムを作っています。
テーブルに表示されている行を選択して、ボタンを押下することで選択行が削除される
機能を搭載しているのですが、「java.lang.ArrayIndexOutOfBoundsException:」が発生しました。

テーブルの行数と選択行がうまく「removeRow()」に送られていないのでしょうか?

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

【エラーメッセージ】 Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfBoundsException: 2 >= 0 at java.base/java.util.Vector.removeElementAt(Vector.java:549) at java.desktop/javax.swing.table.DefaultTableModel.removeRow(DefaultTableModel.java:469) at practice.no14.ListPractice.actionPerformed(ListPractice.java:163) at java.desktop/javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:1972) at java.desktop/javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2313) at java.desktop/javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:405) at java.desktop/javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:262) at java.desktop/javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:279) at java.desktop/java.awt.Component.processMouseEvent(Component.java:6620) at java.desktop/javax.swing.JComponent.processMouseEvent(JComponent.java:3398) at java.desktop/java.awt.Component.processEvent(Component.java:6385) at java.desktop/java.awt.Container.processEvent(Container.java:2266) at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4995) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2324) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4827) at java.desktop/java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4948) at java.desktop/java.awt.LightweightDispatcher.processMouseEvent(Container.java:4575) at java.desktop/java.awt.LightweightDispatcher.dispatchEvent(Container.java:4516) at java.desktop/java.awt.Container.dispatchEventImpl(Container.java:2310) at java.desktop/java.awt.Window.dispatchEventImpl(Window.java:2780) at java.desktop/java.awt.Component.dispatchEvent(Component.java:4827) at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720) at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747) at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745) at java.base/java.security.AccessController.doPrivileged(AccessController.java:399) at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86) at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744) at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203) at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124) at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109) at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101) at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90) ### 該当のソースコード ```ここに言語名を入力 【ソースコード】 public class ListPractice extends JFrame implements ActionListener { final JTable table; final TableModel tableModel = new TableModel(); final TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(tableModel); final JTextField filterText = new JTextField(); final DefaultTableModel model = new DefaultTableModel(); ListPractice() { // フレームのセットアップ setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // 画面サイズの決定 setSize(400, 300); // 画面位置の設定(null指定で画面中央) setLocationRelativeTo(null); table = new JTable(model); ListSelectionModel lsModel = table.getSelectionModel(); lsModel.addListSelectionListener(new ListSelectionListener() { @Override public void valueChanged(ListSelectionEvent e) { // TODO 自動生成されたメソッド・スタブ if (e.getValueIsAdjusting()) { return; } ListSelectionModel lsm = (ListSelectionModel) e.getSource(); } }); // フィルターパネル JPanel filterPanel = new JPanel(); // 横レイアウトを指定(X_AXIS) BoxLayout boxLayout = new BoxLayout(filterPanel, BoxLayout.X_AXIS); filterPanel.setLayout(boxLayout); JLabel filterLabel = new JLabel("検索"); filterPanel.add(filterLabel); // 検索処理 filterText.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { // TODO 自動生成されたメソッド・スタブ RowFilter<TableModel, Object> filter = null; try { filter = RowFilter.regexFilter(filterText.getText(), 0); } catch (Exception ex) { // TODO: handle exception } sorter.setRowFilter(filter); } }); filterLabel.setLabelFor(filterText); filterPanel.add(filterText); add(filterPanel,BorderLayout.NORTH); // フィルターパネル JPanel filterPanel2 = new JPanel(); // 縦レイアウトを指定(Y_AXIS) BoxLayout boxLayout2 = new BoxLayout(filterPanel2, BoxLayout.Y_AXIS); filterPanel2.setLayout(boxLayout2); // 削除ボタン作成 JButton Rbutton = new JButton("削除"); Rbutton.setAlignmentX(RIGHT_ALIGNMENT); //Rbutton.addActionListener(new ClickAction()); // filterPanel2にボタンを登録 filterPanel2.add(Rbutton); // 削除処理 Rbutton.setActionCommand("DELETE"); Rbutton.addActionListener(this); // テーブルの設定 table.setRowSorter(sorter); table.setModel(tableModel); add(filterPanel2,BorderLayout.CENTER); TableColumn col = table.getColumnModel().getColumn(0); JScrollPane sp = new JScrollPane(table); filterPanel2.add(sp); //getContentPane().add(sp, BorderLayout.CENTER); getContentPane().add(filterPanel, BorderLayout.NORTH); getContentPane().add(filterPanel2, BorderLayout.CENTER); } public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // TODO 自動生成されたメソッド・スタブ ListPractice app = new ListPractice(); app.setVisible(true); } }); } ** @Override public void actionPerformed(ActionEvent e) { // TODO 自動生成されたメソッド・スタブ String command = (String) e.getActionCommand(); // 削除ボタンが押下された時の処理 if ("DELETE".equals(command)) { ListSelectionModel lsModel = table.getSelectionModel(); for (int i=0; i< table.getRowCount(); i++) { if (lsModel.isSelectedIndex(i)) { model.removeRow(i); } } table.repaint(); } }** } 【ソースコード】 public class TableModel extends AbstractTableModel implements Serializable { Object[][] data = { {"田中", "大阪", true}, {"長谷川", "東京", false}, {"藤原", "奈良", false}, {"橋本", "和歌山", false}, {"山田", "北海道", false} }; String[] columns = {"名前", "出身", "選択"}; @Override public Class<?> getColumnClass(int columnIndex) { return data[0][columnIndex].getClass(); } // データのカラム数を返す @Override public int getColumnCount() { // TODO 自動生成されたメソッド・スタブ return columns.length; } // データの行数を返す @Override public int getRowCount() { // TODO 自動生成されたメソッド・スタブ return data.length; } // カラム名をStringで返す @Override public String getColumnName(int column) { // TODO 自動生成されたメソッド・スタブ return columns[column]; } @Override public Object getValueAt(int rowIndex, int columnIndex) { // TODO 自動生成されたメソッド・スタブ return data[rowIndex][columnIndex]; } // セルの編集に関するメソッド @Override public boolean isCellEditable(int rowIndex, int columnIndex) { // TODO 自動生成されたメソッド・スタブ // 編集可能なセルの設定 if(columnIndex == 2) { return true; } else { return false; } } @Override public void setValueAt(Object aValue, int rowIndex, int columnIndex) { // TODO 自動生成されたメソッド・スタブ data[rowIndex][columnIndex] = aValue; fireTableCellUpdated(rowIndex, columnIndex); } public static void main(String[] args) { // TODO 自動生成されたメソッド・スタブ } } ### 補足情報(FW/ツールのバージョンなど) 参考にしたサイト http://asistobe851.web.fc2.com/my-memo/RowManagement.html 初学者のため無駄なコードがあると思いますが、ご容赦ください。

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

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

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

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

jimbe

2023/05/20 18:35 編集

エラーメッセージやコードはファイル毎等別々のマークダウンとし、コード以外の説明等はコードのマークダウンの外に出してください。コードのマークダウンは最小化/最大化が出来、通常は最小状態で表示されますので、パっと見で説明があるのが分かりません。 コードのマークダウン内では修飾等は使えません。 また、javafx は swing とは無関係ですので、タグには入れないでください。
guest

回答2

0

ベストアンサー

テーブルの行数と選択行がうまく「removeRow()」に送られていないのでしょうか?

いいえ。TableModel tableModelと、DefaultTableModel modelがごっちゃになっています。

tableModelにはデータがありますが、modelはカラです。
そのためmodel.removeRow(i);が範囲外となります。

tableModel.removeRow(i);としたいところですが、AbstractTableModelにはremoveRowがありませんし自前実装も面倒です。
DefaultTableModelから派生したほうが楽でしょう(既にTableModelインターフェースがあるので、TableModelクラスでなくMyTableModel等がいいです)
TableModel (Java Platform SE 8 )

参考にしたサイト
http://asistobe851.web.fc2.com/my-memo/RowManagement.html

複数行選択や並び替えに未対応です。

JTableに表示されている表から行を選択して削除したい
テーブルに表示されている行を選択して、ボタンを押下することで選択行が削除される機能

JTableの選択した行でしょうか?
選択カラムにチェックが入った行でしょうか?

チェック行ならjimbeさんの回答通り、逆順に回せばいいですね。

選択行の場合は、並び替えを考慮する必要があります。
How do you remove selected rows from a JTable? - Stack Overflow

はっきり言ってかなり混乱が見られますが、こちらの手元(Java17)では当該質問コードでおかしい状況を再現できませんでした(回答コードも本質的には同じはず)
もしかしたら何かバグがあって、どこかの時点で改善されたのかもしれません??

Java

1import javax.swing.*; 2import javax.swing.table.DefaultTableModel; 3import javax.swing.table.TableRowSorter; 4import java.awt.BorderLayout; 5import java.awt.event.ActionEvent; 6import java.awt.event.ActionListener; 7 8 9public class ListPractice extends JFrame implements ActionListener { 10 public static void main(String[] args) { 11 SwingUtilities.invokeLater(() -> new ListPractice().setVisible(true)); 12 } 13 14 final JTable table; 15 final DefaultTableModel model; 16 final TableRowSorter<DefaultTableModel> sorter; 17 final JTextField filterText = new JTextField(); 18 19 ListPractice() { 20 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 21 setSize(400, 300); 22 setLocationRelativeTo(null); 23 24 25 Object[][] data = { 26 { "田中", "大阪", true, }, 27 { "長谷川", "東京", false, }, 28 { "藤原", "奈良", false, }, 29 { "橋本", "和歌山", false, }, 30 { "山田", "北海道", false, }, 31 }; 32 String[] columns = { "名前", "出身", "選択", }; 33 34 // 匿名(無名)クラス(別にMyTableModelクラスを作ってもいいのだが^^; 35 model = new DefaultTableModel(data, columns) { 36 @Override public Class<?> getColumnClass(int columnIndex) { 37 return getValueAt(0, columnIndex).getClass(); 38 } 39 40 @Override public boolean isCellEditable(int rowIndex, int columnIndex) { 41 return columnIndex == 2; 42 } 43 }; 44 45 sorter = new TableRowSorter<>(model); 46 47 table = new JTable(model); 48 table.setRowSorter(sorter); 49 50 var filterPanel = Box.createHorizontalBox(); 51 52 var filterLabel = new JLabel("検索"); 53 filterLabel.setLabelFor(filterText); 54 filterPanel.add(filterLabel); 55 56 filterText.addActionListener(e -> { 57 var filter = RowFilter.regexFilter(filterText.getText(), 0); 58 sorter.setRowFilter(filter); 59 }); 60 filterPanel.add(filterText); 61 62 add(filterPanel, BorderLayout.NORTH); 63 64 65 var mainPanel = Box.createVerticalBox(); 66 67 var deleteButton = new JButton("削除"); 68 deleteButton.setAlignmentX(RIGHT_ALIGNMENT); 69 deleteButton.setActionCommand("DELETE"); 70 deleteButton.addActionListener(this); 71 mainPanel.add(deleteButton); 72 73 mainPanel.add(new JScrollPane(table)); 74 75 add(mainPanel, BorderLayout.CENTER); 76 } 77 78 @Override public void actionPerformed(ActionEvent e) { 79 var command = e.getActionCommand(); 80 if ("DELETE".equals(command)) { 81 82// これではおかしい 83// ListSelectionModel lsModel = table.getSelectionModel(); 84// for (int i = 0; i < table.getRowCount(); i++) { 85// if (lsModel.isSelectedIndex(i)) { 86// model.removeRow(i); 87// } 88// } 89 90 // こちらの手元ではコレで動いているが... 91 while (table.getSelectedRow() != -1) { 92 model.removeRow(table.convertRowIndexToModel(table.getSelectedRow())); 93 } 94 } 95 } 96}

投稿2023/05/20 22:06

TN8001

総合スコア9441

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

テーブルの行数と選択行がうまく「removeRow()」に送られていないのでしょうか

そもそも削除対象のモデルが違います。
ご自身で作成された TableModel から削除しなければならないのに、中身のない DefaultTableModel から作った model から削除しようとしています。

また、"選択"列と SelectionModel は関係ありません。
選択列の値によって処理を行うのであれば、そのようなコードを書く必要があります。

クラス名を変更、モデルを内部に取り込み、パネルをクラス化、ActionListener は無名クラスにしています。
モデルのデータを配列から(削除し易いように)リスト化、行削除メソッド(removeRow)を作成、 ControllPanel の削除ボタンを押すとリストの最後から順に選択状態を調べてモデルの行削除メソッドを呼びます。

java

1import java.awt.BorderLayout; 2import java.awt.event.ActionEvent; 3import java.awt.event.ActionListener; 4import java.util.*; 5 6import javax.swing.*; 7import javax.swing.table.AbstractTableModel; 8import javax.swing.table.TableRowSorter; 9 10public class TableFrame extends JFrame { 11 public static void main(String[] args) { 12 SwingUtilities.invokeLater(new Runnable() { 13 @Override 14 public void run() { 15 new TableFrame().setVisible(true); 16 } 17 }); 18 } 19 20 TableFrame() { 21 super("TableFrame"); 22 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 23 setSize(400, 300); 24 setLocationRelativeTo(null); 25 26 LocalTableModel model = new LocalTableModel(); 27 28 JTable table = new JTable(model); 29 add(new JScrollPane(table), BorderLayout.CENTER); 30 31 TableRowSorter<?> sorter = new TableRowSorter<LocalTableModel>(model); 32 table.setRowSorter(sorter); 33 FilterPanel filterPanel = new FilterPanel(sorter); 34 35 ControllPanel controllPanel = new ControllPanel(model); 36 37 JPanel northPanel = new JPanel(null); 38 northPanel.setLayout(new BoxLayout(northPanel, BoxLayout.Y_AXIS)); 39 northPanel.add(filterPanel); 40 northPanel.add(controllPanel); 41 add(northPanel, BorderLayout.NORTH); 42 } 43 44 /** モデル */ 45 private static class LocalTableModel extends AbstractTableModel { 46 private static final String[] columns = {"名前", "出身", "選択"}; 47 48 private static class Data { 49 String name, birthplace; 50 boolean select; 51 52 Data(String name, String birthplace, boolean select) { 53 this.name = name; 54 this.birthplace = birthplace; 55 this.select = select; 56 } 57 } 58 59 private List<Data> dataList = new ArrayList<>(Arrays.asList( 60 new Data("田中", "大阪", true), 61 new Data("長谷川", "東京", false), 62 new Data("藤原", "奈良", false), 63 new Data("橋本", "和歌山", false), 64 new Data("山田", "北海道", false) 65 )); 66 67 @Override 68 public Class<?> getColumnClass(int columnIndex) { 69 return columnIndex == 2 ? Boolean.class : String.class; 70 } 71 72 @Override 73 public int getColumnCount() { 74 return columns.length; 75 } 76 77 @Override 78 public int getRowCount() { 79 return dataList.size(); 80 } 81 82 @Override 83 public String getColumnName(int column) { 84 return columns[column]; 85 } 86 87 @Override 88 public Object getValueAt(int rowIndex, int columnIndex) { 89 Data data = dataList.get(rowIndex); 90 switch(columnIndex) { 91 case 0: return data.name; 92 case 1: return data.birthplace; 93 case 2: return data.select; 94 } 95 return null; 96 } 97 98 @Override 99 public boolean isCellEditable(int rowIndex, int columnIndex) { 100 return columnIndex == 2; // 編集可能なセルの設定 101 } 102 103 @Override 104 public void setValueAt(Object aValue, int rowIndex, int columnIndex) { 105 if(columnIndex != 2) return; 106 dataList.get(rowIndex).select = (boolean)aValue; 107 fireTableCellUpdated(rowIndex, columnIndex); 108 } 109 110 //削除 111 void removeRow(int rowIndex) { 112 dataList.remove(rowIndex); 113 fireTableRowsDeleted(rowIndex, rowIndex); 114 } 115 } 116 117 /** フィルターパネル */ 118 private static class FilterPanel extends JPanel { 119 FilterPanel(TableRowSorter<?> sorter) { 120 super(null); 121 setLayout(new BoxLayout(this, BoxLayout.X_AXIS)); 122 123 JLabel filterLabel = new JLabel("検索"); 124 add(filterLabel); 125 126 JTextField filterText = new JTextField(); 127 filterText.addActionListener(new ActionListener() { 128 @Override 129 public void actionPerformed(ActionEvent e) { 130 sorter.setRowFilter(RowFilter.regexFilter(filterText.getText(), 0)); 131 } 132 }); 133 add(filterText); 134 135 filterLabel.setLabelFor(filterText); 136 } 137 } 138 139 /** コントロールパネル */ 140 private static class ControllPanel extends JPanel { 141 ControllPanel(LocalTableModel model) { 142 super(null); 143 setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 144 145 //削除ボタン 146 JButton deleteButton = new JButton("削除"); 147 deleteButton.setAlignmentX(RIGHT_ALIGNMENT); 148 deleteButton.addActionListener(new ActionListener() { 149 @Override 150 public void actionPerformed(ActionEvent e) { 151 for(int i=model.getRowCount()-1; i>=0; i--) { //先頭からやると削除時に後続のインデックスがズレてくるので、最期からやる 152 if((boolean)model.getValueAt(i, 2)) { //選択 153 model.removeRow(i); 154 } 155 } 156 } 157 }); 158 add(deleteButton); 159 } 160 } 161}

投稿2023/05/20 18:56

編集2023/05/20 19:50
jimbe

総合スコア12834

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.44%

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

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

質問する

関連した質問