1 19 20 package org.netbeans.modules.xml.xam.ui.column; 21 22 import java.awt.Color ; 23 import java.awt.Component ; 24 import java.awt.Container ; 25 import java.awt.Dimension ; 26 import java.awt.EventQueue ; 27 import java.awt.Point ; 28 import java.awt.Rectangle ; 29 import java.awt.event.ComponentAdapter ; 30 import java.awt.event.ComponentEvent ; 31 import java.util.ArrayList ; 32 import java.util.List ; 33 import java.util.ListIterator ; 34 import javax.swing.JComponent ; 35 import javax.swing.JPanel ; 36 import javax.swing.JViewport ; 37 import javax.swing.Scrollable ; 38 import org.netbeans.modules.xml.xam.ui.layout.JSplitterBar; 39 import org.netbeans.modules.xml.xam.ui.layout.SplitterLayout; 40 41 48 public class BasicColumnView extends JPanel implements ColumnView { 49 private static final String COLUMN_WEIGHT_1 = "1"; private static final int SCROLL_DELAY = 20; 51 static final long serialVersionUID = 1L; 52 53 private List <Column> columnList; 54 55 private List <JSplitterBar> splitterList; 56 57 private JPanel mainParentPanel; 58 59 62 public BasicColumnView() { 63 initComponents(); 64 columnList = new ArrayList <Column>(); 65 splitterList = new ArrayList <JSplitterBar>(); 66 67 mainParentPanel = new MainPanel(); 68 mainParentPanel.setBackground(Color.WHITE); 69 mainParentPanel.setLayout(new SplitterLayout(false)); 70 scrollPane.setViewportView(mainParentPanel); 71 scrollPane.setViewportBorder(null); 72 scrollPane.getViewport().setBackground(Color.WHITE); 73 74 addComponentListener(new ComponentAdapter (){ 75 public void componentResized(ComponentEvent e) { 76 super.componentResized(e); 77 validate(); 78 revalidate(); 79 } 80 81 }); 82 } 83 84 89 protected void appendColumnToList(Column column) { 90 if (column == null) { 91 return; 92 } 93 JComponent comp = column.getComponent(); 94 if (comp == null) { 95 return; 96 } 97 columnList.add(column); 98 mainParentPanel.add(COLUMN_WEIGHT_1, comp); 99 JSplitterBar bar = new JSplitterBar(); 100 mainParentPanel.add(bar); 101 splitterList.add(bar); 102 } 103 104 public void appendColumn(Column column) { 105 appendColumnToList(column); 106 validate(); 110 mainParentPanel.revalidate(); 111 scrollToColumn(column, false); 112 } 113 114 public void appendColumns(Column[] columns) { 115 for (Column column : columns) { 116 appendColumnToList(column); 117 } 118 validate(); 119 mainParentPanel.revalidate(); 120 scrollToColumn(columns[columns.length - 1], false); 121 } 122 123 public void clearColumns(){ 124 mainParentPanel.removeAll(); 125 columnList.clear(); 126 splitterList.clear(); 127 mainParentPanel.revalidate(); 128 mainParentPanel.repaint(); 129 } 130 131 public void removeColumnsAfter(Column column) { 132 if (column == null) { 133 return; 134 } 135 136 if (!isLastColumn(column)) { 137 scrollToColumn(getNextColumn(column), true); 141 } 142 143 int loc = columnList.indexOf(column); 145 for (int ii = columnList.size() - 1; ii > loc; ii--) { 146 Column col = columnList.remove(ii); 147 Component comp = col.getComponent(); 148 mainParentPanel.remove(comp); 149 } 150 for (int ii = splitterList.size() - 1; ii > loc; ii--) { 151 JSplitterBar bar = splitterList.remove(ii); 152 mainParentPanel.remove(bar); 153 } 154 mainParentPanel.revalidate(); 155 mainParentPanel.repaint(); 156 } 157 158 public void scrollToColumn(final Column column, boolean synchronous) { 159 if (column == null) { 160 return; 161 } 162 if (synchronous) { 163 if (!EventQueue.isDispatchThread()) { 164 try { 165 EventQueue.invokeAndWait(new Runnable () { 167 public void run() { 168 scrollToColumn(column); 169 } 170 }); 171 } catch (Exception e) { 172 return; 173 } 174 } else { 175 scrollToColumn(column); 177 } 178 } else { 179 EventQueue.invokeLater(new Runnable () { 181 public void run() { 182 scrollToColumn(column); 184 } 185 }); 186 } 187 } 188 189 196 protected void scrollToColumn(Column column) { 197 if (!EventQueue.isDispatchThread()) { 198 throw new IllegalStateException ("This method can only be " + 199 "invoked on the AWT event processing thread"); 200 } 201 202 int columnIndex = columnList.indexOf(column); 205 if (columnIndex == -1 || columnList.size() <= 1) { 206 return; 207 } 208 209 Rectangle viewBounds = column.getComponent().getBounds(); 213 viewBounds.width += 5; 214 215 JViewport viewport = scrollPane.getViewport(); 217 Rectangle viewportBounds = viewport.getViewRect(); 218 219 final int DELTA = (int) ((viewportBounds.getX() + 221 viewportBounds.getWidth()) - (viewBounds.getX() + 222 viewBounds.getWidth())); 223 if (DELTA == 0) { 224 return; 225 } 226 227 int deltaColumns = Math.abs(lastShowingColumnIndex() - columnIndex); 234 235 Point position = viewport.getViewPosition(); 236 237 final int STEPS = 5 * (deltaColumns == 0 ? 1 : deltaColumns); 238 final int INCREMENT = DELTA / STEPS; 239 240 for (int step = 0; step < STEPS; step++) { 241 int newX = (int) position.getX() - INCREMENT; 242 if (newX <= 0) { 243 break; 244 } 245 newX += 1; 248 249 try { 250 Thread.currentThread().sleep(SCROLL_DELAY); 254 } catch (InterruptedException ie) { 255 } 257 258 position = new Point (newX, (int) position.getY()); 259 viewport.setViewPosition(position); 260 } 261 } 262 263 268 protected boolean isLastColumn(Column column){ 269 if (column == null){ 270 return false; 271 } 272 return columnList.indexOf(column) == columnList.size()-1; 273 274 } 275 276 public int getColumnCount() { 277 return columnList.size(); 278 } 279 280 public Column getFirstColumn() { 281 if (columnList.size() > 0) { 282 return columnList.get(0); 283 } else { 284 return null; 285 } 286 } 287 288 public Column getNextColumn(Column column){ 289 if (column == null) { 290 return null; 291 } 292 if (isLastColumn(column)) { 293 return null; 294 } 295 return columnList.get(columnList.indexOf(column) + 1); 296 } 297 298 @Override 299 public void requestFocus() { 300 super.requestFocus(); 301 int index = lastShowingColumnIndex(); 302 if (index > -1) { 303 Column column = columnList.get(index); 304 column.getComponent().requestFocus(); 305 } 306 } 307 308 @Override 309 public boolean requestFocusInWindow() { 310 boolean retVal = super.requestFocusInWindow(); 311 int index = lastShowingColumnIndex(); 312 if (index > -1) { 313 Column column = columnList.get(index); 314 return column.getComponent().requestFocusInWindow(); 315 } 316 return retVal; 317 } 318 319 324 private int lastShowingColumnIndex() { 325 int index = -1; 326 for (int ii = columnList.size() - 1; ii > -1; ii--){ 327 if (columnList.get(ii).getComponent().isShowing()) { 328 index = ii; 329 break; 330 } 331 } 332 return index; 333 } 334 335 344 private int locationToIndex(Point location, int direction) { 345 int index = -1; 346 Component comp = mainParentPanel.getComponentAt(location); 347 if (comp instanceof JSplitterBar) { 348 index = splitterList.indexOf(comp); 352 if (direction > 0) { 353 index++; 356 } 357 } else { 358 Component [] comps = mainParentPanel.getComponents(); 359 for (int ii = 0; ii < comps.length; ii += 2) { 361 if (comps[ii] == comp) { 362 index = ii / 2; 363 break; 364 } 365 } 366 } 367 return index; 368 } 369 370 public int getColumnIndex(Column column) { 371 return columnList.indexOf(column); 372 } 373 374 public void addNotify() { 375 super.addNotify(); 376 Container parent = getParent(); 377 assert !(parent instanceof JViewport ) : 378 "BasicColumnView has its own scrollpane. " + 379 "Do not place BasicColumnView in a scrollpane."; 380 } 381 382 385 private class MainPanel extends JPanel implements Scrollable { 386 387 private static final long serialVersionUID = 1L; 388 389 public Dimension getPreferredScrollableViewportSize() { 390 return getPreferredSize(); 391 } 392 393 public int getScrollableBlockIncrement(Rectangle visibleRect, 394 int orientation, int direction) { 395 int inc = visibleRect.width; 397 if (direction > 0) { 398 int last = locationToIndex(new Point (visibleRect.x + 400 visibleRect.width - 1, visibleRect.y), direction); 401 if (last >= 0 && last < columnList.size()) { 402 Column col = columnList.get(last); 403 Rectangle lastRect = col.getComponent().getBounds(); 404 if (lastRect != null) { 405 inc = lastRect.x - visibleRect.x; 406 if (inc < 0) { 407 inc += lastRect.width; 408 } else if (inc == 0 && last < columnList.size() - 1) { 409 inc = lastRect.width; 410 } 411 } 412 } 413 } else { 414 int first = locationToIndex(new Point (visibleRect.x - 416 visibleRect.width, visibleRect.y), direction); 417 if (first >= 0 && first < columnList.size()) { 418 Column col = columnList.get(first); 419 Rectangle firstRect = col.getComponent().getBounds(); 420 if (firstRect != null) { 421 if (firstRect.x < visibleRect.x - visibleRect.width) { 422 if (firstRect.x + firstRect.width >= visibleRect.x) { 423 inc = visibleRect.x - firstRect.x; 424 } else { 425 inc = visibleRect.x - firstRect.x - firstRect.width; 426 } 427 } else { 428 inc = visibleRect.x - firstRect.x; 429 } 430 } 431 } 432 } 433 return inc; 434 } 435 436 public boolean getScrollableTracksViewportHeight() { 437 return true; 438 } 439 440 public boolean getScrollableTracksViewportWidth() { 441 if (getParent() instanceof JViewport ) { 442 return (getParent().getWidth() > getPreferredSize().width); 443 } 444 return false; 445 } 446 447 public int getScrollableUnitIncrement(Rectangle visibleRect, 448 int orientation, int direction) { 449 int index = locationToIndex(visibleRect.getLocation(), direction); 450 if (index >= 0 && index < columnList.size()) { 451 Column col = columnList.get(index); 452 Rectangle bounds = col.getComponent().getBounds(); 453 if (bounds != null) { 454 if (bounds.x != visibleRect.x) { 455 if (direction < 0) { 456 return Math.abs(bounds.x - visibleRect.x); 457 } 458 return bounds.width + bounds.x - visibleRect.x; 459 } 460 JSplitterBar bar = splitterList.get(0); 463 return bounds.width + bar.getWidth(); 464 } 465 } 466 return 1; 468 } 469 } 470 471 476 private void initComponents() { 478 scrollPane = new javax.swing.JScrollPane (); 479 480 setLayout(new java.awt.BorderLayout ()); 481 482 setBackground(java.awt.Color.white); 483 scrollPane.setBackground(java.awt.Color.white); 484 scrollPane.setBorder(null); 485 scrollPane.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER); 486 add(scrollPane, java.awt.BorderLayout.CENTER); 487 488 } 490 private javax.swing.JScrollPane scrollPane; 492 } 494 | Popular Tags |