~ubuntu-branches/debian/stretch/insubstantial/stretch

« back to all changes in this revision

Viewing changes to laf-widget/src/main/java/org/pushingpixels/lafwidget/contrib/blogofbug/swing/components/JCarouselMenu.java

  • Committer: Package Import Robot
  • Author(s): Felix Natter
  • Date: 2016-01-18 20:58:45 UTC
  • Revision ID: package-import@ubuntu.com-20160118205845-crbmrkda61qsi5qa
Tags: upstream-7.3+dfsg2
ImportĀ upstreamĀ versionĀ 7.3+dfsg2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * JCarouselMenu.java
 
3
 *
 
4
 * Created on January 13, 2007, 12:42 PM
 
5
 *
 
6
 * Copyright 2006-2007 Nigel Hughes
 
7
 *
 
8
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 
9
 * in compliance with the License. You may obtain a copy of the License at http://www.apache.org/
 
10
 * licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
 
12
 * CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language
 
13
 * governing permissions and limitations under the License.
 
14
 */
 
15
 
 
16
package org.pushingpixels.lafwidget.contrib.blogofbug.swing.components;
 
17
 
 
18
import java.awt.*;
 
19
import java.awt.event.*;
 
20
import java.net.URL;
 
21
import java.security.InvalidParameterException;
 
22
import java.util.*;
 
23
 
 
24
import javax.swing.*;
 
25
import javax.swing.event.*;
 
26
 
 
27
import org.pushingpixels.lafwidget.contrib.blogofbug.swing.borders.ImageBorder;
 
28
import org.pushingpixels.lafwidget.contrib.blogofbug.swing.layout.OffsetCaroselLayout;
 
29
 
 
30
 
 
31
/**
 
32
 * Shows a carousel offset to the left with a menu of actions on the right.
 
33
 * @author nigel
 
34
 */
 
