Statistics
| Revision:

svn-gvsig-desktop / trunk / org.gvsig.desktop / org.gvsig.desktop.library / org.gvsig.ui / src / main / java / org / gvsig / gui / beans / listview / ListViewComponent.java @ 42097

History | View | Annotate | Download (27.1 KB)

1
/**
2
 * gvSIG. Desktop Geographic Information System.
3
 *
4
 * Copyright (C) 2007-2013 gvSIG Association.
5
 *
6
 * This program is free software; you can redistribute it and/or
7
 * modify it under the terms of the GNU General Public License
8
 * as published by the Free Software Foundation; either version 3
9
 * of the License, or (at your option) any later version.
10
 *
11
 * This program is distributed in the hope that it will be useful,
12
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 * GNU General Public License for more details.
15
 *
16
 * You should have received a copy of the GNU General Public License
17
 * along with this program; if not, write to the Free Software
18
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19
 * MA  02110-1301, USA.
20
 *
21
 * For any additional information, do not hesitate to contact us
22
 * at info AT gvsig.com, or visit our website www.gvsig.com.
23
 */
24
package org.gvsig.gui.beans.listview;
25

    
26
import java.awt.*;
27
import java.awt.color.ColorSpace;
28
import java.awt.event.*;
29
import java.awt.image.BufferedImage;
30
import java.awt.image.ColorConvertOp;
31
import java.util.*;
32

    
33
import javax.swing.*;
34
import javax.swing.event.AncestorEvent;
35
import javax.swing.event.AncestorListener;
36

    
37
import org.gvsig.gui.beans.listview.painters.*;
38
import org.gvsig.i18n.Messages;
39

    
40
/**
41
 * Componente grafico para representar una lista de valores
42
 *
43
 * @version 28/06/2007
44
 * @author BorSanZa - Borja S?nchez Zamorano (borja.sanchez@iver.es)
45
 */
46
public class ListViewComponent extends JComponent implements MouseListener,
47
    MouseMotionListener, ActionListener, KeyListener, FocusListener,
