1 package be
.nikiroo
.utils
.ui
;
3 import java
.awt
.Dimension
;
4 import java
.awt
.LayoutManager
;
5 import java
.awt
.event
.ActionEvent
;
6 import java
.awt
.event
.ActionListener
;
8 import javax
.swing
.BoxLayout
;
9 import javax
.swing
.Icon
;
10 import javax
.swing
.JButton
;
11 import javax
.swing
.JLabel
;
12 import javax
.swing
.JTextField
;
15 * A Swing-based navigation bar, that displays first/previous/next/last page
20 public class NavBar
extends ListenerPanel
{
21 private static final long serialVersionUID
= 1L;
23 /** The event that is fired on page change. */
24 public static final String PAGE_CHANGED
= "page changed";
26 private JTextField page
;
27 private JLabel maxPage
;
30 private int index
= 0;
33 private String extraLabel
= null;
35 private JButton first
;
36 private JButton previous
;
41 * Create a new navigation bar.
43 * The minimum must be lower or equal to the maximum.
45 * Note than a max of "-1" means "infinite".
48 * the minimum page number (cannot be negative)
50 * the maximum page number (cannot be lower than min, except if
53 * @throws IndexOutOfBoundsException
54 * if min > max and max is not "-1"
56 public NavBar(int min
, int max
) {
57 if (min
> max
&& max
!= -1) {
58 throw new IndexOutOfBoundsException(
59 String
.format("min (%d) > max (%d)", min
, max
));
62 LayoutManager layout
= new BoxLayout(this, BoxLayout
.X_AXIS
);
66 first
= new JButton();
67 first
.addActionListener(new ActionListener() {
69 public void actionPerformed(ActionEvent e
) {
74 previous
= new JButton();
75 previous
.addActionListener(new ActionListener() {
77 public void actionPerformed(ActionEvent e
) {
82 page
= new JTextField(Integer
.toString(min
));
83 page
.setPreferredSize(
84 new Dimension(new JButton("1234").getPreferredSize().width
,
85 new JButton("dummy").getPreferredSize().height
));
86 page
.setMaximumSize(new Dimension(Integer
.MAX_VALUE
,
87 page
.getPreferredSize().height
));
88 page
.addActionListener(new ActionListener() {
90 public void actionPerformed(ActionEvent e
) {
92 int pageNb
= Integer
.parseInt(page
.getText());
93 if (pageNb
< NavBar
.this.min
|| pageNb
> NavBar
.this.max
) {
94 throw new NumberFormatException("invalid");
98 fireActionPerformed(PAGE_CHANGED
);
99 } catch (NumberFormatException nfe
) {
100 page
.setText(Integer
.toString(index
));
105 maxPage
= new JLabel("of " + max
);
107 next
= new JButton();
108 next
.addActionListener(new ActionListener() {
110 public void actionPerformed(ActionEvent e
) {
115 last
= new JButton();
116 last
.addActionListener(new ActionListener() {
118 public void actionPerformed(ActionEvent e
) {
123 // Set the << < > >> "icons"
124 setIcons(null, null, null, null);
128 this.add(new JLabel(" "));
130 this.add(new JLabel(" "));
132 this.add(new JLabel(" "));
136 this.add(label
= new JLabel(""));
144 fireActionPerformed(PAGE_CHANGED
);
148 * The current index, must be between {@link NavBar#min} and
149 * {@link NavBar#max}, both inclusive.
153 public int getIndex() {
158 * The current index, should be between {@link NavBar#min} and
159 * {@link NavBar#max}, both inclusive.
164 * @return TRUE if the index changed, FALSE if not (either it was already at
165 * that value, or it is outside of the bounds set by
166 * {@link NavBar#min} and {@link NavBar#max})
168 public synchronized boolean setIndex(int index
) {
169 if (index
!= this.index
) {
170 if (index
< min
|| (index
> max
&& max
!= -1)) {
185 * The minimun page number. Cannot be negative.
189 public int getMin() {
194 * The minimum page number. Cannot be negative.
196 * May update the index if needed (if the index is < the new min).
198 * Will also (always) update the label and enable/disable the required
204 public synchronized void setMin(int min
) {
215 * The maximum page number. Cannot be lower than min, except if -1
220 public int getMax() {
225 * The maximum page number. Cannot be lower than min, except if -1
228 * May update the index if needed (if the index is > the new max).
230 * Will also (always) update the label and enable/disable the required
236 public synchronized void setMax(int max
) {
238 if (index
> max
&& max
!= -1) {
242 maxPage
.setText("of " + max
);
248 * The current extra label to display.
250 * @return the current label
252 public String
getExtraLabel() {
257 * The current extra label to display.
259 * @param currentLabel
260 * the new current label
262 public void setExtraLabel(String currentLabel
) {
263 this.extraLabel
= currentLabel
;
268 * Change the page to the next one.
270 * @return TRUE if it changed
272 public synchronized boolean next() {
273 if (setIndex(index
+ 1)) {
274 fireActionPerformed(PAGE_CHANGED
);
282 * Change the page to the previous one.
284 * @return TRUE if it changed
286 public synchronized boolean previous() {
287 if (setIndex(index
- 1)) {
288 fireActionPerformed(PAGE_CHANGED
);
296 * Change the page to the first one.
298 * @return TRUE if it changed
300 public synchronized boolean first() {
302 fireActionPerformed(PAGE_CHANGED
);
310 * Change the page to the last one.
312 * @return TRUE if it changed
314 public synchronized boolean last() {
316 fireActionPerformed(PAGE_CHANGED
);
324 * Set icons for the buttons instead of square brackets.
326 * Any NULL value will make the button use square brackets again.
329 * the icon of the button "go to first page"
331 * the icon of the button "go to previous page"
333 * the icon of the button "go to next page"
335 * the icon of the button "go to last page"
337 public void setIcons(Icon first
, Icon previous
, Icon next
, Icon last
) {
338 this.first
.setIcon(first
);
339 this.first
.setText(first
== null ?
"<<" : "");
340 this.previous
.setIcon(previous
);
341 this.previous
.setText(previous
== null ?
"<" : "");
342 this.next
.setIcon(next
);
343 this.next
.setText(next
== null ?
">" : "");
344 this.last
.setIcon(last
);
345 this.last
.setText(last
== null ?
">>" : "");
349 * Update the label displayed in the UI.
351 private void updateLabel() {
352 label
.setText(getExtraLabel());
353 page
.setText(Integer
.toString(index
));
357 * Update the navigation buttons "enabled" state according to the current
360 private synchronized void updateEnabled() {
361 first
.setEnabled(index
> min
);
362 previous
.setEnabled(index
> min
);
363 next
.setEnabled(index
< max
|| max
== -1);
364 last
.setEnabled(index
< max
|| max
== -1);