1 package be
.nikiroo
.fanfix
.reader
.ui
;
3 import java
.awt
.BorderLayout
;
4 import java
.awt
.Graphics
;
5 import java
.awt
.event
.MouseEvent
;
6 import java
.awt
.event
.MouseListener
;
7 import java
.util
.ArrayList
;
9 import java
.util
.EventListener
;
10 import java
.util
.List
;
12 import javax
.swing
.JLabel
;
13 import javax
.swing
.JPanel
;
15 import be
.nikiroo
.fanfix
.data
.Story
;
16 import be
.nikiroo
.fanfix
.reader
.Reader
;
19 * A book item presented in a {@link GuiReaderFrame}.
23 class GuiReaderBook
extends JPanel
{
25 * Action on a book item.
29 interface BookActionListener
extends EventListener
{
31 * The book was selected (single click).
34 * the {@link GuiReaderBook} itself
36 public void select(GuiReaderBook book
);
39 * The book was double-clicked.
42 * the {@link GuiReaderBook} itself
44 public void action(GuiReaderBook book
);
47 * A popup menu was requested for this {@link GuiReaderBook}.
50 * the {@link GuiReaderBook} itself
52 * the {@link MouseEvent} that generated this call
54 public void popupRequested(GuiReaderBook book
, MouseEvent e
);
57 private static final long serialVersionUID
= 1L;
59 private static final String AUTHOR_COLOR
= "#888888";
60 private static final long doubleClickDelay
= 200; // in ms
64 private boolean selected
;
65 private boolean hovered
;
66 private Date lastClick
;
68 private List
<BookActionListener
> listeners
;
69 private GuiReaderBookInfo info
;
70 private boolean cached
;
71 private boolean seeWordCount
;
74 * Create a new {@link GuiReaderBook} item for the given {@link Story}.
77 * the associated reader
79 * the information about the story to represent
81 * TRUE if it is locally cached
83 * TRUE to see word counts, FALSE to see authors
85 public GuiReaderBook(Reader reader
, GuiReaderBookInfo info
, boolean cached
,
86 boolean seeWordCount
) {
89 this.seeWordCount
= seeWordCount
;
91 icon
= new JLabel(GuiReaderCoverImager
.generateCoverIcon(
92 reader
.getLibrary(), info
));
97 setLayout(new BorderLayout(10, 10));
98 add(icon
, BorderLayout
.CENTER
);
99 add(title
, BorderLayout
.SOUTH
);
105 * The book current selection state.
107 * @return the selection state
109 public boolean isSelected() {
114 * The book current selection state.
117 * TRUE if it is selected
119 public void setSelected(boolean selected
) {
120 if (this.selected
!= selected
) {
121 this.selected
= selected
;
127 * The item mouse-hover state.
129 * @return TRUE if it is mouse-hovered
131 private boolean isHovered() {
136 * The item mouse-hover state.
139 * TRUE if it is mouse-hovered
141 private void setHovered(boolean hovered
) {
142 if (this.hovered
!= hovered
) {
143 this.hovered
= hovered
;
149 * Setup the mouse listener that will activate {@link BookActionListener}
152 private void setupListeners() {
153 listeners
= new ArrayList
<GuiReaderBook
.BookActionListener
>();
154 addMouseListener(new MouseListener() {
156 public void mouseReleased(MouseEvent e
) {
157 if (e
.isPopupTrigger()) {
163 public void mousePressed(MouseEvent e
) {
164 if (e
.isPopupTrigger()) {
170 public void mouseExited(MouseEvent e
) {
175 public void mouseEntered(MouseEvent e
) {
180 public void mouseClicked(MouseEvent e
) {
182 Date now
= new Date();
183 if (lastClick
!= null
184 && now
.getTime() - lastClick
.getTime() < doubleClickDelay
) {
194 private void click(boolean doubleClick
) {
195 for (BookActionListener listener
: listeners
) {
197 listener
.action(GuiReaderBook
.this);
199 listener
.select(GuiReaderBook
.this);
204 private void popup(MouseEvent e
) {
205 for (BookActionListener listener
: listeners
) {
206 listener
.select((GuiReaderBook
.this));
207 listener
.popupRequested(GuiReaderBook
.this, e
);
214 * Add a new {@link BookActionListener} on this item.
219 public void addActionListener(BookActionListener listener
) {
220 listeners
.add(listener
);
224 * The information about the book represented by this item.
228 public GuiReaderBookInfo
getInfo() {
233 * This item {@link GuiReader} library cache state.
235 * @return TRUE if it is present in the {@link GuiReader} cache
237 public boolean isCached() {
242 * This item {@link GuiReader} library cache state.
245 * TRUE if it is present in the {@link GuiReader} cache
247 public void setCached(boolean cached
) {
248 if (this.cached
!= cached
) {
249 this.cached
= cached
;
255 * Update the title, paint the item, then call
256 * {@link GuiReaderCoverImager#paintOverlay(Graphics, boolean, boolean, boolean, boolean)}
260 public void paint(Graphics g
) {
263 GuiReaderCoverImager
.paintOverlay(g
, isEnabled(), isSelected(),
264 isHovered(), isCached());
268 * Update the title with the currently registered information.
270 private void updateTitle() {
271 String optSecondary
= info
.getSecondaryInfo(seeWordCount
);
274 + "<body style='width: %d px; height: %d px; text-align: center'>"
275 + "%s" + "<br>" + "<span style='color: %s;'>" + "%s"
276 + "</span>" + "</body>" + "</html>",
277 GuiReaderCoverImager
.TEXT_WIDTH
,
278 GuiReaderCoverImager
.TEXT_HEIGHT
, info
.getMainInfo(),
279 AUTHOR_COLOR
, optSecondary
));