48
    AncestorListener {
49

    
50
  private static final long serialVersionUID = 6177600314634665863L;
51

    
52
  /**
53
   * Lista de los tipos de vista existentes
54
   */
55
  private ArrayList<IListViewPainter> painters = new ArrayList<IListViewPainter>();
56

    
57
  private ArrayList<JRadioButtonMenuItem> paintersMenu = new ArrayList<JRadioButtonMenuItem>();
58

    
59
  /**
60
   * Lista de items
61
   */
62
  private ArrayList<ListViewItem> items = new ArrayList<ListViewItem>();
63

    
64
  /**
65
   * Selecciona el tipo de vista
66
   */
67
  private int view = 0;
68

    
69
  /**
70
   * Booleano para saber si se permite la multiselecci?n
71
   */
72
  private boolean multiSelect = false;
73

    
74
  private Image image = null;
75

    
76
  private int width = 0;
77

    
78
  private int height = 0;
79

    
80
  private Graphics2D widgetGraphics = null;
81

    
82
  private JMenu jMenu = null;
83

    
84
  private ButtonGroup buttonGroup = null;
85

    
86
  private JPopupMenu jPopupMenu = null;
87

    
88
  private JTextField jRenameEdit = null;
89

    
90
  private int itemEdited = -1;
91

    
92
  private int lastSelected = -1;
93

    
94
  private int cursorPos = -1;
95

    
96
  private boolean editable = false;
97

    
98
  private ArrayList<ListViewListener> actionCommandListeners = new ArrayList<ListViewListener>();
99

    
100
  private ListViewItem lastSelectedItem = null;
101

    
102
  /**
103
   * Construye un <code>ListViewComponent</code>
104
   */
105
  public ListViewComponent() {
106
    setFocusable(true);
107

    
108
    initialize();
109
  }
110

    
111
  /**
112
   * Inicializa el <code>ListViewComponent</code>
113
   */
114
  private void initialize() {
115
    addListViewPainter(new PaintList(items));
116
    addListViewPainter(new SmallIcon(items));
117
    addListViewPainter(new LargeIcon(items));
118

    
119
    addAncestorListener(this);
120

    
121
    addKeyListener(this);
122
    addMouseListener(this);
123
    addMouseMotionListener(this);
124
  }
125

    
126
  /**
127
   * Obtiene que vista se esta usando en el componente
128
   *
129
   * @return
130
   */
131
  public int getView() {
132
    return view;
133
  }
134

    
135
  /**
136
   * Define que vista es la que se va a usar
137
   *
138
   * @param view
139
   */
140
  public void setView(int view) {
141
    this.view = view;
142
  }
143

    
144
  /**
145
   * Agrega una vista al componente
146
   *
147
   * @param item
148
   */
149
  public void addListViewPainter(IListViewPainter item) {
150
    painters.add(item);
151

    
152
    JRadioButtonMenuItem jRadioButtonMenuItem = new JRadioButtonMenuItem();
153
    getButtonGroup().add(jRadioButtonMenuItem);
154

    
155
    jRadioButtonMenuItem.setText(item.getName());
156
    if (paintersMenu.size() == 0) jRadioButtonMenuItem.setSelected(true);
157
    getJMenu().add(jRadioButtonMenuItem);
158

    
159
    jRadioButtonMenuItem.addActionListener(this);
160

    
161
    paintersMenu.add(jRadioButtonMenuItem);
162
  }
163

    
164
  /**
165
   * Sorts the specified array of objects into ascending order
166
   */
167
  public void sort() {
168
    Object[] list = items.toArray();
169
    Arrays.sort(list);
170
    items.clear();
171
    for (int i = 0; i < list.length; i++)
172
      items.add((ListViewItem) list[i]);
173
  }
174

    
175
  /**
176
   * Agrega un item al componente
177
   *
178
   * @param item
179
   */
180
  public void addItem(ListViewItem item) {
181
    addItem(item, false);
182
  }
183

    
184
  /**
185
   * Agrega un item al componente, si acceptRepeatNames es false no se aceptaran
186
   * nombres repetidos
187
   *
188
   * @param item
189
   * @param acceptRepeatNames
190
   */
191
  public void addItem(ListViewItem item, boolean acceptRepeatNames) {
192
    items.add(item);
193
    if (!acceptRepeatNames) changeName(item.getName(), items.size() - 1);
194

    
195
    viewItem(items.size() - 1);
196
  }
197

    
198
  /**
199
   * Agrega el item en la posicion especificada de la lista.
200
   *
201
   * @param pos
202
   * @param item
203
   */
204
  public void addItem(int pos, ListViewItem item) {
205
    items.add(pos, item);
206
    changeName(item.getName(), pos);
207

    
208
    viewItem(pos);
209
  }
210

    
211
  /**
212
   * Agrega un item al componente
213
   *
214
   * @param item
215
   */
216
  public void removeItem(int index) {
217
    items.remove(index);
218
    repaint();
219
  }
220

    
221
  /**
222
   * Borra todos los items seleccionados
223
   */
224
  public void removeSelecteds() {
225
    for (int i = (items.size() - 1); i >= 0; i--)
226
      if (((ListViewItem) items.get(i)).isSelected()) items.remove(i);
227

    
228
    repaint();
229
  }
230

    
231
  /**
232
   * Devuelve un ArrayList con todos los items
233
   *
234
   * @return
235
   */
236
  @SuppressWarnings("unchecked")
237
  public ArrayList getItems() {
238
    return items;
239
  }
240

    
241
  private Graphics2D getWidgetGraphics() {
242
    getWidgetImage();
243
    return widgetGraphics;
244
  }
245

    
246
  private Image getWidgetImage() {
247
    int width2 = getVisibleRect().width;
248
    int height2 = getVisibleRect().height;
249
    if (width2 <= 0) width2 = 1;
250
    if (height2 <= 0) height2 = 1;
251

    
252
    if ((width != width2) || (height != height2)) {
253
      image = createImage(width2, height2);
254
      if (image == null) return null;
255
      widgetGraphics = (Graphics2D) image.getGraphics();
256
    }
257

    
258
    width = width2;
259
    height = height2;
260
    return image;
261
  }
262

    
263
  /**
264
   * Redibujar el componente en el graphics temporal
265
   */
266
  private void redrawBuffer() {
267
    if (getWidgetGraphics() == null) return;
268

    
269
    /** desactivaci?n del anti-aliasing */
270
    getWidgetGraphics().setRenderingHint(RenderingHints.KEY_ANTIALIASING,
271
        RenderingHints.VALUE_ANTIALIAS_OFF);
272
    getWidgetGraphics().setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
273
        RenderingHints.VALUE_TEXT_ANTIALIAS_OFF);
274

    
275
    /** demanda de rendimiento r?pido */
276
    getWidgetGraphics().setRenderingHint(RenderingHints.KEY_RENDERING,
277
        RenderingHints.VALUE_RENDER_SPEED);
278
    getWidgetGraphics().setRenderingHint(RenderingHints.KEY_COLOR_RENDERING,
279
        RenderingHints.VALUE_COLOR_RENDER_SPEED);
280
    getWidgetGraphics().setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
281
        RenderingHints.VALUE_FRACTIONALMETRICS_OFF);
