PageRenderTime 43ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/etl.editor/src/org/netbeans/modules/sql/framework/ui/graph/impl/ListArea.java

https://bitbucket.org/openesb/netbeans-soa
Java | 763 lines | 371 code | 118 blank | 274 comment | 78 complexity | c68317dd807d0217b292cee37e5ab447 MD5 | raw file
  1. /*
  2. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
  3. *
  4. * Copyright 1997-2010 Oracle and/or its affiliates. All rights reserved.
  5. *
  6. * Oracle and Java are registered trademarks of Oracle and/or its affiliates.
  7. * Other names may be trademarks of their respective owners.
  8. *
  9. * The contents of this file are subject to the terms of either the GNU
  10. * General Public License Version 2 only ("GPL") or the Common
  11. * Development and Distribution License("CDDL") (collectively, the
  12. * "License"). You may not use this file except in compliance with the
  13. * License. You can obtain a copy of the License at
  14. * http://www.netbeans.org/cddl-gplv2.html
  15. * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
  16. * specific language governing permissions and limitations under the
  17. * License. When distributing the software, include this License Header
  18. * Notice in each file and include the License file at
  19. * nbbuild/licenses/CDDL-GPL-2-CP. Oracle designates this
  20. * particular file as subject to the "Classpath" exception as provided
  21. * by Oracle in the GPL Version 2 section of the License file that
  22. * accompanied this code. If applicable, add the following below the
  23. * License Header, with the fields enclosed by brackets [] replaced by
  24. * your own identifying information:
  25. * "Portions Copyrighted [year] [name of copyright owner]"
  26. *
  27. * Contributor(s):
  28. *
  29. * The Original Software is NetBeans. The Initial Developer of the Original
  30. * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
  31. * Microsystems, Inc. All Rights Reserved.
  32. *
  33. * If you wish your version of this file to be governed by only the CDDL
  34. * or only the GPL Version 2, indicate your decision by adding
  35. * "[Contributor] elects to include this software in this distribution
  36. * under the [CDDL or GPL Version 2] license." If you do not indicate a
  37. * single choice of license, a recipient has the option to distribute
  38. * your version of this file under either the CDDL, the GPL Version 2 or
  39. * to extend the choice of license to its licensees as provided above.
  40. * However, if you add GPL Version 2 code and therefore, elected the GPL
  41. * Version 2 license, then the option applies only if the new code is
  42. * made subject to such option by the copyright holder.
  43. */
  44. package org.netbeans.modules.sql.framework.ui.graph.impl;
  45. import java.awt.Color;
  46. import java.awt.Graphics2D;
  47. import java.awt.Insets;
  48. import java.awt.Point;
  49. import java.awt.Rectangle;
  50. import java.util.ArrayList;
  51. import javax.swing.DefaultListModel;
  52. import javax.swing.ListModel;
  53. import javax.swing.event.ListDataEvent;
  54. import javax.swing.event.ListDataListener;
  55. import org.netbeans.modules.sql.framework.ui.graph.ListAreaCellRenderer;
  56. import com.nwoods.jgo.JGoBrush;
  57. import com.nwoods.jgo.JGoDrawable;
  58. import com.nwoods.jgo.JGoObject;
  59. import com.nwoods.jgo.JGoPen;
  60. import com.nwoods.jgo.JGoRectangle;
  61. import com.nwoods.jgo.JGoScrollBar;
  62. import com.nwoods.jgo.JGoView;
  63. /**
  64. * @author Ritesh Adval
  65. * @version $Revision$
  66. */
  67. public class ListArea extends CanvasArea {
  68. private static final JGoPen DEFAULT_PEN = JGoPen.makeStockPen(Color.lightGray);
  69. private ListModel dataModel;
  70. private ListAreaCellRenderer cellRenderer;
  71. private ListDataAdapter listDataAdapter;
  72. private ArrayList cells;
  73. private JGoRectangle columnRect;
  74. private int vSpacing = 1;
  75. private JGoPen linePen = null;
  76. //constants for first , last visible row
  77. //by default set to 0 so that first row is visible
  78. private int firstVisibleRow = 0;
  79. private int lastVisibleRow = -1;
  80. //vertical scrollbar
  81. private JGoScrollBar vScrollBar;
  82. private int vScrollBarGap = 0;
  83. //this is the size of the scrollbar
  84. private static int scrollBarSize = 14;
  85. private int prefferedWidth = -1;
  86. private ArrayList areaList = new ArrayList();
  87. private boolean drawBoundingRect = true;
  88. private boolean drawLines = true;
  89. private boolean showScrollBar = true;
  90. /** Creates a new instance of BasicListArea */
  91. public ListArea() {
  92. listDataAdapter = new ListDataAdapter();
  93. if (drawBoundingRect) {
  94. columnRect = new JGoRectangle();
  95. columnRect.setSelectable(false);
  96. columnRect.setResizable(false);
  97. columnRect.setPen(JGoPen.lightGray);
  98. columnRect.setBrush(JGoBrush.makeStockBrush(Color.WHITE));
  99. addObjectAtTail(columnRect);
  100. }
  101. //add scrollbar
  102. vScrollBar = new JGoScrollBar();
  103. vScrollBar.setVertical(true);
  104. vScrollBar.setSelectable(false);
  105. addObjectAtTail(vScrollBar);
  106. this.setSelectable(false);
  107. this.setResizable(false);
  108. this.setDraggable(true);
  109. //set the insets around column
  110. //this.insets = new Insets(1, 5, 0, 10);
  111. // have a default cell renderer
  112. cellRenderer = new DefaultListAreaRenderer();
  113. }
  114. /**
  115. * create an instance of list area
  116. *
  117. * @param listData list data values
  118. */
  119. public ListArea(Object[] listData) {
  120. this();
  121. DefaultListModel model = new DefaultListModel();
  122. for (int i = 0; i < listData.length; i++) {
  123. model.addElement(listData[i]);
  124. }
  125. setModel(model);
  126. }
  127. /**
  128. * set the list model
  129. *
  130. * @param model list model
  131. */
  132. public void setModel(ListModel model) {
  133. ListModel oldModel = dataModel;
  134. this.dataModel = model;
  135. if (oldModel != null) {
  136. oldModel.removeListDataListener(listDataAdapter);
  137. }
  138. dataModel.addListDataListener(listDataAdapter);
  139. //by setting the model we need to also set the renderer for objects
  140. //in the model
  141. for (int i = 0; i < dataModel.getSize(); i++) {
  142. Object val = dataModel.getElementAt(i);
  143. ListAreaCellRenderer listCellRenderer = getCellRenderer(i);
  144. JGoObject cell = listCellRenderer.getListAreaCellRenderer(this, val, i, false, false);
  145. areaList.add(cell);
  146. this.addObjectAtTail(cell);
  147. }
  148. }
  149. /**
  150. * get the list model
  151. *
  152. * @return list model
  153. */
  154. public ListModel getModel() {
  155. return dataModel;
  156. }
  157. /**
  158. * set the default cell renderer
  159. *
  160. * @param cellRenderer cell renderer
  161. */
  162. public void setCellRenderer(ListAreaCellRenderer cellRenderer) {
  163. this.cellRenderer = cellRenderer;
  164. }
  165. /**
  166. * get the default cell renderer
  167. *
  168. * @return cell renderer
  169. */
  170. public ListAreaCellRenderer getCellRenderer() {
  171. return cellRenderer;
  172. }
  173. /**
  174. * get cell renderer at an index
  175. *
  176. * @param row row index
  177. * @return cell renderer
  178. */
  179. protected ListAreaCellRenderer getCellRenderer(int row) {
  180. return getCellRenderer();
  181. }
  182. /**
  183. * get the cell renderer component at an index
  184. *
  185. * @param row row index
  186. * @return cell renderer
  187. */
  188. public JGoObject getCellRendererComponent(int row) {
  189. if ((row >= areaList.size()) || row < 0) {
  190. return null;
  191. }
  192. return (JGoObject) areaList.get(row);
  193. }
  194. /**
  195. * set whether to draw lines after each cell in this list
  196. *
  197. * @param drawLines whether to draw lines
  198. */
  199. public void setDrawLines(boolean drawLines) {
  200. this.drawLines = drawLines;
  201. }
  202. /**
  203. * get whether list draws line after each cell
  204. *
  205. * @return drawlines
  206. */
  207. public boolean isDrawLines() {
  208. return this.drawLines;
  209. }
  210. /**
  211. * get value at a particular point
  212. *
  213. * @param loc location
  214. * @return cell value
  215. */
  216. public Object getValueAt(Point loc) {
  217. ListModel model = getModel();
  218. if (model == null) {
  219. return null;
  220. }
  221. for (int i = 0; i < model.getSize(); i++) {
  222. Object val = model.getElementAt(i);
  223. JGoObject renderer = getCellRendererComponent(i);
  224. if (renderer != null && renderer.getBoundingRect().contains(loc)) {
  225. return val;
  226. }
  227. }
  228. return null;
  229. }
  230. /**
  231. * get the vertical scrollbar
  232. *
  233. * @return vertical scroll bar
  234. */
  235. public JGoScrollBar getVerticalScrollBar() {
  236. return vScrollBar;
  237. }
  238. /**
  239. * set the gap of vertical scrollbar from the edge of this area
  240. *
  241. * @param gap gap
  242. */
  243. public void setVerticalScrollBarGapFromEdge(int gap) {
  244. vScrollBarGap = gap;
  245. }
  246. public void setShowScrollBar(boolean showScrollBar) {
  247. this.showScrollBar = showScrollBar;
  248. }
  249. public boolean isShowScrollBar() {
  250. return this.showScrollBar;
  251. }
  252. /**
  253. * since setVisible() doesn't automatically call setVisible() on all the children, we
  254. * need to do this manually to handle the scroll bar
  255. *
  256. * @param bFlag boolean
  257. */
  258. public void setVisible(boolean bFlag) {
  259. super.setVisible(bFlag);
  260. if (getVerticalScrollBar() != null && isShowScrollBar()) {
  261. getVerticalScrollBar().setVisible(bFlag);
  262. if (bFlag) {
  263. this.addObjectAtTail(getVerticalScrollBar());
  264. } else {
  265. this.removeObject(getVerticalScrollBar());
  266. }
  267. }
  268. }
  269. /**
  270. * updates the vertical scroll bar
  271. */
  272. public void updateVerticalScrollBar() {
  273. JGoScrollBar bar = getVerticalScrollBar();
  274. if (bar != null) {
  275. if (!this.isShowScrollBar()) {
  276. bar.setVisible(false);
  277. return;
  278. }
  279. if (getFirstVisibleRow() == 0 && getLastVisibleRow() == getRowCount() - 1) {
  280. bar.setVisible(false);
  281. scrollBarSize = 0;
  282. } else {
  283. bar.setVisible(true);
  284. bar.setValues(getFirstVisibleRow(), getLastVisibleRow() - getFirstVisibleRow() + 1, 0, getRowCount(), 1, Math.max(getLastVisibleRow()
  285. - getFirstVisibleRow(), 1));
  286. scrollBarSize = 14;
  287. //set the height so that only visible rows can be dispalced
  288. //this avoids extra space at the end of scroll bar
  289. //any parent should listen to change in child geometry
  290. if (this.getParent() instanceof BasicListArea) {
  291. ((BasicListArea) this.getParent()).adjustHeight(this);
  292. }
  293. }
  294. }
  295. }
  296. /**
  297. * this gets the notification from the JGoScrollBar when the scroll bar value,
  298. * representing the first visible index, has changed
  299. *
  300. * @param hint event hint
  301. * @param prevInt previous integer value
  302. * @param prevVal previous object value
  303. */
  304. public void update(int hint, int prevInt, Object prevVal) {
  305. if (hint == JGoScrollBar.ChangedScrollBarValue) {
  306. if (getVerticalScrollBar() != null) {
  307. // optimization: assume area doesn't change when scrolling items
  308. setFirstVisibleRow(getVerticalScrollBar().getValue());
  309. }
  310. } else {
  311. super.update(hint, prevInt, prevVal);
  312. }
  313. }
  314. /**
  315. * get the graph rectangle
  316. *
  317. * @return graph rectangle
  318. */
  319. public JGoObject getRect() {
  320. return columnRect;
  321. }
  322. /**
  323. * get the number of rows in this column area
  324. *
  325. * @return number of rows in this column
  326. */
  327. public int getRowCount() {
  328. if (dataModel == null) {
  329. return -1;
  330. }
  331. return dataModel.getSize();
  332. }
  333. /**
  334. * add a new cell in the column area int val value to represent in a cell
  335. *
  336. * @param row row
  337. * @param val value
  338. */
  339. public void addItem(int row, Object val) {
  340. }
  341. /**
  342. * get the cell at an index
  343. *
  344. * @param row row
  345. * @return cell area
  346. */
  347. public CellArea getCellAt(int row) {
  348. if (row <= cells.size() - 1) {
  349. return (CellArea) cells.get(row);
  350. }
  351. return null;
  352. }
  353. /**
  354. * set the preffered width
  355. *
  356. * @param width preffered width
  357. */
  358. public void setPrefferedWidth(int width) {
  359. this.prefferedWidth = width;
  360. }
  361. /**
  362. * get the preffered width
  363. *
  364. * @return preffered width
  365. */
  366. public int getPrefferedWidth() {
  367. return prefferedWidth;
  368. }
  369. /**
  370. * get maximum width of this area
  371. *
  372. * @return max width
  373. */
  374. public int getMaximumWidth() {
  375. int maxWidth = getInsets().left + getInsets().right;
  376. int w = 0;
  377. for (int i = 0; i < getModel().getSize(); i++) {
  378. JGoObject renderer = getCellRendererComponent(i);
  379. if (renderer != null) {
  380. int rendererWidth = renderer.getWidth();
  381. if (w < rendererWidth) {
  382. w = rendererWidth;
  383. }
  384. }
  385. }
  386. maxWidth += w;
  387. return maxWidth;
  388. }
  389. /**
  390. * get the maximum height of this area
  391. *
  392. * @return max height
  393. */
  394. public int getMaximumHeight() {
  395. int maxHeight = getInsets().top + getInsets().bottom;
  396. for (int i = 0; i < getModel().getSize(); i++) {
  397. JGoObject renderer = getCellRendererComponent(i);
  398. if (renderer != null) {
  399. int rendererHeight = renderer.getHeight();
  400. maxHeight += rendererHeight;
  401. maxHeight += vSpacing;
  402. }
  403. }
  404. //remove one extra vspace
  405. maxHeight -= vSpacing;
  406. return maxHeight;
  407. }
  408. /**
  409. * get first visible row index
  410. *
  411. * @return first visible row index
  412. */
  413. public int getFirstVisibleRow() {
  414. return firstVisibleRow;
  415. }
  416. /**
  417. * set the first visible row
  418. *
  419. * @param rowIdx index of first visible row
  420. */
  421. public void setFirstVisibleRow(int rowIdx) {
  422. int oldIndex = firstVisibleRow;
  423. if (rowIdx >= 0 && rowIdx <= getRowCount() && oldIndex != rowIdx) {
  424. firstVisibleRow = rowIdx;
  425. }
  426. }
  427. /**
  428. * get the height of all visible rows in this column
  429. *
  430. * @return height of visible rows
  431. */
  432. public int getVisibleRowHeights() {
  433. int rowHeights = 0;
  434. for (int i = this.getFirstVisibleRow(); i <= this.getLastVisibleRow(); i++) {
  435. JGoObject renderer = getCellRendererComponent(i);
  436. if (renderer != null) {
  437. rowHeights += renderer.getHeight() + getVerticalSpacing();
  438. }
  439. }
  440. rowHeights += insets.top + insets.bottom - getVerticalSpacing();
  441. return rowHeights;
  442. }
  443. /**
  444. * get the last visible row of this list area
  445. *
  446. * @return list visible row
  447. */
  448. public int getLastVisibleRow() {
  449. return lastVisibleRow;
  450. }
  451. /**
  452. * set the last visible row
  453. *
  454. * @param rowIdx index of first visible row
  455. */
  456. public void setLastVisibleRow(int rowIdx) {
  457. int oldIndex = lastVisibleRow;
  458. if (rowIdx >= 0 && rowIdx <= getRowCount() && oldIndex != rowIdx) {
  459. lastVisibleRow = rowIdx;
  460. }
  461. }
  462. /**
  463. * get the vertical spacing
  464. *
  465. * @return vertical spacing
  466. */
  467. public int getVerticalSpacing() {
  468. return vSpacing;
  469. }
  470. /**
  471. * set the vertical spacing between cells of this list area
  472. *
  473. * @param newspace new vertical space
  474. */
  475. public void setVerticalSpacing(int newspace) {
  476. int oldSpacing = vSpacing;
  477. if (oldSpacing != newspace) {
  478. vSpacing = newspace;
  479. }
  480. }
  481. /**
  482. * get the line pen
  483. *
  484. * @return line pen
  485. */
  486. public JGoPen getLinePen() {
  487. return (linePen != null) ? linePen : DEFAULT_PEN;
  488. }
  489. /**
  490. * set line pen for drawing border
  491. *
  492. * @param pen pen
  493. */
  494. public void setLinePen(JGoPen pen) {
  495. JGoPen oldPen = linePen;
  496. if (oldPen != pen) {
  497. linePen = pen;
  498. layoutChildren();
  499. }
  500. }
  501. /**
  502. * set the out of scroll cell bounds
  503. *
  504. * @param rect rect
  505. */
  506. public void setOutOfScrollCellBounds(Rectangle rect) {
  507. }
  508. /**
  509. * paint this area
  510. *
  511. * @param g Graphics2D
  512. * @param view view
  513. */
  514. public void paint(Graphics2D g, JGoView view) {
  515. super.paint(g, view);
  516. if (!drawLines) {
  517. return;
  518. }
  519. int penwidth = 0;
  520. if (getLinePen() != null) {
  521. penwidth = getLinePen().getWidth();
  522. }
  523. if (penwidth == 0) {
  524. return;
  525. }
  526. JGoObject r = getRect();
  527. if (r == null) {
  528. return; // not yet initialized
  529. }
  530. Insets insets1 = getInsets();
  531. int rectleft = r.getLeft();
  532. int recttop = r.getTop();
  533. int rectwidth = r.getWidth();
  534. int rectheight = r.getHeight();
  535. int top = recttop + insets1.top;
  536. int height = rectheight - insets1.top - insets1.bottom;
  537. int limit = 0;
  538. limit = height;
  539. int s = 0; // height/width of visible items so far
  540. for (int i = getFirstVisibleRow(); i < getLastVisibleRow(); i++) {
  541. JGoObject cell = this.getCellRendererComponent(i);
  542. int h = cell.getHeight();
  543. s += h;
  544. int sep = Math.max(penwidth, getVerticalSpacing());
  545. if (s + sep <= limit) {
  546. JGoDrawable.drawLine(g, getLinePen(), rectleft, top + s + sep / 2, rectleft + rectwidth, top + s + sep / 2);
  547. }
  548. s += sep;
  549. }
  550. }
  551. /**
  552. * layout all of this children of this column area
  553. */
  554. public void layoutChildren() {
  555. columnRect.setPen(getLinePen());
  556. if (drawBoundingRect) {
  557. columnRect.setBoundingRect(this.getBoundingRect());
  558. }
  559. //get the bounding rectangle of this column area
  560. int x = getLeft() + insets.left;
  561. int y = getTop() + insets.top;
  562. int width = getWidth() - insets.left - insets.right;
  563. int height = getHeight() - insets.top - insets.bottom;
  564. int oldLastVisibleRow = lastVisibleRow;
  565. int cellWidth = width;
  566. int nextCellDeltaTop = 0;
  567. //row count
  568. int cnt = 0;
  569. for (int i = 0; i < dataModel.getSize(); i++) {
  570. JGoObject cell = (JGoObject) areaList.get(i);
  571. if (cnt < getFirstVisibleRow()) {
  572. cell.setVisible(false);
  573. cell.setBoundingRect(x, y + nextCellDeltaTop, cellWidth, cell.getHeight());
  574. cnt++;
  575. continue;
  576. }
  577. //if cell is going out of the height of this
  578. //area then we mark it invisible
  579. //if (nextCellTop > (y + height)) {
  580. if (nextCellDeltaTop + cell.getHeight() > height) {
  581. cell.setVisible(false);
  582. cell.setBoundingRect(x, y + nextCellDeltaTop, cellWidth, cell.getHeight());
  583. } else {
  584. cell.setVisible(true);
  585. lastVisibleRow = cnt;
  586. cell.setBoundingRect(x, y + nextCellDeltaTop, cellWidth, cell.getHeight());
  587. nextCellDeltaTop += cell.getHeight() + getVerticalSpacing();
  588. }
  589. cnt++;
  590. }
  591. //layout vertical scrollbar
  592. JGoScrollBar sbar = getVerticalScrollBar();
  593. if (sbar != null) {
  594. sbar.setBoundingRect(x + width - scrollBarSize - vScrollBarGap, y, scrollBarSize, height);
  595. if (oldLastVisibleRow != lastVisibleRow) {
  596. updateVerticalScrollBar();
  597. }
  598. }
  599. }
  600. class ListDataAdapter implements ListDataListener {
  601. /**
  602. * Sent when the contents of the list has changed in a way that's too complex to
  603. * characterize with the previous methods. For example, this is sent when an item
  604. * has been replaced. Index0 and index1 bracket the change.
  605. *
  606. * @param e a <code>ListDataEvent</code> encapsulating the event information
  607. */
  608. public void contentsChanged(ListDataEvent e) {
  609. }
  610. /**
  611. * Sent after the indices in the index0,index1 interval have been inserted in the
  612. * data model. The new interval includes both index0 and index1.
  613. *
  614. * @param e a <code>ListDataEvent</code> encapsulating the event information
  615. */
  616. public void intervalAdded(ListDataEvent e) {
  617. //list model has new items so get renderer for them and add it
  618. for (int i = e.getIndex0(); i <= e.getIndex1(); i++) {
  619. Object val = getModel().getElementAt(i);
  620. ListAreaCellRenderer listCellRenderer = getCellRenderer(i);
  621. JGoObject cell = listCellRenderer.getListAreaCellRenderer(ListArea.this, val, i, false, false);
  622. //set location of the cell otherwise it will be 0 0 causing
  623. //width and height of listarea to start from 0,0 till current list
  624. //are x, y position see computeBoundingRect() for how it is calculated
  625. cell.setLocation(ListArea.this.getLocation());
  626. areaList.add(cell);
  627. addObjectAtTail(cell);
  628. }
  629. }
  630. /**
  631. * Sent after the indices in the index0,index1 interval have been removed from the
  632. * data model. The interval includes both index0 and index1.
  633. *
  634. * @param e a <code>ListDataEvent</code> encapsulating the event information
  635. */
  636. public void intervalRemoved(ListDataEvent e) {
  637. //list model has some items removed so remove renderer for them
  638. for (int i = e.getIndex0(); i <= e.getIndex1(); i++) {
  639. JGoObject obj = (JGoObject) areaList.get(i);
  640. areaList.remove(i);
  641. removeObject(obj);
  642. }
  643. }
  644. }
  645. }