35
public class JCarouselMenu extends GradientPanel implements ListSelectionListener,MouseListener,KeyListener, ChangeListener, MouseWheelListener{
 
36
    /**
 
37
     * The carousel used and drawn on the left.
 
38
     */
 
39
    private JCarosel    carousel;
 
40
    /**
 
41
     * A JList with the menu items in
 
42
     */
 
43
    private JList       menu;
 
44
    /**
 
45
     * The scroll pane the menu is in
 
46
     */
 
47
    private JScrollPane menuScroll;
 
48
    /**
 
49
     * The model for the action menu
 
50
     */
 
51
    private DefaultListModel menuModel=new DefaultListModel();
 
52
    /**
 
53
     * Linked list of the items in the menu
 
54
     */
 
55
    private LinkedList<MenuItem>    menuItems=new LinkedList<MenuItem>();
 
56
    /**
 
57
     * A hashtable connecting the actions to the components in the carousel
 
58
     */
 
59
    private Map<Component, MenuItem> menuMap = new HashMap<Component, MenuItem>();
 
60
    /**
 
61
     * The last item selected
 
62
     */
 
63
    private int lastSelection   = -1;
 
64
 
 
65
    /**
 
66
     * The button that is drawn when it is possible to scroll up
 
67
     */
 
68
    private UpDownButton  upButton = new UpDownButton("Up");
 
69
    /**
 
70
     * The button shown when you can scroll down
 
71
     */
 
72
    private UpDownButton  downButton = new UpDownButton("Down");
 
73
    
 
74
    /**
 
75
     * Creates a new instance of JCarouselMenu
 
76
     * @param border The border to use to draw items in the menu
 
77
     */
 
78
    public JCarouselMenu(ImageBorder border) {
 
79
        carousel = new JCarosel();
 
80
        carousel.setLayout(new OffsetCaroselLayout(carousel));
 
81
        carousel.setBackground(null);
 
82
        carousel.setOpaque(false);
 
83
        carousel.setContentWidth(256);
 
84
        
 
85
        super.setLayout(new GridLayout(1,2));
 
86
        super.add(carousel);
 
87
        
 
88
        upButton.setForeground(Color.WHITE);
 
89
        downButton.setForeground(Color.WHITE);
 
90
        
 
91
        JPanel menuPanel = new JPanel();
 
92
        menuPanel.setBackground(null);
 
93
        menuPanel.setOpaque(false);
 
94
        menuPanel.setLayout(new GridBagLayout());
 
95
        GridBagConstraints gbc  = new GridBagConstraints();
 
96
        
 
97
        menu = new JList();
 
98
        menuScroll = new JScrollPane(menu, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
 
99
        menuScroll.getViewport().setOpaque(false);
 
100
        menuScroll.setBorder(null);
 
101
        menuScroll.getViewport().addChangeListener(this);
 
102
        menu.setModel(menuModel);
 
103
        menu.setCellRenderer(new CarouselListCellRenderer(border));
 
104
        menu.setBackground(null);       
 
105
        menu.setOpaque(false);
 
106
        menu.addListSelectionListener(this);
 
107
        menuScroll.setOpaque(true);
 
108
        menuScroll.setBackground(Color.BLACK);
 
109
        menuScroll.setBorder(BorderFactory.createEmptyBorder());
 
110
        
 
111
        gbc.weightx=0.0;
 
112
        gbc.weighty=0.0;
 
113
        gbc.gridy=0;
 
114
        gbc.fill=GridBagConstraints.HORIZONTAL;
 
115
        menuPanel.add(upButton,gbc);
 
116
        gbc.weighty=1.0;
 
117
        gbc.weightx=1.0;
 
118
        gbc.gridy++;
 
119
        gbc.fill=GridBagConstraints.BOTH;
 
120
        menuPanel.add(menuScroll,gbc);
 
121
        gbc.weighty=0.0;
 
122
        gbc.weightx=0.0;
 
123
        gbc.gridy++;
 
124
        gbc.fill=GridBagConstraints.HORIZONTAL;
 
125
        menuPanel.add(downButton,gbc);
 
126
        menu.addMouseListener(this);
 
127
        menu.addKeyListener(this);
 
128
                
 
129
        //Don't want it to listen to itself...
 
130
        carousel.removeMouseWheelListener(carousel);
 
131
        carousel.addMouseWheelListener(this);
 
132
        menu.addMouseWheelListener(this);
 
133
        menuScroll.addMouseWheelListener(this);
 
134
        menuPanel.addMouseWheelListener(this);
 
135
        
 
136
        super.add(menuPanel);
 
137
    }
 
138
    
 
139
    /**
 
140
     * Creates a new instance
 
141
     */
 
142
    public JCarouselMenu(){
 
143
        this(new ImageBorder(JCarouselMenu.class.getResource("/com/blogofbug/swing/borders/images/menu_highlight.png"),new Insets(10,12,16,12)));
 
144
    }
 
145
    
 
146
    /**
 
147
     * Sets the color the up and down buttons are drawn
 
148
     * @param color The desired color
 
149
     */
 
150
    public void setUpDownColor(Color color){
 
151
        upButton.setForeground(color);
 
152
        downButton.setForeground(color);
 
153
    }
 
154
    
 
155
    /**
 
156
     * Returns the list part of the carousel menu
 
157
     *
 
158
     * @return The JList object
 
159
     */
 
160
    public JList getList(){
 
161
        return this.menu;
 
162
    }
 
163
    
 
164
    /**
 
165
     * Sets the selected item in the menu
 
166
     * @param i The index of the item to select
 
167
     */
 
168
    public void setSelectedIndex(int i){
 
169
        menu.setSelectedIndex(i);
 
170
    }
 
171
    
 
172
    /**
 
173
     * Adds a component to the carousel menu that will be brought into view when the user clicks
 
174
     * on the associated item
 
175
     * @param component The component
 
176
     * @param label The text to appear in the menu
 
177
     * @return The created component
 
178
     */
 
179
    public Component add(Component component,String label){
 
180
        carousel.add(label,component);
 
181
        MenuItem item = new MenuItem(component,label,null);
 
182
        menuItems.addLast(item);
 
183
        menuModel.addElement(item);
 
184
        menuMap.put(component, item);
 
185
        component.removeMouseListener(carousel);
 
186
        return component;
 
187
    }
 
188
    
 
189
    /**
 
190
     * Removes a component from the menu
 
191
     * @param component The component to remove
 
192
     */
 
193
    @Override
 
194
    public void remove(Component component) {
 
195
        carousel.remove(component);
 
196
        MenuItem menuItem = menuMap.remove(component);
 
197
        if (menuItem != null) {
 
198
            menuItems.remove(menuItem);
 
199
            menuModel.removeElement(menuItem);
 
200
        }
 
201
    }
 
202
    
 
203
    
 
204
    /**
 
205
     * Adds an image to the menu.
 
206
     * @deprecated Use add(Image, String) instead
 
207
     * @param image The image
 
208
     * @param label The text
 
209
     * @param width Prefered width
 
210
     * @param height Prefered height
 
211
     * @return The created component
 
212
     */
 
213
    public Component add(Image image, String label, int width, int height) {
 
214
        Component comp = carousel.add(image, null);
 
215
        MenuItem item = new MenuItem(comp, label, null);
 
216
        menuItems.addLast(item);
 
217
        menuModel.addElement(item);
 
218
        comp.removeMouseListener(carousel);
 
219
        menuMap.put(comp, item);
 
220
        return comp;
 
221
    }    
 
222
    
 
223
 
 
224
    /**
 
225
     * Adds an image (with a label) and returns the component created to represent them
 
226
     * @param image The image to display
 
227
     * @param label The label to show
 
228
     * @return The component created
 
229
     */
 
230
    public Component add(Image image, String label) {
 
231
        Component comp = carousel.add(image, null);
 
232
        MenuItem item = new MenuItem(comp, label, null);
 
233
        menuItems.addLast(item);
 
234
        menuModel.addElement(item);
 
235
        comp.removeMouseListener(carousel);
 
236
        menuMap.put(comp, item);
 
237
        return comp;
 
238
    }     
 
239
    
 
240
    /**
 
241
     * Adds an action to the menu
 
242
     * @deprecated Use add(imageURL) instead
 
243
     * @param action The action to add
 
244
     * @param width The width
 
245
     * @param height The height
 
246
     * @return The created component
 
247
     */
 
248
    public Component add(Action action, int width, int height){
 
249
        URL url = (URL) action.getValue(AbstractCarouselMenuAction.ACTION_IMAGE_URL);
 
250
        if (url==null){
 
251
            throw new InvalidParameterException("Supplied action does not have Image URL key (AbstractCarouselMenuAction.ACTION_IMAGE_URL)"
 
252
                    );
 
253
        }
 
254
        Component comp = carousel.add(url.toString());
 
255
        MenuItem item = new MenuItem(comp,(String) action.getValue(Action.SHORT_DESCRIPTION),action);
 
256
        menuItems.addLast(item);
 
257
        menuMap.put(comp, item);
 
258
        menuModel.addElement(item);
 
259
        comp.removeMouseListener(carousel);
 
260
        return comp;        
 
261
    }
 
262
    
 
263
    /**
 
264
     * Adds an action to the list, creating a menu item and a carousel entry
 
265
     * @param action The action to add
 
266
     * @return The resultant component
 
267
     */
 
268
    public Component add(Action action){
 
269
        URL url = (URL) action.getValue(AbstractCarouselMenuAction.ACTION_IMAGE_URL);
 
270
        if (url==null){
 
271
            throw new InvalidParameterException("Supplied action does not have Image URL key (AbstractCarouselMenuAction.ACTION_IMAGE_URL)"
 
272
                    );
 
273
        }
 
274
        Component comp = carousel.add(url.toString());
 
275
        MenuItem item = new MenuItem(comp,(String) action.getValue(Action.SHORT_DESCRIPTION),action);
 
276
        menuItems.addLast(item);
 
277
        menuMap.put(comp, item);
 
278
        menuModel.addElement(item);
 
279
        comp.removeMouseListener(carousel);
 
280
        return comp;        
 
281
    }    
 
282
    
 
283
    /**
 
284
     * Adds an image (through a URL) to the menu
 
285
     * @deprecated Use add(imageURL, label) instead
 
286
     * @param imageURL URL of the image
 
287
     * @param label Text message
 
288
     * @param width width
 
289
     * @param height height
 
290
     * @return The created component
 
291
     */
 
292
    public Component add(String imageURL, String label, int width, int height){
 
293
        Component comp = carousel.add(imageURL);
 
294
        MenuItem item = new MenuItem(comp,label,null);
 
295
        menuMap.put(comp, item);
 
296
        menuItems.addLast(item);
 
297
        menuModel.addElement(item);
 
298
        comp.removeMouseListener(carousel);
 
299
        return comp;
 
300
    }
 
301
    
 
302
    /**
 
303
     * Adds an image based on the imageURL and a text label, returning the component that is created as a result
 
304
     * @param imageURL The URL of the image
 
305
     * @param label Text label to be shown in the menu
 
306
     * @return The created component
 
307
     */
 
308
    public Component add(String imageURL, String label){
 
309
        Component comp = carousel.add(imageURL);
 
310
        MenuItem item = new MenuItem(comp,label,null);
 
311
        menuMap.put(comp, item);
 
312
        menuItems.addLast(item);
 
313
        menuModel.addElement(item);
 
314
        comp.removeMouseListener(carousel);
 
315
        return comp;
 
316
    }    
 
317
    
 
318
    /**
 
319
     * Return the preferred size of the component
 
320
     * @return The prefered dimensions of the component
 
321
     */
 
322
    @Override
 
323
    public Dimension getPreferredSize() {
 
324
        Dimension size = super.getPreferredSize();
 
325
        size.width /= 2;
 
326
        return size;
 
327
    }
 
328
    
 
329
    /**
 
330
     * Detect when the list selection changes, and respond by updating the state
 
331
     * of the two "arrow" buttons. Contributed by Sebastian Charpentier.
 
332
     * @see javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent)
 
333
     * @param e The state changed event
 
334
     */
 
335
    @Override
 
336
    public void stateChanged(ChangeEvent e) {
 
337
        // Check if the scroll bar is at the top or at the bottom
 
338
        // Note: It's a trick, I don't know if this is the best/correct way to handle that
 
339
        // We show the "go up" arrow if were not at the beginning
 
340
        JViewport viewport = menuScroll.getViewport();
 
341
        int       yPos = (int)viewport.getViewPosition().getY();
 
342
        upButton.setDoPaint(yPos > 0);
 
343
        // We show the "go down" arrow if were not at the end (having the view as down as we could)
 
344
        downButton.setDoPaint((yPos + viewport.getExtentSize().getHeight()) != menu.getHeight());
 
345
    }    
 
346
    
 
347
    
 
348
    /**
 
349
     * Detect when the list selection changes, and respond by rotating the carousel to show
 
350
     * that item
 
351
     * @param listSelectionEvent The list selection change event
 
352
     */
 
353
    @Override
 
354
    public void valueChanged(ListSelectionEvent listSelectionEvent) {
 
355
        MenuItem item = (MenuItem) menu.getSelectedValue();
 
356
        if (item==null){
 
357
            return;
 
358
        }
 
359
        
 
360
        carousel.bringToFront(item.carouselComponent);
 
361
    }
 
362
    
 
363
    /**
 
364
     * Launch the action associated with the currently selected list item
 
365
     *
 
366
     */
 
367
    protected void processAction(){
 
368
        MenuItem item = (MenuItem) menu.getSelectedValue();
 
369
        if (item==null){
 
370
            return;
 
371
        }
 
372
        if (item.action==null){
 
373
            return;
 
374
        }
 
375
        item.action.actionPerformed(new ActionEvent(this,ActionEvent.ACTION_PERFORMED,item.label));
 
376
    }
 
377
    
 
378
    /**
 
379
     * Look to see if an item in the list is double clicked, and launch the action if it is
 
380
     * @param mouseEvent The mouse event
 
381
     */
 
382
    @Override
 
383
    public void mouseClicked(MouseEvent mouseEvent) {
 
384
        if (mouseEvent.getClickCount()==2){
 
385
            processAction();
 
386
        }
 
387
    }
 
388
    
 
389
    /**
 
390
     * Don't Care *
 
391
     * @param mouseEvent The mouse event
 
392
     */
 
393
    @Override
 
394
    public void mousePressed(MouseEvent mouseEvent) {    }
 
395
    
 
396
    /**
 
397
     * Don't Care *
 
398
     * @param mouseEvent The mouse event
 
399
     */
 
400
    @Override
 
401
    public void mouseReleased(MouseEvent mouseEvent) {}
 
402
    
 
403
    /**
 
404
     * Don't Care *
 
405
     * @param mouseEvent The mouse event
 
406
     */
 
407
    @Override
 
408
    public void mouseEntered(MouseEvent mouseEvent) {}
 
409
    
 
410
    /**
 
411
     * Don't Care *
 
412
     * @param mouseEvent The mouse event
 
413
     */
 
414
    @Override
 
415
    public void mouseExited(MouseEvent mouseEvent) {}
 
416
    
 
417
    /**
 
418
     * Don't Care *
 
419
     * @param keyEvent The key event
 
420
     */
 
421
    @Override
 
422
    public void keyTyped(KeyEvent keyEvent) {    }
 
423
    
 
424
    /**
 
425
     * Listen for key events, when we see one that looks like it should wrap, set up the lastSelection variable to
 
426
     * trigger a change on release of the key
 
427
     * @param keyEvent The key event
 
428
     */
 
429
    @Override
 
430
    public void keyPressed(KeyEvent keyEvent) {
 
431
        switch (keyEvent.getKeyCode()){
 
432
            case KeyEvent.VK_ENTER:
 
433
                processAction();
 
434
                break;
 
435
            case KeyEvent.VK_UP:
 
436
                if (menu.getSelectedIndex()==0){
 
437
                    this.lastSelection = menuModel.size()-1;
 
438
                } else {
 
439
                    this.lastSelection = -1;
 
440
                }
 
441
                break;
 
442
            case KeyEvent.VK_DOWN:
 
443
                if (menu.getSelectedIndex()==menuModel.size()-1){
 
444
                    this.lastSelection = 0;
 
445
                } else {
 
446
                    this.lastSelection = -1;
 
447
                }
 
448
                break;
 
449
                
 
450
        }
 
451
    }
 
452
    
 
453
    /**
 
454
     * Sets the image border used to draw around the items in the menu
 
455
     * @param imageBorder The desired image border
 
456
     */
 
457
    public void setCellImageBorder(ImageBorder imageBorder){
 
458
        CarouselListCellRenderer renderer = (CarouselListCellRenderer) menu.getCellRenderer();
 
459
        
 
460
        renderer.setImageBorder(imageBorder);
 
461
    }
 
462
    
 
463
    /**
 
464
     * Specifies the list cell renderer used to draw the items in the menu
 
465
     * @param cellRenderer The list cell renderer
 
466
     */
 
467
    public void setCellRenderer(ListCellRenderer cellRenderer){
 
468
        menu.setCellRenderer(cellRenderer);
 
469
    }
 
470
    
 
471
    /**
 
472
     * If the wrap-around has detected the need to wrap, sets the selection to the value
 
473
     * calculated when the key was first pressed.
 
474
     * @param keyEvent The key event
 
475
     */
 
476
    @Override
 
477
    public void keyReleased(KeyEvent keyEvent) {
 
478
        if (lastSelection!=-1){
 
479
            menu.setSelectedIndex(lastSelection);
 
480
            menu.ensureIndexIsVisible(lastSelection);
 
481
            lastSelection=-1;
 
482
        }
 
483
    }
 
484
 
 
485
    /**
 
486
     * Moves the selected menu up or down when the mouse wheel scrolls
 
487
     * @param mouseWheelEvent The mouse wheel event
 
488
     */
 
489
    @Override
 
490
    public void mouseWheelMoved(MouseWheelEvent mouseWheelEvent) {
 
491
        if (mouseWheelEvent.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) {
 
492
            int amount = mouseWheelEvent.getWheelRotation();
 
493
 
 
494
            int lastSelection;
 
495
            if (amount < 0) {
 
496
                if (menu.getSelectedIndex()==0){
 
497
                    lastSelection = menuModel.size()-1;
 
498
                } else {
 
499
                    lastSelection = menu.getSelectedIndex()-1;
 
500
                }
 
501
            } else {
 
502
                if (menu.getSelectedIndex()==menuModel.size()-1){
 
503
                    lastSelection = 0;
 
504
                } else {
 
505
                    lastSelection = menu.getSelectedIndex()+1;
 
506
                }
 
507
            }
 
508
            
 
509
            final int indexToSelect = lastSelection;
 
510
            SwingUtilities.invokeLater(new Runnable() {
 
511
                @Override
 
512
                public void run() {
 
513
                    menu.setSelectedIndex(indexToSelect);
 
514
                    menu.ensureIndexIsVisible(indexToSelect);
 
515
                    menu.repaint();
 
516
                }
 
517
            });                        
 
518
        }        
 
519
    }
 
520
    
 
521
    /**
 
522
     * Sets icons to use to show the up and down buttons
 
523
     * @param upIcon The icon to use for up
 
524
     * @param downIcon The icon to use for down
 
525
     */
 
526
    public void setUpDownIcons(Icon upIcon, Icon downIcon) {
 
527
        upButton.setIcon(upIcon);
 
528
        downButton.setIcon(downIcon);
 
529
    }
 
530
 
 
531
    /**
 
532
     * Allows the background color to the menu (left side) to be set
 
533
     * @param color Sets the background color to the menu
 
534
     */
 
535
    public void setMenuScrollColor(Color color) {
 
536
        this.menuScroll.setBackground(color);
 
537
    }    
 
538
    
 
539
    /**
 
540
     * ListCellRenderer for the Carousel uses an image border to draw a nice border around the menu item when it is selected
 
541
     *
 
542
     */
 
543
    protected class CarouselListCellRenderer extends JLabel implements ListCellRenderer{
 
544
        ImageBorder imageBorder;
 
545
        /**
 
546
         * Creates a new list cell renderer for the menu with the specified image border
 
547
         * @param border The border to use
 
548
         */
 
549
        public CarouselListCellRenderer(ImageBorder border){
 
550
            imageBorder = border;
 
551
            setBorder(imageBorder);
 
552
        }
 
553
        
 
554
        /**
 
555
         * Allows the setting of the image border
 
556
         * @param border The border to use
 
557
         */
 
558
        public void setImageBorder(ImageBorder border){
 
559
            imageBorder = border;
 
560
            setBorder(imageBorder);
 
561
        }
 
562
        
 
563
        /**
 
564
         * Sets up the component for stamping
 
565
         * @param jList The list
 
566
         * @param object The object being drawn
 
567
         * @param i The index of the object
 
568
         * @param isSelected If the object is selected
 
569
         * @param cellHasFocus Does the cell have the focus
 
570
         * @return The object to use to stamp the list item
 
571
         */
 
572
        @Override
 
573
        public Component getListCellRendererComponent(JList jList, Object object, int i, boolean isSelected, boolean cellHasFocus) {
 
574
            MenuItem item = (MenuItem) object;
 
575
            setText(item.label);
 
576
            if (!isSelected){
 
577
                setBackground(null);
 
578
                imageBorder.setPaintBorder(false);
 
579
                setOpaque(false);
 
580
            } else {
 
581
                imageBorder.setPaintBorder(false);
 
582
                setOpaque(false);
 
583
            }
 
584
            setForeground(Color.WHITE);
 
585
            
 
586
            return this;
 
587
        }
 
588
        
 
589
        /**
 
590
         * Our image border can paint a center as well as a surround. Call paint center if we want it to do this. 
 
591
         * @param g The graphcis context
 
592
         */
 
593
        @Override
 
594
        public void paintComponent(Graphics g){
 
595
            imageBorder.paintCenter((Graphics2D)g,this);
 
596
            super.paintComponent(g);
 
597
        }
 
598
        
 
599
        /**
 
600
         * I want it to be wider than it needs to be
 
601
         * @return The desired width of the cell
 
602
         */
 
603
        @Override
 
604
        public Dimension getPreferredSize() {
 
605
            Dimension d = super.getPreferredSize();
 
606
            d.width+=20;
 
607
            return d;
 
608
        }
 
609
    }
 
610
    
 
611
    /**
 
612
     * A menu item inside the carousel
 
613
     */
 
614
    public class MenuItem{
 
615
        /**
 
616
         * The component inside the caroulse
 
617
         */
 
618
        protected Component carouselComponent;
 
619
        /**
 
620
         * The text label
 
621
         */
 
622
        protected String    label;
 
623
        /**
 
624
         * An associated action
 
625
         */
 
626
        protected Action    action;
 
627
        
 
628
        /**
 
629
         * Creates a new instance of the menu item
 
630
         * @param component The component to use
 
631
         * @param label The text label
 
632
         * @param action The associated action
 
633
         */
 
634
        public MenuItem(Component component, String label,Action action){
 
635
            this.label = label;
 
636
            carouselComponent = component;
 
637
            this.action = action;
 
638
        }
 
639
 
 
640
        /**
 
641
         * Retreives the label associated with the entry
 
642
         * @return The label
 
643
         */
 
644
        public String getLabel() {
 
645
            return label;
 
646
        }
 
647
 
 
648
        /**
 
649
         * Gets the action associated with the entry
 
650
         * @return The action associated with the entry
 
651
         */
 
652
        public Action getAction() {
 
653
            return action;
 
654
        }
 
655
 
 
656
        /**
 
657
         * Gets the component in the carousel associated with the entry
 
658
         * @return The component
 
659
         */
 
660
        public Component getCarouselComponent() {
 
661
            return carouselComponent;
 
662
        }
 
663
 
 
664
    }
 
665
    
 
666
    /**
 
667
     * This class represents the up and down buttons that allow the scrolling through the menu when it is too big to fit in the avaiable space
 
668
     */
 
669
    private class UpDownButton extends JLabel implements MouseListener{
 
670
        /**
 
671
         * True if they should be painted
 
672
         */
 
673
        private boolean doPaint = true;
 
674
        
 
675
        /**
 
676
         * Creates the up down button
 
677
         * @param text Test, ignored
 
678
         */
 
679
        public UpDownButton(String text){
 
680
            super(text);
 
681
            addMouseListener(this);
 
682
            setBorder(BorderFactory.createEmptyBorder(4,4,4,4));
 
683
        }
 
684
        
 
685
        /**
 
686
         * Controls if the button should paint itself or not
 
687
         * @param shouldPaint True if it should, false if it shouldn't
 
688
         */
 
689
        public void setDoPaint(boolean shouldPaint){
 
690
            doPaint = shouldPaint;
 
691
            repaint();
 
692
        }
 
693
        
 
694
        /**
 
695
         * Paint the component
 
696
         * @param g The graphics context
 
697
         */
 
698
        @Override
 
699
        public void paintComponent(Graphics g){
 
700
            if (doPaint) {
 
701
                Icon icon = this.getIcon();
 
702
                if (icon != null) {
 
703
                    int centerX = getWidth()
 
704
                            - (getInsets().left + getInsets().right);
 
705
                    centerX = getInsets().left + centerX / 2;
 
706
                    int centerY = getHeight()
 
707
                            - (getInsets().top + getInsets().bottom);
 
708
                    centerY = getInsets().top + centerY / 2;
 
709
                    icon.paintIcon(this, g, centerX - icon.getIconWidth() / 2,
 
710
                            centerY - icon.getIconHeight() / 2);
 
711
                } else {
 
712
                    Graphics2D g2 = (Graphics2D) g;
 
713
                    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
 
714
                    g.setColor(getForeground());
 
715
                    int centerX = getWidth()-(getInsets().left+getInsets().right);
 
716
                    centerX = getInsets().left + centerX/2;
 
717
                    int height = getHeight()-(getInsets().top+getInsets().bottom);
 
718
                    int width = height*2;
 
719
                    if ("Up".equals(getText())){
 
720
                        g.fillPolygon(new int[]{centerX-width,centerX,centerX+width},new int[]{height,getInsets().top,height},3);                
 
721
                    } else {
 
722
                        g.fillPolygon(new int[]{centerX-width,centerX,centerX+width},new int[]{getInsets().top,height,getInsets().top},3);                
 
723
                    }
 
724
                    
 
725
                }
 
726
            }            
 
727
        }
 
728
 
 
729
 
 
730
        /**
 
731
         * Listens for a mouse click and scroll up or down in the menu when it gets one
 
732
         * @param mouseEvent The mouse event
 
733
         */
 
734
        @Override
 
735
        public void mouseClicked(MouseEvent mouseEvent) {
 
736
            if (!doPaint){
 
737
                return;
 
738
            }
 
739
            if (mouseEvent.getClickCount()==1){
 
740
                int height = menu.getCellBounds(menu.getSelectedIndex(),menu.getSelectedIndex()).height;
 
741
                if (getText().equals("Up")) {
 
742
                        setSelectedIndex(menu.getSelectedIndex()-1);
 
743
                        Point pos = menuScroll.getViewport().getViewPosition();
 
744
                        pos.y-=height;
 
745
                        menuScroll.getViewport().setViewPosition(pos);
 
746
                } else if (getText().equals("Down")) {
 
747
                        setSelectedIndex(menu.getSelectedIndex()+1);
 
748
                        Point pos = menuScroll.getViewport().getViewPosition();
 
749
                        pos.y+=height;
 
750
                        menuScroll.getViewport().setViewPosition(pos);
 
751
                }                
 
752
            }
 
753
        }
 
754
 
 
755
        /**
 
756
         * Don't care
 
757
         * @param mouseEvent The mouse event
 
758
         */
 
759
        @Override
 
760
        public void mousePressed(MouseEvent mouseEvent) {
 
761
        }
 
762
 
 
763
        /**
 
764
         * Don't care
 
765
         * @param mouseEvent The mouse event
 
766
         */
 
767
        @Override
 
768
        public void mouseReleased(MouseEvent mouseEvent) {
 
769
        }
 
770
 
 
771
        /**
 
772
         * Don't care
 
773
         * @param mouseEvent The mouse event
 
774
         */
 
775
        @Override
 
776
        public void mouseEntered(MouseEvent mouseEvent) {
 
777
        }
 
778
 
 
779
        /**
 
780
         * Don't care
 
781
         * @param mouseEvent The mouse event
 
782
         */
 
783
        @Override
 
784
        public void mouseExited(MouseEvent mouseEvent) {
 
785
        }
 
786
        
 
787
    }
 
788
}