Move the RSS button down to the status bar, along with the price summary information. Fix up the status text area to fit itself between the two. Remove the status line from individual tabs, and generally clean up the status bar handling.
- ~
- jbidwatcher
- trunk
- src
- com
- jbidwatcher
- ui
- AuctionsUIModel.java
| AuctionsUIModel.java |
|---|
cyberfox 1 package com.jbidwatcher.ui; cyberfox 2 /* cyberfox 3 * Copyright (c) 2000-2007, CyberFOX Software, Inc. All Rights Reserved. cyberfox 4 * cyberfox 5 * Developed by mrs (Morgan Schweers) cyberfox 6 */ cyberfox 7 mrs 8 import com.jbidwatcher.util.config.*; cyberfox 9 import com.jbidwatcher.util.Currency; mrs 10 import com.jbidwatcher.util.Constants; mrs 11 import com.jbidwatcher.util.queue.MQFactory; cyberfox 12 import com.jbidwatcher.auction.AuctionEntry; cyberfox 13 import com.jbidwatcher.auction.Auctions; mrs 14 import com.jbidwatcher.auction.EntryInterface; mrs 15 import com.jbidwatcher.ui.util.*; mrs 16 import com.jbidwatcher.ui.table.TableColumnController; mrs 17 import com.jbidwatcher.ui.table.CSVExporter; mrs 18 import com.jbidwatcher.ui.table.TableSorter; mrs 19 import com.jbidwatcher.ui.table.AuctionTable; mrs 20 import com.jbidwatcher.platform.Platform; cyberfox 21 cyberfox 22 import javax.swing.*; cyberfox 23 import javax.swing.event.ListSelectionEvent; cyberfox 24 import javax.swing.event.ListSelectionListener; mrs 25 import javax.swing.event.TableModelEvent; mrs 26 import javax.swing.event.TableModelListener; cyberfox 27 import javax.swing.table.TableColumn; cyberfox 28 import java.awt.*; mrs 29 import java.awt.event.ActionListener; cyberfox 30 import java.awt.dnd.DropTarget; cyberfox 31 import java.util.*; cyberfox 32 import java.util.List; cyberfox 33 cyberfox 34 public class AuctionsUIModel { cyberfox 35 private Auctions _dataModel; cyberfox 36 private JTable _table; cyberfox 37 private JScrollPane _scroller; cyberfox 38 /** @noinspection FieldCanBeLocal*/ cyberfox 39 private DropTarget[] _targets; /* This can't be local, otherwise it gets GC'ed, which is bad. */ cyberfox 40 private Color _bgColor; cyberfox 41 private JPrintable _print; mrs 42 private CSVExporter _export; mrs 43 private JPanel mPanel; cyberfox 44 cyberfox 45 private static final myTableCellRenderer _myRenderer = new myTableCellRenderer(); mrs 46 private TableSorter _tSort; cyberfox 47 cyberfox 48 /** cyberfox 49 * @brief Construct a new UI model for a provided auction list. cyberfox 50 * @param newAuctionList - The auction list to use as a 'backing mrs 51 * store' for displaying lists of auctions. mrs 52 * @param tableContextMenu - The context menu to present for this table. mrs 53 * @param frameContextMenu - The context menu to present for whitespace outside the table. mrs 54 * @param cornerButtonListener - The button to sit above the scrollbar. cyberfox 55 */ mrs 56 public AuctionsUIModel(Auctions newAuctionList, JContext tableContextMenu, JContext frameContextMenu, ActionListener cornerButtonListener) { cyberfox 57 _dataModel = newAuctionList; cyberfox 58 cyberfox 59 _targets = new DropTarget[2]; cyberfox 60 mrs 61 _tSort = new TableSorter(_dataModel.getName(), "Time left", new auctionTableModel(_dataModel.getList())); mrs 62 mrs 63 _table = new AuctionTable(_dataModel.getName(), _tSort); cyberfox 64 if(newAuctionList.isCompleted()) { cyberfox 65 if(_table.convertColumnIndexToView(TableColumnController.END_DATE) == -1) { mrs 66 _table.addColumn(new TableColumn(TableColumnController.END_DATE, Constants.DEFAULT_COLUMN_WIDTH, _myRenderer, null)); cyberfox 67 } cyberfox 68 } cyberfox 69 if(JConfig.queryConfiguration("show_shipping", "false").equals("true")) { cyberfox 70 if(_table.convertColumnIndexToView(TableColumnController.SHIPPING_INSURANCE) == -1) { cyberfox 71 _table.addColumn(new TableColumn(TableColumnController.SHIPPING_INSURANCE)); cyberfox 72 } cyberfox 73 JConfig.killAll("show_shipping"); cyberfox 74 } mrs 75 mrs 76 // provide sufficient vertical height in the rows for micro-thumbnails list view mrs 77 adjustRowHeight(); mrs 78 mrs 79 _table.addMouseListener(tableContextMenu); mrs 80 _tSort.addMouseListenerToHeaderInTable(_table); mrs 81 if(Platform.isMac() || JConfig.queryConfiguration("ui.useCornerButton", "true").equals("true")) { cyberfox 82 _scroller = new JScrollPane(_table, ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); cyberfox 83 } else { cyberfox 84 _scroller = new JScrollPane(_table, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); cyberfox 85 } cyberfox 86 mrs 87 // This is a button to manage the custom columns for the current tab. mrs 88 if(JConfig.queryConfiguration("ui.useCornerButton", "true").equals("true")) { mrs 89 JButton cornerButton = new JButton("*"); mrs 90 cornerButton.addActionListener(cornerButtonListener); mrs 91 _scroller.setCorner(ScrollPaneConstants.UPPER_RIGHT_CORNER, cornerButton); cyberfox 92 } cyberfox 93 cyberfox 94 _bgColor = UIManager.getColor("window"); cyberfox 95 _scroller.getViewport().setBackground(_bgColor); mrs 96 _scroller.getViewport().addMouseListener(frameContextMenu); cyberfox 97 cyberfox 98 JDropListener _dropEar; cyberfox 99 if(newAuctionList.isCompleted()) { mrs 100 _dropEar = new JDropListener(new TargetDrop()); cyberfox 101 } else { mrs 102 _dropEar = new JDropListener(new TargetDrop(_dataModel.getName())); cyberfox 103 } cyberfox 104 _targets[0] = new DropTarget(_scroller.getViewport(), _dropEar); cyberfox 105 _targets[1] = new DropTarget(_table, _dropEar); cyberfox 106 cyberfox 107 _targets[0].setActive(true); cyberfox 108 _targets[1].setActive(true); cyberfox 109 cyberfox 110 _print = new JPrintable(_table); mrs 111 _export = new CSVExporter(_table); cyberfox 112 _table.setDefaultRenderer(String.class, _myRenderer); cyberfox 113 _table.setDefaultRenderer(Icon.class, _myRenderer); cyberfox 114 mrs 115 mPanel = new JPanel(); mrs 116 mPanel.setLayout(new BorderLayout()); mrs 117 mPanel.add(_scroller, BorderLayout.CENTER); mrs 118 addSumMonitor(_table, _tSort); mrs 119 JPanel statusPanel = new TabStatusPanel(_dataModel.getName()); mrs 120 mPanel.add(statusPanel, BorderLayout.NORTH); cyberfox 121 } cyberfox 122 mrs 123 public JPanel getPanel() { mrs 124 return mPanel; mrs 125 } mrs 126 mrs 127 private void addSumMonitor(JTable table, TableSorter sort) { mrs 128 table.getSelectionModel().addListSelectionListener(new ListSelectionListener() { cyberfox 129 public void valueChanged(ListSelectionEvent event) { mrs 130 updateSum(); cyberfox 131 } cyberfox 132 }); mrs 133 mrs 134 sort.addTableModelListener(new TableModelListener() { mrs 135 public void tableChanged(TableModelEvent tableModelEvent) { mrs 136 updateSum(); mrs 137 } mrs 138 }); cyberfox 139 } cyberfox 140 mrs 141 private void updateSum() { mrs 142 int[] rowList = _table.getSelectedRows(); mrs 143 String total = sum(rowList); mrs 144 mrs 145 if(total == null) { mrs 146 MQFactory.getConcrete("Swing").enqueue("PRICE "); // A blank space to clear the price mrs 147 } else { mrs 148 MQFactory.getConcrete("Swing").enqueue("PRICE " + rowList.length + " / " + total); mrs 149 } mrs 150 } mrs 151 cyberfox 152 /** cyberfox 153 * @brief Pick and return a value from the entry that best describes cyberfox 154 * how much COULD be spent on it by the buyer. cyberfox 155 * cyberfox 156 * For an item not bid on, it's the current bid price. For an item cyberfox 157 * the user has bid on, it's their maximum bid. For an item the cyberfox 158 * user has a snipe set for, it's the maximum of their snipe bid. cyberfox 159 * If the item is closed, it's just the current bid price. cyberfox 160 * cyberfox 161 * @param checkEntry - The AuctionEntry to operate on. cyberfox 162 * cyberfox 163 * @return - A currency value containing either the current bid, the cyberfox 164 * users high bid, or the users snipe bid. cyberfox 165 */ cyberfox 166 private static Currency getBestBidValue(AuctionEntry checkEntry) { mrs 167 return checkEntry.bestValue(); cyberfox 168 } cyberfox 169 mrs 170 // A single accessor... mrs 171 public TableSorter getTableSorter() { return _tSort; } mrs 172 mrs 173 private static Currency addUSD(Currency inCurr, AuctionEntry ae) { cyberfox 174 boolean newCurrency = (inCurr == null || inCurr.isNull()); cyberfox 175 try { cyberfox 176 if(ae.getShippingWithInsurance().isNull()) { cyberfox 177 if(newCurrency) { cyberfox 178 return ae.getUSCurBid(); cyberfox 179 } cyberfox 180 return inCurr.add(ae.getUSCurBid()); cyberfox 181 } cyberfox 182 cyberfox 183 if(newCurrency) { cyberfox 184 inCurr = ae.getUSCurBid().add(Currency.convertToUSD(ae.getUSCurBid(), ae.getCurBid(), ae.getShippingWithInsurance())); cyberfox 185 } else { cyberfox 186 inCurr = inCurr.add(ae.getUSCurBid().add(Currency.convertToUSD(ae.getUSCurBid(), ae.getCurBid(), ae.getShippingWithInsurance()))); cyberfox 187 } cyberfox 188 } catch(Currency.CurrencyTypeException cte) { mrs 189 JConfig.log().handleException("This should have been cleaned up.", cte); cyberfox 190 } cyberfox 191 return inCurr; cyberfox 192 } cyberfox 193 cyberfox 194 private static Currency addNonUSD(Currency inCurr, AuctionEntry ae) { cyberfox 195 boolean newCurrency = inCurr == null || inCurr.isNull(); cyberfox 196 try { cyberfox 197 if(ae.getShippingWithInsurance().isNull()) { cyberfox 198 if(newCurrency) { cyberfox 199 return ae.getCurBid(); cyberfox 200 } cyberfox 201 return inCurr.add(ae.getCurBid()); cyberfox 202 } cyberfox 203 cyberfox 204 if(newCurrency) { cyberfox 205 inCurr = ae.getCurBid().add(ae.getShippingWithInsurance()); cyberfox 206 } else { cyberfox 207 inCurr = inCurr.add(ae.getCurBid().add(ae.getShippingWithInsurance())); cyberfox 208 } cyberfox 209 } catch(Currency.CurrencyTypeException cte) { mrs 210 JConfig.log().handleException("This should have been cleaned up.", cte); cyberfox 211 } cyberfox 212 cyberfox 213 return inCurr; cyberfox 214 } cyberfox 215 cyberfox 216 protected String sum(int[] rowList) { cyberfox 217 boolean approx = false, i18n = true; cyberfox 218 Currency accum = null; cyberfox 219 Currency withShipping = null; cyberfox 220 Currency withRealShipping = null; cyberfox 221 Currency realAccum = null; cyberfox 222 cyberfox 223 try { cyberfox 224 for (int aRowList : rowList) { cyberfox 225 AuctionEntry ae2; cyberfox 226 try { cyberfox 227 ae2 = (AuctionEntry) _table.getValueAt(aRowList, -1); cyberfox 228 } catch (IndexOutOfBoundsException bounds) { cyberfox 229 ae2 = null; cyberfox 230 approx = true; cyberfox 231 } cyberfox 232 if (ae2 != null) { cyberfox 233 if (accum == null) { cyberfox 234 accum = ae2.getUSCurBid(); cyberfox 235 realAccum = getBestBidValue(ae2); cyberfox 236 withShipping = addUSD(withShipping, ae2); cyberfox 237 withRealShipping = addNonUSD(withRealShipping, ae2); cyberfox 238 } else { cyberfox 239 Currency stepVal = ae2.getUSCurBid(); cyberfox 240 if (!stepVal.isNull() && !accum.isNull() && stepVal.getCurrencyType() != Currency.NONE) { cyberfox 241 accum = accum.add(stepVal); cyberfox 242 withShipping = addUSD(withShipping, ae2); cyberfox 243 cyberfox 244 // If we're still trying to do the internationalization cyberfox 245 // thing, then try to keep track of the 'real' total. cyberfox 246 if (i18n) { cyberfox 247 //noinspection NestedTryStatement cyberfox 248 try { cyberfox 249 realAccum = realAccum.add(getBestBidValue(ae2)); cyberfox 250 withRealShipping = addNonUSD(withRealShipping, ae2); cyberfox 251 } catch (Currency.CurrencyTypeException cte) { cyberfox 252 // We can't handle multiple non-USD currency types, so cyberfox 253 // we stop trying to do the internationalization thing. cyberfox 254 i18n = false; cyberfox 255 } cyberfox 256 } cyberfox 257 } cyberfox 258 } cyberfox 259 if (ae2.getCurBid().getCurrencyType() != Currency.US_DOLLAR) approx = true; cyberfox 260 } cyberfox 261 } cyberfox 262 } catch(Currency.CurrencyTypeException e) { mrs 263 JConfig.log().handleException("Sum currency exception!", e); cyberfox 264 return null; cyberfox 265 } catch(ArrayIndexOutOfBoundsException ignored) { mrs 266 JConfig.log().logDebug("Selection of " + rowList.length + " items changed out from under 'sum'."); cyberfox 267 return null; mrs 268 } catch(NullPointerException npe) { mrs 269 JConfig.log().logDebug("sum got NPE - this is common during delete operations"); mrs 270 return null; cyberfox 271 } catch(Exception e) { mrs 272 JConfig.log().handleException("Sum serious exception!", e); cyberfox 273 return null; cyberfox 274 } cyberfox 275 cyberfox 276 if(accum == null || accum.isNull()) { cyberfox 277 return null; cyberfox 278 } cyberfox 279 cyberfox 280 String sAndH = "s/h"; cyberfox 281 if(!Locale.getDefault().equals(Locale.US)) sAndH = "p/p"; cyberfox 282 cyberfox 283 // If we managed to do the i18n thing through it all, and we have cyberfox 284 // some real values, return it. cyberfox 285 if(i18n && realAccum != null) { cyberfox 286 StringBuffer result = new StringBuffer(realAccum.toString()); cyberfox 287 if(withRealShipping != null && !realAccum.equals(withRealShipping)) { cyberfox 288 result.append(" (").append(withRealShipping).append(" with ").append(sAndH).append(')'); cyberfox 289 } cyberfox 290 return result.toString(); cyberfox 291 } cyberfox 292 cyberfox 293 if(approx) { cyberfox 294 String result; cyberfox 295 if(withShipping != null && !accum.equals(withShipping)) { mrs 296 result = "About " + accum.toString() + " (" + withShipping + " with " + sAndH + ')'; cyberfox 297 } else { mrs 298 result = "About " + accum.toString(); cyberfox 299 } cyberfox 300 return result; cyberfox 301 } cyberfox 302 cyberfox 303 if(withShipping != null && !accum.equals(withShipping)) { cyberfox 304 return accum.toString() + " (" + withShipping + " with " + sAndH + ')'; cyberfox 305 } cyberfox 306 cyberfox 307 return accum.toString(); cyberfox 308 } cyberfox 309 cyberfox 310 /** cyberfox 311 * @brief Sets the background color for this tab to the passed in color. cyberfox 312 * cyberfox 313 * @param bgColor - The color to set the background to. cyberfox 314 */ cyberfox 315 public void setBackground(Color bgColor) { cyberfox 316 _scroller.getViewport().setBackground(bgColor); cyberfox 317 _table.setBackground(bgColor); cyberfox 318 _bgColor = bgColor; cyberfox 319 } cyberfox 320 cyberfox 321 /** cyberfox 322 * @brief Return the background color this was set to. cyberfox 323 * cyberfox 324 * @return - The color, if any, this tab was set to. cyberfox 325 */ cyberfox 326 public Color getBackground() { cyberfox 327 return _bgColor; cyberfox 328 } cyberfox 329 cyberfox 330 /** mrs 331 * Delete an auction entry, using that auction entry to match against. mrs 332 * This also tells the auction entry to unregister itself! mrs 333 * mrs 334 * @param inEntry - The auction entry to delete. mrs 335 */ mrs 336 public void delEntry(EntryInterface inEntry) { mrs 337 _tSort.delete(inEntry); mrs 338 } mrs 339 mrs 340 /** mrs 341 * Add an AuctionEntry that has already been created, denying mrs 342 * duplicates, but allowing duplicates where both have useful mrs 343 * information that is not the same. mrs 344 * mrs 345 * @param aeNew - The new auction entry to add to the tables. mrs 346 */ mrs 347 public void addEntry(EntryInterface aeNew) { mrs 348 if (aeNew != null) { mrs 349 if (_tSort.insert(aeNew) == -1) { mrs 350 JConfig.log().logMessage("JBidWatch: Bad auction entry, cannot add!"); mrs 351 } mrs 352 } mrs 353 } mrs 354 cyberfox 355 public boolean toggleField(String field) { mrs 356 boolean rval; cyberfox 357 int modelColumn = TableColumnController.getInstance().getColumnNumber(field); cyberfox 358 if(_table.convertColumnIndexToView(modelColumn) == -1) { mrs 359 _table.addColumn(new TableColumn(modelColumn, Constants.DEFAULT_COLUMN_WIDTH, _myRenderer, null)); mrs 360 rval = true; cyberfox 361 } else { cyberfox 362 _table.removeColumn(_table.getColumn(field)); mrs 363 _tSort.removeColumn(field, _table); mrs 364 rval = false; cyberfox 365 } mrs 366 mrs 367 adjustRowHeight(); mrs 368 mrs 369 return rval; mrs 370 } mrs 371 mrs 372 // hack and a half - but adding a row height attribute for columns seems like overkill mrs 373 public void adjustRowHeight() { mrs 374 Font def = myTableCellRenderer.getDefaultFont(); mrs 375 Graphics g = _table.getGraphics(); mrs 376 int defaultHeight; mrs 377 mrs 378 if(def == null || g == null) { mrs 379 defaultHeight = Constants.DEFAULT_ROW_HEIGHT; mrs 380 } else { mrs 381 FontMetrics metrics = g.getFontMetrics(def); mrs 382 defaultHeight = metrics.getMaxAscent() + metrics.getMaxDescent() + metrics.getLeading()+4; mrs 383 } mrs 384 mrs 385 if (_table.convertColumnIndexToView(TableColumnController.THUMBNAIL) != -1) { mrs 386 defaultHeight = Math.max(Constants.MICROTHUMBNAIL_ROW_HEIGHT, defaultHeight); mrs 387 } mrs 388 _table.setRowHeight(Math.max(defaultHeight, Constants.DEFAULT_ROW_HEIGHT)); mrs 389 if(def != null) { mrs 390 _table.getTableHeader().setFont(def); mrs 391 } cyberfox 392 } cyberfox 393 cyberfox 394 public List<String> getColumns() { cyberfox 395 ArrayList<String> al = new ArrayList<String>(); cyberfox 396 for(int i = 0; i<_table.getColumnCount(); i++) { cyberfox 397 al.add(_table.getColumnName(i)); cyberfox 398 } cyberfox 399 cyberfox 400 return al; cyberfox 401 } cyberfox 402 cyberfox 403 public boolean export(String fname) { cyberfox 404 return _export.export(fname); cyberfox 405 } cyberfox 406 cyberfox 407 /** cyberfox 408 * @brief Print this table. cyberfox 409 * cyberfox 410 */ cyberfox 411 public void print() { cyberfox 412 _print.doPrint(); cyberfox 413 } cyberfox 414 cyberfox 415 /** cyberfox 416 * @brief Convert current column widths into display properties to cyberfox 417 * be saved for a future session. cyberfox 418 * cyberfox 419 * @param addToProps - The properties object to add the column widths to. cyberfox 420 * @param name - The category name to get the info from. cyberfox 421 */ cyberfox 422 public void getColumnWidthsToProperties(Properties addToProps, String name) { cyberfox 423 for(int j = 0; j<_table.getColumnCount(); j++) { cyberfox 424 TableColumn ct; cyberfox 425 try { cyberfox 426 ct = _table.getColumn(_table.getColumnName(j)); cyberfox 427 } catch(IllegalArgumentException iae) { mrs 428 JConfig.log().logMessage("Column can't be retrieved from the table: " + _table.getColumnName(j)); cyberfox 429 ct = null; cyberfox 430 } cyberfox 431 // ColumnProps cp = new ColumnProps(_dataModel.getColumnName(j), j, ct.getWidth()); cyberfox 432 //noinspection StringContatenationInLoop cyberfox 433 if(ct != null) addToProps.setProperty(name + '.' + _table.getColumnName(j), Integer.toString(j) + '.' + Integer.toString(ct.getWidth())); cyberfox 434 } cyberfox 435 } cyberfox 436 cyberfox 437 public void getColumnWidthsToProperties(Properties addToProps) { cyberfox 438 getColumnWidthsToProperties(addToProps, _dataModel.getName()); cyberfox 439 } cyberfox 440 mrs 441 public void sort() { mrs 442 _tSort.sort(); mrs 443 } mrs 444 mrs 445 public void redrawAll() { mrs 446 _tSort.tableChanged(new TableModelEvent(_tSort)); mrs 447 } cyberfox 448 }
Check out the code: svn co jbidwatcher/trunk/src/com/jbidwatcher/ui/AuctionsUIModel.java
