This Bugzilla instance is a read-only archive of historic NetBeans bug reports. To report a bug in NetBeans please follow the project's instructions for reporting issues.

View | Details | Raw Unified | Return to bug 227588
Collapse All | Expand All

(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataView.java (-39 / +25 lines)
Lines 80-86 Link Here
80
    private boolean hasResultSet = false;
80
    private boolean hasResultSet = false;
81
    private int updateCount;
81
    private int updateCount;
82
    private long executionTime;
82
    private long executionTime;
83
    private boolean supportsLimit = false;
84
83
85
    /**
84
    /**
86
     * Create and populate a DataView Object. Populates 1st data page of default size.
85
     * Create and populate a DataView Object. Populates 1st data page of default size.
Lines 130-137 Link Here
130
129
131
        synchronized (this) {
130
        synchronized (this) {
132
            this.dataViewUI = new DataViewUI(this, nbOutputComponent);
131
            this.dataViewUI = new DataViewUI(this, nbOutputComponent);
133
            setRowsInTableModel();
132
            dataViewUI.getDataViewTableUI().setModel(dataPage.getModel());
134
            dataViewUI.setEditable(tblMeta == null ? false : tblMeta.hasOneTable());
133
            dataViewUI.setEditable(tblMeta == null ? false : tblMeta.hasOneTable());
134
            dataViewUI.setTotalCount(dataPage.getTotalRows());
135
            resetToolbar(hasExceptions());
135
            resetToolbar(hasExceptions());
136
        }
136
        }
137
        results = new ArrayList<Component>();
137
        results = new ArrayList<Component>();
Lines 199-212 Link Here
199
        dataViewUI.setEditable(editable);
199
        dataViewUI.setEditable(editable);
200
    }
200
    }
201
201
202
    public DataViewDBTable getDataViewDBTable() {
202
    // Used by org.netbeans.modules.db.dataview.api.DataViewPageContext#getPageSize
203
    public int getPageSize() {
204
        if (dataViewUI == null) {
205
            return -1;
206
    }
207
        return dataViewUI.getPageSize();
208
    }
209
210
    // Non API modules follow
211
212
    DataViewDBTable getDataViewDBTable() {
203
        return tblMeta;
213
        return tblMeta;
204
    }
214
    }
205
215
    
216
    void setDataViewDBTable(DataViewDBTable tblMeta) {
217
        this.tblMeta = tblMeta;
218
    }
219
    
206
    DataViewPageContext getDataViewPageContext() {
220
    DataViewPageContext getDataViewPageContext() {
207
        return dataPage;
221
        return dataPage;
208
    }
222
    }
209
223
    
210
    DatabaseConnection getDatabaseConnection() {
224
    DatabaseConnection getDatabaseConnection() {
211
        return dbConn;
225
        return dbConn;
212
    }
226
    }
Lines 215-222 Link Here
215
        return sqlString;
229
        return sqlString;
216
    }
230
    }
217
231
218
    UpdatedRowContext getUpdatedRowContext() {
232
    DataViewTableUIModel getDataViewTableUIModel() {
219
        return dataViewUI.getUpdatedRowContext();
233
        return dataViewUI.getDataViewTableUIModel();
220
    }
234
    }
221
235
222
    SQLExecutionHelper getSQLExecutionHelper() {
236
    SQLExecutionHelper getSQLExecutionHelper() {
Lines 237-246 Link Here
237
        return dataViewUI.isEditable();
251
        return dataViewUI.isEditable();
238
    }
252
    }
239
253
240
    boolean isLimitSupported() {
241
        return supportsLimit;
242
    }
243
244
    synchronized void disableButtons() {
254
    synchronized void disableButtons() {
245
        assert dataViewUI != null;
255
        assert dataViewUI != null;
246
        Mutex.EVENT.readAccess(new Runnable() {
256
        Mutex.EVENT.readAccess(new Runnable() {
Lines 310-335 Link Here
310
        });
320
        });
311
    }
321
    }
312
322
313
    void setLimitSupported(boolean supportsLimit) {
323
    synchronized void setTotalRowCount(final int count) {
314
        this.supportsLimit = supportsLimit;
324
        if (dataViewUI != null) {
315
    }
316
317
    void setRowsInTableModel() {
318
        assert dataViewUI != null;
319
        assert dataPage != null;
320
321
        if (dataPage.getCurrentRows() != null) {
322
            Mutex.EVENT.readAccess(new Runnable() {
325
            Mutex.EVENT.readAccess(new Runnable() {
323
324
                @Override
326
                @Override
325
                public void run() {
327
                public void run() {
326
                    dataViewUI.setDataRows(dataPage.getCurrentRows());
328
                    dataViewUI.setTotalCount(count);
327
                    dataViewUI.setTotalCount(dataPage.getTotalRows());
328
                }
329
                }
329
            });
330
            });
330
        }
331
        }
331
    }
332
    }
332
333
    
333
    synchronized void incrementRowSize(int count) {
334
    synchronized void incrementRowSize(int count) {
334
        assert dataViewUI != null;
335
        assert dataViewUI != null;
335
        dataPage.setTotalRows(dataPage.getTotalRows() + count);
336
        dataPage.setTotalRows(dataPage.getTotalRows() + count);
Lines 354-363 Link Here
354
        });
355
        });
355
    }
356
    }
356
357
357
    synchronized void syncPageWithTableModel() {
358
        dataViewUI.syncPageWithTableModel();
359
    }
360
361
    void setHasResultSet(boolean hasResultSet) {
358
    void setHasResultSet(boolean hasResultSet) {
362
        this.hasResultSet = hasResultSet;
359
        this.hasResultSet = hasResultSet;
363
    }
360
    }
Lines 370-386 Link Here
370
        this.executionTime = executionTime;
367
        this.executionTime = executionTime;
371
    }
368
    }
372
369
373
    void setDataViewDBTable(DataViewDBTable tblMeta) {
374
        this.tblMeta = tblMeta;
375
    }
376
377
    private DataView() {
370
    private DataView() {
378
    }
371
    }
379
380
    public int getPageSize() {
381
        if (dataViewUI == null) {
382
            return -1;
383
        }
384
        return dataViewUI.getPageSize();
385
    }
386
}
372
}
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataViewActionHandler.java (-9 / +5 lines)
Lines 84-97 Link Here
84
        synchronized (dataView) {
84
        synchronized (dataView) {
85
            if (selectedOnly) {
85
            if (selectedOnly) {
86
                DataViewTableUI rsTable = dataViewUI.getDataViewTableUI();
86
                DataViewTableUI rsTable = dataViewUI.getDataViewTableUI();
87
                UpdatedRowContext updatedRowCtx = dataView.getUpdatedRowContext();
87
                DataViewTableUIModel updatedRowCtx = dataView.getDataViewTableUIModel();
88
                int[] rows = rsTable.getSelectedRows();
88
                int[] rows = rsTable.getSelectedRows();
89
                for (int i = 0; i < rows.length; i++) {
89
                for (int i = 0; i < rows.length; i++) {
90
                    int row = rows[i];
90
                    int row = rsTable.convertRowIndexToModel(rows[i]);
91
                    for (int col = 0, CNT = rsTable.getColumnCount(); col < CNT; col++) {
91
                    updatedRowCtx.removeUpdateForSelectedRow(row, true);
92
                        dataViewUI.resetValueAt(row, col);
93
                    }
94
                    updatedRowCtx.removeUpdateForSelectedRow(row);
95
                }
92
                }
96
93
97
                if (updatedRowCtx.getUpdateKeys().isEmpty()) {
94
                if (updatedRowCtx.getUpdateKeys().isEmpty()) {
Lines 99-113 Link Here
99
                    dataViewUI.setCommitEnabled(false);
96
                    dataViewUI.setCommitEnabled(false);
100
                }
97
                }
101
            } else {
98
            } else {
102
                dataView.getUpdatedRowContext().removeAllUpdates();
99
                dataView.getDataViewTableUIModel().removeAllUpdates(true);
103
                dataView.setRowsInTableModel();
104
                dataViewUI.setCancelEnabled(false);
100
                dataViewUI.setCancelEnabled(false);
105
                dataViewUI.setCommitEnabled(false);
101
                dataViewUI.setCommitEnabled(false);
106
            }
102
            }
107
        }
103
        }
108
    }
104
    }
109
105
110
    void setMaxActionPerformed() {
106
    void updateActionPerformed() {
111
        if (rejectModifications()) {
107
        if (rejectModifications()) {
112
            int pageSize = dataViewUI.getPageSize();
108
            int pageSize = dataViewUI.getPageSize();
113
            dataPage.setPageSize(pageSize);
109
            dataPage.setPageSize(pageSize);
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataViewDBTable.java (-13 / +5 lines)
Lines 63-69 Link Here
63
63
64
    private final DBTable[] dbTables;
64
    private final DBTable[] dbTables;
65
    private final List<DBColumn> columns;
65
    private final List<DBColumn> columns;
66
    private String[] columnTooltipStr;
67
66
68
    public DataViewDBTable(Collection<DBTable> tables) {
67
    public DataViewDBTable(Collection<DBTable> tables) {
69
        assert tables != null;
68
        assert tables != null;
Lines 114-120 Link Here
114
        return columns.size();
113
        return columns.size();
115
    }
114
    }
116
115
117
    public synchronized Map<String,DBColumn> getColumns() {
116
    public List<DBColumn> getColumns() {
117
        return Collections.unmodifiableList(columns);
118
    }
119
    
120
    public synchronized Map<String,DBColumn> getColumnMap() {
118
        Map<String, DBColumn> colMap = new HashMap<String, DBColumn>();
121
        Map<String, DBColumn> colMap = new HashMap<String, DBColumn>();
119
        for (DBTable tbl : dbTables) {
122
        for (DBTable tbl : dbTables) {
120
            colMap.putAll(tbl.getColumns());
123
            colMap.putAll(tbl.getColumns());
Lines 122-138 Link Here
122
        return Collections.unmodifiableMap(colMap);
125
        return Collections.unmodifiableMap(colMap);
123
    }
126
    }
124
127
125
    public synchronized String[] getColumnToolTips() {
126
        if (columnTooltipStr == null) {
127
            columnTooltipStr = new String[columns.size()];
128
            int i = 0;
129
            for (DBColumn column : columns) {
130
                columnTooltipStr[i++] = DataViewUtils.getColumnToolTip(column);
131
            }
132
        }
133
        return columnTooltipStr;
134
    }
135
136
    final class ColumnOrderComparator implements Comparator<DBColumn> {
128
    final class ColumnOrderComparator implements Comparator<DBColumn> {
137
129
138
        private ColumnOrderComparator() {
130
        private ColumnOrderComparator() {
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataViewPageContext.java (-14 / +6 lines)
Lines 43-49 Link Here
43
 */
43
 */
44
package org.netbeans.modules.db.dataview.output;
44
package org.netbeans.modules.db.dataview.output;
45
45
46
import java.util.List;
46
import org.netbeans.modules.db.dataview.meta.DBColumn;
47
import org.openide.util.NbBundle;
47
import org.openide.util.NbBundle;
48
48
49
/**
49
/**
Lines 56-62 Link Here
56
    private int pageSize = 10;
56
    private int pageSize = 10;
57
    private int totalRows = -1;
57
    private int totalRows = -1;
58
    private int currentPos = 1;
58
    private int currentPos = 1;
59
    private List<Object[]> rows;
59
    private final DataViewTableUIModel model = new DataViewTableUIModel(new DBColumn[0]);
60
60
61
    DataViewPageContext(int pageSize) {
61
    DataViewPageContext(int pageSize) {
62
        this.pageSize = pageSize;
62
        this.pageSize = pageSize;
Lines 70-81 Link Here
70
        return currentPos;
70
        return currentPos;
71
    }
71
    }
72
72
73
    List<Object[]> getCurrentRows() {
73
    DataViewTableUIModel getModel() {
74
        return rows;
74
        return model;
75
    }
76
77
    Object getColumnData(int row, int column) {
78
        return rows.get(row)[column];
79
    }
75
    }
80
76
81
    int getTotalRows() {
77
    int getTotalRows() {
Lines 124-134 Link Here
124
    }
120
    }
125
121
126
    boolean refreshRequiredOnInsert() {
122
    boolean refreshRequiredOnInsert() {
127
        return (isLastPage() && rows.size() <= pageSize) ? true : false;
123
        return (isLastPage() && model.getRowCount() <= pageSize) ? true : false;
128
    }
124
    }
129
125
130
    boolean hasDataRows() {
126
    boolean hasDataRows() {
131
        return (rows != null && !rows.isEmpty());
127
        return model.getRowCount() > 0;
132
    }
128
    }
133
129
134
    String pageOf() {
130
    String pageOf() {
Lines 157-164 Link Here
157
            previous();
153
            previous();
158
        }
154
        }
159
    }
155
    }
160
161
    synchronized void setCurrentRows(List<Object[]> rows) {
162
        this.rows = rows;
163
    }
164
}
156
}
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataViewTablePanel.java (-152 lines)
Lines 1-152 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * Contributor(s):
28
 *
29
 * The Original Software is NetBeans. The Initial Developer of the Original
30
 * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
31
 * Microsystems, Inc. All Rights Reserved.
32
 *
33
 * If you wish your version of this file to be governed by only the CDDL
34
 * or only the GPL Version 2, indicate your decision by adding
35
 * "[Contributor] elects to include this software in this distribution
36
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
37
 * single choice of license, a recipient has the option to distribute
38
 * your version of this file under either the CDDL, the GPL Version 2 or
39
 * to extend the choice of license to its licensees as provided above.
40
 * However, if you add GPL Version 2 code and therefore, elected the GPL
41
 * Version 2 license, then the option applies only if the new code is
42
 * made subject to such option by the copyright holder.
43
 */
44
package org.netbeans.modules.db.dataview.output;
45
46
import org.netbeans.modules.db.dataview.table.JXTableRowHeader;
47
import java.awt.BorderLayout;
48
import javax.swing.table.DefaultTableModel;
49
import java.util.ArrayList;
50
import java.util.List;
51
import java.util.Vector;
52
import javax.swing.JScrollPane;
53
import org.jdesktop.swingx.JXPanel;
54
55
/**
56
 * Renders rows and columns of a given ResultSet via JTable.
57
 *
58
 * @author Ahimanikya Satapathy
59
 */
60
class DataViewTablePanel extends JXPanel {
61
62
    private final DataViewTableUI tableUI;
63
    private DataViewUI dataViewUI;
64
    private DataView dataView;
65
    private boolean isDirty = false;
66
    private UpdatedRowContext updatedRowCtx;
67
    private JXTableRowHeader rowHeader;
68
    private boolean editable;
69
70
    public DataViewTablePanel(DataView dataView, DataViewUI dataViewUI, DataViewActionHandler actionHandler) {
71
        this.setLayout(new BorderLayout());
72
        
73
        this.dataView = dataView;
74
        this.dataViewUI = dataViewUI;
75
        
76
        tableUI = new DataViewTableUI(this, actionHandler, dataView);
77
        updatedRowCtx = new UpdatedRowContext();
78
        
79
        rowHeader = new JXTableRowHeader(tableUI);
80
        JScrollPane sp = new JScrollPane(tableUI);
81
        sp.setRowHeaderView(rowHeader);
82
        
83
        sp.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowHeader.getTableHeader());
84
        this.add(sp, BorderLayout.CENTER);
85
    }
86
87
    public void setEditable(boolean editable) {
88
        this.editable = editable;
89
    }
90
91
    protected boolean isEditable() {
92
        return editable;
93
    }
94
95
    public boolean isDirty() {
96
        return isDirty;
97
    }
98
99
    public void setDirty(boolean dirty) {
100
        isDirty = dirty;
101
        if (!isDirty) {
102
            updatedRowCtx.removeAllUpdates();
103
        }
104
    }
105
106
    DataViewTableUI getDataViewTableUI() {
107
        return tableUI;
108
    }
109
    
110
    UpdatedRowContext getUpdatedRowContext() {
111
        return updatedRowCtx;
112
    }
113
114
    boolean isCommitEnabled() {
115
        return dataViewUI.isCommitEnabled();
116
    }
117
118
    public void createTableModel(List<Object[]> rows) {
119
        setDirty(false);
120
        tableUI.createTableModel(rows, rowHeader);
121
    }
122
123
    void handleColumnUpdated() {
124
        isDirty = true;
125
        dataViewUI.setCommitEnabled(true);
126
        dataViewUI.setCancelEnabled(true);
127
    }
128
129
    List<Object[]> getPageDataFromTable() {
130
        DefaultTableModel dtm = (DefaultTableModel) tableUI.getModel();
131
        List<Object[]> rows = new ArrayList<Object[]>();
132
        int colCnt = dtm.getColumnCount();
133
        for (Object row : dtm.getDataVector()) {
134
            Object[] rowObj = new Object[colCnt];
135
            int i = 0;
136
            for (Object colVal : (Vector) row) {
137
                rowObj[i++] = colVal;
138
            }
139
            rows.add(rowObj);
140
        }
141
        return rows;
142
    }
143
144
    public void enableDeleteBtn(boolean value) {
145
        dataViewUI.enableDeleteBtn(value);
146
    }
147
148
    void setValueAt(Object val, int row, int col) {
149
        DefaultTableModel dtm = (DefaultTableModel) tableUI.getModel();
150
        dtm.setValueAt(val, row, col);
151
    }
152
}
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataViewTableUI.java (-48 / +58 lines)
Lines 66-72 Link Here
66
import javax.swing.border.LineBorder;
66
import javax.swing.border.LineBorder;
67
import javax.swing.event.ListSelectionEvent;
67
import javax.swing.event.ListSelectionEvent;
68
import javax.swing.event.ListSelectionListener;
68
import javax.swing.event.ListSelectionListener;
69
import javax.swing.table.DefaultTableModel;
69
import javax.swing.event.TableModelEvent;
70
import javax.swing.event.TableModelListener;
70
import javax.swing.table.TableCellEditor;
71
import javax.swing.table.TableCellEditor;
71
import javax.swing.table.TableCellRenderer;
72
import javax.swing.table.TableCellRenderer;
72
import javax.swing.table.TableModel;
73
import javax.swing.table.TableModel;
Lines 76-82 Link Here
76
import org.netbeans.modules.db.dataview.meta.DBTable;
77
import org.netbeans.modules.db.dataview.meta.DBTable;
77
import org.netbeans.modules.db.dataview.table.ResultSetCellRenderer;
78
import org.netbeans.modules.db.dataview.table.ResultSetCellRenderer;
78
import org.netbeans.modules.db.dataview.table.ResultSetJXTable;
79
import org.netbeans.modules.db.dataview.table.ResultSetJXTable;
79
import org.netbeans.modules.db.dataview.table.ResultSetTableModel;
80
import org.openide.DialogDisplayer;
80
import org.openide.DialogDisplayer;
81
import org.openide.NotifyDescriptor;
81
import org.openide.NotifyDescriptor;
82
import org.openide.util.Lookup;
82
import org.openide.util.Lookup;
Lines 92-106 Link Here
92
final class DataViewTableUI extends ResultSetJXTable {
92
final class DataViewTableUI extends ResultSetJXTable {
93
93
94
    private JPopupMenu tablePopupMenu;
94
    private JPopupMenu tablePopupMenu;
95
    private final DataViewTablePanel tablePanel;
95
    private final DataViewUI dataviewUI;
96
    private DataViewActionHandler handler;
96
    private DataViewActionHandler handler;
97
    private int selectedRow = -1;
97
    private int selectedRow = -1;
98
    private int selectedColumn = -1;
98
    private int selectedColumn = -1;
99
    private TableModelListener dataChangedListener = new TableModelListener() {
100
        @Override
101
        public void tableChanged(TableModelEvent e) {
102
            dataviewUI.handleColumnUpdated();
103
        }
104
    };
99
105
100
    public DataViewTableUI(final DataViewTablePanel tablePanel, final DataViewActionHandler handler, final DataView dataView) {
106
    public DataViewTableUI(final DataViewUI dataviewUI, final DataViewActionHandler handler, final DataView dataView) {
101
        super(dataView);
107
        this.dataviewUI = dataviewUI;
102
103
        this.tablePanel = tablePanel;
104
        this.handler = handler;
108
        this.handler = handler;
105
109
106
        TableSelectionListener listener = new TableSelectionListener(this);
110
        TableSelectionListener listener = new TableSelectionListener(this);
Lines 114-131 Link Here
114
    @Override
118
    @Override
115
    @SuppressWarnings({"unchecked"})
119
    @SuppressWarnings({"unchecked"})
116
    public void setModel(TableModel dataModel) {
120
    public void setModel(TableModel dataModel) {
121
        if(! (dataModel instanceof DataViewTableUIModel)) {
122
            throw new IllegalArgumentException("DataViewTableUI only supports"
123
                    + " instances of DataViewTableUIModel");
124
        }
117
        RowFilter<?, ?> oldFilter = getRowFilter();
125
        RowFilter<?, ?> oldFilter = getRowFilter();
126
        if(getModel() != null) {
127
            getModel().removeTableModelListener(dataChangedListener); // Remove ChangeListener on replace
128
        }
118
        super.setModel(dataModel);
129
        super.setModel(dataModel);
130
        dataModel.addTableModelListener(dataChangedListener); // Add new change listener
119
        setRowFilter((RowFilter) oldFilter);
131
        setRowFilter((RowFilter) oldFilter);
132
        if(dataviewUI != null) {
133
            dataviewUI.handleColumnUpdated();
134
        }
135
    }
136
    
137
    @Override
138
    public DataViewTableUIModel getModel() {
139
        return (DataViewTableUIModel) super.getModel();
140
    }
141
    
142
    @Override
143
    protected TableModel createDefaultDataModel() {
144
        return new DataViewTableUIModel(new DBColumn[0]);
120
    }
145
    }
121
    
146
    
122
    @Override
147
    @Override
123
    public TableCellRenderer getCellRenderer(int row, int column) {
148
    public TableCellRenderer getCellRenderer(int row, int column) {
124
        if (dView.getUpdatedRowContext().hasUpdates(
149
        if (getModel().hasUpdates(
125
                convertRowIndexToModel(row),
150
                convertRowIndexToModel(row),
126
                convertColumnIndexToModel(column)
151
                convertColumnIndexToModel(column)
127
        )) {
152
        )) {
128
            return new UpdatedResultSetCellRenderer(dView);
153
            return new UpdatedResultSetCellRenderer();
129
        }
154
        }
130
        return super.getCellRenderer(row, column);
155
        return super.getCellRenderer(row, column);
131
    }
156
    }
Lines 135-165 Link Here
135
        return new Control0KeyListener();
160
        return new Control0KeyListener();
136
    }
161
    }
137
162
138
    @Override
139
    protected DefaultTableModel getDefaultTableModel() {
140
        return new DataViewTableUIModel(this);
141
    }
142
143
    private class DataViewTableUIModel extends ResultSetTableModel {
144
145
        protected DataViewTableUIModel(ResultSetJXTable table) {
146
            super(table);
147
        }
148
149
        @Override
150
        protected void handleColumnUpdated(int row, int col, Object value) {
151
            dView.getUpdatedRowContext().addUpdates(row, col, value, getModel());
152
            tablePanel.handleColumnUpdated();
153
        }
154
    }
155
156
    private static class UpdatedResultSetCellRenderer extends ResultSetCellRenderer {
163
    private static class UpdatedResultSetCellRenderer extends ResultSetCellRenderer {
157
        static int borderThickness = 1;
164
        static int borderThickness = 1;
158
        static Color emptyNullForeground;
165
        static Color emptyNullForeground;
159
        static Color selectedForeground;
166
        static Color selectedForeground;
160
        static Color unselectedForeground;
167
        static Color unselectedForeground;
161
        private JComponent holder = new JComponent() {};
168
        private JComponent holder = new JComponent() {};
162
        DataView dataView;
163
169
164
        static {
170
        static {
165
            Color emptyNullFromMngr = UIManager.getColor(
171
            Color emptyNullFromMngr = UIManager.getColor(
Lines 178-200 Link Here
178
                    ? unselectedFgFromMngr
184
                    ? unselectedFgFromMngr
179
                    : new Color(0, 128, 0); // green color
185
                    : new Color(0, 128, 0); // green color
180
        }
186
        }
181
        public UpdatedResultSetCellRenderer(DataView dView) {
187
        public UpdatedResultSetCellRenderer() {
182
            dataView = dView;
183
            holder.setLayout(new BorderLayout());
188
            holder.setLayout(new BorderLayout());
184
        }
189
        }
185
190
186
        @Override
191
        @Override
187
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
192
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
188
            Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
193
            Component c = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
189
            Object obj = dataView.getDataViewPageContext().getColumnData(
194
190
                    table.convertRowIndexToModel(row),
195
            assert (table.getModel() instanceof DataViewTableUIModel) : "Assuming usage with DataViewTableUIModel";
191
                    table.convertColumnIndexToModel(column));
196
            
197
            int modelRow = table.convertRowIndexToModel(row);
198
            int modelColumn = table.convertColumnIndexToModel(column);
199
            
200
            DataViewTableUIModel model = (DataViewTableUIModel) table.getModel();
192
201
193
            Color color;
202
            Color color;
194
            boolean override = false;
203
            boolean override = false;
195
204
196
            if (isSelected) {
205
            if (isSelected) {
197
                if ((obj == null && value == null) || (obj != null && value != null && value.equals(obj))) {
206
                if (! model.hasUpdates(modelRow, modelColumn)) {
198
                    color = emptyNullForeground;
207
                    color = emptyNullForeground;
199
                    override = true;
208
                    override = true;
200
                } else {
209
                } else {
Lines 202-208 Link Here
202
                    override = true;
211
                    override = true;
203
                }
212
                }
204
            } else {
213
            } else {
205
                if ((obj == null && value == null) || (obj != null && value != null && value.equals(obj))) {
214
                if (! model.hasUpdates(modelRow, modelColumn)) {
206
                    color = table.getForeground();
215
                    color = table.getForeground();
207
                } else {
216
                } else {
208
                    color = unselectedForeground;
217
                    color = unselectedForeground;
Lines 246-252 Link Here
246
                    return;
255
                    return;
247
                }
256
                }
248
257
249
                DBColumn dbcol = getDBColumn(col);
258
                int modelColumn = convertColumnIndexToModel(col);
259
                DBColumn dbcol = getModel().getColumn(modelColumn);
250
                if (dbcol.isGenerated() || !dbcol.isNullable()) {
260
                if (dbcol.isGenerated() || !dbcol.isNullable()) {
251
                    Toolkit.getDefaultToolkit().beep();
261
                    Toolkit.getDefaultToolkit().beep();
252
                } else {
262
                } else {
Lines 260-266 Link Here
260
                    return;
270
                    return;
261
                }
271
                }
262
272
263
                DBColumn dbcol = getDBColumn(col);
273
                int modelColumn = convertColumnIndexToModel(col);
274
                DBColumn dbcol = getModel().getColumn(modelColumn);
264
                Object val = getValueAt(row, col);
275
                Object val = getValueAt(row, col);
265
                if (dbcol.isGenerated() || !dbcol.hasDefault()) {
276
                if (dbcol.isGenerated() || !dbcol.hasDefault()) {
266
                    Toolkit.getDefaultToolkit().beep();
277
                    Toolkit.getDefaultToolkit().beep();
Lines 288-303 Link Here
288
299
289
        @Override
300
        @Override
290
        public void valueChanged(ListSelectionEvent e) {
301
        public void valueChanged(ListSelectionEvent e) {
291
            if (tablePanel == null) {
302
            if (dataviewUI == null) {
292
                return;
303
                return;
293
            }
304
            }
294
305
295
            if (e.getSource() == table.getSelectionModel() && table.getRowSelectionAllowed()) {
306
            if (e.getSource() == table.getSelectionModel() && table.getRowSelectionAllowed()) {
296
                boolean rowSelected = table.getSelectedRows().length > 0;
307
                boolean rowSelected = table.getSelectedRows().length > 0;
297
                if (rowSelected && tablePanel.isEditable()) {
308
                if (rowSelected && dataviewUI.isEditable()) {
298
                    tablePanel.enableDeleteBtn(true);
309
                    dataviewUI.enableDeleteBtn(true);
299
                } else {
310
                } else {
300
                    tablePanel.enableDeleteBtn(false);
311
                    dataviewUI.enableDeleteBtn(false);
301
                }
312
                }
302
            }
313
            }
303
        }
314
        }
Lines 428-434 Link Here
428
                    String insertSQL = "";
439
                    String insertSQL = "";
429
                    for (int j = 0; j < rows.length; j++) {
440
                    for (int j = 0; j < rows.length; j++) {
430
                        int modelIndex = convertRowIndexToModel(rows[j]);
441
                        int modelIndex = convertRowIndexToModel(rows[j]);
431
                        Object[] insertRow = dataView.getDataViewPageContext().getCurrentRows().get(modelIndex);
442
                        Object[] insertRow = getModel().getRowData(modelIndex);
432
                        String sql = dataView.getSQLStatementGenerator().generateRawInsertStatement(insertRow);
443
                        String sql = dataView.getSQLStatementGenerator().generateRawInsertStatement(insertRow);
433
                        insertSQL += sql + ";\n"; // NOI18N
444
                        insertSQL += sql + ";\n"; // NOI18N
434
                    }
445
                    }
Lines 471-483 Link Here
471
            @Override
482
            @Override
472
            public void actionPerformed(ActionEvent e) {
483
            public void actionPerformed(ActionEvent e) {
473
                String rawUpdateStmt = "";
484
                String rawUpdateStmt = "";
474
                UpdatedRowContext updatedRowCtx = dataView.getUpdatedRowContext();
475
                SQLStatementGenerator generator = dataView.getSQLStatementGenerator();
485
                SQLStatementGenerator generator = dataView.getSQLStatementGenerator();
476
486
477
                try {
487
                try {
478
                    for (Integer row : updatedRowCtx.getUpdateKeys()) {
488
                    for (Integer row : getModel().getUpdateKeys()) {
479
                        Map<Integer, Object> changedData = updatedRowCtx.getChangedData(row);
489
                        Map<Integer, Object> changedData = getModel().getChangedData(row);
480
                        rawUpdateStmt += generator.generateUpdateStatement(row, changedData, dataModel) + ";\n"; // NOI18N
490
                        rawUpdateStmt += generator.generateUpdateStatement(row, changedData, getModel()) + ";\n"; // NOI18N
481
                    }
491
                    }
482
                    ShowSQLDialog dialog = new ShowSQLDialog();
492
                    ShowSQLDialog dialog = new ShowSQLDialog();
483
                    dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
493
                    dialog.setLocationRelativeTo(WindowManager.getDefault().getMainWindow());
Lines 549-555 Link Here
549
                    if (!inSelection) {
559
                    if (!inSelection) {
550
                        changeSelection(selectedRow, selectedColumn, false, false);
560
                        changeSelection(selectedRow, selectedColumn, false, false);
551
                    }
561
                    }
552
                    if (!tablePanel.isEditable()) {
562
                    if (!dataviewUI.isEditable()) {
553
                        miInsertAction.setEnabled(false);
563
                        miInsertAction.setEnabled(false);
554
                        miDeleteAction.setEnabled(false);
564
                        miDeleteAction.setEnabled(false);
555
                        miTruncateRecord.setEnabled(false);
565
                        miTruncateRecord.setEnabled(false);
Lines 558-564 Link Here
558
                        miDeleteSQLScript.setEnabled(false);
568
                        miDeleteSQLScript.setEnabled(false);
559
                    }
569
                    }
560
570
561
                    if (!tablePanel.isCommitEnabled()) {
571
                    if (!dataviewUI.isCommitEnabled()) {
562
                        miCommitAction.setEnabled(false);
572
                        miCommitAction.setEnabled(false);
563
                        miCancelEdits.setEnabled(false);
573
                        miCancelEdits.setEnabled(false);
564
                        miCommitSQLScript.setEnabled(false);
574
                        miCommitSQLScript.setEnabled(false);
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataViewTableUIModel.java (+181 lines)
Line 0 Link Here
1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2013 Oracle and/or its affiliates. All rights reserved.
5
 *
6
 * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
7
 * Other names may be trademarks of their respective owners.
8
 *
9
 * The contents of this file are subject to the terms of either the GNU
10
 * General Public License Version 2 only ("GPL") or the Common
11
 * Development and Distribution License("CDDL") (collectively, the
12
 * "License"). You may not use this file except in compliance with the
13
 * License. You can obtain a copy of the License at
14
 * http://www.netbeans.org/cddl-gplv2.html
15
 * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
16
 * specific language governing permissions and limitations under the
17
 * License.  When distributing the software, include this License Header
18
 * Notice in each file and include the License file at
19
 * nbbuild/licenses/CDDL-GPL-2-CP.  Oracle designates this
20
 * particular file as subject to the "Classpath" exception as provided
21
 * by Oracle in the GPL Version 2 section of the License file that
22
 * accompanied this code. If applicable, add the following below the
23
 * License Header, with the fields enclosed by brackets [] replaced by
24
 * your own identifying information:
25
 * "Portions Copyrighted [year] [name of copyright owner]"
26
 *
27
 * If you wish your version of this file to be governed by only the CDDL
28
 * or only the GPL Version 2, indicate your decision by adding
29
 * "[Contributor] elects to include this software in this distribution
30
 * under the [CDDL or GPL Version 2] license." If you do not indicate a
31
 * single choice of license, a recipient has the option to distribute
32
 * your version of this file under either the CDDL, the GPL Version 2 or
33
 * to extend the choice of license to its licensees as provided above.
34
 * However, if you add GPL Version 2 code and therefore, elected the GPL
35
 * Version 2 license, then the option applies only if the new code is
36
 * made subject to such option by the copyright holder.
37
 *
38
 * Contributor(s):
39
 *
40
 * Portions Copyrighted 2013 Sun Microsystems, Inc.
41
 */
42
package org.netbeans.modules.db.dataview.output;
43
44
import java.util.HashMap;
45
import java.util.HashSet;
46
import java.util.LinkedHashMap;
47
import java.util.List;
48
import java.util.Map;
49
import java.util.Set;
50
import org.netbeans.modules.db.dataview.meta.DBColumn;
51
import org.netbeans.modules.db.dataview.table.ResultSetTableModel;
52
53
/**
54
 * DataViewTableUIModel
55
 * 
56
 * Extends ResultSetTableModel with update tracking
57
 * 
58
 * @author matthias
59
 */
60
public class DataViewTableUIModel extends ResultSetTableModel {
61
62
    private Map<Integer, Map<Integer, Object>> oldData = new LinkedHashMap<Integer, Map<Integer, Object>>();
63
64
    protected DataViewTableUIModel(DBColumn[] columns) {
65
        super(columns);
66
    }
67
68
    @Override
69
    public void setValueAt(Object value, int row, int col) {
70
        Object oldval = getValueAt(row, col);
71
        if (noUpdateRequired(oldval, value)) {
72
            return;
73
        }
74
        addUpdates(row, col, oldval);
75
        super.setValueAt(value, row, col);
76
    }
77
    
78
    public Object getOriginalValueAt(int row, int col) {
79
        if(hasUpdates(row, col)) {
80
            return oldData.get(row).get(col);
81
        } else {
82
            return getValueAt(row, col);
83
        }
84
    }
85
86
    @Override
87
    public void setData(List<Object[]> data) {
88
        super.setData(data);
89
        oldData.clear();
90
    }
91
92
    @Override
93
    public void removeRow(int row) {
94
        super.removeRow(row);
95
        oldData.remove(row);
96
    }
97
98
    @Override
99
    public void clear() {
100
        super.clear();
101
        oldData.clear();
102
    }
103
104
    private void addUpdates(int row, int col, Object value) {
105
        Map<Integer, Object> rowMap = oldData.get(row);
106
        if (rowMap == null) {
107
            rowMap = new LinkedHashMap<Integer, Object>();
108
            oldData.put(row, rowMap);
109
        }
110
111
        if (!rowMap.containsKey(col)) {
112
            rowMap.put(col, value);
113
        }
114
    }
115
116
117
    public void removeAllUpdates(boolean discardNewValue) {
118
        for(Integer rowIndex: new HashSet<Integer>(oldData.keySet())) {
119
            Map<Integer,Object> oldRow = oldData.remove(rowIndex);
120
            if (discardNewValue) {
121
                for (Integer columnIndex : new HashSet<Integer>(oldRow.keySet())) {
122
                    super.setValueAt(oldRow.remove(columnIndex), rowIndex,
123
                            columnIndex);
124
                }
125
            }
126
        }
127
    }
128
129
    public void removeUpdateForSelectedRow(int row, boolean discardNewValue) {
130
        if (oldData.containsKey(row)) {
131
            Map<Integer, Object> oldRow = oldData.remove(row);
132
            if (discardNewValue) {
133
                for (Integer columnIndex : new HashSet<Integer>(oldRow.keySet())) {
134
                    super.setValueAt(oldRow.remove(columnIndex), row,
135
                            columnIndex);
136
                }
137
            }
138
        }
139
    }
140
    
141
    public void removeUpdate(int row, int col, boolean discardNewValue) {
142
        if (oldData.containsKey(row)) {
143
            Map<Integer, Object> oldRow = oldData.get(row);
144
            if (oldRow.containsKey(col)) {
145
                Object value = oldRow.get(col);
146
                if (oldRow.isEmpty()) {
147
                    oldData.remove(row);
148
                }
149
                if (discardNewValue) {
150
                    super.setValueAt(value, row, col);
151
                }
152
            }
153
        }
154
        fireTableCellUpdated(row, col);
155
    }
156
157
    public Set<Integer> getUpdateKeys() {
158
        return oldData.keySet();
159
    }
160
161
    public Map<Integer, Object> getChangedData(int row) {
162
        Set<Integer> changedColumns = oldData.get(row).keySet();
163
        Map<Integer,Object> result = new HashMap<Integer, Object>();
164
        for(Integer column: changedColumns) {
165
            result.put(column, getValueAt(row, column));
166
        }
167
        return result;
168
    }
169
170
    boolean hasUpdates() {
171
        return oldData.size() > 0;
172
    }
173
    
174
    boolean hasUpdates(int row, int col) {
175
        Map<Integer, Object> rowMap = oldData.get(new Integer(row));
176
        if (rowMap != null && rowMap.containsKey(new Integer(col))) {
177
            return true;
178
        }
179
        return false;
180
    }
181
}
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/DataViewUI.java (-38 / +44 lines)
Lines 64-75 Link Here
64
import javax.swing.ImageIcon;
64
import javax.swing.ImageIcon;
65
import javax.swing.JButton;
65
import javax.swing.JButton;
66
import javax.swing.JPanel;
66
import javax.swing.JPanel;
67
import javax.swing.JScrollPane;
67
import javax.swing.JTextField;
68
import javax.swing.JTextField;
68
import javax.swing.JToolBar;
69
import javax.swing.JToolBar;
69
import javax.swing.SwingUtilities;
70
import javax.swing.SwingUtilities;
70
import org.jdesktop.swingx.JXButton;
71
import org.jdesktop.swingx.JXButton;
71
import org.jdesktop.swingx.JXLabel;
72
import org.jdesktop.swingx.JXLabel;
72
import org.jdesktop.swingx.JXPanel;
73
import org.jdesktop.swingx.JXPanel;
74
import org.jdesktop.swingx.JXTableHeader;
75
import org.netbeans.modules.db.dataview.meta.DBColumn;
76
import org.netbeans.modules.db.dataview.table.JXTableRowHeader;
73
import org.netbeans.modules.db.dataview.table.MultiColPatternFilter;
77
import org.netbeans.modules.db.dataview.table.MultiColPatternFilter;
74
import org.netbeans.modules.db.dataview.table.ResultSetJXTable;
78
import org.netbeans.modules.db.dataview.table.ResultSetJXTable;
75
import static org.netbeans.modules.db.dataview.table.SuperPatternFilter.MODE.LITERAL_FIND;
79
import static org.netbeans.modules.db.dataview.table.SuperPatternFilter.MODE.LITERAL_FIND;
Lines 96-102 Link Here
96
    private JXLabel totalRowsLabel;
100
    private JXLabel totalRowsLabel;
97
    private JXLabel limitRow;
101
    private JXLabel limitRow;
98
    private JXButton[] editButtons = new JXButton[5];
102
    private JXButton[] editButtons = new JXButton[5];
99
    private DataViewTablePanel dataPanel;
103
    private DataViewTableUI dataPanel;
104
    private JScrollPane dataPanelScrollPane;
100
    private final DataView dataView;
105
    private final DataView dataView;
101
    private JXButton cancel;
106
    private JXButton cancel;
102
    private DataViewActionHandler actionHandler;
107
    private DataViewActionHandler actionHandler;
Lines 144-150 Link Here
144
149
145
        //do not show tab view if there is only one tab
150
        //do not show tab view if there is only one tab
146
        this.putClientProperty("TabPolicy", "HideWhenAlone"); //NOI18N
151
        this.putClientProperty("TabPolicy", "HideWhenAlone"); //NOI18N
147
148
        this.putClientProperty("PersistenceType", "Never"); //NOI18N
152
        this.putClientProperty("PersistenceType", "Never"); //NOI18N
149
153
150
        this.setLayout(new BorderLayout());
154
        this.setLayout(new BorderLayout());
Lines 165-193 Link Here
165
        actionHandler = new DataViewActionHandler(this, dataView);
169
        actionHandler = new DataViewActionHandler(this, dataView);
166
170
167
        //add resultset data panel
171
        //add resultset data panel
168
        dataPanel = new DataViewTablePanel(dataView, this, actionHandler);
172
        dataPanel = new DataViewTableUI(this, actionHandler, dataView);
169
        this.add(dataPanel, BorderLayout.CENTER);
173
        dataPanelScrollPane = new JScrollPane(dataPanel);
174
        JXTableRowHeader rowHeader = new JXTableRowHeader(dataPanel);
175
        dataPanelScrollPane.setRowHeaderView(rowHeader);
176
        dataPanelScrollPane.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowHeader.getTableHeader());
177
        
178
        this.add(dataPanelScrollPane, BorderLayout.CENTER);
170
        dataPanel.revalidate();
179
        dataPanel.revalidate();
171
        dataPanel.repaint();
180
        dataPanel.repaint();
172
    }
181
    }
173
182
183
    void handleColumnUpdated() {
184
        if (dataPanel.getModel().hasUpdates()) {
185
            commit.setEnabled(true);
186
            cancel.setEnabled(true);
187
        } else {
188
            commit.setEnabled(false);
189
            cancel.setEnabled(false);
190
        }
191
    }
192
    
174
    JButton[] getEditButtons() {
193
    JButton[] getEditButtons() {
175
        return editButtons;
194
        return editButtons;
176
    }
195
    }
177
196
178
    void setEditable(boolean editable) {
197
    void setEditable(boolean editable) {
179
        dataPanel.setEditable(editable);
198
        getDataViewTableUIModel().setEditable(editable);
180
    }
199
    }
181
200
182
    boolean isEditable() {
201
    boolean isEditable() {
183
        return dataPanel.isEditable();
202
        return getDataViewTableUIModel().isEditable();
184
    }
203
    }
185
204
186
    void setTotalCount(int count) {
205
    void setTotalCount(int count) {
187
        assert SwingUtilities.isEventDispatchThread() : "Must be called from AWT thread";  //NOI18N
206
        assert SwingUtilities.isEventDispatchThread() : "Must be called from AWT thread";  //NOI18N
188
        if (count < 0) {
207
        if (count < 0) {
189
            int pageSize = dataView.getDataViewPageContext().getPageSize();
208
            int pageSize = dataView.getDataViewPageContext().getPageSize();
190
            int totalRows = dataView.getDataViewPageContext().getCurrentRows().size();
209
            int totalRows = dataView.getDataViewPageContext().getModel().getRowCount();
191
            String NA = NbBundle.getMessage(DataViewUI.class, "LBL_not_available");
210
            String NA = NbBundle.getMessage(DataViewUI.class, "LBL_not_available");
192
            totalRowsLabel.setText(totalRows < pageSize ? totalRows + "" : NA);
211
            totalRowsLabel.setText(totalRows < pageSize ? totalRows + "" : NA);
193
        } else {
212
        } else {
Lines 200-210 Link Here
200
    }
219
    }
201
220
202
    DataViewTableUI getDataViewTableUI() {
221
    DataViewTableUI getDataViewTableUI() {
203
        return dataPanel.getDataViewTableUI();
222
        return dataPanel;
204
    }
223
    }
205
224
206
    UpdatedRowContext getUpdatedRowContext() {
225
    DataViewTableUIModel getDataViewTableUIModel() {
207
        return dataPanel.getUpdatedRowContext();
226
        return dataPanel.getModel();
208
    }
227
    }
209
228
210
    void setCommitEnabled(boolean flag) {
229
    void setCommitEnabled(boolean flag) {
Lines 216-238 Link Here
216
    }
235
    }
217
236
218
    void setDataRows(List<Object[]> rows) {
237
    void setDataRows(List<Object[]> rows) {
219
        dataPanel.createTableModel(rows);
238
        assert SwingUtilities.isEventDispatchThread() : "Must be called from AWT thread";  //NOI18N
220
    }
239
        assert rows != null;
221
240
222
    void resetValueAt(int row, int col) {
241
        DBColumn[] columns = dataView.getDataViewDBTable().getColumns().toArray(
223
        Object val = dataView.getDataViewPageContext().getColumnData(row, col);
242
                new DBColumn[0]);
224
        dataPanel.setValueAt(val, row, col);
225
    }
226
243
227
    void syncPageWithTableModel() {
244
        DataViewTableUIModel dvtm = getDataViewTableUIModel();
228
        List<Object[]> newrows = dataPanel.getPageDataFromTable();
229
        List<Object[]> oldRows = dataView.getDataViewPageContext().getCurrentRows();
230
245
231
        for (Integer row : dataView.getUpdatedRowContext().getUpdateKeys()) {
246
        dvtm.removeAllUpdates(false);
232
            newrows.set(row, oldRows.get(row));
247
248
        dvtm.setColumns(columns);
249
        dvtm.setData(rows);
233
        }
250
        }
234
        dataView.getDataViewPageContext().setCurrentRows(newrows);
235
    }
236
251
237
    void disableButtons() {
252
    void disableButtons() {
238
        assert SwingUtilities.isEventDispatchThread() : "Must be called from AWT thread";  //NOI18N
253
        assert SwingUtilities.isEventDispatchThread() : "Must be called from AWT thread";  //NOI18N
Lines 267-273 Link Here
267
    }
282
    }
268
283
269
    boolean isDirty() {
284
    boolean isDirty() {
270
        return dataPanel.isDirty();
285
        return dataPanel.getModel().hasUpdates();
271
    }
286
    }
272
287
273
    void resetToolbar(boolean wasError) {
288
    void resetToolbar(boolean wasError) {
Lines 315-321 Link Here
315
                    dataPage.first();
330
                    dataPage.first();
316
                }
331
                }
317
                insert.setEnabled(true);
332
                insert.setEnabled(true);
318
                if (getUpdatedRowContext().getUpdateKeys().isEmpty()) {
333
                if (getDataViewTableUIModel().getUpdateKeys().isEmpty()) {
319
                    commit.setEnabled(false);
334
                    commit.setEnabled(false);
320
                    cancel.setEnabled(false);
335
                    cancel.setEnabled(false);
321
                } else {
336
                } else {
Lines 352-358 Link Here
352
                } else if (src.equals(previous)) {
367
                } else if (src.equals(previous)) {
353
                    actionHandler.previousActionPerformed();
368
                    actionHandler.previousActionPerformed();
354
                } else if (src.equals(refreshField)) {
369
                } else if (src.equals(refreshField)) {
355
                    actionHandler.setMaxActionPerformed();
370
                    actionHandler.updateActionPerformed();
356
                } else if (src.equals(commit)) {
371
                } else if (src.equals(commit)) {
357
                    actionHandler.commitActionPerformed(false);
372
                    actionHandler.commitActionPerformed(false);
358
                } else if (src.equals(cancel)) {
373
                } else if (src.equals(cancel)) {
Lines 444-466 Link Here
444
        toolbar.add(limitRow);
459
        toolbar.add(limitRow);
445
460
446
        //add refresh text field
461
        //add refresh text field
447
        refreshField = new JTextField(2);
462
        refreshField = new JTextField(5);
448
        refreshField.setMinimumSize(new Dimension(30, 25));
463
        refreshField.setMinimumSize(refreshField.getPreferredSize());
464
        refreshField.setMaximumSize(refreshField.getPreferredSize());
449
        refreshField.addFocusListener(new FocusAdapter() {
465
        refreshField.addFocusListener(new FocusAdapter() {
450
            @Override
466
            @Override
451
            public void focusGained(FocusEvent e) {
467
            public void focusGained(FocusEvent e) {
452
                refreshField.selectAll();
468
                refreshField.selectAll();
453
            }
469
            }
454
            @Override
455
            public void focusLost(FocusEvent e) {
456
                if (refreshField.getText().length() > 2) {
457
                    refreshField.setMinimumSize(new Dimension(10 * refreshField.getText().length(), 25));
458
                    refreshField.setColumns(refreshField.getText().length());
459
                } else {
460
                    refreshField.setMinimumSize(new Dimension(30, 25));
461
                    refreshField.setColumns(2);
462
                }
463
            }
464
        });
470
        });
465
        refreshField.addActionListener(outputListener);
471
        refreshField.addActionListener(outputListener);
466
        toolbar.add(refreshField);
472
        toolbar.add(refreshField);
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/InsertRecordDialog.form (-2 / +2 lines)
Lines 25-31 Link Here
25
    <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
25
    <Property name="AccessibleContext.accessibleDescription" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
26
      <ResourceString bundle="org/netbeans/modules/db/dataview/output/Bundle.properties" key="InsertRecordDialog.AccessibleContext.accessibleDescription" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
26
      <ResourceString bundle="org/netbeans/modules/db/dataview/output/Bundle.properties" key="InsertRecordDialog.AccessibleContext.accessibleDescription" replaceFormat="org.openide.util.NbBundle.getMessage({sourceFileName}.class, &quot;{key}&quot;)"/>
27
    </Property>
27
    </Property>
28
    <Property name="AccessibleContext.accessibleParent" type="javax.accessibility.Accessible" editor="org.netbeans.modules.form.RADVisualComponent$AccessibleParentEditor">
28
    <Property name="AccessibleContext.accessibleParent" type="javax.accessibility.Accessible" editor="org.netbeans.modules.form.ComponentChooserEditor">
29
      <ComponentRef name="null"/>
29
      <ComponentRef name="null"/>
30
    </Property>
30
    </Property>
31
  </AccessibilityProperties>
31
  </AccessibilityProperties>
Lines 49-59 Link Here
49
  <SubComponents>
49
  <SubComponents>
50
    <Component class="javax.swing.JTextArea" name="jTextArea1">
50
    <Component class="javax.swing.JTextArea" name="jTextArea1">
51
      <Properties>
51
      <Properties>
52
        <Property name="editable" type="boolean" value="false"/>
52
        <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
53
        <Property name="background" type="java.awt.Color" editor="org.netbeans.beaninfo.editors.ColorEditor">
53
          <Color blue="f4" green="f4" id="Label.background" palette="3" red="f4" type="palette"/>
54
          <Color blue="f4" green="f4" id="Label.background" palette="3" red="f4" type="palette"/>
54
        </Property>
55
        </Property>
55
        <Property name="columns" type="int" value="20"/>
56
        <Property name="columns" type="int" value="20"/>
56
        <Property name="editable" type="boolean" value="false"/>
57
        <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
57
        <Property name="font" type="java.awt.Font" editor="org.netbeans.modules.form.editors2.FontEditor">
58
          <FontInfo relative="true">
58
          <FontInfo relative="true">
59
            <Font component="jTextArea1" property="font" relativeSize="true" size="0"/>
59
            <Font component="jTextArea1" property="font" relativeSize="true" size="0"/>
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/InsertRecordDialog.java (-19 / +21 lines)
Lines 58-64 Link Here
58
import java.awt.event.ActionEvent;
58
import java.awt.event.ActionEvent;
59
import java.awt.event.KeyEvent;
59
import java.awt.event.KeyEvent;
60
import java.awt.event.KeyListener;
60
import java.awt.event.KeyListener;
61
import java.util.ArrayList;
62
import java.util.Arrays;
61
import java.util.Arrays;
63
import java.util.List;
62
import java.util.List;
64
import java.util.StringTokenizer;
63
import java.util.StringTokenizer;
Lines 77-87 Link Here
77
import javax.swing.border.EmptyBorder;
76
import javax.swing.border.EmptyBorder;
78
import javax.swing.event.TableModelEvent;
77
import javax.swing.event.TableModelEvent;
79
import javax.swing.event.TableModelListener;
78
import javax.swing.event.TableModelListener;
80
import javax.swing.table.DefaultTableModel;
81
import javax.swing.table.TableCellEditor;
79
import javax.swing.table.TableCellEditor;
82
import org.netbeans.modules.db.dataview.meta.DBException;
80
import org.netbeans.modules.db.dataview.meta.DBException;
83
import org.openide.text.CloneableEditorSupport;
81
import org.openide.text.CloneableEditorSupport;
84
import org.netbeans.modules.db.dataview.meta.DBColumn;
82
import org.netbeans.modules.db.dataview.meta.DBColumn;
83
import org.netbeans.modules.db.dataview.table.ResultSetTableModel;
85
import org.netbeans.modules.db.dataview.util.DBReadWriteHelper;
84
import org.netbeans.modules.db.dataview.util.DBReadWriteHelper;
86
import org.netbeans.modules.db.dataview.util.DataViewUtils;
85
import org.netbeans.modules.db.dataview.util.DataViewUtils;
87
import org.openide.DialogDisplayer;
86
import org.openide.DialogDisplayer;
Lines 98-104 Link Here
98
 *
97
 *
99
 */
98
 */
100
class InsertRecordDialog extends javax.swing.JDialog {
99
class InsertRecordDialog extends javax.swing.JDialog {
101
100
    private final ResultSetTableModel insertDataModel;
102
    private final DataView dataView;
101
    private final DataView dataView;
103
    InsertRecordTableUI insertRecordTableUI;
102
    InsertRecordTableUI insertRecordTableUI;
104
    private JXTableRowHeader rowHeader;
103
    private JXTableRowHeader rowHeader;
Lines 106-116 Link Here
106
    public InsertRecordDialog(DataView dataView) {
105
    public InsertRecordDialog(DataView dataView) {
107
        super(WindowManager.getDefault().getMainWindow(), true);
106
        super(WindowManager.getDefault().getMainWindow(), true);
108
        this.dataView = dataView;
107
        this.dataView = dataView;
109
        insertRecordTableUI = new InsertRecordTableUI(dataView) {
108
109
        insertDataModel = new ResultSetTableModel(
110
                dataView.getDataViewDBTable().getColumns().toArray(new DBColumn[0])
111
                );
112
        insertDataModel.setEditable(true);
113
        
114
        insertRecordTableUI = new InsertRecordTableUI() {
110
115
111
            @Override
116
            @Override
112
            public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
117
            public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
113
                if (rowIndex != -1 && columnIndex != -1 && ((DefaultTableModel) insertRecordTableUI.getModel()).getRowCount() > 1) {
118
                if (rowIndex != -1 && columnIndex != -1 && getModel().getRowCount() > 1) {
114
                    removeBtn.setEnabled(true);
119
                    removeBtn.setEnabled(true);
115
                }
120
                }
116
                AWTEvent awtEvent = EventQueue.getCurrentEvent();
121
                AWTEvent awtEvent = EventQueue.getCurrentEvent();
Lines 120-127 Link Here
120
                        return;
125
                        return;
121
                    }
126
                    }
122
                    if (rowIndex == 0 && columnIndex == 0 && KeyStroke.getKeyStrokeForEvent(keyEvt).equals(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0))) {
127
                    if (rowIndex == 0 && columnIndex == 0 && KeyStroke.getKeyStrokeForEvent(keyEvt).equals(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0))) {
123
                        DefaultTableModel model = (DefaultTableModel) getModel();
128
                        appendEmptyRow();
124
                        model.addRow(createNewRow());
125
                        rowIndex = getRowCount() - 1; //Otherwise the selection switches to the first row
129
                        rowIndex = getRowCount() - 1; //Otherwise the selection switches to the first row
126
                        editCellAt(rowIndex, 0);
130
                        editCellAt(rowIndex, 0);
127
                    } else if (KeyStroke.getKeyStrokeForEvent(keyEvt).equals(KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT + KeyEvent.VK_TAB, 0))) {
131
                    } else if (KeyStroke.getKeyStrokeForEvent(keyEvt).equals(KeyStroke.getKeyStroke(KeyEvent.VK_SHIFT + KeyEvent.VK_TAB, 0))) {
Lines 133-138 Link Here
133
                super.changeSelection(rowIndex, columnIndex, toggle, extend);
137
                super.changeSelection(rowIndex, columnIndex, toggle, extend);
134
            }
138
            }
135
        };
139
        };
140
        
141
        insertRecordTableUI.setModel(insertDataModel);
142
        
136
        initComponents();
143
        initComponents();
137
        addInputFields();
144
        addInputFields();
138
        insertRecordTableUI.addKeyListener(new TableKeyListener());
145
        insertRecordTableUI.addKeyListener(new TableKeyListener());
Lines 331-338 Link Here
331
    }// </editor-fold>//GEN-END:initComponents
338
    }// </editor-fold>//GEN-END:initComponents
332
339
333
private void addBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addBtnActionPerformed
340
private void addBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_addBtnActionPerformed
334
    DefaultTableModel model = (DefaultTableModel) insertRecordTableUI.getModel();
341
    insertRecordTableUI.appendEmptyRow();
335
    model.addRow(insertRecordTableUI.createNewRow());
336
}//GEN-LAST:event_addBtnActionPerformed
342
}//GEN-LAST:event_addBtnActionPerformed
337
343
338
private void removeBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeBtnActionPerformed
344
private void removeBtnActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_removeBtnActionPerformed
Lines 390-396 Link Here
390
                    if (wasException) {
396
                    if (wasException) {
391
                        // remove i already inserted
397
                        // remove i already inserted
392
                        for (int j = 0; j < i; j++) {
398
                        for (int j = 0; j < i; j++) {
393
                            ((DefaultTableModel) insertRecordTableUI.getModel()).removeRow(0);
399
                            insertRecordTableUI.getModel().removeRow(0);
394
                        }
400
                        }
395
                        // return without closing
401
                        // return without closing
396
                        return;
402
                        return;
Lines 441-448 Link Here
441
    }
447
    }
442
448
443
    private void addInputFields() {
449
    private void addInputFields() {
444
        List<Object[]> rows = new ArrayList<Object[]>();
450
        insertRecordTableUI.appendEmptyRow();
445
        rows.add(insertRecordTableUI.createNewRow());
446
        jScrollPane1.setViewportView(insertRecordTableUI);
451
        jScrollPane1.setViewportView(insertRecordTableUI);
447
        rowHeader = new JXTableRowHeader(insertRecordTableUI);
452
        rowHeader = new JXTableRowHeader(insertRecordTableUI);
448
        final Component order[] = new Component[]{rowHeader, insertRecordTableUI};
453
        final Component order[] = new Component[]{rowHeader, insertRecordTableUI};
Lines 484-502 Link Here
484
        setFocusTraversalPolicy(policy);
489
        setFocusTraversalPolicy(policy);
485
        jScrollPane1.setRowHeaderView(rowHeader);
490
        jScrollPane1.setRowHeaderView(rowHeader);
486
        jScrollPane1.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowHeader.getTableHeader());
491
        jScrollPane1.setCorner(JScrollPane.UPPER_LEFT_CORNER, rowHeader.getTableHeader());
487
        insertRecordTableUI.createTableModel(rows, rowHeader);
488
    }
492
    }
489
493
490
    private Object[] getInsertValues(int row) throws DBException {
494
    private Object[] getInsertValues(int row) throws DBException {
491
        DefaultTableModel model = (DefaultTableModel) insertRecordTableUI.getModel();
495
        Object[] insertData = new Object[insertDataModel.getColumnCount()];
492
        int rsColumnCount = insertRecordTableUI.getRSColumnCount();
493
        Object[] insertData = new Object[rsColumnCount];
494
        if (insertRecordTableUI.getRowCount() <= 0) {
496
        if (insertRecordTableUI.getRowCount() <= 0) {
495
            return insertData;
497
            return insertData;
496
        }
498
        }
497
        for (int i = 0; i < rsColumnCount; i++) {
499
        for (int i = 0; i < insertDataModel.getColumnCount(); i++) {
498
            DBColumn col = insertRecordTableUI.getDBColumn(i);
500
            DBColumn col = insertDataModel.getColumn(i);
499
            Object val = model.getValueAt(row, i);
501
            Object val = insertDataModel.getValueAt(row, i);
500
502
501
            // Check for Constant e.g <NULL>, <DEFAULT>, <CURRENT_TIMESTAMP> etc
503
            // Check for Constant e.g <NULL>, <DEFAULT>, <CURRENT_TIMESTAMP> etc
502
            if (DataViewUtils.isSQLConstantString(val, col)) {
504
            if (DataViewUtils.isSQLConstantString(val, col)) {
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/InsertRecordTableUI.java (-15 / +26 lines)
Lines 44-52 Link Here
44
import org.netbeans.modules.db.dataview.table.ResultSetJXTable;
44
import org.netbeans.modules.db.dataview.table.ResultSetJXTable;
45
import java.sql.Types;
45
import java.sql.Types;
46
import java.util.Arrays;
46
import java.util.Arrays;
47
import javax.swing.table.DefaultTableModel;
48
import org.jdesktop.swingx.JXTable;
47
import org.jdesktop.swingx.JXTable;
49
import org.netbeans.modules.db.dataview.meta.DBColumn;
48
import org.netbeans.modules.db.dataview.meta.DBColumn;
49
import org.netbeans.modules.db.dataview.table.ResultSetTableModel;
50
50
51
/**
51
/**
52
 * @author Shankari
52
 * @author Shankari
Lines 55-72 Link Here
55
55
56
    boolean isRowSelectionAllowed = rowSelectionAllowed;
56
    boolean isRowSelectionAllowed = rowSelectionAllowed;
57
57
58
    public InsertRecordTableUI(DataView dataView) {
58
    public InsertRecordTableUI() {
59
        super(dataView);
59
        if (getColumnModel().getColumnCount() < 7) {
60
        if (getRSColumnCount() < 7) {
61
            setAutoResizeMode(JXTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
60
            setAutoResizeMode(JXTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS);
62
        }
61
        }
63
    }   
62
    }   
64
63
65
    // Must correspond to DataViewUtils#isSQLConstantString!
64
    // Must correspond to DataViewUtils#isSQLConstantString!
66
    protected Object[] createNewRow() {
65
    protected void appendEmptyRow() {
67
        Object[] row = new Object[getRSColumnCount()];
66
        Object[] row = new Object[getModel().getColumnCount()];
68
        for (int i = 0, I = getRSColumnCount(); i < I; i++) {
67
        for (int i = 0, I = getModel().getColumnCount(); i < I; i++) {
69
            DBColumn col = getDBColumn(i);
68
            DBColumn col = getModel().getColumn(i);
70
            if (col.isGenerated()) {
69
            if (col.isGenerated()) {
71
                row[i] = "<GENERATED>";
70
                row[i] = "<GENERATED>";
72
            } else if (col.hasDefault()) {
71
            } else if (col.hasDefault()) {
Lines 79-100 Link Here
79
                row[i] = "<CURRENT_TIME>";
78
                row[i] = "<CURRENT_TIME>";
80
            }
79
            }
81
        }
80
        }
82
        return row;
81
        getModel().addRow(row);
83
    }
82
    }
84
83
85
    protected void removeRows() {
84
    protected void removeRows() {
86
        if (isEditing()) {
85
        if (isEditing()) {
87
            getCellEditor().cancelCellEditing();
86
            getCellEditor().cancelCellEditing();
88
        }
87
        }
88
        
89
        int[] rows = getSelectedRows();
89
        int[] rows = getSelectedRows();
90
        if (rows.length == 0) return ;
90
        
91
        Arrays.sort(rows);
91
        if (rows.length == 0) {
92
        DefaultTableModel model = (DefaultTableModel) getModel();
92
            return ;
93
        for (int i = (rows.length - 1); i >= 0; i--) {
94
            model.removeRow(rows[i]);
95
        }
93
        }
94
95
        int[] modelRows = new int[rows.length];
96
        
97
        for(int i = 0; i < modelRows.length; i++) {
98
            modelRows[i] = convertRowIndexToModel(rows[i]);
99
        }
100
        
101
        Arrays.sort(modelRows);
102
        
103
        for (int i = (modelRows.length - 1); i >= 0; i--) {
104
            getModel().removeRow(modelRows[i]);
105
        }
106
        
96
        if (getRowCount() == 0) {
107
        if (getRowCount() == 0) {
97
            model.addRow(createNewRow());
108
            appendEmptyRow();
98
        }
109
        }
99
    }
110
    }
100
}
111
}
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/SQLExecutionHelper.java (-26 / +32 lines)
Lines 51-56 Link Here
51
import java.sql.Types;
51
import java.sql.Types;
52
import java.text.NumberFormat;
52
import java.text.NumberFormat;
53
import java.util.ArrayList;
53
import java.util.ArrayList;
54
import java.util.Arrays;
54
import java.util.Collection;
55
import java.util.Collection;
55
import java.util.HashSet;
56
import java.util.HashSet;
56
import java.util.List;
57
import java.util.List;
Lines 86-91 Link Here
86
    private static final String LIMIT_CLAUSE = "LIMIT "; // NOI18N
87
    private static final String LIMIT_CLAUSE = "LIMIT "; // NOI18N
87
    public static final String OFFSET_CLAUSE = "OFFSET "; // NOI18N
88
    public static final String OFFSET_CLAUSE = "OFFSET "; // NOI18N
88
    private static final Logger LOGGER = Logger.getLogger(SQLExecutionHelper.class.getName());
89
    private static final Logger LOGGER = Logger.getLogger(SQLExecutionHelper.class.getName());
90
    private boolean limitSupported = false;
89
91
90
    SQLExecutionHelper(DataView dataView) {
92
    SQLExecutionHelper(DataView dataView) {
91
        this.dataView = dataView;
93
        this.dataView = dataView;
Lines 133-139 Link Here
133
                        throw new SQLException(msg, t);
135
                        throw new SQLException(msg, t);
134
                    }
136
                    }
135
                    DBMetaDataFactory dbMeta = new DBMetaDataFactory(conn);
137
                    DBMetaDataFactory dbMeta = new DBMetaDataFactory(conn);
136
                    dataView.setLimitSupported(dbMeta.supportsLimit());
138
                    limitSupported = dbMeta.supportsLimit();
137
                    String sql = dataView.getSQLString();
139
                    String sql = dataView.getSQLString();
138
                    boolean isSelect = isSelectStatement(sql);
140
                    boolean isSelect = isSelectStatement(sql);
139
141
Lines 145-150 Link Here
145
                    if (Thread.interrupted()) {
147
                    if (Thread.interrupted()) {
146
                        return;
148
                        return;
147
                    }
149
                    }
150
                    
148
                    executeSQLStatement(stmt, sql);
151
                    executeSQLStatement(stmt, sql);
149
152
150
                    if (dataView.getUpdateCount() != -1) {
153
                    if (dataView.getUpdateCount() != -1) {
Lines 172-179 Link Here
172
                    Collection<DBTable> tables = dbMeta.generateDBTables(
175
                    Collection<DBTable> tables = dbMeta.generateDBTables(
173
                            rs, sql, isSelect);
176
                            rs, sql, isSelect);
174
                    DataViewDBTable dvTable = new DataViewDBTable(tables);
177
                    DataViewDBTable dvTable = new DataViewDBTable(tables);
178
                    dataView.getDataViewPageContext().getModel().setColumns(
179
                            dvTable.getColumns().toArray(new DBColumn[0]));
175
                    dataView.setDataViewDBTable(dvTable);
180
                    dataView.setDataViewDBTable(dvTable);
176
                    if (resultSetNeedsReloading()) {
181
                    if (resultSetNeedsReloading(dvTable)) {
177
                        executeSQLStatement(stmt, sql);
182
                        executeSQLStatement(stmt, sql);
178
                        rs = stmt.getResultSet();
183
                        rs = stmt.getResultSet();
179
                    }
184
                    }
Lines 299-319 Link Here
299
    void executeDeleteRow(final DataViewTableUI rsTable) {
304
    void executeDeleteRow(final DataViewTableUI rsTable) {
300
        String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_delete");
305
        String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_delete");
301
        final int[] rows = rsTable.getSelectedRows();
306
        final int[] rows = rsTable.getSelectedRows();
307
        for(int i = 0; i < rows.length; i++) {
308
            rows[i] = rsTable.convertRowIndexToModel(rows[i]);
309
        }
310
        Arrays.sort(rows);
302
        SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") {
311
        SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") {
303
312
304
            @Override
313
            @Override
305
            public void execute() throws SQLException, DBException {
314
            public void execute() throws SQLException, DBException {
306
                dataView.setEditable(false);
315
                dataView.setEditable(false);
307
316
                for (int j = (rows.length - 1); j >= 0 && !error; j--) {
308
                for (int j = 0; j < rows.length && !error; j++) {
309
                    if (Thread.currentThread().isInterrupted()) {
317
                    if (Thread.currentThread().isInterrupted()) {
310
                        break;
318
                        break;
311
                    }
319
                    }
312
                    deleteARow(rsTable.convertRowIndexToModel(rows[j]), rsTable.getModel());
320
                    deleteARow(rows[j], rsTable.getModel());
313
                }
321
                }
314
            }
322
            }
315
323
316
            private void deleteARow(int rowNum, TableModel tblModel) throws SQLException, DBException {
324
            private void deleteARow(int rowNum, DataViewTableUIModel tblModel) throws SQLException, DBException {
317
                final List<Object> values = new ArrayList<Object>();
325
                final List<Object> values = new ArrayList<Object>();
318
                final List<Integer> types = new ArrayList<Integer>();
326
                final List<Integer> types = new ArrayList<Integer>();
319
327
Lines 360-366 Link Here
360
    }
368
    }
361
369
362
    void executeUpdateRow(final DataViewTableUI rsTable, final boolean selectedOnly) {
370
    void executeUpdateRow(final DataViewTableUI rsTable, final boolean selectedOnly) {
363
        String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_update");
371
        final DataViewTableUIModel dataViewTableUIModel = rsTable.getModel();
372
        String title = NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_update");        
364
        SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") {
373
        SQLStatementExecutor executor = new SQLStatementExecutor(dataView, title, "") {
365
374
366
            private PreparedStatement pstmt;
375
            private PreparedStatement pstmt;
Lines 372-378 Link Here
372
                if (selectedOnly) {
381
                if (selectedOnly) {
373
                    updateSelected();
382
                    updateSelected();
374
                } else {
383
                } else {
375
                    for (Integer key : dataView.getUpdatedRowContext().getUpdateKeys()) {
384
                    for (Integer key : dataViewTableUIModel.getUpdateKeys()) {
376
                        if (Thread.currentThread().isInterrupted()) {
385
                        if (Thread.currentThread().isInterrupted()) {
377
                            break;
386
                            break;
378
                        } else {
387
                        } else {
Lines 385-393 Link Here
385
394
386
            private void updateSelected() throws SQLException, DBException {
395
            private void updateSelected() throws SQLException, DBException {
387
                int[] rows = rsTable.getSelectedRows();
396
                int[] rows = rsTable.getSelectedRows();
388
                UpdatedRowContext tblContext = dataView.getUpdatedRowContext();
389
                for (int j = 0; j < rows.length && !error; j++) {
397
                for (int j = 0; j < rows.length && !error; j++) {
390
                    Set<Integer> keys = tblContext.getUpdateKeys();
398
                    Set<Integer> keys = dataViewTableUIModel.getUpdateKeys();
391
                    for (Integer key : keys) {
399
                    for (Integer key : keys) {
392
                        if (Thread.currentThread().isInterrupted()) {
400
                        if (Thread.currentThread().isInterrupted()) {
393
                            break;
401
                            break;
Lines 400-411 Link Here
400
            }
408
            }
401
409
402
            private void updateARow(Integer key) throws SQLException, DBException {
410
            private void updateARow(Integer key) throws SQLException, DBException {
403
                UpdatedRowContext updatedRowCtx = dataView.getUpdatedRowContext();
404
                SQLStatementGenerator generator = dataView.getSQLStatementGenerator();
411
                SQLStatementGenerator generator = dataView.getSQLStatementGenerator();
405
412
406
                List<Object> values = new ArrayList<Object>();
413
                List<Object> values = new ArrayList<Object>();
407
                List<Integer> types = new ArrayList<Integer>();
414
                List<Integer> types = new ArrayList<Integer>();
408
                String updateStmt = generator.generateUpdateStatement(key, updatedRowCtx.getChangedData(key), values, types, rsTable.getModel());
415
                String updateStmt = generator.generateUpdateStatement(key, dataViewTableUIModel.getChangedData(key), values, types, rsTable.getModel());
409
416
410
                pstmt = conn.prepareStatement(updateStmt);
417
                pstmt = conn.prepareStatement(updateStmt);
411
                int pos = 1;
418
                int pos = 1;
Lines 437-447 Link Here
437
444
438
            @Override
445
            @Override
439
            protected void executeOnSucess() {
446
            protected void executeOnSucess() {
440
                UpdatedRowContext tblContext = dataView.getUpdatedRowContext();
447
                DataViewTableUIModel tblContext = dataView.getDataViewTableUIModel();
441
                for (Integer key : keysToRemove) {
448
                for (Integer key : keysToRemove) {
442
                    tblContext.removeUpdateForSelectedRow(key);
449
                    tblContext.removeUpdateForSelectedRow(key, false);
443
                }
450
                }
444
                dataView.syncPageWithTableModel();
445
                reinstateToolbar();
451
                reinstateToolbar();
446
            }
452
            }
447
        };
453
        };
Lines 553-561 Link Here
553
                    if (error) {
559
                    if (error) {
554
                        dataView.setErrorStatusText(ex);
560
                        dataView.setErrorStatusText(ex);
555
                    }
561
                    }
556
                    dataView.getUpdatedRowContext().removeAllUpdates();
557
                    dataView.resetToolbar(error);
562
                    dataView.resetToolbar(error);
558
                    dataView.setRowsInTableModel();
559
                }
563
                }
560
            }
564
            }
561
565
Lines 585-591 Link Here
585
589
586
        int pageSize = dataView.getDataViewPageContext().getPageSize();
590
        int pageSize = dataView.getDataViewPageContext().getPageSize();
587
        int startFrom = 0;
591
        int startFrom = 0;
588
        if (!dataView.isLimitSupported() || isLimitUsedInSelect(dataView.getSQLString())) {
592
        if (! limitSupported || isLimitUsedInSelect(dataView.getSQLString())) {
589
            startFrom = dataView.getDataViewPageContext().getCurrentPos() - 1;
593
            startFrom = dataView.getDataViewPageContext().getCurrentPos() - 1;
590
        }
594
        }
591
595
Lines 628-634 Link Here
628
            LOGGER.log(Level.SEVERE, "Failed to set up table model.", e); // NOI18N
632
            LOGGER.log(Level.SEVERE, "Failed to set up table model.", e); // NOI18N
629
            throw e;
633
            throw e;
630
        } finally {
634
        } finally {
631
            dataView.getDataViewPageContext().setCurrentRows(rows);
635
            dataView.getDataViewPageContext().getModel().setData(rows);
632
        }
636
        }
633
    }
637
    }
634
638
Lines 636-645 Link Here
636
        try {
640
        try {
637
            if (countresultSet == null) {
641
            if (countresultSet == null) {
638
                dataView.getDataViewPageContext().setTotalRows(-1);
642
                dataView.getDataViewPageContext().setTotalRows(-1);
643
                dataView.setTotalRowCount(-1);
639
            } else {
644
            } else {
640
                if (countresultSet.next()) {
645
                if (countresultSet.next()) {
641
                    int count = countresultSet.getInt(1);
646
                    int count = countresultSet.getInt(1);
642
                    dataView.getDataViewPageContext().setTotalRows(count);
647
                    dataView.getDataViewPageContext().setTotalRows(count);
648
                    dataView.setTotalRowCount(count);
643
                }
649
                }
644
            }
650
            }
645
        } catch (SQLException ex) {
651
        } catch (SQLException ex) {
Lines 648-654 Link Here
648
    }
654
    }
649
655
650
    private String appendLimitIfRequired(String sql) {
656
    private String appendLimitIfRequired(String sql) {
651
        if (dataView.isLimitSupported() && isSelectStatement(sql)) {
657
        if (limitSupported && isSelectStatement(sql)) {
652
            if (!isLimitUsedInSelect(sql)) {
658
            if (!isLimitUsedInSelect(sql)) {
653
                sql += ' ' + LIMIT_CLAUSE + dataView.getDataViewPageContext().getPageSize();
659
                sql += ' ' + LIMIT_CLAUSE + dataView.getDataViewPageContext().getPageSize();
654
                sql += ' ' + OFFSET_CLAUSE + (dataView.getDataViewPageContext().getCurrentPos() - 1);
660
                sql += ' ' + OFFSET_CLAUSE + (dataView.getDataViewPageContext().getCurrentPos() - 1);
Lines 661-667 Link Here
661
    private Statement prepareSQLStatement(Connection conn, String sql) throws SQLException {
667
    private Statement prepareSQLStatement(Connection conn, String sql) throws SQLException {
662
        Statement stmt = null;
668
        Statement stmt = null;
663
        if (sql.startsWith("{")) { // NOI18N
669
        if (sql.startsWith("{")) { // NOI18N
664
665
            stmt = conn.prepareCall(sql);
670
            stmt = conn.prepareCall(sql);
666
        } else if (isSelectStatement(sql)) {
671
        } else if (isSelectStatement(sql)) {
667
            stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
672
            stmt = conn.createStatement(ResultSet.TYPE_FORWARD_ONLY, ResultSet.CONCUR_READ_ONLY);
Lines 675-681 Link Here
675
            }
680
            }
676
681
677
            try {
682
            try {
678
                if (dataView.isLimitSupported() && ! isLimitUsedInSelect(sql)) {
683
                if ( limitSupported && ! isLimitUsedInSelect(sql)) {
679
                    stmt.setMaxRows(pageSize);
684
                    stmt.setMaxRows(pageSize);
680
                } else {
685
                } else {
681
                    stmt.setMaxRows(dataView.getDataViewPageContext().getCurrentPos() + pageSize);
686
                    stmt.setMaxRows(dataView.getDataViewPageContext().getCurrentPos() + pageSize);
Lines 689-695 Link Here
689
        return stmt;
694
        return stmt;
690
    }
695
    }
691
696
692
    private void executeSQLStatement(Statement stmt, String sql) throws SQLException {
697
    private boolean executeSQLStatement(Statement stmt, String sql) throws SQLException {
693
        LOGGER.log(Level.FINE, "Statement: {0}", sql); // NOI18N
698
        LOGGER.log(Level.FINE, "Statement: {0}", sql); // NOI18N
694
        dataView.setInfoStatusText(NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_executestmt") + sql);
699
        dataView.setInfoStatusText(NbBundle.getMessage(SQLExecutionHelper.class, "LBL_sql_executestmt") + sql);
695
700
Lines 719-724 Link Here
719
            dataView.setUpdateCount(stmt.getUpdateCount());
724
            dataView.setUpdateCount(stmt.getUpdateCount());
720
            dataView.setExecutionTime(executionTime);
725
            dataView.setExecutionTime(executionTime);
721
        }
726
        }
727
        return isResultSet;
722
    }
728
    }
723
729
724
    private void executePreparedStatement(PreparedStatement stmt) throws SQLException {
730
    private void executePreparedStatement(PreparedStatement stmt) throws SQLException {
Lines 840-853 Link Here
840
     *
846
     *
841
     * @return True if and only if the result set needs to be reloaded.
847
     * @return True if and only if the result set needs to be reloaded.
842
     */
848
     */
843
    private boolean resultSetNeedsReloading() {
849
    private boolean resultSetNeedsReloading(DataViewDBTable metadata) {
844
        if (!dataView.getDatabaseConnection().getDriverClass().contains(
850
        if (!dataView.getDatabaseConnection().getDriverClass().contains(
845
                "oracle")) {                                            //NOI18N
851
                "oracle")) {                                            //NOI18N
846
            return false;
852
            return false;
847
        }
853
        }
848
        int colCnt = dataView.getDataViewDBTable().getColumnCount();
854
        int colCnt = metadata.getColumnCount();
849
        for (int i = 0; i < colCnt; i++) {
855
        for (int i = 0; i < colCnt; i++) {
850
            DBColumn column = dataView.getDataViewDBTable().getColumn(i);
856
            DBColumn column = metadata.getColumn(i);
851
            int jdbcType = column.getJdbcType();
857
            int jdbcType = column.getJdbcType();
852
            if (jdbcType == Types.LONGVARCHAR || jdbcType == Types.LONGNVARCHAR
858
            if (jdbcType == Types.LONGVARCHAR || jdbcType == Types.LONGNVARCHAR
853
                    || jdbcType == Types.LONGVARBINARY || jdbcType == Types.BLOB
859
                    || jdbcType == Types.LONGVARBINARY || jdbcType == Types.BLOB
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/output/SQLStatementGenerator.java (-11 / +10 lines)
Lines 52-58 Link Here
52
import java.util.Map;
52
import java.util.Map;
53
import java.util.logging.Level;
53
import java.util.logging.Level;
54
import java.util.logging.Logger;
54
import java.util.logging.Logger;
55
import javax.swing.table.TableModel;
56
import org.netbeans.modules.db.dataview.meta.DBColumn;
55
import org.netbeans.modules.db.dataview.meta.DBColumn;
57
import org.netbeans.modules.db.dataview.meta.DBConnectionFactory;
56
import org.netbeans.modules.db.dataview.meta.DBConnectionFactory;
58
import org.netbeans.modules.db.dataview.meta.DBException;
57
import org.netbeans.modules.db.dataview.meta.DBException;
Lines 174-180 Link Here
174
        return rawInsertSql.toString();
173
        return rawInsertSql.toString();
175
    }
174
    }
176
175
177
    String generateUpdateStatement(int row, Map<Integer, Object> changedRow, List<Object> values, List<Integer> types, TableModel tblModel) throws DBException {
176
    String generateUpdateStatement(int row, Map<Integer, Object> changedRow, List<Object> values, List<Integer> types, DataViewTableUIModel tblModel) throws DBException {
178
        StringBuilder updateStmt = new StringBuilder();
177
        StringBuilder updateStmt = new StringBuilder();
179
        updateStmt.append("UPDATE ").append(tblMeta.getFullyQualifiedName(0, true)).append(" SET "); // NOI18N
178
        updateStmt.append("UPDATE ").append(tblMeta.getFullyQualifiedName(0, true)).append(" SET "); // NOI18N
180
        String commaStr = ", "; // NOI18N
179
        String commaStr = ", "; // NOI18N
Lines 214-220 Link Here
214
        return updateStmt.toString();
213
        return updateStmt.toString();
215
    }
214
    }
216
215
217
    String generateUpdateStatement(int row, Map<Integer, Object> changedRow, TableModel tblModel) throws DBException {
216
    String generateUpdateStatement(int row, Map<Integer, Object> changedRow, DataViewTableUIModel tblModel) throws DBException {
218
        StringBuilder rawUpdateStmt = new StringBuilder();
217
        StringBuilder rawUpdateStmt = new StringBuilder();
219
        rawUpdateStmt.append("UPDATE ").append(tblMeta.getFullyQualifiedName(0, false)).append(" SET "); // NOI18N
218
        rawUpdateStmt.append("UPDATE ").append(tblMeta.getFullyQualifiedName(0, false)).append(" SET "); // NOI18N
220
219
Lines 250-256 Link Here
250
        return rawUpdateStmt.toString();
249
        return rawUpdateStmt.toString();
251
    }
250
    }
252
251
253
    String generateDeleteStatement(List<Integer> types, List<Object> values, int rowNum, TableModel tblModel) {
252
    String generateDeleteStatement(List<Integer> types, List<Object> values, int rowNum, DataViewTableUIModel tblModel) {
254
        StringBuilder deleteStmt = new StringBuilder();
253
        StringBuilder deleteStmt = new StringBuilder();
255
        deleteStmt.append("DELETE FROM ").append(tblMeta.getFullyQualifiedName(0, true)).append(" WHERE "); // NOI18N
254
        deleteStmt.append("DELETE FROM ").append(tblMeta.getFullyQualifiedName(0, true)).append(" WHERE "); // NOI18N
256
255
Lines 258-264 Link Here
258
        return deleteStmt.toString();
257
        return deleteStmt.toString();
259
    }
258
    }
260
259
261
    String generateDeleteStatement(int rowNum, TableModel tblModel) {
260
    String generateDeleteStatement(int rowNum, DataViewTableUIModel tblModel) {
262
        StringBuilder rawDeleteStmt = new StringBuilder();
261
        StringBuilder rawDeleteStmt = new StringBuilder();
263
        rawDeleteStmt.append("DELETE FROM ").append(tblMeta.getFullyQualifiedName(0, false)).append(" WHERE "); // NOI18N
262
        rawDeleteStmt.append("DELETE FROM ").append(tblMeta.getFullyQualifiedName(0, false)).append(" WHERE "); // NOI18N
264
263
Lines 395-401 Link Here
395
        }
394
        }
396
    }
395
    }
397
396
398
    private void generateWhereCondition(StringBuilder result, List<Integer> types, List<Object> values, int rowNum, TableModel model) {
397
    private void generateWhereCondition(StringBuilder result, List<Integer> types, List<Object> values, int rowNum, DataViewTableUIModel model) {
399
        DBPrimaryKey key = tblMeta.geTable(0).getPrimaryKey();
398
        DBPrimaryKey key = tblMeta.geTable(0).getPrimaryKey();
400
        boolean keySelected = false;
399
        boolean keySelected = false;
401
        boolean and = false;
400
        boolean and = false;
Lines 405-411 Link Here
405
                for (int i = 0; i < model.getColumnCount(); i++) {
404
                for (int i = 0; i < model.getColumnCount(); i++) {
406
                    String columnName = tblMeta.getColumnName(i);
405
                    String columnName = tblMeta.getColumnName(i);
407
                    if (columnName.equals(keyName)) {
406
                    if (columnName.equals(keyName)) {
408
                        Object val = dataView.getDataViewPageContext().getColumnData(rowNum, i);
407
                        Object val = model.getOriginalValueAt(rowNum, i);
409
                        if (val != null) {
408
                        if (val != null) {
410
                            keySelected = true;
409
                            keySelected = true;
411
                            and = addSeparator(and, result, " AND "); // NOI18N
410
                            and = addSeparator(and, result, " AND "); // NOI18N
Lines 419-432 Link Here
419
418
420
        if (key == null || !keySelected) {
419
        if (key == null || !keySelected) {
421
            for (int i = 0; i < model.getColumnCount(); i++) {
420
            for (int i = 0; i < model.getColumnCount(); i++) {
422
                Object val = dataView.getDataViewPageContext().getColumnData(rowNum, i);
421
                Object val = model.getOriginalValueAt(rowNum, i);
423
                and = addSeparator(and, result, " AND "); // NOI18N
422
                and = addSeparator(and, result, " AND "); // NOI18N
424
                generateNameValue(i, result, val, values, types);
423
                generateNameValue(i, result, val, values, types);
425
            }
424
            }
426
        }
425
        }
427
    }
426
    }
428
427
429
    private void generateWhereCondition(StringBuilder sql, int rowNum, TableModel model) {
428
    private void generateWhereCondition(StringBuilder sql, int rowNum, DataViewTableUIModel model) {
430
        DBPrimaryKey key = tblMeta.geTable(0).getPrimaryKey();
429
        DBPrimaryKey key = tblMeta.geTable(0).getPrimaryKey();
431
        boolean keySelected = false;
430
        boolean keySelected = false;
432
        boolean and = false;
431
        boolean and = false;
Lines 436-442 Link Here
436
                for (int i = 0; i < model.getColumnCount(); i++) {
435
                for (int i = 0; i < model.getColumnCount(); i++) {
437
                    String columnName = tblMeta.getColumnName(i);
436
                    String columnName = tblMeta.getColumnName(i);
438
                    if (columnName.equals(keyName)) {
437
                    if (columnName.equals(keyName)) {
439
                        Object val = dataView.getDataViewPageContext().getColumnData(rowNum, i);
438
                        Object val = model.getOriginalValueAt(rowNum, i);
440
                        if (val != null) {
439
                        if (val != null) {
441
                            keySelected = true;
440
                            keySelected = true;
442
                            and = addSeparator(and, sql, " AND "); // NOI18N
441
                            and = addSeparator(and, sql, " AND "); // NOI18N
Lines 450-456 Link Here
450
449
451
        if (key == null || !keySelected) {
450
        if (key == null || !keySelected) {
452
            for (int i = 0; i < model.getColumnCount(); i++) {
451
            for (int i = 0; i < model.getColumnCount(); i++) {
453
                Object val = dataView.getDataViewPageContext().getColumnData(rowNum, i);
452
                Object val = model.getOriginalValueAt(rowNum, i);
454
                and = addSeparator(and, sql, " AND "); // NOI18N
453
                and = addSeparator(and, sql, " AND "); // NOI18N
455
                generateNameValue(i, sql, val);
454
                generateNameValue(i, sql, val);
456
            }
455
            }
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/table/ResultSetJXTable.java (-101 / +94 lines)
Lines 41-47 Link Here
41
 */
41
 */
42
package org.netbeans.modules.db.dataview.table;
42
package org.netbeans.modules.db.dataview.table;
43
43
44
import java.awt.Color;
45
import java.awt.datatransfer.StringSelection;
44
import java.awt.datatransfer.StringSelection;
46
import java.awt.datatransfer.Transferable;
45
import java.awt.datatransfer.Transferable;
47
import java.awt.event.KeyEvent;
46
import java.awt.event.KeyEvent;
Lines 60-71 Link Here
60
import javax.swing.DefaultRowSorter;
59
import javax.swing.DefaultRowSorter;
61
import javax.swing.JComponent;
60
import javax.swing.JComponent;
62
import javax.swing.JLabel;
61
import javax.swing.JLabel;
63
import javax.swing.JTable;
64
import javax.swing.JTextField;
62
import javax.swing.JTextField;
65
import javax.swing.RowFilter;
63
import javax.swing.RowFilter;
66
import javax.swing.RowSorter;
64
import javax.swing.RowSorter;
67
import javax.swing.SwingUtilities;
68
import javax.swing.TransferHandler;
65
import javax.swing.TransferHandler;
66
import javax.swing.event.TableModelEvent;
67
import javax.swing.event.TableModelListener;
69
import javax.swing.plaf.UIResource;
68
import javax.swing.plaf.UIResource;
70
import javax.swing.table.*;
69
import javax.swing.table.*;
71
import org.jdesktop.swingx.JXTable;
70
import org.jdesktop.swingx.JXTable;
Lines 78-84 Link Here
78
import org.jdesktop.swingx.renderer.StringValues;
77
import org.jdesktop.swingx.renderer.StringValues;
79
import org.jdesktop.swingx.table.DatePickerCellEditor;
78
import org.jdesktop.swingx.table.DatePickerCellEditor;
80
import org.netbeans.modules.db.dataview.meta.DBColumn;
79
import org.netbeans.modules.db.dataview.meta.DBColumn;
81
import org.netbeans.modules.db.dataview.output.DataView;
82
import org.netbeans.modules.db.dataview.table.celleditor.*;
80
import org.netbeans.modules.db.dataview.table.celleditor.*;
83
import org.netbeans.modules.db.dataview.util.BinaryToStringConverter;
81
import org.netbeans.modules.db.dataview.util.BinaryToStringConverter;
84
import org.netbeans.modules.db.dataview.util.DataViewUtils;
82
import org.netbeans.modules.db.dataview.util.DataViewUtils;
Lines 95-119 Link Here
95
 * @author Ahimanikya Satapathy
93
 * @author Ahimanikya Satapathy
96
 */
94
 */
97
public class ResultSetJXTable extends JXTableDecorator {
95
public class ResultSetJXTable extends JXTableDecorator {
98
96
    private static final String data = "WE WILL EITHER FIND A WAY, OR MAKE ONE."; // NOI18N
97
    private static final Logger mLogger = Logger.getLogger(ResultSetJXTable.class.getName());
98
    private static final int MAX_COLUMN_WIDTH = 25;
99
    
100
    private final int multiplier;
101
    
99
    private DateFormat timeFormat = new SimpleDateFormat(TimeType.DEFAULT_FOMAT_PATTERN);
102
    private DateFormat timeFormat = new SimpleDateFormat(TimeType.DEFAULT_FOMAT_PATTERN);
100
    private DateFormat dateFormat = new SimpleDateFormat(DateType.DEFAULT_FOMAT_PATTERN);
103
    private DateFormat dateFormat = new SimpleDateFormat(DateType.DEFAULT_FOMAT_PATTERN);
101
    private DateFormat timestampFormat = new SimpleDateFormat(TimestampType.DEFAULT_FORMAT_PATTERN);
104
    private DateFormat timestampFormat = new SimpleDateFormat(TimestampType.DEFAULT_FORMAT_PATTERN);
102
105
103
    private String[] columnToolTips;
106
    // If structure changes, enforce relayout
104
    private final int multiplier;
107
    private TableModelListener dataExchangedListener = new TableModelListener() {
105
    private static final String data = "WE WILL EITHER FIND A WAY, OR MAKE ONE."; // NOI18N
108
        @Override
106
    private static final Logger mLogger = Logger.getLogger(ResultSetJXTable.class.getName());
109
        public void tableChanged(TableModelEvent e) {
107
    protected DataView dView;
110
            if(e.getFirstRow() == TableModelEvent.HEADER_ROW) {
108
    private final List<Integer> columnWidthList;
111
                updateHeader();
109
    private final static int MAX_COLUMN_WIDTH = 25;
112
            }
110
113
        }
114
    };
115
    
111
    @SuppressWarnings("OverridableMethodCallInConstructor")
116
    @SuppressWarnings("OverridableMethodCallInConstructor")
112
    public ResultSetJXTable(final DataView dataView) {
117
    public ResultSetJXTable() {
118
        this.setAutoCreateColumnsFromModel(false);
113
        this.setTransferHandler(new TableTransferHandler());
119
        this.setTransferHandler(new TableTransferHandler());
114
120
115
        this.dView = dataView;
116
117
        setShowGrid(true, true);
121
        setShowGrid(true, true);
118
        setGridColor(GRID_COLOR);
122
        setGridColor(GRID_COLOR);
119
123
Lines 130-141 Link Here
130
        setDefaultCellRenderers();
134
        setDefaultCellRenderers();
131
        setDefaultCellEditors();
135
        setDefaultCellEditors();
132
136
133
        if (dView.getDataViewDBTable() != null) {
134
            columnToolTips = dView.getDataViewDBTable().getColumnToolTips();
135
        }
136
        multiplier = getFontMetrics(getFont()).stringWidth(data) / data.length() + 4;
137
        multiplier = getFontMetrics(getFont()).stringWidth(data) / data.length() + 4;
137
        columnWidthList = getColumnWidthList();
138
        putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
138
        putClientProperty("terminateEditOnFocusLost", Boolean.TRUE);
139
        this.setModel(createDefaultDataModel());
139
    }
140
    }
140
141
141
    @Override
142
    @Override
Lines 149-154 Link Here
149
    }
150
    }
150
151
151
    @Override
152
    @Override
153
    protected TableModel createDefaultDataModel() {
154
        return new ResultSetTableModel(new DBColumn[0]);
155
    }
156
157
    @Override
152
    @SuppressWarnings("unchecked")
158
    @SuppressWarnings("unchecked")
153
    public <R extends TableModel> void setRowFilter(RowFilter<? super R, ? super Integer> filter) {
159
    public <R extends TableModel> void setRowFilter(RowFilter<? super R, ? super Integer> filter) {
154
        if(getRowSorter() instanceof DefaultRowSorter) {
160
        if(getRowSorter() instanceof DefaultRowSorter) {
Lines 158-176 Link Here
158
        }
164
        }
159
    }
165
    }
160
166
161
    public void createTableModel(List<Object[]> rows, final JXTableRowHeader rowHeader) {
167
    @Override
162
        assert SwingUtilities.isEventDispatchThread() : "Must be called from AWT thread";  //NOI18N
168
    public void setModel(TableModel dataModel) {
163
        assert rows != null;
169
        if(! (dataModel instanceof ResultSetTableModel)) {
164
        final TableModel tempModel = createModelFrom(rows);
170
            throw new IllegalArgumentException(
165
        setModel(tempModel);
171
                    "TableModel for ResultSetJXTable must be an "  // NOI18N
166
        if (!columnWidthList.isEmpty()) {
172
                    + " instance of ResultSetTableModel"           // NOI18N
167
            setHeader(ResultSetJXTable.this, columnWidthList);
173
            );
168
        }
174
        }
169
        if (rowHeader != null) {
175
        if(getModel() != null) {
170
            rowHeader.setTable(ResultSetJXTable.this);
176
            getModel().removeTableModelListener(dataExchangedListener);   
171
        }
177
        }
178
        super.setModel(dataModel);
179
        updateHeader();
180
        dataModel.addTableModelListener(dataExchangedListener);
172
    }
181
    }
173
182
    
183
    @Override
184
    public ResultSetTableModel getModel() {
185
        return (ResultSetTableModel) super.getModel();
186
    }
187
    
174
    @SuppressWarnings("deprecation")
188
    @SuppressWarnings("deprecation")
175
    protected void setDefaultCellRenderers() {
189
    protected void setDefaultCellRenderers() {
176
        setDefaultRenderer(Object.class, new ResultSetCellRenderer());
190
        setDefaultRenderer(Object.class, new ResultSetCellRenderer());
Lines 236-322 Link Here
236
            }
250
            }
237
        };
251
        };
238
    }
252
    }
253
    
254
    protected void updateHeader() {
255
        DefaultTableColumnModel dtcm = new DefaultTableColumnModel();
256
        
257
        DBColumn[] columns = getModel().getColumns();
239
258
240
    private void setHeader(JTable table, List<Integer> columnWidthList) {
259
        List<Integer> columnWidthList = getColumnWidthList(columns);
241
        try {
260
242
            TableColumnModel cModel = table.getColumnModel();
261
        for (int i = 0; i < columns.length; i++) {
243
            for (int i = 0; i < columnWidthList.size(); i++) {
262
            TableColumn tc = getColumnFactory().createTableColumn(i);
244
                TableColumn column = cModel.getColumn(i);
263
            tc.setPreferredWidth(columnWidthList.get(i));
245
                column.setPreferredWidth(columnWidthList.get(i));
264
265
            DBColumn col = columns[i];
266
            StringBuilder sb = new StringBuilder();
267
            sb.append("<html>");                                    //NOI18N
268
            if (col.getDisplayName() != null) {
269
                sb.append(DataViewUtils.escapeHTML(
270
                        col.getDisplayName().toString()));
246
            }
271
            }
247
            table.getTableHeader().setColumnModel(cModel);
272
            sb.append("</html>");                                  // NOI18N
248
            for (int i = 0, I = getRSColumnCount(); i < I; i++) {
273
            tc.setHeaderValue(sb.toString());
249
                DBColumn col = getDBColumn(i);
274
            tc.setIdentifier(col.getDisplayName() == null
250
                TableColumn tc = cModel.getColumn(i);
275
                    ? "COL_" + i : col.getDisplayName());           //NOI18N
251
                StringBuilder sb = new StringBuilder();
276
            
252
                sb.append("<html>");                                    //NOI18N
277
            dtcm.addColumn(tc);
253
                if (col.getDisplayName() != null) {
254
                    sb.append(DataViewUtils.escapeHTML(
255
                            col.getDisplayName().toString()));
256
                }
257
                sb.append("</html>");                                  // NOI18N
258
                tc.setHeaderValue(sb.toString());
259
                tc.setIdentifier(col.getDisplayName() == null
260
                        ? "COL_" + i : col.getDisplayName());           //NOI18N
261
            }
262
        } catch (Exception e) {
263
            mLogger.log(Level.INFO, "Failed to set the size of the table headers" + e, e);
264
        }
278
        }
279
        
280
        setColumnModel(dtcm);
265
    }
281
    }
266
282
267
    private List<Integer> getColumnWidthList() {
283
    private List<Integer> getColumnWidthList(DBColumn[] columns) {
268
        List<Integer> colWidthList = new ArrayList<Integer>();
284
        List<Integer> result = new ArrayList<Integer>();
269
        try {
285
270
            for (int i = 0, I = getRSColumnCount(); i < I; i++) {
286
        for (DBColumn col : columns) {
271
                DBColumn col = getDBColumn(i);
287
            int fieldWidth = col.getDisplaySize();
272
                int fieldWidth = col.getDisplaySize();
288
            int labelWidth = col.getDisplayName().length();
273
                int labelWidth = col.getDisplayName().length();
289
            int colWidth = Math.max(fieldWidth, labelWidth) * multiplier;
274
                int colWidth = Math.max(fieldWidth, labelWidth) * multiplier;
290
            if (colWidth < 5) {
275
                if (colWidth < 5) {
291
                colWidth = 15 * multiplier;
276
                    colWidth = 15 * multiplier;
277
                }
278
                if (colWidth > MAX_COLUMN_WIDTH * multiplier) {
279
                    colWidth = MAX_COLUMN_WIDTH * multiplier;
280
                }
281
                colWidthList.add(colWidth);
282
            }
292
            }
283
        } catch (Exception e) {
293
            if (colWidth > MAX_COLUMN_WIDTH * multiplier) {
284
            mLogger.log(Level.INFO, "Failed to set the size of the table headers" + e, e); // NOI18N
294
                colWidth = MAX_COLUMN_WIDTH * multiplier;
285
        }
295
            }
286
        return colWidthList;
296
            result.add(colWidth);
287
    }
288
289
    private TableModel createModelFrom(List<Object[]> rows) {
290
        DefaultTableModel dtm = getDefaultTableModel();
291
        for (int i = 0, I = getRSColumnCount(); i < I; i++) {
292
            DBColumn col = getDBColumn(i);
293
            dtm.addColumn(col.getDisplayName() != null
294
                    ? col.getDisplayName() : "COL_" + i);               //NOI18N
295
        }
297
        }
296
298
297
        for (Object[] row : rows) {
299
        return result;
298
            dtm.addRow(row);
299
        }
300
        return dtm;
301
    }
302
303
    public DBColumn getDBColumn(int col) {
304
        DBColumn dbcol = dView.getDataViewDBTable().getColumn(col);
305
        return dbcol;
306
    }
307
308
    public int getRSColumnCount() {
309
        return dView.getDataViewDBTable().getColumnCount();
310
    }
311
312
    protected DefaultTableModel getDefaultTableModel() {
313
        return new ResultSetTableModel(this);
314
    }
300
    }
315
301
316
    @Override
302
    @Override
317
    public boolean isEditable() {
303
    public boolean isCellEditable(int row, int column) {
318
        if(dView != null && dView.isEditable()) {
304
        if(getModel() != null) {
319
            return dView.isEditable();
305
            int modelRow = convertRowIndexToModel(row);
306
            int modelColumn = convertColumnIndexToModel(column);
307
            return getModel().isCellEditable(modelRow, modelColumn);
320
        }
308
        }
321
        return false;
309
        return false;
322
    }
310
    }
Lines 459-465 Link Here
459
            int index = columnModel.getColumnIndexAtX(p.x);
447
            int index = columnModel.getColumnIndexAtX(p.x);
460
            try {
448
            try {
461
                int realIndex = columnModel.getColumn(index).getModelIndex();
449
                int realIndex = columnModel.getColumn(index).getModelIndex();
462
                return columnToolTips[realIndex];
450
                ResultSetTableModel tm = getModel();
451
                if (tm != null) {
452
                    return tm.getColumnTooltip(realIndex);
453
                } else {
454
                    return "";
455
                }
463
            } catch (ArrayIndexOutOfBoundsException aio) {
456
            } catch (ArrayIndexOutOfBoundsException aio) {
464
                return null;
457
                return null;
465
            }
458
            }
(-)a/db.dataview/src/org/netbeans/modules/db/dataview/table/ResultSetTableModel.java (-26 / +132 lines)
Lines 43-48 Link Here
43
 */
43
 */
44
package org.netbeans.modules.db.dataview.table;
44
package org.netbeans.modules.db.dataview.table;
45
45
46
import java.beans.PropertyChangeListener;
47
import java.beans.PropertyChangeSupport;
46
import java.math.BigDecimal;
48
import java.math.BigDecimal;
47
import java.sql.Blob;
49
import java.sql.Blob;
48
import java.sql.Clob;
50
import java.sql.Clob;
Lines 50-56 Link Here
50
import java.sql.Time;
52
import java.sql.Time;
51
import java.sql.Timestamp;
53
import java.sql.Timestamp;
52
import java.sql.Types;
54
import java.sql.Types;
53
import javax.swing.table.DefaultTableModel;
55
import java.util.ArrayList;
56
import java.util.Arrays;
57
import java.util.List;
58
import javax.swing.table.AbstractTableModel;
54
import org.netbeans.modules.db.dataview.meta.DBColumn;
59
import org.netbeans.modules.db.dataview.meta.DBColumn;
55
import org.netbeans.modules.db.dataview.util.DBReadWriteHelper;
60
import org.netbeans.modules.db.dataview.util.DBReadWriteHelper;
56
import org.netbeans.modules.db.dataview.util.DataViewUtils;
61
import org.netbeans.modules.db.dataview.util.DataViewUtils;
Lines 60-69 Link Here
60
/**
65
/**
61
 * @author Ahimanikya Satapathy
66
 * @author Ahimanikya Satapathy
62
 */
67
 */
63
public class ResultSetTableModel extends DefaultTableModel {
68
public class ResultSetTableModel extends AbstractTableModel {
64
69
65
    private Class[] collumnClasses;
70
    private boolean editable = false;
66
    protected ResultSetJXTable table;
71
    private DBColumn[] columns;
72
    private List<Object[]> data = new ArrayList<Object[]>();
73
    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
67
74
68
    public static Class<? extends Object> getTypeClass(DBColumn col) {
75
    public static Class<? extends Object> getTypeClass(DBColumn col) {
69
        int colType = col.getJdbcType();
76
        int colType = col.getJdbcType();
Lines 122-180 Link Here
122
    }
129
    }
123
130
124
    @SuppressWarnings("rawtypes")
131
    @SuppressWarnings("rawtypes")
125
    public ResultSetTableModel(ResultSetJXTable table) {
132
    public ResultSetTableModel(DBColumn[] columns) {
126
        super();
133
        super();
127
        this.table = table;
134
        this.columns = columns;
128
        collumnClasses = new Class[table.getRSColumnCount()];
129
        for (int i = 0, I = table.getRSColumnCount(); i < I; i++) {
130
            collumnClasses[i] = getTypeClass(table.getDBColumn(i));
131
        }
135
        }
136
    
137
    public void setColumns(DBColumn[] columns) {
138
        this.data.clear();
139
        this.columns = columns;
140
        fireTableStructureChanged();
132
    }
141
    }
133
142
143
    public DBColumn[] getColumns() {
144
        return Arrays.copyOf(columns, columns.length);
145
    }
146
147
    public void setEditable(boolean editable) {
148
        boolean old = this.editable;
149
        this.editable = editable;
150
        pcs.firePropertyChange("editable", old, editable);
151
    }
152
153
    public boolean isEditable() {
154
        return editable;
155
    }
156
    
134
    @Override
157
    @Override
135
    public boolean isCellEditable(int row, int column) {
158
    public boolean isCellEditable(int row, int column) {
136
        return true;
159
        if (!editable) {
160
            return false;
161
    }
162
        DBColumn col = this.columns[column];
163
        return (!col.isGenerated()) && col.isEditable();
137
    }
164
    }
138
165
139
    @Override
166
    @Override
140
    public void setValueAt(Object value, int row, int col) {
167
    public void setValueAt(Object value, int row, int col) {
141
        if (table.dView.getDataViewDBTable() == null) {
142
            return;
143
        }
144
        Object oldVal = getValueAt(row, col);
168
        Object oldVal = getValueAt(row, col);
145
        if (noUpdateRequired(oldVal, value)) {
169
        if (noUpdateRequired(oldVal, value)) {
146
            return;
170
            return;
147
        }
171
        }
148
        try {
172
        try {
149
            if (!DataViewUtils.isSQLConstantString(value, table.getDBColumn(col))) {
173
            if (!DataViewUtils.isSQLConstantString(value, columns[col])) {
150
                value = DBReadWriteHelper.validate(value, table.getDBColumn(col));
174
                value = DBReadWriteHelper.validate(value, columns[col]);
151
            }
175
            }
152
            super.setValueAt(value, row, col);
176
            data.get(row)[col] = value;
153
            handleColumnUpdated(row, col, value);
177
            fireTableCellUpdated(row, col);
154
            fireTableDataChanged();
155
        } catch (Exception dbe) {
178
        } catch (Exception dbe) {
156
            NotifyDescriptor nd = new NotifyDescriptor.Message(dbe.getMessage(), NotifyDescriptor.ERROR_MESSAGE);
179
            NotifyDescriptor nd = new NotifyDescriptor.Message(dbe.getMessage(),
180
                    NotifyDescriptor.ERROR_MESSAGE);
157
            DialogDisplayer.getDefault().notify(nd);
181
            DialogDisplayer.getDefault().notify(nd);
158
        }
182
        }
159
        table.revalidate();
160
        table.repaint();
161
    }
183
    }
162
184
163
    @Override
185
    @Override
164
    @SuppressWarnings("unchecked")
186
    @SuppressWarnings("unchecked")
165
    public Class<? extends Object> getColumnClass(int columnIndex) {
187
    public Class<? extends Object> getColumnClass(int columnIndex) {
166
        if (collumnClasses[columnIndex] == null) {
188
        if (columns[columnIndex] == null) {
167
            return super.getColumnClass(columnIndex);
189
            return super.getColumnClass(columnIndex);
168
        } else {
190
        } else {
169
            return collumnClasses[columnIndex];
191
            return getTypeClass(columns[columnIndex]);
170
        }
192
        }
171
    }
193
    }
172
194
173
    protected boolean noUpdateRequired(Object oldVal, Object value) {
195
    public DBColumn getColumn(int columnIndex) {
174
        return oldVal != null && oldVal.toString().equals(value == null ? "" : value.toString()) || (oldVal == null && value == null);
196
        return columns[columnIndex];
175
    }
197
    }
176
198
177
    protected void handleColumnUpdated(int row, int col, Object value) {
199
    @Override
200
    public int getColumnCount() {
201
        return columns.length;
202
    }
203
204
    public String getColumnTooltip(int columnIndex) {
205
        return DataViewUtils.getColumnToolTip(columns[columnIndex]);
206
    }
207
208
    @Override
209
    public String getColumnName(int columnIndex) {
210
        String displayName = columns[columnIndex].getDisplayName();
211
        return displayName != null ? displayName : "COL_" + columnIndex;
212
    }
213
214
    protected boolean noUpdateRequired(Object oldVal, Object value) {
215
        if (oldVal == null && value == null) {
216
            return true;
217
        } else if (oldVal != null) {
218
            return oldVal.equals(value);
219
    }
220
        return false;
221
    }
222
223
    @Override
224
    public int getRowCount() {
225
        return data.size();
226
    }
178
        
227
        
228
    @Override
229
    public Object getValueAt(int rowIndex, int columnIndex) {
230
        Object[] dataRow = data.get(rowIndex);
231
        return dataRow[columnIndex];
232
    }
233
    
234
    public Object[] getRowData(int rowIndex) {
235
        Object[] dataRow = data.get(rowIndex);
236
        return Arrays.copyOf(dataRow, dataRow.length);
237
}
238
239
    public void setData(List<Object[]> data) {
240
        this.data.clear();
241
        for (Object[] dataRow : data) {
242
            this.data.add(Arrays.copyOf(dataRow, dataRow.length));
243
        }
244
        fireTableDataChanged();
245
    }
246
247
    public List<Object[]> getData() {
248
        ArrayList<Object[]> result = new ArrayList<Object[]>();
249
        for (Object[] dataRow : this.data) {
250
            result.add(Arrays.copyOf(dataRow, dataRow.length));
251
        }
252
        return result;
253
    }
254
255
    public void addRow(Object[] dataRow) {
256
        int addedRowIndex = this.data.size();
257
        this.data.add(Arrays.copyOf(dataRow, dataRow.length));
258
        fireTableRowsInserted(addedRowIndex, addedRowIndex);
259
    }
260
261
    public void removeRow(int row) {
262
        this.data.remove(row);
263
        fireTableRowsDeleted(row, row);
264
    }
265
266
    public void clear() {
267
        this.data.clear();
268
        fireTableDataChanged();
269
    }
270
271
    public void addPropertyChangeListener(PropertyChangeListener listener) {
272
        pcs.addPropertyChangeListener(listener);
273
    }
274
275
    public void removePropertyChangeListener(PropertyChangeListener listener) {
276
        pcs.removePropertyChangeListener(listener);
277
    }
278
279
    public void addPropertyChangeListener(String propertyName, PropertyChangeListener listener) {
280
        pcs.addPropertyChangeListener(propertyName, listener);
281
    }
282
283
    public void removePropertyChangeListener(String propertyName, PropertyChangeListener listener) {
284
        pcs.removePropertyChangeListener(propertyName, listener);
179
    }
285
    }
180
}
286
}
(-)a/db.dataview/test/unit/src/org/netbeans/modules/db/dataview/output/DataViewTest.java (-10 lines)
Lines 194-208 Link Here
194
        assertEquals(expResult, result);
194
        assertEquals(expResult, result);
195
    }
195
    }
196
196
197
    public void testGetUpdatedRowContext() {
198
        String selectStr = "select * from simpletable";
199
        int pageSize = 5;
200
        DataView instance = DataView.create(dbconn, selectStr, pageSize);
201
        instance.createComponents();
202
        UpdatedRowContext result = instance.getUpdatedRowContext();
203
        assertNotNull(result);
204
    }
205
206
    /**
197
    /**
207
     * Test of getSQLExecutionHelper method, of class DataView.
198
     * Test of getSQLExecutionHelper method, of class DataView.
208
     */
199
     */
Lines 214-220 Link Here
214
        assertFalse(instance.hasExceptions());
205
        assertFalse(instance.hasExceptions());
215
        assertNotNull(instance);
206
        assertNotNull(instance);
216
        assertNotNull(result);
207
        assertNotNull(result);
217
218
    }
208
    }
219
209
220
    /**
210
    /**
(-)a/db.dataview/test/unit/src/org/netbeans/modules/db/dataview/output/InsertRecordTableUITest.java (-5 / +5 lines)
Lines 49-54 Link Here
49
import org.netbeans.junit.MockServices;
49
import org.netbeans.junit.MockServices;
50
import org.netbeans.junit.NbTestCase;
50
import org.netbeans.junit.NbTestCase;
51
import org.netbeans.modules.db.dataview.spi.DBConnectionProviderImpl;
51
import org.netbeans.modules.db.dataview.spi.DBConnectionProviderImpl;
52
import org.netbeans.modules.db.dataview.table.ResultSetTableModel;
52
import org.netbeans.modules.db.dataview.util.DBTestUtil;
53
import org.netbeans.modules.db.dataview.util.DBTestUtil;
53
import org.netbeans.modules.db.dataview.util.DbUtil;
54
import org.netbeans.modules.db.dataview.util.DbUtil;
54
import org.netbeans.modules.db.dataview.util.TestCaseContext;
55
import org.netbeans.modules.db.dataview.util.TestCaseContext;
Lines 98-108 Link Here
98
99
99
        InsertRecordDialog ird = new InsertRecordDialog(dv);
100
        InsertRecordDialog ird = new InsertRecordDialog(dv);
100
101
101
        DefaultTableModel model =
102
        ResultSetTableModel model = ird.insertRecordTableUI.getModel();
102
                (DefaultTableModel) ird.insertRecordTableUI.getModel();
103
        ird.insertRecordTableUI.appendEmptyRow();
103
        ird.insertRecordTableUI.createNewRow();
104
        ird.insertRecordTableUI.appendEmptyRow();
104
        model.addRow(ird.insertRecordTableUI.createNewRow());
105
105
        model.addRow(ird.insertRecordTableUI.createNewRow());
106
        // Column 5 is the date column => Insert a "real" Date
106
        // Column 5 is the date column => Insert a "real" Date
107
        // => creates conflict with String inserted by "createNewRow"
107
        // => creates conflict with String inserted by "createNewRow"
108
        ird.insertRecordTableUI.setValueAt(
108
        ird.insertRecordTableUI.setValueAt(

Return to bug 227588