James Moger
2012-09-10 fabe060d3a435f116128851f828e35c2af5fde67
commit | author | age
841651 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.client;
17
18 import java.awt.BasicStroke;
19 import java.awt.Color;
20 import java.awt.Component;
21 import java.awt.Dimension;
22 import java.awt.FlowLayout;
23 import java.awt.Graphics;
24 import java.awt.Graphics2D;
25 import java.awt.Stroke;
26 import java.awt.event.ActionEvent;
27 import java.awt.event.ActionListener;
28 import java.awt.event.MouseAdapter;
29 import java.awt.event.MouseEvent;
30 import java.awt.event.MouseListener;
31
32 import javax.swing.AbstractButton;
33 import javax.swing.BorderFactory;
34 import javax.swing.ImageIcon;
35 import javax.swing.JButton;
36 import javax.swing.JLabel;
37 import javax.swing.JPanel;
38 import javax.swing.JTabbedPane;
39 import javax.swing.plaf.basic.BasicButtonUI;
40
41 /**
42  * Closable tab control.
43  */
44 public class ClosableTabComponent extends JPanel {
45
46     private static final long serialVersionUID = 1L;
47
48     private static final MouseListener BUTTON_MOUSE_LISTENER = new MouseAdapter() {
49         public void mouseEntered(MouseEvent e) {
50             Component component = e.getComponent();
51             if (component instanceof AbstractButton) {
52                 AbstractButton button = (AbstractButton) component;
53                 button.setBorderPainted(true);
54             }
55         }
56
57         public void mouseExited(MouseEvent e) {
58             Component component = e.getComponent();
59             if (component instanceof AbstractButton) {
60                 AbstractButton button = (AbstractButton) component;
61                 button.setBorderPainted(false);
62             }
63         }
64     };
65
66     private final JTabbedPane pane;
67     private final JLabel label;
68     private final JButton button = new TabButton();
69
70     private final CloseTabListener closeListener;
71
72     public interface CloseTabListener {
73         void closeTab(Component c);
74     }
75
76     public ClosableTabComponent(String title, ImageIcon icon, JTabbedPane pane,
77             CloseTabListener closeListener) {
78         super(new FlowLayout(FlowLayout.LEFT, 0, 0));
79         this.closeListener = closeListener;
80
81         if (pane == null) {
82             throw new NullPointerException("TabbedPane is null");
83         }
84         this.pane = pane;
85         setOpaque(false);
86         label = new JLabel(title);
87         if (icon != null) {
88             label.setIcon(icon);
89         }
90
91         add(label);
92         label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 5));
93         add(button);
94         setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
95     }
96
97     private class TabButton extends JButton implements ActionListener {
98
99         private static final long serialVersionUID = 1L;
100
101         public TabButton() {
102             int size = 17;
103             setPreferredSize(new Dimension(size, size));
104             setToolTipText("Close");
105             setUI(new BasicButtonUI());
106             setContentAreaFilled(false);
107             setFocusable(false);
108             setBorder(BorderFactory.createEtchedBorder());
109             setBorderPainted(false);
110             addMouseListener(BUTTON_MOUSE_LISTENER);
111             setRolloverEnabled(true);
112             addActionListener(this);
113         }
114
115         public void actionPerformed(ActionEvent e) {
116             int i = pane.indexOfTabComponent(ClosableTabComponent.this);
117             Component c = pane.getComponentAt(i);
118             if (i != -1) {
119                 pane.remove(i);
120             }
121             if (closeListener != null) {
122                 closeListener.closeTab(c);
123             }
124         }
125
126         public void updateUI() {
127         }
128
129         @Override
130         protected void paintComponent(Graphics g) {
131             super.paintComponent(g);
132             Graphics2D g2 = (Graphics2D) g;
133             Stroke stroke = g2.getStroke();
134             g2.setStroke(new BasicStroke(2));
135             g.setColor(Color.BLACK);
136             if (getModel().isRollover()) {
137                 Color highlight = new Color(0, 51, 153);
138                 g.setColor(highlight);
139             }
140             int delta = 5;
141             g.drawLine(delta, delta, getWidth() - delta - 1, getHeight() - delta - 1);
142             g.drawLine(getWidth() - delta - 1, delta, delta, getHeight() - delta - 1);
143             g2.setStroke(stroke);
144
145             int i = pane.indexOfTabComponent(ClosableTabComponent.this);
146             pane.setTitleAt(i, label.getText());
147         }
148     }
149 }