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.
40 * Note than a max of "-1" means "infinite".
43 * the minimum page number (cannot be negative)
45 * the maximum page number (cannot be lower than min, except if
48 * @throws IndexOutOfBoundsException
49 * if min > max and max is not "-1"
51 public GuiReaderNavBar(int min
, int max
) {
52 if (min
> max
&& max
!= -1) {
53 throw new IndexOutOfBoundsException(String
.format(
54 "min (%d) > max (%d)", min
, max
));
57 LayoutManager layout
= new BoxLayout(this, BoxLayout
.X_AXIS
);
60 navButtons
= new JButton
[4];
62 navButtons
[0] = createNavButton("<<", new ActionListener() {
64 public void actionPerformed(ActionEvent e
) {
65 setIndex(GuiReaderNavBar
.this.min
);
69 navButtons
[1] = createNavButton(" < ", new ActionListener() {
71 public void actionPerformed(ActionEvent e
) {
76 navButtons
[2] = createNavButton(" > ", new ActionListener() {
78 public void actionPerformed(ActionEvent e
) {
83 navButtons
[3] = createNavButton(">>", new ActionListener() {
85 public void actionPerformed(ActionEvent e
) {
86 setIndex(GuiReaderNavBar
.this.max
);
91 for (JButton navButton
: navButtons
) {
95 label
= new JLabel("");
108 * The current index, must be between {@link GuiReaderNavBar#min} and
109 * {@link GuiReaderNavBar#max}, both inclusive.
113 public int getIndex() {
118 * The current index, must be between {@link GuiReaderNavBar#min} and
119 * {@link GuiReaderNavBar#max}, both inclusive.
124 public void setIndex(int index
) {
125 if (index
!= this.index
) {
126 if (index
< min
|| (index
> max
&& max
!= -1)) {
127 throw new IndexOutOfBoundsException(String
.format(
128 "Index %d but min/max is [%d/%d]", index
, min
, max
));
139 * The minimun page number. Cannot be negative.
143 public int getMin() {
148 * The minimum page number. Cannot be negative.
150 * May update the index if needed (if the index is < the new min).
152 * Will also (always) update the label and enable/disable the required
158 public void setMin(int min
) {
169 * The maximum page number. Cannot be lower than min, except if -1
174 public int getMax() {
179 * The maximum page number. Cannot be lower than min, except if -1
182 * May update the index if needed (if the index is > the new max).
184 * Will also (always) update the label and enable/disable the required
190 public void setMax(int max
) {
192 if (index
> max
&& max
!= -1) {
200 * The current extra label to display with the default
201 * {@link GuiReaderNavBar#computeLabel(int, int, int)} implementation.
203 * @return the current label
205 public String
getExtraLabel() {
210 * The current extra label to display with the default
211 * {@link GuiReaderNavBar#computeLabel(int, int, int)} implementation.
213 * @param currentLabel
214 * the new current label
216 public void setExtraLabel(String currentLabel
) {
217 this.extraLabel
= currentLabel
;
222 * Add a listener that will be called on each page change.
227 public void addActionListener(ActionListener listener
) {
228 listeners
.add(listener
);
232 * Remove the given listener if possible.
235 * the listener to remove
236 * @return TRUE if it was removed, FALSE if it was not found
238 public boolean removeActionListener(ActionListener listener
) {
239 return listeners
.remove(listener
);
243 * Remove all the listeners.
245 public void clearActionsListeners() {
250 * Notify a change of page.
252 public void fireEvent() {
253 for (ActionListener listener
: listeners
) {
255 listener
.actionPerformed(new ActionEvent(this,
256 ActionEvent
.ACTION_FIRST
, "page changed"));
257 } catch (Exception e
) {
258 Instance
.getTraceHandler().error(e
);
264 * Create a single navigation button.
267 * the text to display
269 * the action to take on click
272 private JButton
createNavButton(String text
, ActionListener action
) {
273 JButton navButton
= new JButton(text
);
274 navButton
.addActionListener(action
);
275 navButton
.setForeground(Color
.BLUE
);
280 * Update the label displayed in the UI.
282 private void updateLabel() {
283 label
.setText(computeLabel(index
, min
, max
));
287 * Update the navigation buttons "enabled" state according to the current
290 private void updateEnabled() {
291 navButtons
[0].setEnabled(index
> min
);
292 navButtons
[1].setEnabled(index
> min
);
293 navButtons
[2].setEnabled(index
< max
|| max
== -1);
294 navButtons
[3].setEnabled(index
< max
|| max
== -1);
298 * Return the label to display for the given index.
300 * Swing HTML (HTML3) is supported if surrounded by <HTML> and
303 * By default, return "Page 1/5: current_label" (with the current index and
304 * {@link GuiReaderNavBar#getCurrentLabel()}).
307 * the new index number
309 * the minimum index (inclusive)
311 * the maximum index (inclusive)
314 protected String
computeLabel(int index
,
315 @SuppressWarnings("unused") int min
, int max
) {
317 String base
= " <B>Page <SPAN COLOR='#444466'>%d</SPAN> ";
323 String ifLabel
= ": %s";
325 String display
= base
;
326 String label
= getExtraLabel();
327 if (label
!= null && !label
.trim().isEmpty()) {
331 display
= "<HTML>" + display
+ "</HTML>";
334 return String
.format(display
, index
, max
, label
);
337 return String
.format(display
, index
, label
);