282
    getWidgetGraphics().setRenderingHint(RenderingHints.KEY_DITHERING,
283
        RenderingHints.VALUE_DITHER_DISABLE);
284

    
285
    getWidgetGraphics().translate(-getVisibleRect().x, -getVisibleRect().y);
286
    getWidgetGraphics().setColor(Color.white);
287
    getWidgetGraphics().fillRect(getVisibleRect().x, getVisibleRect().y,
288
        getVisibleRect().width, getVisibleRect().height);
289

    
290
    ((IListViewPainter) painters.get(view)).paint(
291
        (Graphics2D) getWidgetGraphics(), getVisibleRect());
292
    getWidgetGraphics().translate(getVisibleRect().x, getVisibleRect().y);
293
  }
294

    
295
  public void paint(Graphics g) {
296
    redrawBuffer();
297

    
298
    if (image != null) {
299
      if (isEnabled()) {
300
        g.drawImage(image, getVisibleRect().x, getVisibleRect().y, this);
301
      }
302
      else {
303
        // Dibujar en escala de grises y aclarado para cuando esta inactivo
304
        BufferedImage bi = new BufferedImage(width, height,
305
            BufferedImage.TYPE_INT_RGB);
306

    
307
        Graphics big = bi.createGraphics();
308
        big.drawImage(image, 0, 0, this);
309

    
310
        ColorConvertOp colorConvert = new ColorConvertOp(
311
            ColorSpace.getInstance(ColorSpace.CS_GRAY), null);
312
        colorConvert.filter(bi, bi);
313

    
314
        big.setColor(new Color(255, 255, 255, 164));
315
        big.fillRect(0, 0, width, height);
316

    
317
        g.drawImage(bi, getVisibleRect().x, getVisibleRect().y, this);
318
      }
319
    }
320

    
321
    Dimension size = getPreferredSize();
322
    Dimension aux = ((IListViewPainter) painters.get(view)).getPreferredSize();
323
    if (!size.equals(aux)) {
324
      setPreferredSize(aux);
325
      setSize(aux);
326
    }
327

    
328
    if (getParent() instanceof JViewport) {
329
      JViewport jViewport = (JViewport) getParent();
330
      if (jViewport.getParent() instanceof JScrollPane) {
331
        if (items.size() > 0)
332
          ((JScrollPane) jViewport.getParent()).getVerticalScrollBar()
333
              .setUnitIncrement(
334
                  ((ListViewItem) items.get(0)).getItemRectangle().height);
335
      }
336
    }
337
  }
338

    
339
  public boolean isMultiSelect() {
340
    return multiSelect;
341
  }
342

    
343
  public void setMultiSelect(boolean multiSelect) {
344
    if (multiSelect == false) {
345
      for (int i = 0; i < items.size(); i++)
346
        ((ListViewItem) items.get(i)).setSelected(false);
347
      if ((lastSelected != -1) && (lastSelected < items.size()))
348
        ((ListViewItem) items.get(lastSelected)).setSelected(true);
349
    }
350

    
351
    this.multiSelect = multiSelect;
352
    repaint();
353
  }
354

    
355
  private int getItem(int x, int y) {
356
    Point point = new Point(x, y);
357
    Rectangle rectangle = null;
358
    for (int i = 0; i < items.size(); i++) {
359
      rectangle = ((ListViewItem) items.get(i)).getItemRectangle();
360
      if ((rectangle != null) && (rectangle.getBounds().contains(point)))
361
        return i;
362
    }
363

    
364
    return -1;
365
  }
366

    
367
  /*
368
   * (non-Javadoc)
369
   * @see java.awt.event.MouseListener#mousePressed(java.awt.event.MouseEvent)
370
   */
