| /* |
| * Copyright 2000-2010 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.util.ui; |
| |
| import com.intellij.openapi.Disposable; |
| import com.intellij.openapi.util.Disposer; |
| import com.intellij.ui.DocumentAdapter; |
| import com.intellij.ui.table.TableView; |
| |
| import javax.swing.*; |
| import javax.swing.event.ChangeEvent; |
| import javax.swing.event.ChangeListener; |
| import javax.swing.event.DocumentEvent; |
| import javax.swing.table.TableCellEditor; |
| import javax.swing.text.Document; |
| import java.awt.*; |
| import java.awt.event.ActionEvent; |
| import java.awt.event.ActionListener; |
| import java.util.EventObject; |
| |
| public abstract class ChangesTrackingTableView<T> extends TableView<T> { |
| |
| private Disposable myEditorListenerDisposable; |
| |
| protected abstract void onCellValueChanged(int row, int column, Object value); |
| |
| protected abstract void onEditingStopped(); |
| |
| @Override |
| public boolean editCellAt(final int row, final int column, EventObject e) { |
| if (super.editCellAt(row, column, e)) { |
| assert myEditorListenerDisposable == null; |
| myEditorListenerDisposable = Disposer.newDisposable(); |
| addChangeListener(getEditorComponent(), new ChangeListener() { |
| @Override |
| public void stateChanged(ChangeEvent e) { |
| onCellValueChanged(row, column, getValue(getEditorComponent())); |
| } |
| }, myEditorListenerDisposable); |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public TableCellEditor getCellEditor(int row, int column) { |
| final TableCellEditor editor = super.getCellEditor(row, column); |
| if (column == 0 && editor instanceof DefaultCellEditor) { |
| //((DefaultCellEditor)editor).setClickCountToStart(1); |
| } |
| return editor; |
| } |
| |
| @Override |
| public void removeEditor() { |
| if (myEditorListenerDisposable != null) { |
| Disposer.dispose(myEditorListenerDisposable); |
| myEditorListenerDisposable = null; |
| } |
| |
| onEditingStopped(); |
| super.removeEditor(); |
| } |
| |
| public static Object getValue(Component component) { |
| if (component instanceof CellEditorComponentWithBrowseButton) { |
| final JTextField textField = (JTextField)((CellEditorComponentWithBrowseButton)component).getChildComponent(); |
| return textField.getText(); |
| } |
| else if (component instanceof JTextField) { |
| return ((JTextField)component).getText(); |
| } |
| else if (component instanceof JComboBox) { |
| return ((JComboBox)component).getSelectedItem(); |
| } |
| else if (component instanceof JCheckBox) { |
| return Boolean.valueOf(((JCheckBox)component).isSelected()); |
| } |
| throw new UnsupportedOperationException("editor control of type " + component.getClass().getName() + " is not supported"); |
| } |
| |
| private static void addChangeListener(final Component component, final ChangeListener listener, Disposable parentDisposable) { |
| if (component instanceof CellEditorComponentWithBrowseButton) { |
| addChangeListener(((CellEditorComponentWithBrowseButton)component).getChildComponent(), listener, parentDisposable); |
| } |
| else if (component instanceof JTextField) { |
| final DocumentAdapter documentListener = new DocumentAdapter() { |
| @Override |
| protected void textChanged(DocumentEvent e) { |
| listener.stateChanged(new ChangeEvent(component)); |
| } |
| }; |
| final Document document = ((JTextField)component).getDocument(); |
| document.addDocumentListener(documentListener); |
| Disposer.register(parentDisposable, new Disposable() { |
| @Override |
| public void dispose() { |
| document.removeDocumentListener(documentListener); |
| } |
| }); |
| } |
| else if (component instanceof JComboBox) { |
| final ActionListener comboListener = new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| listener.stateChanged(new ChangeEvent(component)); |
| } |
| }; |
| ((JComboBox)component).addActionListener(comboListener); |
| Disposer.register(parentDisposable, new Disposable() { |
| @Override |
| public void dispose() { |
| ((JComboBox)component).removeActionListener(comboListener); |
| } |
| }); |
| } |
| else if (component instanceof JCheckBox) { |
| final ActionListener checkBoxListener = new ActionListener() { |
| @Override |
| public void actionPerformed(ActionEvent e) { |
| listener.stateChanged(new ChangeEvent(component)); |
| } |
| }; |
| ((JCheckBox)component).addActionListener(checkBoxListener); |
| Disposer.register(parentDisposable, new Disposable() { |
| @Override |
| public void dispose() { |
| ((JCheckBox)component).removeActionListener(checkBoxListener); |
| } |
| }); |
| } |
| else { |
| throw new UnsupportedOperationException("editor control of type " + component.getClass().getName() + " is not supported"); |
| } |
| } |
| |
| } |