/* 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; import java.awt.BorderLayout; import java.awt.Rectangle; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.List; import javax.swing.FocusManager; import javax.swing.SwingUtilities; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.event.ListDataEvent; import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import com.servoy.j2db.IApplication; import com.servoy.j2db.IView; import com.servoy.j2db.dataprocessing.IFoundSetInternal; import com.servoy.j2db.dataprocessing.ISaveConstants; import com.servoy.j2db.dataprocessing.ISwingFoundSet; import com.servoy.j2db.dataprocessing.PrototypeState; import com.servoy.j2db.smart.dataui.DataRenderer; import com.servoy.j2db.smart.dataui.StyledEnablePanel; import com.servoy.j2db.util.EnablePanel; import com.servoy.j2db.util.model.IEditListModel; /** * The recordview controller from mvc architecture * * @author jblok */ public class RecordView extends EnablePanel implements ChangeListener, ListDataListener, IView, ListSelectionListener { private Slider slider; private ISwingFoundSet model; private DataRenderer renderer; private final IApplication application; private boolean isAdjusting; public RecordView(IApplication app) { application = app; isAdjusting = false; setLayout(new BorderLayout()); setOpaque(false); getSliderComponent(); } public void destroy() { if (model != null) { model.removeListDataListener(this); model.getSelectionModel().removeListSelectionListener(this); } removeAll(); } private void setModelInternal(IEditListModel m) { if (m == model) { return;//no change } isAdjusting = true; if (model != null) { model.removeListDataListener(this); model.getSelectionModel().removeListSelectionListener(this); slider.setMax(0, false); } model = (ISwingFoundSet)m; if (model != null) { slider.setMax(model.getSize(), model.hadMoreRows()); model.addListDataListener(this); model.getSelectionModel().addListSelectionListener(this); // setSelectedIndex(model.getSelectedIndex()); } isAdjusting = false; if (model != null) { valueChanged(null); //make sure data is set. } } public void setCellRenderer(DataRenderer r) { renderer = r; } public void start(final IApplication app) { if (renderer != null) { renderer.setRenderer(false); add(renderer, BorderLayout.CENTER); validate(); } slider.addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { if (isEnabled()) { app.getFoundSetManager().getEditRecordList().stopEditing(false); } } }); } public void stop() { if (renderer != null) { remove(renderer); } setModel(null); } public StyledEnablePanel getSliderComponent() { if (slider == null) { slider = new Slider(application); slider.addChangeListener(this); // slider.setMax(model.getSize()); } return slider; } // public void setUI(ComponentUI ui) // { // super.setUI(ui); // if (slider != null) slider.setUI(ui); // } public void stateChanged(ChangeEvent e) { if (!isAdjusting && !slider.getValueIsAdjusting() && model != null) { if (model.getSize() != 0) { int row = slider.getValue(); if (row > 0) { final int modelSelection = model.getSelectionModel().getSelectedRow(); if (modelSelection != row - 1) { if ((application.getFoundSetManager().getEditRecordList().stopIfEditing(model) & (ISaveConstants.STOPPED + ISaveConstants.AUTO_SAVE_BLOCKED)) != 0) { model.getSelectionModel().setSelectedRow(row - 1); } else { SwingUtilities.invokeLater(new Runnable() { public void run() { slider.setValue(modelSelection + 1); } }); } } } } else { model.getSelectionModel().setSelectedRow(-1); } } } private void syncSliderAndRefresh() { // check if the model wasn't already cleared. if (model == null) return; isAdjusting = true; int index = model.getSelectedIndex(); if (slider.getValue() - 1 != index) { slider.setValue(index + 1); } // if the same refresh to be sure!! if (renderer != null) { if (index != -1) { Object value = model.getElementAt(index);//minus 1 for the slider renderer.getListCellRendererComponent(this, value, index, false, true); } else { PrototypeState state = null; if (model != null) { state = ((IFoundSetInternal)model).getPrototypeState(); } else { state = new PrototypeState(null); } renderer.getListCellRendererComponent(this, state, -1, false, true); } } isAdjusting = false; } public void contentsChanged(ListDataEvent e) { if (slider != null && model != null) { // refresh int selectedIndex = model.getSelectedIndex(); if (e.getIndex0() <= selectedIndex && selectedIndex <= e.getIndex1()) { syncSliderAndRefresh(); } } } public void intervalAdded(ListDataEvent e) { if (slider != null && model != null) { int selectedIndex = model.getSelectedIndex(); if (e.getIndex0() <= selectedIndex) { syncSliderAndRefresh(); } slider.setMax(model.getSize(), model.hadMoreRows()); } } public void intervalRemoved(ListDataEvent e) { if (slider != null && model != null) { int selectedIndex = model.getSelectedIndex(); if (e.getIndex0() <= selectedIndex) { syncSliderAndRefresh(); } slider.setMax(model.getSize(), model.hadMoreRows()); } } // private void fireListSelectionChanged(int index) // { // if(isAdjusting) return; // ListSelectionEvent e = null; // for(int l = 0 ; l < listeners.size() ; l++) // { // if (e == null) e = new ListSelectionEvent(this,index,index,false); // ListSelectionListener lsl = (ListSelectionListener)listeners.get(l); // lsl.valueChanged(e); // } // } // public void addListSelectionListener(ListSelectionListener listener) // { // listeners.add(listener); // } // public void removeListSelectionListener(ListSelectionListener listener) // { // listeners.remove(listener); // } // private ArrayList listeners = new ArrayList(1); /** * @see com.servoy.j2db.IView#editCellAt(int) */ public boolean editCellAt(int i) { model.setSelectedIndex(i); FocusManager.getCurrentManager().focusNextComponent(renderer); return true; } /** * @see com.servoy.j2db.IView#setModel(com.servoy.j2db.dataprocessing.IFoundSetInternal) */ public void setModel(IFoundSetInternal fs) { if (fs instanceof IEditListModel) { setModelInternal((IEditListModel)fs); } else if (fs == null) { setModelInternal((IEditListModel)null); } } public boolean stopUIEditing(boolean looseFocus) { if (renderer != null) { return renderer.stopUIEditing(looseFocus); } return true; } /* * (non-Javadoc) * * @see javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event.ListSelectionEvent) */ public void valueChanged(ListSelectionEvent e) { if (e != null && e.getValueIsAdjusting()) return; syncSliderAndRefresh(); } /* * (non-Javadoc) * * @see com.servoy.j2db.IController#isEditing() */ public boolean isEditing() { // TODO what to return here? Is recordview always in editing or never?? return false; } private String bgColorScript; private List<Object> bgColorArgs; public String getRowBGColorScript() { return bgColorScript; } public List<Object> getRowBGColorArgs() { return bgColorArgs; } public void setRowBGColorScript(String bgColorScript, List<Object> args) { this.bgColorScript = bgColorScript; this.bgColorArgs = args; } public void ensureIndexIsVisible(int index) { //ignore not needed in record view } public boolean isDisplayingMoreThanOneRecord() { return false; } public void setEditable(boolean findMode) { //TODO: done elsewhere? } public void setVisibleRect(Rectangle scrollPosition) { if (isVisible()) { scrollRectToVisible(scrollPosition); } } }