371
  public void mousePressed(MouseEvent e) {
372
    if (!isEnabled()) return;
373
    requestFocus();
374

    
375
    try {
376
      if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != InputEvent.BUTTON1_MASK)
377
        return;
378

    
379
      cursorPos = getItem(e.getX(), e.getY());
380
      viewItem(cursorPos);
381
      if (cursorPos == -1) return;
382

    
383
      if (isMultiSelect()) {
384
        if ((e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK) {
385
          int pos1 = cursorPos;
386
          int pos2 = lastSelected;
387
          if (pos2 < pos1) {
388
            pos1 = lastSelected;
389
            pos2 = cursorPos;
390
          }
391

    
392
          if ((e.getModifiers() & InputEvent.CTRL_MASK) != InputEvent.CTRL_MASK)
393
            for (int i = 0; i < items.size(); i++)
394
              ((ListViewItem) items.get(i)).setSelected(false);
395

    
396
          for (int i = pos1; i <= pos2; i++)
397
            ((ListViewItem) items.get(i)).setSelected(true);
398
          return;
399
        }
400

    
401
        lastSelected = cursorPos;
402

    
403
        if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK) {
404
          ((ListViewItem) items.get(cursorPos))
405
              .setSelected(!((ListViewItem) items.get(cursorPos)).isSelected());
406
          return;
407
        }
408

    
409
        for (int i = 0; i < items.size(); i++)
410
          ((ListViewItem) items.get(i)).setSelected(false);
411

    
412
        ((ListViewItem) items.get(cursorPos)).setSelected(true);
413
      }
414
      else {
415
        boolean selected = true;
416

    
417
        lastSelected = cursorPos;
418

    
419
        if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK)
420
          selected = !((ListViewItem) items.get(cursorPos)).isSelected();
421

    
422
        for (int i = 0; i < items.size(); i++)
423
          ((ListViewItem) items.get(i)).setSelected(false);
424

    
425
        ((ListViewItem) items.get(cursorPos)).setSelected(selected);
426
      }
427
    }
428
    finally {
429
      repaint();
430
    }
431
  }
432

    
433
  /**
434
   * Establece que un item debe estar visible en la vista
435
   *
436
   * @param pos
437
   */
438
  private void viewItem(int pos) {
439
    if ((pos == -1) || (items.size() == 0)) return;
440
    redrawBuffer();
441
    Dimension aux = ((IListViewPainter) painters.get(view)).getPreferredSize();
442
    setPreferredSize(aux);
443
    setSize(aux);
444

    
445
    if (pos < 0) pos = 0;
446

    
447
    if (pos >= items.size()) pos = items.size() - 1;
448

    
449
    if (getParent() instanceof JViewport) {
450
      JViewport jViewport = (JViewport) getParent();
451

    
452
      if (jViewport.getParent() instanceof JScrollPane) {
453
        ListViewItem lvi = ((ListViewItem) items.get(pos));
454
        Rectangle rectangle = (Rectangle) lvi.getItemRectangle().clone();
455
        if (rectangle == null) return;
456
        rectangle.setLocation((int) rectangle.getX() - getVisibleRect().x,
457
            (int) rectangle.getY() - getVisibleRect().y);
458
        jViewport.scrollRectToVisible(rectangle);
459
        ((JScrollPane) jViewport.getParent()).getVerticalScrollBar()
460
            .paintImmediately(
461
                ((JScrollPane) jViewport.getParent()).getVerticalScrollBar()
462
                    .getVisibleRect());
463
      }
464
    }
465
  }
466

    
467
  public void mouseDragged(MouseEvent e) {
468
    if (!isEnabled()) return;
469
    if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != InputEvent.BUTTON1_MASK)
470
      return;
471

    
472
    if (isMultiSelect()) {
473
      if ((e.getModifiers() & InputEvent.SHIFT_MASK) == InputEvent.SHIFT_MASK)
474
        return;
475
      if ((e.getModifiers() & InputEvent.CTRL_MASK) == InputEvent.CTRL_MASK)
476
        return;
477
    }
478

    
479
    int itemSelected = getItem(e.getX(), e.getY());
480

    
481
    if (itemSelected == -1) return;
482

    
483
    lastSelected = itemSelected;
484
    cursorPos = itemSelected;
485

    
486
    for (int i = 0; i < items.size(); i++)
487
      ((ListViewItem) items.get(i)).setSelected(false);
488

    
489
    ((ListViewItem) items.get(itemSelected)).setSelected(true);
490

    
491
    repaint();
492

    
493
    viewItem(itemSelected);
494
  }
