/* This file belongs to the Servoy development and deployment environment, Copyright (C) 1997-2010 Servoy BV This program is free software; you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program; if not, see http://www.gnu.org/licenses or write to the Free Software Foundation,Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 */ package com.servoy.j2db.smart.dataui; import java.awt.dnd.DropTargetDragEvent; import java.awt.dnd.DropTargetDropEvent; import java.awt.dnd.DropTargetEvent; import java.awt.dnd.DropTargetListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JRootPane; import javax.swing.SwingUtilities; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; import com.servoy.j2db.IApplication; import com.servoy.j2db.dataprocessing.IDisplay; import com.servoy.j2db.dataprocessing.IDisplayData; import com.servoy.j2db.dataprocessing.IEditListener; import com.servoy.j2db.ui.IEditProvider; /** * Listener object for various listeners influencing the edit state * @author jblok */ public class EditProvider implements FocusListener, PropertyChangeListener, ItemListener, ActionListener, DocumentListener, DropTargetListener, IEditProvider { private boolean editable = true; private int isAdjusting; private final boolean isDocumentListener; private boolean documentChanged; private IEditListener listner; private final IDisplayData src; private final IApplication application; public EditProvider(IDisplayData s) { this(s, false); } public EditProvider(IDisplayData s, IApplication application) { this(s, false, application); } public void resetState() { documentChanged = false; } public EditProvider(IDisplayData s, boolean documentListener) { this(s, documentListener, null); } public EditProvider(IDisplayData s, boolean documentListener, IApplication application) { src = s; isDocumentListener = documentListener; isAdjusting = 0; documentChanged = false; this.application = application; } public void addEditListener(IEditListener l) { listner = l; } public IEditListener getEditListener() { return listner; } public void focusGained(FocusEvent e) { JRootPane pane = SwingUtilities.getRootPane((JComponent)src); if (pane == null) { // Component comp = (Component) e.getSource(); // if(comp != null) // { // comp.requestFocus(); // } } else { if (((JComponent)src).isEnabled()) { if (src instanceof IDisplay && ((IDisplay)src).isReadOnly()) { return; } listner.startEdit(src); } } } public void focusLost(FocusEvent e) { // // only document listeners when documentChanged will do commit edit on focuslost // // don't turn this off because it is needed in textarea ect if (!isAdjusting() && isDocumentListener && documentChanged) { documentChanged = false; listner.commitEdit(src); } } public void propertyChange(PropertyChangeEvent e) { if (!isAdjusting()) { listner.commitEdit(src); documentChanged = false; } } public void itemStateChanged(ItemEvent e) { // careful: e.getSource can be null (DataSpinner) if (e.getSource() instanceof JComboBox && e.getStateChange() == ItemEvent.DESELECTED) return; if (e.getSource() instanceof JCheckBox && application != null) { if (!isAdjusting()) { // see: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6998897 , http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6988854 application.invokeLater(new Runnable() { public void run() { // i have to start edit first because an edit in a list view of a checkbox // doesn't have always focusGained (which starts the edit) listner.startEdit(src); listner.commitEdit(src); } }); } } else { if (!isAdjusting()) { // i have to start edit first because an edit in a list view of a checkbox // doesn't have always focusGained (which starts the edit) listner.startEdit(src); listner.commitEdit(src); } } } public void actionPerformed(ActionEvent e) { if (!isAdjusting()) { listner.commitEdit(src); documentChanged = false; } } public void setAdjusting(boolean b) { if (editable) { if (b) { isAdjusting++; } else { isAdjusting--; } } } public boolean isAdjusting() { return (isAdjusting != 0); } /** * @see javax.swing.event.DocumentListener#changedUpdate(javax.swing.event.DocumentEvent) */ public void changedUpdate(DocumentEvent e) { if (!isAdjusting()) { documentChanged = true; } } /** * @see javax.swing.event.DocumentListener#insertUpdate(javax.swing.event.DocumentEvent) */ public void insertUpdate(DocumentEvent e) { if (!isAdjusting()) { documentChanged = true; } } /** * @see javax.swing.event.DocumentListener#removeUpdate(javax.swing.event.DocumentEvent) */ public void removeUpdate(DocumentEvent e) { if (!isAdjusting()) { documentChanged = true; } } public void commitData() { if (!isAdjusting()) { listner.startEdit(src); listner.commitEdit(src); } } //if the IDisplayData recieves stopEditing() and if it should commit it's current value and call this method public void forceCommit() { if (isDocumentListener && !documentChanged) { return; } documentChanged = false; listner.startEdit(src);//make sure it is started,otherwise changes are not seen listner.commitEdit(src); } /** * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent) public void valueChanged(ListSelectionEvent e) { * System.out.println(((JList)e.getSource()).getSelectedValue()); if (!isAdjusting) { listner.startEdit(e); listner.commitEdit(e); } } */ public void setEditable(boolean b) { editable = b; //prevents isAdjusting being set if (!editable) { isAdjusting = 1; //this prevents any change } else { isAdjusting = 0; } } public boolean isEditable() { return editable; } public void startEdit() { listner.startEdit(src); } public void dragEnter(DropTargetDragEvent dtde) { JRootPane pane = SwingUtilities.getRootPane((JComponent)src); if (pane == null) { // Component comp = (Component) e.getSource(); // if(comp != null) // { // comp.requestFocus(); // } } else { startEdit(); } } public void dragExit(DropTargetEvent dte) { } public void dragOver(DropTargetDragEvent dtde) { } public void drop(DropTargetDropEvent dtde) { } public void dropActionChanged(DropTargetDragEvent dtde) { } }