1 package be
.nikiroo
.fanfix
.reader
.ui
;
4 import java
.awt
.LayoutManager
;
5 import java
.awt
.event
.ActionEvent
;
6 import java
.awt
.event
.ActionListener
;
7 import java
.util
.ArrayList
;
10 import javax
.swing
.BoxLayout
;
11 import javax
.swing
.JButton
;
12 import javax
.swing
.JLabel
;
13 import javax
.swing
.JPanel
;
15 import be
.nikiroo
.fanfix
.Instance
;
18 * A Swing-based navigation bar, that displays first/previous/next/last page
23 public class GuiReaderNavBar
extends JPanel
{
24 private static final long serialVersionUID
= 1L;
27 private int index
= 0;
30 private JButton
[] navButtons
;
31 String extraLabel
= null;
33 private List
<ActionListener
> listeners
= new ArrayList
<ActionListener
>();
36 * Create a new navigation bar.
38 * The minimum must be lower or equal to the maximum.
41 * the minimum page number
43 * the maximum page number
45 * @throws IndexOutOfBoundsException
48 public GuiReaderNavBar(int min
, int max
) {
50 throw new IndexOutOfBoundsException(String
.format(
51 "min (%d) > max (%d)", min
, max
));
54 LayoutManager layout
= new BoxLayout(this, BoxLayout
.X_AXIS
);
57 navButtons
= new JButton
[4];
59 navButtons
[0] = createNavButton("<<", new ActionListener() {
61 public void actionPerformed(ActionEvent e
) {
62 setIndex(GuiReaderNavBar
.this.min
);
65 navButtons
[1] = createNavButton(" < ", new ActionListener() {
67 public void actionPerformed(ActionEvent e
) {
71 navButtons
[2] = createNavButton(" > ", new ActionListener() {
73 public void actionPerformed(ActionEvent e
) {
77 navButtons
[3] = createNavButton(">>", new ActionListener() {
79 public void actionPerformed(ActionEvent e
) {
80 setIndex(GuiReaderNavBar
.this.max
);
84 for (JButton navButton
: navButtons
) {
88 label
= new JLabel("");
101 * The current index, must be between {@link GuiReaderNavBar#min} and
102 * {@link GuiReaderNavBar#max}, both inclusive.
106 public int getIndex() {
111 * The current index, must be between {@link GuiReaderNavBar#min} and
112 * {@link GuiReaderNavBar#max}, both inclusive.
117 private void setIndex(int index
) {
118 if (index
!= this.index
) {
119 if (index
< min
|| index
> max
) {
120 throw new IndexOutOfBoundsException(String
.format(
121 "Index %d but min/max is [%d/%d]", index
, min
, max
));
133 * The minimun page number.
137 public int getMin() {
142 * The minimum page number.
144 * May update the index if needed (if the index is < the new min).
146 * Will also (always) update the label and enable/disable the required
152 public void setMin(int min
) {
166 * The maximum page number.
170 public int getMax() {
175 * The maximum page number.
177 * May update the index if needed (if the index is > the new max).
179 * Will also (always) update the label and enable/disable the required
185 public void setMax(int max
) {
199 * The current extra label to display with the default
200 * {@link GuiReaderNavBar#computeLabel(int, int, int)} implementation.
202 * @return the current label
204 public String
getExtraLabel() {
209 * The current extra label to display with the default
210 * {@link GuiReaderNavBar#computeLabel(int, int, int)} implementation.
212 * @param currentLabel
213 * the new current label
215 public void setExtraLabel(String currentLabel
) {
216 this.extraLabel
= currentLabel
;
221 * Add a listener that will be called on each page change.
226 public void addActionListener(ActionListener listener
) {
227 listeners
.add(listener
);
231 * Remove the given listener if possible.
234 * the listener to remove
235 * @return TRUE if it was removed, FALSE if it was not found
237 public boolean removeActionListener(ActionListener listener
) {
238 return listeners
.remove(listener
);
242 * Remove all the listeners.
244 public void clearActionsListeners() {
249 * Notify a chnge of page.
251 private void fireEvent() {
252 for (ActionListener listener
: listeners
) {
254 listener
.actionPerformed(new ActionEvent(this,
255 ActionEvent
.ACTION_FIRST
, "page changed"));
256 } catch (Exception e
) {
257 Instance
.getTraceHandler().error(e
);
263 * Create a single navigation button.
266 * the text to display
268 * the action to take on click
271 private JButton
createNavButton(String text
, ActionListener action
) {
272 JButton navButton
= new JButton(text
);
273 navButton
.addActionListener(action
);
274 navButton
.setForeground(Color
.BLUE
);
279 * Update the label displayed in the UI.
281 private void updateLabel() {
282 label
.setText(computeLabel(index
, min
, max
));
286 * Update the navigation buttons "enabled" state according to the current
289 private void updateEnabled() {
290 navButtons
[0].setEnabled(index
> min
);
291 navButtons
[1].setEnabled(index
> min
);
292 navButtons
[2].setEnabled(index
< max
);
293 navButtons
[3].setEnabled(index
< max
);
297 * Return the label to display for the given index.
299 * Swing HTML (HTML3) is supported if surrounded by <HTML> and
302 * By default, return "Page 1/5: current_label" (with the current index and
303 * {@link GuiReaderNavBar#getCurrentLabel()}).
306 * the new index number
308 * the minimum index (inclusive)
310 * the maximum index (inclusive)
313 protected String
computeLabel(int index
,
314 @SuppressWarnings("unused") int min
, int max
) {
316 String base
= " <B>Page <SPAN COLOR='#444466'>%d</SPAN> / %d</B>";
317 String ifLabel
= ": %s";
319 String display
= base
;
320 String label
= getExtraLabel();
321 if (label
!= null && !label
.trim().isEmpty()) {
325 display
= "<HTML>" + display
+ "</HTML>";
327 return String
.format(display
, index
, max
, label
);