495

    
496
  private JPopupMenu getPopupMenu() {
497
    if (jPopupMenu == null) {
498
      jPopupMenu = new JPopupMenu();
499
      getJMenu().setText(Messages.getText("view"));
500

    
501
      jPopupMenu.add(getJMenu());
502
    }
503
    return jPopupMenu;
504
  }
505

    
506
  public void mouseReleased(MouseEvent e) {
507
    if (!isEnabled()) return;
508
    if ((e.getModifiers() & InputEvent.BUTTON3_MASK) == InputEvent.BUTTON3_MASK)
509
      getPopupMenu().show(this, e.getX(), e.getY());
510

    
511
    if ((e.getModifiers() & InputEvent.BUTTON1_MASK) == InputEvent.BUTTON1_MASK) {
512
      fireSelectionValueChanged();
513
    }
514
  }
515

    
516
  public void mouseMoved(MouseEvent e) {
517
    if (!isEnabled()) return;
518
    int itemSelected = getItem(e.getX(), e.getY());
519

    
520
    if (itemSelected == -1) {
521
      setToolTipText(null);
522
      return;
523
    }
524
    if (((ListViewItem) items.get(itemSelected)).isShowTooltip())
525
      setToolTipText(((ListViewItem) items.get(itemSelected)).getName());
526
    else
527
      setToolTipText(null);
528
  }
529

    
530
  private ButtonGroup getButtonGroup() {
531
    if (buttonGroup == null) buttonGroup = new ButtonGroup();
532
    return buttonGroup;
533
  }
534

    
535
  private JMenu getJMenu() {
536
    if (jMenu == null) jMenu = new JMenu();
537
    return jMenu;
538
  }
539

    
540
  /*
541
   * (non-Javadoc)
542
   * @see
543
   * java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent)
544
   */
545
  public void actionPerformed(ActionEvent e) {
546
    int pos = paintersMenu.indexOf(e.getSource());
547
    view = pos;
548
    viewItem(cursorPos);
549
  }
550

    
551
  /**
552
   * Returns an array of the values for the selected cells. The returned values
553
   * are sorted in increasing index order.
554
   *
555
   * @return the selected values or an empty list if nothing is selected
556
   */
557
  public ListViewItem[] getSelectedValues() {
558
    int cont = 0;
559
    for (int i = 0; i < items.size(); i++) {
560
      if (((ListViewItem) items.get(i)).isSelected()) cont++;
561
    }
562
    ListViewItem[] values = new ListViewItem[cont];
563
    cont = 0;
564
    for (int i = 0; i < items.size(); i++) {
565
      if (((ListViewItem) items.get(i)).isSelected()) {
566
        values[cont] = (ListViewItem) items.get(i);
567
        cont++;
568
      }
569
    }
570

    
571
    return values;
572
  }
573

    
574
  /**
575
   * Returns the first selected index; returns -1 if there is no selected item.
576
   *
577
   * @return the value of <code>getMinSelectionIndex</code>
578
   */
579
  public int getSelectedIndex() {
580
    for (int i = 0; i < items.size(); i++) {
581
      if (((ListViewItem) items.get(i)).isSelected()) return i;
582
    }
583
    return -1;
584
  }
585

    
586
  /**
587
   * Select the index value
588
   *
589
   * @return the value of <code>getMinSelectionIndex</code>
590
   */
591
  public void setSelectedIndex(int value) {
592
    if (value < 0) value = 0;
593
    if (value >= items.size()) value = items.size() - 1;
594
    for (int i = 0; i < items.size(); i++) {
595
      ((ListViewItem) items.get(i)).setSelected(i == value);
596
    }
597
    lastSelectedItem = getSelectedValue();
598
    viewItem(value);
599
    update(getGraphics());
600
  }
601

    
602
  /**
603
   * Returns the first selected value, or <code>null</code> if the selection is
604
   * empty.
605
   *
606
   * @return the first selected value
607
   */
608
  public ListViewItem getSelectedValue() {
609
    for (int i = 0; i < items.size(); i++) {
610
      if (((ListViewItem) items.get(i)).isSelected())
611
        return (ListViewItem) items.get(i);
612
    }
613
    return null;
614
  }
615

    
616
  /**
617
   * Returns an array of all of the selected indices in increasing order.
618
   *
619
   * @return all of the selected indices, in increasing order
620
   */
