OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [javax/] [swing/] [plaf/] [basic/] [BasicTableHeaderUI.java] - Blame information for rev 772

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 772 jeremybenn
/* BasicTableHeaderUI.java --
2
   Copyright (C) 2004 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
 
39
package javax.swing.plaf.basic;
40
 
41
import java.awt.Component;
42
import java.awt.Cursor;
43
import java.awt.Dimension;
44
import java.awt.Graphics;
45
import java.awt.Rectangle;
46
import java.awt.event.ActionEvent;
47
import java.awt.event.ActionListener;
48
import java.awt.event.MouseEvent;
49
 
50
import javax.swing.CellRendererPane;
51
import javax.swing.JComponent;
52
import javax.swing.LookAndFeel;
53
import javax.swing.Timer;
54
import javax.swing.UIManager;
55
import javax.swing.border.Border;
56
import javax.swing.event.MouseInputListener;
57
import javax.swing.plaf.ComponentUI;
58
import javax.swing.plaf.TableHeaderUI;
59
import javax.swing.table.JTableHeader;
60
import javax.swing.table.TableCellRenderer;
61
import javax.swing.table.TableColumn;
62
import javax.swing.table.TableColumnModel;
63
 
64
/**
65
 * Basic pluggable look and feel interface for JTableHeader.
66
 */
