1 | package com.jsql.view.swing.table; | |
2 | ||
3 | import javax.swing.*; | |
4 | import javax.swing.event.ChangeEvent; | |
5 | import javax.swing.event.ChangeListener; | |
6 | import javax.swing.table.DefaultTableModel; | |
7 | import javax.swing.table.TableColumn; | |
8 | import javax.swing.table.TableColumnModel; | |
9 | import java.beans.PropertyChangeEvent; | |
10 | import java.beans.PropertyChangeListener; | |
11 | ||
12 | /** | |
13 | * Prevent the specified number of columns from scrolling horizontally in | |
14 | * the scroll pane. The table must already exist in the scroll pane. | |
15 | * | |
16 | * The functionality is accomplished by creating a second JTable (fixed) | |
17 | * that will share the TableModel and SelectionModel of the main table. | |
18 | * This table will be used as the row header of the scroll pane. | |
19 | * | |
20 | * The fixed table created can be accessed by using the getFixedTable() | |
21 | * method. will be returned from this method. It will allow you to: | |
22 | * | |
23 | * You can change the model of the main table and the change will be | |
24 | * reflected in the fixed model. However, you cannot change the structure | |
25 | * of the model. | |
26 | */ | |
27 | public class FixedColumnTable implements ChangeListener, PropertyChangeListener { | |
28 | | |
29 | private JTable mainTable; | |
30 | | |
31 | private JTable fixedTable; | |
32 | | |
33 | private JScrollPane scrollPane; | |
34 | ||
35 | /** | |
36 | * Specify the number of columns to be fixed and the scroll pane | |
37 | * containing the table. | |
38 | */ | |
39 | public void fixColumnSize(int fixedColumns, JScrollPane scrollPane) { | |
40 | this.scrollPane = scrollPane; | |
41 | ||
42 | this.mainTable = (JTable) scrollPane.getViewport().getView(); | |
43 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setAutoCreateColumnsFromModel → NO_COVERAGE |
this.mainTable.setAutoCreateColumnsFromModel(false); |
44 |
1
1. fixColumnSize : removed call to javax/swing/JTable::addPropertyChangeListener → NO_COVERAGE |
this.mainTable.addPropertyChangeListener(this); |
45 | ||
46 | // Use the existing table to create a new table sharing | |
47 | // the DataModel and ListSelectionModel | |
48 | this.fixedTable = new JTable() { | |
49 | @Override | |
50 | public boolean isCellEditable(int row,int column) { | |
51 |
1
1. isCellEditable : replaced boolean return with true for com/jsql/view/swing/table/FixedColumnTable$1::isCellEditable → NO_COVERAGE |
return false; |
52 | } | |
53 | }; | |
54 | | |
55 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setAutoCreateColumnsFromModel → NO_COVERAGE |
this.fixedTable.setAutoCreateColumnsFromModel(false); |
56 | | |
57 | final DefaultTableModel modelFixedTable = new DefaultTableModel() { | |
58 | @Override | |
59 | public int getColumnCount() { | |
60 |
1
1. getColumnCount : replaced int return with 0 for com/jsql/view/swing/table/FixedColumnTable$2::getColumnCount → NO_COVERAGE |
return 2; |
61 | } | |
62 | @Override | |
63 | public boolean isCellEditable(int row, int col) { | |
64 |
1
1. isCellEditable : replaced boolean return with true for com/jsql/view/swing/table/FixedColumnTable$2::isCellEditable → NO_COVERAGE |
return false; |
65 | } | |
66 | @Override | |
67 | public int getRowCount() { | |
68 |
1
1. getRowCount : replaced int return with 0 for com/jsql/view/swing/table/FixedColumnTable$2::getRowCount → NO_COVERAGE |
return FixedColumnTable.this.mainTable.getRowCount(); |
69 | } | |
70 | @Override | |
71 | public Class<?> getColumnClass(int colNum) { | |
72 | Class<?> columnClass; | |
73 |
1
1. getColumnClass : negated conditional → NO_COVERAGE |
if (colNum == 0) { |
74 | columnClass = String.class; | |
75 | } else { | |
76 | columnClass = super.getColumnClass(colNum); | |
77 | } | |
78 |
1
1. getColumnClass : replaced return value with null for com/jsql/view/swing/table/FixedColumnTable$2::getColumnClass → NO_COVERAGE |
return columnClass; |
79 | } | |
80 | }; | |
81 | | |
82 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setModel → NO_COVERAGE |
this.fixedTable.setModel(modelFixedTable); |
83 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setSelectionModel → NO_COVERAGE |
this.fixedTable.setSelectionModel(this.mainTable.getSelectionModel()); |
84 | | |
85 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setRowHeight → NO_COVERAGE |
this.fixedTable.setRowHeight(20); |
86 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setFocusable → NO_COVERAGE |
this.fixedTable.setFocusable(false); |
87 |
1
1. fixColumnSize : removed call to javax/swing/table/JTableHeader::setReorderingAllowed → NO_COVERAGE |
this.fixedTable.getTableHeader().setReorderingAllowed(false); |
88 | | |
89 | // Remove the fixed columns from the main table | |
90 | // and add them to the fixed table | |
91 | TableColumnModel columnModel = this.mainTable.getColumnModel(); | |
92 |
2
1. fixColumnSize : negated conditional → NO_COVERAGE 2. fixColumnSize : changed conditional boundary → NO_COVERAGE |
for (var i = 0 ; i < fixedColumns ; i++) { |
93 | TableColumn column = columnModel.getColumn(i); | |
94 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setMinWidth → NO_COVERAGE |
column.setMinWidth(0); |
95 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setMaxWidth → NO_COVERAGE |
column.setMaxWidth(0); |
96 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumnModel::addColumn → NO_COVERAGE |
this.fixedTable.getColumnModel().addColumn(new TableColumn(i)); |
97 | } | |
98 | ||
99 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setCellRenderer → NO_COVERAGE |
this.fixedTable.getColumnModel().getColumn(0).setCellRenderer(new RowHeaderRenderer()); |
100 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setResizable → NO_COVERAGE |
this.fixedTable.getColumnModel().getColumn(0).setResizable(false); |
101 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setPreferredWidth → NO_COVERAGE |
this.fixedTable.getColumnModel().getColumn(0).setPreferredWidth(38); |
102 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setCellRenderer → NO_COVERAGE |
this.fixedTable.getColumnModel().getColumn(1).setCellRenderer(new RowHeaderRenderer()); |
103 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setResizable → NO_COVERAGE |
this.fixedTable.getColumnModel().getColumn(1).setResizable(false); |
104 |
1
1. fixColumnSize : removed call to javax/swing/table/TableColumn::setPreferredWidth → NO_COVERAGE |
this.fixedTable.getColumnModel().getColumn(1).setPreferredWidth(38); |
105 | ||
106 |
1
1. fixColumnSize : removed call to javax/swing/RowSorter::addRowSorterListener → NO_COVERAGE |
this.mainTable.getRowSorter().addRowSorterListener(rowSorterEvent -> { |
107 |
1
1. lambda$fixColumnSize$0 : removed call to javax/swing/table/DefaultTableModel::fireTableDataChanged → NO_COVERAGE |
modelFixedTable.fireTableDataChanged(); |
108 | // Copy data from hidden column in main table | |
109 |
2
1. lambda$fixColumnSize$0 : negated conditional → NO_COVERAGE 2. lambda$fixColumnSize$0 : changed conditional boundary → NO_COVERAGE |
for (var i = 0; i < this.mainTable.getRowCount() ; i++) { |
110 |
1
1. lambda$fixColumnSize$0 : removed call to javax/swing/JTable::setValueAt → NO_COVERAGE |
this.fixedTable.setValueAt(this.mainTable.getValueAt(i, 0), i, 0); |
111 |
1
1. lambda$fixColumnSize$0 : removed call to javax/swing/JTable::setValueAt → NO_COVERAGE |
this.fixedTable.setValueAt(this.mainTable.getValueAt(i, 1), i, 1); |
112 | } | |
113 | }); | |
114 | | |
115 |
1
1. fixColumnSize : removed call to javax/swing/ListSelectionModel::addListSelectionListener → NO_COVERAGE |
this.mainTable.getSelectionModel().addListSelectionListener(listSelectionEvent -> |
116 |
2
1. lambda$fixColumnSize$1 : Replaced integer subtraction with addition → NO_COVERAGE 2. lambda$fixColumnSize$1 : removed call to javax/swing/table/DefaultTableModel::fireTableRowsUpdated → NO_COVERAGE |
modelFixedTable.fireTableRowsUpdated(0, modelFixedTable.getRowCount() - 1) |
117 | ); | |
118 | | |
119 | // Copy data from first column of main table to fixed column | |
120 |
2
1. fixColumnSize : changed conditional boundary → NO_COVERAGE 2. fixColumnSize : negated conditional → NO_COVERAGE |
for (var i = 0 ; i < this.mainTable.getRowCount() ; i++) { |
121 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setValueAt → NO_COVERAGE |
this.fixedTable.setValueAt(this.mainTable.getValueAt(i, 0), i, 0); |
122 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setValueAt → NO_COVERAGE |
this.fixedTable.setValueAt(this.mainTable.getValueAt(i, 1), i, 1); |
123 | } | |
124 | | |
125 | // Add the fixed table to the scroll pane | |
126 |
1
1. fixColumnSize : removed call to javax/swing/JTable::setPreferredScrollableViewportSize → NO_COVERAGE |
this.fixedTable.setPreferredScrollableViewportSize(this.fixedTable.getPreferredSize()); |
127 |
1
1. fixColumnSize : removed call to javax/swing/JScrollPane::setRowHeaderView → NO_COVERAGE |
scrollPane.setRowHeaderView(this.fixedTable); |
128 |
1
1. fixColumnSize : removed call to javax/swing/JScrollPane::setCorner → NO_COVERAGE |
scrollPane.setCorner(ScrollPaneConstants.UPPER_LEFT_CORNER, this.fixedTable.getTableHeader()); |
129 | ||
130 | // Synchronize scrolling of the row header with the main table | |
131 |
1
1. fixColumnSize : removed call to javax/swing/JViewport::addChangeListener → NO_COVERAGE |
scrollPane.getRowHeader().addChangeListener(this); |
132 | } | |
133 | ||
134 | /** | |
135 | * Implement the ChangeListener | |
136 | */ | |
137 | @Override | |
138 | public void stateChanged(ChangeEvent e) { | |
139 | // Sync the scroll pane scrollbar with the row header | |
140 | JViewport viewport = (JViewport) e.getSource(); | |
141 |
1
1. stateChanged : removed call to javax/swing/JScrollBar::setValue → NO_COVERAGE |
this.scrollPane.getVerticalScrollBar().setValue(viewport.getViewPosition().y); |
142 | } | |
143 | | |
144 | /** | |
145 | * Implement the PropertyChangeListener | |
146 | */ | |
147 | @Override | |
148 | public void propertyChange(PropertyChangeEvent e) { | |
149 | // Keep the fixed table in sync with the main table | |
150 |
1
1. propertyChange : negated conditional → NO_COVERAGE |
if ("selectionModel".equals(e.getPropertyName())) { |
151 |
1
1. propertyChange : removed call to javax/swing/JTable::setSelectionModel → NO_COVERAGE |
this.fixedTable.setSelectionModel(this.mainTable.getSelectionModel()); |
152 | } | |
153 | ||
154 |
1
1. propertyChange : negated conditional → NO_COVERAGE |
if ("model".equals(e.getPropertyName())) { |
155 |
1
1. propertyChange : removed call to javax/swing/JTable::setModel → NO_COVERAGE |
this.fixedTable.setModel(this.mainTable.getModel()); |
156 | } | |
157 | } | |
158 | } | |
Mutations | ||
43 |
1.1 |
|
44 |
1.1 |
|
51 |
1.1 |
|
55 |
1.1 |
|
60 |
1.1 |
|
64 |
1.1 |
|
68 |
1.1 |
|
73 |
1.1 |
|
78 |
1.1 |
|
82 |
1.1 |
|
83 |
1.1 |
|
85 |
1.1 |
|
86 |
1.1 |
|
87 |
1.1 |
|
92 |
1.1 2.2 |
|
94 |
1.1 |
|
95 |
1.1 |
|
96 |
1.1 |
|
99 |
1.1 |
|
100 |
1.1 |
|
101 |
1.1 |
|
102 |
1.1 |
|
103 |
1.1 |
|
104 |
1.1 |
|
106 |
1.1 |
|
107 |
1.1 |
|
109 |
1.1 2.2 |
|
110 |
1.1 |
|
111 |
1.1 |
|
115 |
1.1 |
|
116 |
1.1 2.2 |
|
120 |
1.1 2.2 |
|
121 |
1.1 |
|
122 |
1.1 |
|
126 |
1.1 |
|
127 |
1.1 |
|
128 |
1.1 |
|
131 |
1.1 |
|
141 |
1.1 |
|
150 |
1.1 |
|
151 |
1.1 |
|
154 |
1.1 |
|
155 |
1.1 |