621
  public int[] getSelectedIndices() {
622
    int cont = 0;
623
    for (int i = 0; i < items.size(); i++) {
624
      if (((ListViewItem) items.get(i)).isSelected()) cont++;
625
    }
626
    int[] values = new int[cont];
627
    cont = 0;
628
    for (int i = 0; i < items.size(); i++) {
629
      if (((ListViewItem) items.get(i)).isSelected()) {
630
        values[cont] = i;
631
        cont++;
632
      }
633
    }
634

    
635
    return values;
636
  }
637

    
638
  /**
639
   * A?adir un listener a la lista de eventos
640
   *
641
   * @param listener
642
   */
643
  public void addListSelectionListener(ListViewListener listener) {
644
    if (!actionCommandListeners.contains(listener))
645
      actionCommandListeners.add(listener);
646
  }
647

    
648
  /**
649
   * Borrar un listener de la lista de eventos
650
   *
651
   * @param listener
652
   */
653
  public void removeListSelectionListener(ListViewListener listener) {
654
    actionCommandListeners.remove(listener);
655
  }
656

    
657
  /**
658
   * Invocar a los eventos asociados al componente
659
   */
660
  private void fireSelectionValueChanged() {
661
    lastSelectedItem = getSelectedValue();
662
    Iterator<ListViewListener> acIterator = actionCommandListeners.iterator();
663
    EventObject e = null;
664
    while (acIterator.hasNext()) {
665
      ListViewListener listener = acIterator.next();
666
      if (e == null) e = new EventObject(this);
667
      listener.actionValueChanged(e);
668
    }
669
  }
670

    
671
  /**
672
   * Invocar a los eventos asociados al componente
673
   */
674
  private void fireItemNameChanged(String oldName, ListViewItem item) {
675
    Iterator<ListViewListener> acIterator = actionCommandListeners.iterator();
676
    EventObject e = null;
677
    while (acIterator.hasNext()) {
678
      ListViewListener listener = acIterator.next();
679
      if (e == null) e = new EventObject(this);
680
      listener.actionItemNameChanged(e, oldName, item);
681
    }
682
  }
683

    
684
  public void renameItem(int item) {
685
    if (!isEditable()) return;
686

    
687
    if ((item >= 0) && (item < items.size())) {
688
      if (((ListViewItem) items.get(item)).isSelected()) {
689
        Rectangle rectangle = ((ListViewItem) items.get(item))
690
            .getNameRectangle();
691

    
692
        if (rectangle != null) {
693
          itemEdited = item;
694
          ((ListViewItem) items.get(itemEdited)).setSelected(false);
695
          repaint();
696
          this.setLayout(null);
697
          getJRenameEdit().setText(((ListViewItem) items.get(item)).getName());
698
          this.add(getJRenameEdit());
699
          getJRenameEdit().setBounds(rectangle);
700
          getJRenameEdit().addFocusListener(this);
701
          getJRenameEdit().addKeyListener(this);
702
          getJRenameEdit().requestFocus();
703
          getJRenameEdit().setSelectionStart(0);
704
          getJRenameEdit().setSelectionEnd(getJRenameEdit().getText().length());
705
        }
706
      }
707
    }
708
  }
709

    
710
  public JTextField getJRenameEdit() {
711
    if (jRenameEdit == null) {
712
      jRenameEdit = new JTextField();
713
    }
714
    return jRenameEdit;
715
  }
716

    
717
  public void changeName(String newName, int pos) {
718
    newName = newName.trim();
719
    if (newName.length() == 0) return;
720
    String newNameAux = newName;
721
    boolean isItem;
722
    int newNumber = 0;
723
    do {
724
      isItem = false;
725
      for (int i = 0; i < items.size(); i++) {
726
        if ((i != pos)
727
            && (((ListViewItem) items.get(i)).getName().equals(newNameAux))) {
728
          isItem = true;
729
          newNumber++;
730
          newNameAux = newName + "_" + newNumber;
731
          break;
732
        }
733
      }
734
    }
735
    while (isItem);
736
    ((ListViewItem) items.get(pos)).setName(newNameAux);
737
  }
738

    
739
  public void closeRenameEdit() {
740
    if (jRenameEdit == null) return;
741

    
742
    if (itemEdited != -1) {
743
      String oldName = ((ListViewItem) items.get(itemEdited)).getName();
744

    
745
      changeName(getJRenameEdit().getText(), itemEdited);
746

    
747
      fireItemNameChanged(oldName, (ListViewItem) items.get(itemEdited));
748

    
749
      ((ListViewItem) items.get(cursorPos)).setSelected(true);
750
      itemEdited = -1;
751
      repaint();
752
    }
753
    this.remove(getJRenameEdit());
754
    jRenameEdit = null;
755
    this.requestFocus();
756
  }
