FixedColumnTable.java

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

Mutations

45

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setAutoCreateColumnsFromModel → NO_COVERAGE

46

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::addPropertyChangeListener → NO_COVERAGE

53

1.1
Location : isCellEditable
Killed by : none
replaced boolean return with true for com/jsql/view/swing/table/FixedColumnTable$1::isCellEditable → NO_COVERAGE

57

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setAutoCreateColumnsFromModel → NO_COVERAGE

63

1.1
Location : getColumnCount
Killed by : none
replaced int return with 0 for com/jsql/view/swing/table/FixedColumnTable$2::getColumnCount → NO_COVERAGE

68

1.1
Location : isCellEditable
Killed by : none
replaced boolean return with true for com/jsql/view/swing/table/FixedColumnTable$2::isCellEditable → NO_COVERAGE

73

1.1
Location : getRowCount
Killed by : none
replaced int return with 0 for com/jsql/view/swing/table/FixedColumnTable$2::getRowCount → NO_COVERAGE

81

1.1
Location : getColumnClass
Killed by : none
negated conditional → NO_COVERAGE

87

1.1
Location : getColumnClass
Killed by : none
replaced return value with null for com/jsql/view/swing/table/FixedColumnTable$2::getColumnClass → NO_COVERAGE

91

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setModel → NO_COVERAGE

92

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setSelectionModel → NO_COVERAGE

94

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setRowHeight → NO_COVERAGE

95

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setFocusable → NO_COVERAGE

96

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/JTableHeader::setReorderingAllowed → NO_COVERAGE

97

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setGridColor → NO_COVERAGE

99

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/JTableHeader::setDefaultRenderer → NO_COVERAGE

110

1.1
Location : getTableCellRendererComponent
Killed by : none
removed call to javax/swing/JComponent::setBorder → NO_COVERAGE

112

1.1
Location : getTableCellRendererComponent
Killed by : none
replaced return value with null for com/jsql/view/swing/table/FixedColumnTable$3::getTableCellRendererComponent → NO_COVERAGE

119

1.1
Location : fixColumnSize
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : fixColumnSize
Killed by : none
negated conditional → NO_COVERAGE

122

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setMinWidth → NO_COVERAGE

123

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setMaxWidth → NO_COVERAGE

125

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumnModel::addColumn → NO_COVERAGE

128

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setCellRenderer → NO_COVERAGE

129

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setResizable → NO_COVERAGE

130

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setPreferredWidth → NO_COVERAGE

131

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setCellRenderer → NO_COVERAGE

132

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setResizable → NO_COVERAGE

133

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/table/TableColumn::setPreferredWidth → NO_COVERAGE

135

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/RowSorter::addRowSorterListener → NO_COVERAGE

137

1.1
Location : lambda$fixColumnSize$0
Killed by : none
removed call to javax/swing/table/DefaultTableModel::fireTableDataChanged → NO_COVERAGE

140

1.1
Location : lambda$fixColumnSize$0
Killed by : none
negated conditional → NO_COVERAGE

2.2
Location : lambda$fixColumnSize$0
Killed by : none
changed conditional boundary → NO_COVERAGE

142

1.1
Location : lambda$fixColumnSize$0
Killed by : none
removed call to javax/swing/JTable::setValueAt → NO_COVERAGE

143

1.1
Location : lambda$fixColumnSize$0
Killed by : none
removed call to javax/swing/JTable::setValueAt → NO_COVERAGE

147

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/ListSelectionModel::addListSelectionListener → NO_COVERAGE

148

1.1
Location : lambda$fixColumnSize$1
Killed by : none
Replaced integer subtraction with addition → NO_COVERAGE

2.2
Location : lambda$fixColumnSize$1
Killed by : none
removed call to javax/swing/table/DefaultTableModel::fireTableRowsUpdated → NO_COVERAGE

152

1.1
Location : fixColumnSize
Killed by : none
changed conditional boundary → NO_COVERAGE

2.2
Location : fixColumnSize
Killed by : none
negated conditional → NO_COVERAGE

154

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setValueAt → NO_COVERAGE

155

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setValueAt → NO_COVERAGE

159

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JTable::setPreferredScrollableViewportSize → NO_COVERAGE

160

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JScrollPane::setRowHeaderView → NO_COVERAGE

161

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JScrollPane::setCorner → NO_COVERAGE

164

1.1
Location : fixColumnSize
Killed by : none
removed call to javax/swing/JViewport::addChangeListener → NO_COVERAGE

175

1.1
Location : stateChanged
Killed by : none
removed call to javax/swing/JScrollBar::setValue → NO_COVERAGE

185

1.1
Location : propertyChange
Killed by : none
negated conditional → NO_COVERAGE

186

1.1
Location : propertyChange
Killed by : none
removed call to javax/swing/JTable::setSelectionModel → NO_COVERAGE

189

1.1
Location : propertyChange
Killed by : none
negated conditional → NO_COVERAGE

190

1.1
Location : propertyChange
Killed by : none
removed call to javax/swing/JTable::setModel → NO_COVERAGE

Active mutators

Tests examined


Report generated by PIT 1.16.1