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
);
61 // JButton up = new BasicArrowButton(BasicArrowButton.NORTH);
62 // JButton down = new BasicArrowButton(BasicArrowButton.SOUTH);
64 navButtons
= new JButton
[4];
66 navButtons
[0] = createNavButton("<<", new ActionListener() {
68 public void actionPerformed(ActionEvent e
) {
69 setIndex(GuiReaderNavBar
.this.min
);
73 navButtons
[1] = createNavButton(" < ", new ActionListener() {
75 public void actionPerformed(ActionEvent e
) {
80 navButtons
[2] = createNavButton(" > ", new ActionListener() {
82 public void actionPerformed(ActionEvent e
) {
87 navButtons
[3] = createNavButton(">>", new ActionListener() {
89 public void actionPerformed(ActionEvent e
) {
90 setIndex(GuiReaderNavBar
.this.max
);
95 for (JButton navButton
: navButtons
) {
99 label
= new JLabel("");
112 * The current index, must be between {@link GuiReaderNavBar#min} and
113 * {@link GuiReaderNavBar#max}, both inclusive.
117 public int getIndex() {
122 * The current index, must be between {@link GuiReaderNavBar#min} and
123 * {@link GuiReaderNavBar#max}, both inclusive.
128 public void setIndex(int index
) {
129 if (index
!= this.index
) {
130 if (index
< min
|| (index
> max
&& max
!= -1)) {
131 throw new IndexOutOfBoundsException(String
.format(
132 "Index %d but min/max is [%d/%d]", index
, min
, max
));
143 * The minimun page number. Cannot be negative.
147 public int getMin() {
152 * The minimum page number. Cannot be negative.
154 * May update the index if needed (if the index is < the new min).
156 * Will also (always) update the label and enable/disable the required
162 public void setMin(int min
) {
173 * The maximum page number. Cannot be lower than min, except if -1
178 public int getMax() {
183 * The maximum page number. Cannot be lower than min, except if -1
186 * May update the index if needed (if the index is > the new max).
188 * Will also (always) update the label and enable/disable the required
194 public void setMax(int max
) {
196 if (index
> max
&& max
!= -1) {
204 * The current extra label to display with the default
205 * {@link GuiReaderNavBar#computeLabel(int, int, int)} implementation.
207 * @return the current label
209 public String
getExtraLabel() {
214 * The current extra label to display with the default
215 * {@link GuiReaderNavBar#computeLabel(int, int, int)} implementation.
217 * @param currentLabel
218 * the new current label
220 public void setExtraLabel(String currentLabel
) {
221 this.extraLabel
= currentLabel
;
226 * Add a listener that will be called on each page change.
231 public void addActionListener(ActionListener listener
) {
232 listeners
.add(listener
);
236 * Remove the given listener if possible.
239 * the listener to remove
240 * @return TRUE if it was removed, FALSE if it was not found
242 public boolean removeActionListener(ActionListener listener
) {
243 return listeners
.remove(listener
);
247 * Remove all the listeners.
249 public void clearActionsListeners() {
254 * Notify a change of page.
256 public void fireEvent() {
257 for (ActionListener listener
: listeners
) {
259 listener
.actionPerformed(new ActionEvent(this,
260 ActionEvent
.ACTION_FIRST
, "page changed"));
261 } catch (Exception e
) {
262 Instance
.getTraceHandler().error(e
);
268 * Create a single navigation button.
271 * the text to display
273 * the action to take on click
276 private JButton
createNavButton(String text
, ActionListener action
) {
277 JButton navButton
= new JButton(text
);
278 navButton
.addActionListener(action
);
279 navButton
.setForeground(Color
.BLUE
);
284 * Update the label displayed in the UI.
286 private void updateLabel() {
287 label
.setText(computeLabel(index
, min
, max
));
291 * Update the navigation buttons "enabled" state according to the current
294 private void updateEnabled() {
295 navButtons
[0].setEnabled(index
> min
);
296 navButtons
[1].setEnabled(index
> min
);
297 navButtons
[2].setEnabled(index
< max
|| max
== -1);
298 navButtons
[3].setEnabled(index
< max
|| max
== -1);
302 * Return the label to display for the given index.
304 * Swing HTML (HTML3) is supported if surrounded by <HTML> and
307 * By default, return "Page 1/5: current_label" (with the current index and
308 * {@link GuiReaderNavBar#getCurrentLabel()}).
311 * the new index number
313 * the minimum index (inclusive)
315 * the maximum index (inclusive)
318 protected String
computeLabel(int index
,
319 @SuppressWarnings("unused") int min
, int max
) {
321 String base
= " <B>Page <SPAN COLOR='#444466'>%d</SPAN> ";
327 String ifLabel
= ": %s";
329 String display
= base
;
330 String label
= getExtraLabel();
331 if (label
!= null && !label
.trim().isEmpty()) {
335 display
= "<HTML>" + display
+ "</HTML>";
338 return String
.format(display
, index
, max
, label
);
341 return String
.format(display
, index
, label
);