757

    
758
  /**
759
   * Mueve el cursor hacia abajo
760
   */
761
  private void moveDown() {
762
    int selItem = -1;
763

    
764
    for (int i = 0; i < items.size(); i++) {
765
      if (cursorPos == i) continue;
766
      if (((ListViewItem) items.get(i)).getItemRectangle().y >= (((ListViewItem) items
767
          .get(cursorPos)).getItemRectangle().y + ((ListViewItem) items
768
          .get(cursorPos)).getItemRectangle().height)) {
769
        if (((ListViewItem) items.get(i)).getItemRectangle().x == ((ListViewItem) items
770
            .get(cursorPos)).getItemRectangle().x) {
771
          selItem = i;
772
          break;
773
        }
774
      }
775
    }
776

    
777
    if (selItem != -1) {
778
      cursorPos = selItem;
779
      setSelectedIndex(selItem);
780
    }
781
  }
782

    
783
  /**
784
   * Mueve el cursor hacia la izquierda
785
   */
786
  private void moveLeft() {
787
    int selItem = -1;
788
    for (int i = items.size() - 1; i >= 0; i--) {
789
      if (cursorPos == i) continue;
790
      if ((((ListViewItem) items.get(i)).getItemRectangle().x + ((ListViewItem) items
791
          .get(i)).getItemRectangle().width) <= ((ListViewItem) items
792
          .get(cursorPos)).getItemRectangle().x) {
793
        if (((ListViewItem) items.get(i)).getItemRectangle().y == ((ListViewItem) items
794
            .get(cursorPos)).getItemRectangle().y) {
795
          selItem = i;
796
          break;
797
        }
798
      }
799
    }
800

    
801
    if (selItem != -1) {
802
      cursorPos = selItem;
803
      setSelectedIndex(selItem);
804
    }
805
  }
806

    
807
  /**
808
   * Mueve el cursor hacia la derecha
809
   */
810
  private void moveRight() {
811
    int selItem = -1;
812
    for (int i = 0; i < items.size(); i++) {
813
      if (cursorPos == i) continue;
814
      if (((ListViewItem) items.get(i)).getItemRectangle().x >= (((ListViewItem) items
815
          .get(cursorPos)).getItemRectangle().x + ((ListViewItem) items
816
          .get(cursorPos)).getItemRectangle().width)) {
817
        if (((ListViewItem) items.get(i)).getItemRectangle().y == ((ListViewItem) items
818
            .get(cursorPos)).getItemRectangle().y) {
819
          selItem = i;
820
          break;
821
        }
822
      }
823
    }
824

    
825
    if (selItem != -1) {
826
      cursorPos = selItem;
827
      setSelectedIndex(selItem);
828
    }
829
  }
830

    
831
  /**
832
   * Mueve el cursor hacia arriba
833
   */
834
  private void moveUp() {
835
    int selItem = -1;
836
    for (int i = items.size() - 1; i >= 0; i--) {
837
      if (cursorPos == i) continue;
838
      if ((((ListViewItem) items.get(i)).getItemRectangle().y + ((ListViewItem) items
839
          .get(i)).getItemRectangle().height) <= ((ListViewItem) items
840
          .get(cursorPos)).getItemRectangle().y) {
841
        if (((ListViewItem) items.get(i)).getItemRectangle().x == ((ListViewItem) items
842
            .get(cursorPos)).getItemRectangle().x) {
843
          selItem = i;
844
          break;
845
        }
846
      }
847
    }
848

    
849
    if (selItem != -1) {
850
      cursorPos = selItem;
851
      setSelectedIndex(selItem);
852
    }
853
  }
