1// BEGIN LICENSE BLOCK 2// Version: CMPL 1.1 3// 4// The contents of this file are subject to the Cisco-style Mozilla Public 5// License Version 1.1 (the "License"); you may not use this file except 6// in compliance with the License. You may obtain a copy of the License 7// at www.eclipse-clp.org/license. 8// 9// Software distributed under the License is distributed on an "AS IS" 10// basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 11// the License for the specific language governing rights and limitations 12// under the License. 13// 14// The Original Code is The ECLiPSe Constraint Logic Programming System. 15// The Initial Developer of the Original Code is Cisco Systems, Inc. 16// Portions created by the Initial Developer are 17// Copyright (C) 2006 Cisco Systems, Inc. All Rights Reserved. 18// 19// Contributor(s): 20// 21// END LICENSE BLOCK 22 23package com.parctechnologies.eclipse.visualisation; 24 25 26import java.util.*; 27import java.awt.*; 28import java.beans.*; 29import java.awt.event.*; 30import javax.swing.*; 31import javax.swing.table.*; 32import com.parctechnologies.eclipse.*; 33import com.parctechnologies.eclipse.visualisation.*; 34 35 36/** 37 * A text table viewer based on JTable 38 */ 39public class TableViewer 40 extends ViewletArrayViewer 41 implements ZoomableViewer 42{ 43 protected static int DEFAULT_ROW_HEIGHT = 70; 44 protected static int DEFAULT_COLUMN_WIDTH = 100; 45 46 private SpreadSheet table; 47 private JScrollPane scrollpane; 48 //private ScrollingViewletGrid scrollingViewletGrid; 49 private boolean trackExpansions = false; 50 // private ViewletTracker viewletTracker; 51 52 53 public TableViewer(//ViewletFactory viewletFactory, 54 ViewletType viewletType, 55 VisClientStateModel stateModel, 56 Viewable viewable) 57 { 58 super(viewletType, stateModel, viewable); 59 initialiseMenu(); 60 } 61 62 private void initialiseMenu() 63 { 64 //JCheckBoxMenuItem trackExpansionsItem = new JCheckBoxMenuItem("Track expansions"); 65 //trackExpansionsItem.setModel(new BooleanPropertyModel("trackExpansions", 66 // this, getPropertyChangeSupport())); 67 //addMenuItem("Options", trackExpansionsItem); 68 } 69 70 protected Action getZoomToFitWidthAction() 71 { 72 return(new ZoomToFitWidthAction(this)); 73 } 74 75 protected Action getZoomToFitHeightAction() 76 { 77 return(new ZoomToFitHeightAction(this)); 78 } 79 80 public void startEvent(VisEvent event, java.util.List goalResults) 81 { 82 if(event instanceof UpdateEvent) 83 { 84 super.startEvent(event, goalResults); 85 return; 86 } 87 88 // for create event, initialise the component 89 if(event instanceof CreateEvent) 90 { 91 super.startEvent(event, goalResults); 92 93 initialiseComponent(); 94 return; 95 } 96 97 if(event instanceof ExpandEvent) 98 { 99 super.startEvent(event, goalResults); 100 101 // if the "track expansions" option is on, scroll to the expanded bit of 102 // the grid. 103 //if(trackExpansions) 104 // scrollToTrackExpansion((ExpandEvent) event); 105 return; 106 } 107 108 super.startEvent(event, goalResults); 109 } 110 111 private void initialiseComponent() 112 { 113 // disable the "trackUpdates" feature 114 trackUpdatesMenuItem.setEnabled(false); 115 //table = new JTable(getViewletArray()); 116 table = new SpreadSheet(getViewletDataStore(), null, null); 117 table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF); 118 table.setAutoCreateColumnsFromModel(false); 119 table.setColumnSelectionAllowed(true); 120 table.setRowSelectionAllowed(true); 121 table.setCellSelectionEnabled(true); 122 // set the default cell renderer 123 table.setDefaultRenderer((new Object()).getClass(), 124 viewletType.getTableCellRenderer()); 125 scrollpane = new JScrollPane(table); 126 scrollpane.setPreferredSize(new Dimension(430, 200)); 127 //scrollingViewletGrid = 128 // new ScrollingViewletGrid(getViewletArray(), this); 129 //viewletTracker = new ViewletTracker(scrollingViewletGrid); 130 MouseViewletMenuUpPopper mouseViewletMenuUpPopper = 131 new MouseViewletMenuUpPopper(this, table); 132 // create the selection for this table 133 //selection = new ViewletSelectionSpreadSheet((SpreadSheet)table, this); 134 // set the row height to equal the column width 135 table.setColumnWidth(DEFAULT_COLUMN_WIDTH); 136 table.setRowHeight(DEFAULT_ROW_HEIGHT); 137 } 138 139 140 public Component getComponent() 141 { 142 return scrollpane; 143 } 144 145 public void setTrackExpansions(boolean newValue) 146 { 147 //(new ViewerSetBooleanPropertyCommand(this, "trackExpansions", newValue)).issue(); 148 } 149 150 public void setTrackExpansionsPrivate(boolean newValue) 151 { 152 //boolean oldValue = trackExpansions; 153 //trackExpansions = newValue; 154 //this.getPropertyChangeSupport(). 155 // firePropertyChange("trackExpansions", oldValue, newValue); 156 } 157 158 public boolean getTrackExpansions() 159 { 160 return false; 161 //return(trackExpansions); 162 } 163 164 165 public void zoomToLevel(float zoomLevel) 166 { 167 // scale the column widths and row heights 168 table.setColumnWidth((int)(DEFAULT_COLUMN_WIDTH*zoomLevel)); 169 table.setRowHeight((int)(DEFAULT_ROW_HEIGHT*zoomLevel)); 170 table.revalidate(); 171 } 172 173 public void zoomInByRatio(float zoomRatio) 174 { 175 // scale the column widths and row heights 176 final int col_count = table.getColumnCount(); 177 final TableColumnModel col_model = table.getColumnModel(); 178 for(int i = 0; i < col_count; i++) { 179 int w = col_model.getColumn(i).getPreferredWidth(); 180 col_model.getColumn(i).setPreferredWidth((int)(w*zoomRatio)); 181 } 182 table.setRowHeight((int)(table.getRowHeight()*zoomRatio)); 183 table.revalidate(); 184 } 185 186 // move the scrollbars so that the new row/column comes into view. 187 private void scrollToTrackExpansion(ExpandEvent event) 188 { 189 //scrollingViewletGrid.scrollToTrackExpansion(event.getExpandingDimension()); 190 } 191 192// protected ViewletTracker getViewletTracker() 193// { 194// return(viewletTracker); 195// } 196 197 198 private class ZoomToFitWidthAction extends AbstractAction 199 { 200 private TableViewer viewer; 201 ZoomToFitWidthAction(TableViewer viewer) 202 { 203 super("Zoom to fit width"); 204 this.viewer = viewer; 205 } 206 207 public void actionPerformed(ActionEvent event) 208 { 209 (new ZoomableViewerZoomToFitWidthCommand(viewer)).issue(); 210 } 211 } 212 213 public void zoomToFitWidth() 214 { 215 table.fitWidth(); 216 table.revalidate(); 217 } 218 219 private class ZoomToFitHeightAction extends AbstractAction 220 { 221 private TableViewer viewer; 222 ZoomToFitHeightAction(TableViewer viewer) 223 { 224 super("Zoom to fit height"); 225 this.viewer = viewer; 226 } 227 228 public void actionPerformed(ActionEvent event) 229 { 230 (new ZoomableViewerZoomToFitHeightCommand(viewer)).issue(); 231 } 232 } 233 234 public void zoomToFitHeight() 235 { 236 table.fitHeight(); 237 table.revalidate(); 238 } 239 240 // public void setSelection(ViewletRange newSelection) { 241 //(new ViewerSetSelectionCommand(this, newSelection)).issue(); 242 // } 243 244 Rectangle rangeToBounds(ViewletRange range) { 245 if (((ViewableType.ArrayType)getViewable().getType()).getNDimensions() == 1) { 246 int min=Integer.MAX_VALUE; 247 int max=-1; 248 for(Iterator it = range.iterator(); it.hasNext(); ) { 249 java.util.List index = (java.util.List)it.next(); 250 int i = ((Integer)index.get(0)).intValue(); 251 if (i < min) { 252 min = i; 253 } 254 if (i > max) { 255 max = i; 256 } 257 } 258 return new Rectangle(0,min-1,1,(max-min)+1); 259 } 260 int minCol=Integer.MAX_VALUE; 261 int maxCol=-1; 262 int minRow=Integer.MAX_VALUE; 263 int maxRow=-1; 264 for(Iterator it = range.iterator(); it.hasNext(); ) { 265 java.util.List index = (java.util.List)it.next(); 266 int row = ((Integer)index.get(0)).intValue(); 267 int col = ((Integer)index.get(1)).intValue(); 268 if (col < minCol) { 269 minCol = col; 270 } 271 if (col > maxCol) { 272 maxCol = col; 273 } 274 if (row < minRow) { 275 minRow = row; 276 } 277 if (row > maxRow) { 278 maxRow = row; 279 } 280 } 281 return new Rectangle(minCol-1,minRow-1,(maxCol-minCol)+1,(maxRow-minRow)+1); 282 } 283 284 /** 285 * Called by the ViewerSetSelectionCommand 286 */ 287 protected void setSelectionPrivate(ViewletRange newSelection) { 288 DebuggingSupport. 289 logMessage(this, 290 "setSelectionPrivate called with newSelection=" + 291 newSelection); 292 if (newSelection.isEmpty()) { 293 table.clearSelection(); 294 return; 295 } 296 // Find the bounding box for these viewlets and select everything 297 // within that box 298 // Rectangle box = table.findBoundingBox(newSelection); 299 Rectangle box = rangeToBounds(newSelection); 300 table.setColumnSelectionInterval(box.x, box.x + box.width - 1); 301 table.setRowSelectionInterval(box.y, box.y + box.height - 1); 302 } 303 304 305 /** 306 * Returns a copy of the current selection 307 */ 308 public ViewletRange getSelection() { 309 return new SpreadSheetSelectionViewletRange(table); 310 } 311 312 313 /** 314 * Return a collection of actions which can be applied to viewlets 315 * in this table 316 */ 317 public Collection getCompoundActions(ViewletRange selected) { 318 return viewletType.getActions(viewletDataStore,selected); 319 // Collection ll = new LinkedList(); 320 // ll.add((new ToggleHoldAction()).createCompoundAction(selected)); 321 // return ll; 322 } 323 324// private class ToggleHoldAction extends ViewletAction 325// { 326// ToggleHoldAction() 327// { 328// super("Hold on updates"); 329// putValue(Action.NAME, "Hold on updates"); 330// putValue(Action.LONG_DESCRIPTION, 331// "Change whether control is held by the visualisation client during element updates"); 332// putValue(Action.SHORT_DESCRIPTION, 333// "Change whether control is held on updates"); 334// putValue(Action.SMALL_ICON, new HoldIcon(20, 20)); 335 336// } 337 338// public void actionPerformed(ActionEvent e) 339// { 340// // do nothing 341// } 342 343// /** 344// * If all viewlets in the collection have hold set to true, then the 345// * compound version sets it to false. If any of them have it set to false 346// * then the compound version sets all to true. 347// */ 348// public ViewletAction createCompoundAction(Collection viewlets) 349// { 350// boolean allHold = true; 351// ViewletImpl currentViewlet; 352// Iterator viewletsIterator = viewlets.iterator(); 353// while(viewletsIterator.hasNext()) 354// { 355// currentViewlet = (ViewletImpl) viewletsIterator.next(); 356// if(!currentViewlet.getHoldsOnUpdates()) 357// { 358// allHold = false; 359// break; 360// } 361// } 362// return(new CompoundToggleHoldAction(!allHold, viewlets)); 363// } 364// } 365 366// private class CompoundToggleHoldAction extends ToggleHoldAction 367// { 368// private boolean newValue; 369// private Collection viewlets; 370// CompoundToggleHoldAction(boolean newValue, Collection viewlets) 371// { 372// super(); 373// this.newValue = newValue; 374// this.viewlets = viewlets; 375// } 376 377// public void actionPerformed(ActionEvent e) 378// { 379// ViewletImpl currentViewlet; 380// Iterator viewletsIterator = viewlets.iterator(); 381// while(viewletsIterator.hasNext()) 382// { 383// currentViewlet = (ViewletImpl) viewletsIterator.next(); 384// currentViewlet.setHoldsOnUpdates(newValue); 385// } 386// // trigger the jtable to update as a whole bunch of viewlets have just 387// // changed 388// ((AbstractTableModel)table.getModel()).fireTableDataChanged(); 389// } 390 391// } 392 393 /** 394 * The default text cell render 395 */ 396// private class MyRenderer extends DefaultTableCellRenderer { 397// public MyRenderer() { 398// super(); 399// setHorizontalAlignment(SwingConstants.CENTER); 400// } 401 402// public Component getTableCellRendererComponent(JTable table, 403// Object value, 404// boolean isSelected, 405// boolean hasFocus, 406// int row, 407// int column) { 408// JLabel result = 409// (JLabel)(super.getTableCellRendererComponent(table, 410// value, 411// isSelected, 412// hasFocus, 413// row, 414// column)); 415// ViewletImpl viewlet = (ViewletImpl)value; 416// String updating = viewlet.getUpdating(); 417// Color col = Color.white; 418// if ("no".equals(updating)) { 419// // do nothing 420// } else if ("updatingForward".equals(updating)) { 421// col = Color.green; 422// } else /* updatingBack */ { 423// col = Color.red; 424// } 425// if (viewlet.getHoldsOnUpdates()) { 426// col = col.darker(); 427// } 428// if (isSelected) { 429// col = col.darker().darker(); 430// } 431// result.setBackground(col); 432// return result; 433// } 434 435 436// public void setValue(Object value) { 437// super.setValue(value); 438// ViewletImpl viewlet = (ViewletImpl)value; 439// setToolTipText(viewlet.getToolTipText()); 440// } 441// } 442 443 444} 445