Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
JDropDownButton |
|
| 1.1111111111111112;1.111 | ||||
JDropDownButton$1 |
|
| 1.1111111111111112;1.111 | ||||
JDropDownButton$ArrowIcon |
|
| 1.1111111111111112;1.111 |
1 | package org.jtheque.primary.view.impl.components; | |
2 | ||
3 | /* | |
4 | * This file is part of JTheque. | |
5 | * | |
6 | * JTheque 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 3 of the License. | |
9 | * | |
10 | * JTheque is distributed in the hope that it will be useful, | |
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
13 | * GNU General Public License for more details. | |
14 | * | |
15 | * You should have received a copy of the GNU General Public License | |
16 | * along with JTheque. If not, see <http://www.gnu.org/licenses/>. | |
17 | */ | |
18 | ||
19 | import javax.swing.Action; | |
20 | import javax.swing.Icon; | |
21 | import javax.swing.JButton; | |
22 | import javax.swing.JPanel; | |
23 | import javax.swing.JPopupMenu; | |
24 | import java.awt.Color; | |
25 | import java.awt.Component; | |
26 | import java.awt.Dimension; | |
27 | import java.awt.FlowLayout; | |
28 | import java.awt.Graphics; | |
29 | import java.awt.event.ActionEvent; | |
30 | import java.awt.event.ActionListener; | |
31 | import java.awt.geom.Dimension2D; | |
32 | import java.util.Arrays; | |
33 | ||
34 | /** | |
35 | * A drop down button. | |
36 | * | |
37 | * @author Baptiste Wicht | |
38 | */ | |
39 | public final class JDropDownButton extends JPanel implements ActionListener { | |
40 | private final JPopupMenu popup; | |
41 | ||
42 | /** | |
43 | * Construct a new Drop Down Button with a list of action to provide. | |
44 | * | |
45 | * @param actions All the actions of the Drop Down Button. | |
46 | */ | |
47 | public JDropDownButton(Iterable<Action> actions){ | |
48 | 0 | super(); |
49 | ||
50 | 0 | setBorder(null); |
51 | 0 | setLayout(new FlowLayout(FlowLayout.LEFT, 2, 0)); |
52 | 0 | setBackground(Color.white); |
53 | ||
54 | 0 | JButton mainButton = buildMainButton(actions.iterator().next()); |
55 | 0 | add(mainButton); |
56 | ||
57 | 0 | JButton arrowButton = buildArrowButton(); |
58 | 0 | add(arrowButton); |
59 | ||
60 | 0 | calculateSizes(mainButton.getPreferredSize(), arrowButton.getPreferredSize()); |
61 | ||
62 | 0 | popup = new JPopupMenu(); |
63 | ||
64 | 0 | for (Action a : actions){ |
65 | 0 | popup.add(a); |
66 | } | |
67 | 0 | } |
68 | ||
69 | /** | |
70 | * Construct a new JDropDownButton with the specified actions. | |
71 | * | |
72 | * @param actions All the actions to be displayed in the view. | |
73 | */ | |
74 | public JDropDownButton(Action... actions){ | |
75 | 0 | this(Arrays.asList(actions)); |
76 | 0 | } |
77 | ||
78 | /** | |
79 | * Build the main button. | |
80 | * | |
81 | * @param action The action executing by this button. | |
82 | * | |
83 | * @return The builded button. | |
84 | */ | |
85 | private static JButton buildMainButton(Action action){ | |
86 | 0 | JButton button = new JButton(action); |
87 | 0 | button.setRequestFocusEnabled(false); |
88 | 0 | button.setRolloverEnabled(true); |
89 | ||
90 | 0 | return button; |
91 | } | |
92 | ||
93 | /** | |
94 | * Build the arrow button. | |
95 | * | |
96 | * @return The builded button. | |
97 | */ | |
98 | private JButton buildArrowButton(){ | |
99 | 0 | JButton button = new JButton(); |
100 | ||
101 | 0 | button.setIcon(new ArrowIcon()); |
102 | 0 | button.addActionListener(this); |
103 | 0 | button.setRequestFocusEnabled(false); |
104 | 0 | button.setRolloverEnabled(true); |
105 | ||
106 | 0 | return button; |
107 | } | |
108 | ||
109 | /** | |
110 | * Define the size of the button basing on the size of the two buttons. | |
111 | * | |
112 | * @param buttonSize1 The preferred size of the main button. | |
113 | * @param buttonSize2 The preferred size of the arrow button. | |
114 | */ | |
115 | private void calculateSizes(Dimension2D buttonSize1, Dimension2D buttonSize2){ | |
116 | 0 | int width = (int) (buttonSize1.getWidth() + buttonSize2.getWidth()); |
117 | 0 | int height = (int) Math.max(buttonSize1.getHeight(), buttonSize2.getHeight()); |
118 | ||
119 | 0 | Dimension dimension = new Dimension(width + 7, height); |
120 | ||
121 | 0 | setMaximumSize(dimension); |
122 | 0 | setMinimumSize(dimension); |
123 | 0 | setPreferredSize(dimension); |
124 | 0 | } |
125 | ||
126 | @Override | |
127 | public void actionPerformed(ActionEvent event){ | |
128 | 0 | popup.show(this, 0, getHeight()); |
129 | 0 | } |
130 | ||
131 | /** | |
132 | * An icon representing an arrow. | |
133 | * | |
134 | * @author Baptiste Wicht | |
135 | */ | |
136 | 0 | private static final class ArrowIcon implements Icon { |
137 | @Override | |
138 | public void paintIcon(Component c, Graphics g, int x, int y){ | |
139 | 0 | g.setColor(Color.black); |
140 | 0 | g.drawLine(x, y, x + 4, y); |
141 | 0 | g.drawLine(x + 1, y + 1, x + 3, y + 1); |
142 | 0 | g.drawLine(x + 2, y + 2, x + 2, y + 2); |
143 | 0 | } |
144 | ||
145 | @Override | |
146 | public int getIconWidth(){ | |
147 | 0 | return 6; |
148 | } | |
149 | ||
150 | @Override | |
151 | public int getIconHeight(){ | |
152 | 0 | return 4; |
153 | } | |
154 | } | |
155 | } |