854

    
855
  public void keyPressed(KeyEvent e) {
856
    if (e.getSource() == this) {
857
      switch (e.getKeyCode()) {
858
        case KeyEvent.VK_F2:
859
          renameItem(cursorPos);
860
          break;
861
        case KeyEvent.VK_DOWN:
862
          moveDown();
863
          break;
864
        case KeyEvent.VK_LEFT:
865
          moveLeft();
866
          break;
867
        case KeyEvent.VK_RIGHT:
868
          moveRight();
869
          break;
870
        case KeyEvent.VK_UP:
871
          moveUp();
872
          break;
873
        case KeyEvent.VK_HOME:
874
          cursorPos = 0;
875
          setSelectedIndex(cursorPos);
876
          break;
877
        case KeyEvent.VK_END:
878
          cursorPos = items.size() - 1;
879
          setSelectedIndex(cursorPos);
880
          break;
881
        case KeyEvent.VK_PAGE_UP:
882
          if (items.size() > 0) {
883
            int cont = (int) Math.floor(this.getVisibleRect().getHeight()
884
                / ((ListViewItem) items.get(0)).getItemRectangle().height);
885
            for (int i = 0; i < cont; i++)
886
              moveUp();
887
          }
888
          break;
889
        case KeyEvent.VK_PAGE_DOWN:
890
          if (items.size() > 0) {
891
            int cont = (int) Math.floor(this.getVisibleRect().getHeight()
892
                / ((ListViewItem) items.get(0)).getItemRectangle().height);
893
            for (int i = 0; i < cont; i++)
894
              moveDown();
895
          }
896
          break;
897
      }
898
      return;
899
    }
900
    if (e.getSource() == getJRenameEdit()) {
901
      switch (e.getKeyCode()) {
902
        case KeyEvent.VK_ESCAPE:
903
          getJRenameEdit().setText(
904
              ((ListViewItem) items.get(itemEdited)).getName());
905
          closeRenameEdit();
906
          break;
907
        case KeyEvent.VK_ENTER:
908
          closeRenameEdit();
909
          break;
910
      }
911
    }
912
  }
913

    
914
  public void keyReleased(KeyEvent e) {
915
    if (e.getSource() == this) {
916
      switch (e.getKeyCode()) {
917
        case KeyEvent.VK_DOWN:
918
        case KeyEvent.VK_UP:
919
        case KeyEvent.VK_LEFT:
920
        case KeyEvent.VK_RIGHT:
921
        case KeyEvent.VK_HOME:
922
        case KeyEvent.VK_END:
923
        case KeyEvent.VK_PAGE_UP:
924
        case KeyEvent.VK_PAGE_DOWN:
925
          fireSelectionValueChanged();
926
          break;
927
      }
928
    }
929
  }
930

    
931
  public void focusLost(FocusEvent e) {
932
    closeRenameEdit();
933
  }
934

    
935
  public void mouseClicked(MouseEvent e) {
936
    if (!isEnabled()) return;
937
    if (e.getSource() == this)
938
    // Si es doble click y hay alg?n elemento seleccionado en la lista lo
939
    // eliminamos
940
      if (e.getClickCount() == 2) {
941
        renameItem(cursorPos);
942
      }
943
  }
944

    
945
  /**
946
   * Devuelve si se puede cambiar el nombre de los items
947
   *
948
   * @return
949
   */
950
  public boolean isEditable() {
951
    return editable;
952
  }
953

    
954
  /**
955
   * Define si se puede cambiar el nombre de los items
956
   *
957
   * @param editable
958
   */
959
  public void setEditable(boolean editable) {
960
    this.editable = editable;
961
  }
962

    
963
  /**
964
   * Quito los eventos del JScrollPane para gestionarlos yo
965
   */
966
  public void ancestorAdded(AncestorEvent event) {
967
    if (getParent() instanceof JViewport) {
968
      JViewport jViewport = (JViewport) getParent();
969
      if (jViewport.getParent() instanceof JScrollPane) {
970
        ((JScrollPane) jViewport.getParent()).setActionMap(null);
971
      }
972
    }
973
  }
974

    
975
  /**
976
   * Devuelve el ?ltimo item seleccionado. Solo el que provoco el evento.
977
   *
978
   * @return
979
   */
980
  public ListViewItem getLastSelectedItem() {
981
    return lastSelectedItem;
982
  }
983

    
984
  /*
985
   * (non-Javadoc)
986
   * @see javax.swing.JComponent#setEnabled(boolean)
987
   */
988
  public void setEnabled(boolean enabled) {
989
    super.setEnabled(enabled);
990
    update(getGraphics());
991
  }
992

    
993
  // [start] Codigo no usado
994
  public void mouseEntered(MouseEvent e) {}
995

    
996
  public void mouseExited(MouseEvent e) {}
997

    
998
  public void keyTyped(KeyEvent e) {}
999

    
1000
  public void focusGained(FocusEvent e) {}
1001

    
1002
  public void ancestorMoved(AncestorEvent event) {}
1003

    
1004
  public void ancestorRemoved(AncestorEvent event) {}
1005
  // [end]
1006
}