67
public class BasicTableHeaderUI extends TableHeaderUI
68
{
69
  /**
70
   * The width of the space (in both direction) around the column boundary,
71
   * where mouse cursor changes shape into "resize"
72
   */
73
  static int COLUMN_BOUNDARY_TOLERANCE = 3;
74
 
75
  public static ComponentUI createUI(JComponent h)
76
  {
77
    return new BasicTableHeaderUI();
78
  }
79
 
80
  /**
81
   * The table header that is using this interface.
82
   */
83
  protected JTableHeader header;
84
 
85
  /**
86
   * The mouse input listener, responsible for mouse manipulations with
87
   * the table header.
88
   */
89
  protected MouseInputListener mouseInputListener;
90
 
91
  /**
92
   * Paint the header cell.
93
   */
94
  protected CellRendererPane rendererPane;
95
 
96
  /**
97
   * The header cell border.
98
   */
99
  private Border cellBorder;
100
 
101
  /**
102
   * Original mouse cursor prior to resizing.
103
   */
104
  private Cursor originalCursor;
105
 
106
  /**
107
   * If not null, one of the columns is currently being dragged.
108
   */
109
  Rectangle draggingHeaderRect;
110
 
111
  /**
112
   * Handles column movement and rearrangement by mouse. The same instance works
113
   * both as mouse listener and the mouse motion listner.
114
   */
115
  public class MouseInputHandler
116
      implements MouseInputListener
117
  {
118
    /**
119
     * If true, the cursor is being already shown in the alternative "resize"
120
     * shape.
121
     */
122
    boolean showingResizeCursor;
123
 
124
    /**
125
     * The position, from where the cursor is dragged during resizing. Double
126
     * purpose field (absolute value during resizing and relative offset during
127
     * column dragging).
128
     */
129
    int draggingFrom = - 1;
130
 
131
    /**
132
     * The number of the column being dragged.
133
     */
134
    int draggingColumnNumber;
135
 
136
    /**
137
     * The previous preferred width of the column.
138
     */
139
    int prevPrefWidth = - 1;
140
 
141
    /**
142
     * The timer to coalesce column resizing events.
143
     */
144
    Timer timer;
145
 
146
    /**
147
     * Returns without action, part of the MouseInputListener interface.
148
     */
149
    public void mouseClicked(MouseEvent e)
150
    {
151
      // Nothing to do.
152
    }
153
 
154
    /**
155
     * If being in the resizing mode, handle resizing.
156
     */
157
    public void mouseDragged(MouseEvent e)
158
    {
159
      TableColumn resizeIt = header.getResizingColumn();
160
      if (resizeIt != null && header.getResizingAllowed())
161
        {
162
          // The timer is intialised on demand.
163
          if (timer == null)
164
            {
165
              // The purpose of timer is to coalesce events. If the queue
166
              // is free, the repaint event is fired immediately.
167
              timer = new Timer(1, new ActionListener()
168
              {
169
                public void actionPerformed(ActionEvent e)
170
                {
171
                  header.getTable().doLayout();
172
                }
173
              });
174
              timer.setRepeats(false);
175
              timer.setCoalesce(true);
176
            }
177
          resizeIt.setPreferredWidth(prevPrefWidth + e.getX() - draggingFrom);
178
          timer.restart();
179
        }
180
      else if (draggingHeaderRect != null && header.getReorderingAllowed())
181
        {
182
          draggingHeaderRect.x = e.getX() + draggingFrom;
183
          header.repaint();
184
        }
185
    }
186
 
187
    /**
188
     * Returns without action, part of the MouseInputListener interface.
189
     */
190
    public void mouseEntered(MouseEvent e)
191
    {
192
      // Nothing to do.
193
    }
194
 
195
    /**
196
     * Reset drag information of the column resizing.
197
     */
198
    public void mouseExited(MouseEvent e)
199
    {
200
      // Nothing to do.
201
    }
202
 
203
    /**
204
     * Change the mouse cursor if the mouse if above the column boundary.
205
     */
206
    public void mouseMoved(MouseEvent e)
207
    {
208
      // When dragging, the functionality is handled by the mouseDragged.
209
      if (e.getButton() == 0 && header.getResizingAllowed())
210
        {
211
          TableColumnModel model = header.getColumnModel();
212
          int n = model.getColumnCount();
213
          if (n < 2)
214
            // It must be at least two columns to have at least one boundary.
215
            // Otherwise, nothing to do.
216
            return;
217
 
218
          boolean onBoundary = false;
219
 
220
          int x = e.getX();
221
          int a = x - COLUMN_BOUNDARY_TOLERANCE;
222
          int b = x + COLUMN_BOUNDARY_TOLERANCE;
223
 
224
          int p = 0;
225
 
226
          Scan: for (int i = 0; i < n - 1; i++)
227
            {
228
              p += model.getColumn(i).getWidth();
229
 
230
              if (p >= a && p <= b)
231
                {
232
                  TableColumn column = model.getColumn(i);
233
                  onBoundary = true;
234
 
235
                  draggingFrom = x;
236
                  prevPrefWidth = column.getWidth();
237
                  header.setResizingColumn(column);
238
                  break Scan;
239
                }
240
            }
241
 
242
          if (onBoundary != showingResizeCursor)
243
            {
244
              // Change the cursor shape, if needed.
245
              if (onBoundary)
246
                {
247
 
248
                  originalCursor = header.getCursor();
249
                  if (p < x)
250
                    header.setCursor(Cursor.getPredefinedCursor(
251
                        Cursor.W_RESIZE_CURSOR));
252
                  else
253
                    header.setCursor(Cursor.getPredefinedCursor(
254
                        Cursor.E_RESIZE_CURSOR));
255
                }
256
              else
257
                {
258
                  header.setCursor(originalCursor);
259
                  header.setResizingColumn(null);
260
                }
261
 
262
              showingResizeCursor = onBoundary;
263
            }
264
        }
265
    }
266
 
267
    /**
268
     * Starts the dragging/resizing procedure.
269
     */
270
    public void mousePressed(MouseEvent e)
271
    {
272
      if (header.getResizingAllowed())
273
        {
274
          TableColumn resizingColumn = header.getResizingColumn();
275
          if (resizingColumn != null)
276
            {
277
              resizingColumn.setPreferredWidth(resizingColumn.getWidth());
278
              return;
279
            }
280
        }
281
 
282
      if (header.getReorderingAllowed())
283
        {
284
          TableColumnModel model = header.getColumnModel();
285
          int n = model.getColumnCount();
286
          if (n < 2)
287
            // It must be at least two columns to change the column location.
288
            return;
289
 
290
          boolean onBoundary = false;
291
 
292
          int x = e.getX();
293
          int p = 0;
294
          int col = - 1;
295
 
296
          Scan: for (int i = 0; i < n; i++)
297
            {
298
              p += model.getColumn(i).getWidth();
299
              if (p > x)
300
                {
301
                  col = i;
302
                  break Scan;
303
                }
304
            }
305
          if (col < 0)
306
            return;
307
 
308
          TableColumn dragIt = model.getColumn(col);
309
          header.setDraggedColumn(dragIt);
310
 
311
          draggingFrom = (p - dragIt.getWidth()) - x;
312
          draggingHeaderRect = new Rectangle(header.getHeaderRect(col));
313
          draggingColumnNumber = col;
314
        }
315
    }
316
 
317
    /**
318
     * Set all column preferred width to the current width to prevend abrupt
319
     * width changes during the next resize.
320
     */
321
    public void mouseReleased(MouseEvent e)
322
    {
323
      if (header.getResizingColumn() != null && header.getResizingAllowed())
324
        endResizing();
325
      if (header.getDraggedColumn() != null &&  header.getReorderingAllowed())
326
        endDragging(e);
327
    }
328
 
329
    /**
330
     * Stop resizing session.
331
     */
332
    void endResizing()
333
    {
334
      TableColumnModel model = header.getColumnModel();
335
      int n = model.getColumnCount();
336
      if (n > 2)
337
        {
338
          TableColumn c;
339
          for (int i = 0; i < n; i++)
340
            {
341
              c = model.getColumn(i);
342
              c.setPreferredWidth(c.getWidth());
343
            }
344
        }
345
      header.setResizingColumn(null);
346
      showingResizeCursor = false;
347
      if (timer != null)
348
        timer.stop();
349
      header.setCursor(originalCursor);
350
    }
351
 
352
    /**
353
     * Stop the dragging session.
354
     *
355
     * @param e the "mouse release" mouse event, needed to determing the final
356
     *          location for the dragged column.
357
     */
358
    void endDragging(MouseEvent e)
359
    {
360
      header.setDraggedColumn(null);
361
      draggingHeaderRect = null;
362
 
363
      TableColumnModel model = header.getColumnModel();
364
 
365
      // Find where have we dragged the column.
366
      int x = e.getX();
367
      int p = 0;
368
 
369
      int col = model.getColumnCount() - 1;
370
      int n = model.getColumnCount();
371
 
372
      // This loop does not find the column if the mouse if out of the
373
      // right boundary of the table header. Then we make this column the
374
      // rightmost column.
375
      Scan: for (int i = 0; i < n; i++)
376
        {
377
          p += model.getColumn(i).getWidth();
378
          if (p > x)
379
            {
380
              col = i;
381
              break Scan;
382
            }
383
        }
384
 
385
      header.getTable().moveColumn(draggingColumnNumber, col);
386
    }
387
  }
388
 
389
  /**
390
   * Create and return the mouse input listener.
391
   *
392
   * @return the mouse listener ({@link MouseInputHandler}, if not overridden.
393
   */
394
  protected MouseInputListener createMouseInputListener()
395
  {
396
    return new MouseInputHandler();
397
  }
398
 
399
  /**
400
   * Construct a new BasicTableHeaderUI, create mouse listeners.
401
   */
402
  public BasicTableHeaderUI()
403
  {
404
    mouseInputListener = createMouseInputListener();
405
  }
406
 
407
  protected void installDefaults()
408
  {
409
    LookAndFeel.installColorsAndFont(header, "TableHeader.background",
410
                                     "TableHeader.foreground",
411
                                     "TableHeader.font");
412
    cellBorder = UIManager.getBorder("TableHeader.cellBorder");
413
  }
414
 
415
  protected void installKeyboardActions()
416
  {
417
    // AFAICS, the RI does nothing here.
418
  }
419
 
420
  /**
421
   * Add the mouse listener and the mouse motion listener to the table
422
   * header. The listeners support table column resizing and rearrangement
423
   * by mouse.
424
   */
425
  protected void installListeners()
426
  {
427
    header.addMouseListener(mouseInputListener);
428
    header.addMouseMotionListener(mouseInputListener);
429
  }
430
 
431
  public void installUI(JComponent c)
432
  {
433
    header = (JTableHeader) c;
434
    rendererPane = new CellRendererPane();
435
    installDefaults();
436
    installKeyboardActions();
437
    installListeners();
438
  }
439
 
440
  protected void uninstallDefaults()
441
  {
442
    header.setBackground(null);
443
    header.setForeground(null);
444
    header.setFont(null);
445
  }
446
 
447
  protected void uninstallKeyboardActions()
448
  {
449
    // AFAICS, the RI does nothing here.
450
  }
451
 
452
  /**
453
   * Remove the previously installed listeners.
454
   */
455
  protected void uninstallListeners()
456
  {
457
    header.removeMouseListener(mouseInputListener);
458
    header.removeMouseMotionListener(mouseInputListener);
459
  }
460
 
461
  public void uninstallUI(JComponent c)
462
  {
463
    uninstallListeners();
464
    uninstallKeyboardActions();
465
    uninstallDefaults();
466
  }
467
 
468
  /**
469
   * Repaint the table header.
470
   */
471
  public void paint(Graphics gfx, JComponent c)
472
  {
473
    TableColumnModel cmod = header.getColumnModel();
474
    int ncols = cmod.getColumnCount();
475
    if (ncols == 0)
476
      return;
477
 
478
    Rectangle clip = gfx.getClipBounds();
479
    TableCellRenderer defaultRend = header.getDefaultRenderer();
480
 
481
    for (int i = 0; i < ncols; ++i)
482
      {
483
        Rectangle bounds = header.getHeaderRect(i);
484
        if (bounds.intersects(clip))
485
          {
486
            Rectangle oldClip = gfx.getClipBounds();
487
            TableColumn col = cmod.getColumn(i);
488
            TableCellRenderer rend = col.getHeaderRenderer();
489
            if (rend == null)
490
              rend = defaultRend;
491
            Object val = col.getHeaderValue();
492
            Component comp = rend.getTableCellRendererComponent(header.getTable(),
493
                                                                val,
494
                                                                false, // isSelected
495
                                                                false, // isFocused
496
                                                                -1, i);
497
            // FIXME: The following settings should be performed in
498
            // rend.getTableCellRendererComponent().
499
            comp.setFont(header.getFont());
500
            comp.setBackground(header.getBackground());
501
            comp.setForeground(header.getForeground());
502
            if (comp instanceof JComponent)
503
              ((JComponent) comp).setBorder(cellBorder);
504
            rendererPane.paintComponent(gfx, comp, header, bounds.x, bounds.y,
505
                                        bounds.width, bounds.height);
506
          }
507
      }
508
 
509
    // This displays a running rectangle that is much simplier than the total
510
    // animation, as it is seen in Sun's application.
511
    // TODO animate the collumn dragging like in Sun's jre.
512
    if (draggingHeaderRect != null)
513
      {
514
        gfx.setColor(header.getForeground());
515
        gfx.drawRect(draggingHeaderRect.x, draggingHeaderRect.y + 2,
516
            draggingHeaderRect.width - 1, draggingHeaderRect.height - 6);
517
      }
518
  }
519
 
520
  /**
521
   * Get the preferred header size.
522
   *
523
   * @param ignored unused
524
   *
525
   * @return the preferred size of the associated header.
526
   */
527
  public Dimension getPreferredSize(JComponent ignored)
528
  {
529
    TableColumnModel cmod = header.getColumnModel();
530
    TableCellRenderer defaultRend = header.getDefaultRenderer();
531
    int ncols = cmod.getColumnCount();
532
    Dimension ret = new Dimension(0, 0);
533
    int spacing = 0;
534
 
535
    if (header.getTable() != null
536
        && header.getTable().getIntercellSpacing() != null)
537
      spacing = header.getTable().getIntercellSpacing().width;
538
 
539
    for (int i = 0; i < ncols; ++i)
540
      {
541
        TableColumn col = cmod.getColumn(i);
542
        TableCellRenderer rend = col.getHeaderRenderer();
543
        if (rend == null)
544
          rend = defaultRend;
545
        Object val = col.getHeaderValue();
546
        Component comp = rend.getTableCellRendererComponent(header.getTable(),
547
                                                            val,
548
                                                            false, // isSelected
549
                                                            false, // isFocused
550
                                                            -1, i);
551
        comp.setFont(header.getFont());
552
        comp.setBackground(header.getBackground());
553
        comp.setForeground(header.getForeground());
554
        if (comp instanceof JComponent)
555
          ((JComponent) comp).setBorder(cellBorder);
556
 
557
        Dimension d = comp.getPreferredSize();
558
        ret.width += spacing;
559
        ret.height = Math.max(d.height, ret.height);
560
      }
561
    ret.width = cmod.getTotalColumnWidth();
562
    return ret;
563
  }
564
 
565
 
566
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.