much quicker BooksPanel display, set max title size for BookBlocks
[fanfix.git] / src / be / nikiroo / fanfix_swing / gui / book / BookLine.java
1 package be.nikiroo.fanfix_swing.gui.book;
2
3 import java.awt.BorderLayout;
4 import java.awt.Color;
5 import java.awt.Graphics;
6
7 import javax.swing.JLabel;
8 import javax.swing.JPanel;
9 import javax.swing.SwingConstants;
10
11 import be.nikiroo.fanfix.data.Story;
12 import be.nikiroo.fanfix_swing.gui.BooksPanel;
13
14 /**
15 * A book item presented in a {@link BooksPanel}.
16 * <p>
17 * Can be a story, or a comic or... a group.
18 *
19 * @author niki
20 */
21 public class BookLine extends JPanel {
22 private static final long serialVersionUID = 1L;
23
24 private static final int MAX_DISPLAY_SIZE = 40;
25
26 /** Colour used for the seconday item (author/word count). */
27 protected static final Color AUTHOR_COLOR = new Color(128, 128, 128);
28
29 private boolean selected;
30 private boolean hovered;
31
32 private BookInfo info;
33 private boolean seeWordCount;
34
35 private JLabel title;
36 private JLabel secondary;
37 private JLabel iconCached;
38 private JLabel iconNotCached;
39
40 /**
41 * Create a new {@link BookLine} item for the given {@link Story}.
42 *
43 * @param info
44 * the information about the story to represent
45 * @param seeWordCount
46 * TRUE to see word counts, FALSE to see authors
47 */
48 public BookLine(BookInfo info, boolean seeWordCount) {
49 this.info = info;
50 this.seeWordCount = seeWordCount;
51
52 init();
53 }
54
55 /**
56 * Initialise this {@link BookLine}.
57 */
58 protected void init() {
59 iconCached = new JLabel(" ◉ ");
60 iconNotCached = new JLabel(" ○ ");
61
62 iconNotCached.setForeground(BookCoverImager.UNCACHED_ICON_COLOR);
63 iconCached.setForeground(BookCoverImager.UNCACHED_ICON_COLOR);
64 iconCached.setPreferredSize(iconNotCached.getPreferredSize());
65
66 title = new JLabel();
67 secondary = new JLabel();
68 secondary.setForeground(AUTHOR_COLOR);
69
70 String luid = null;
71 if (info.getMeta() != null) {
72 luid = info.getMeta().getLuid();
73 }
74 JLabel id = new JLabel(luid);
75 id.setPreferredSize(new JLabel(" 999 ").getPreferredSize());
76 id.setForeground(Color.gray);
77 id.setHorizontalAlignment(SwingConstants.CENTER);
78
79 JPanel idTitle = new JPanel(new BorderLayout());
80 idTitle.setOpaque(false);
81 idTitle.add(id, BorderLayout.WEST);
82 idTitle.add(title, BorderLayout.CENTER);
83
84 setLayout(new BorderLayout());
85 add(idTitle, BorderLayout.CENTER);
86 add(secondary, BorderLayout.EAST);
87
88 updateMeta();
89 }
90
91 /**
92 * The book current selection state.
93 *
94 * @return the selection state
95 */
96 public boolean isSelected() {
97 return selected;
98 }
99
100 /**
101 * The book current selection state,
102 *
103 * @param selected
104 * TRUE if it is selected
105 */
106 public void setSelected(boolean selected) {
107 if (this.selected != selected) {
108 this.selected = selected;
109 repaint();
110 }
111 }
112
113 /**
114 * The item mouse-hover state.
115 *
116 * @return TRUE if it is mouse-hovered
117 */
118 public boolean isHovered() {
119 return this.hovered;
120 }
121
122 /**
123 * The item mouse-hover state.
124 *
125 * @param hovered
126 * TRUE if it is mouse-hovered
127 */
128 public void setHovered(boolean hovered) {
129 if (this.hovered != hovered) {
130 this.hovered = hovered;
131 repaint();
132 }
133 }
134
135 /**
136 * The secondary value content: word count or author.
137 *
138 * @return TRUE to see word counts, FALSE to see authors
139 */
140 public boolean isSeeWordCount() {
141 return seeWordCount;
142 }
143
144 /**
145 * The secondary value content: word count or author.
146 *
147 * @param seeWordCount
148 * TRUE to see word counts, FALSE to see authors
149 */
150 public void setSeeWordCount(boolean seeWordCount) {
151 if (this.seeWordCount != seeWordCount) {
152 this.seeWordCount = seeWordCount;
153 repaint();
154 }
155 }
156
157 /**
158 * The information about the book represented by this item.
159 *
160 * @return the meta
161 */
162 public BookInfo getInfo() {
163 return info;
164 }
165
166 /**
167 * Update the title, paint the item.
168 */
169 @Override
170 public void paint(Graphics g) {
171 updateMeta();
172 super.paint(g);
173 }
174
175 /**
176 * Return a display-ready version of {@link BookInfo#getMainInfo()}.
177 *
178 * @return the main info in a ready-to-display version
179 */
180 protected String getMainInfoDisplay() {
181 return toDisplay(getInfo().getMainInfo());
182 }
183
184 /**
185 * Return a display-ready version of
186 * {@link BookInfo#getSecondaryInfo(boolean)}.
187 *
188 * @param seeCount
189 * TRUE for word/image/story count, FALSE for author name
190 *
191 * @return the main info in a ready-to-display version
192 */
193 protected String getSecondaryInfoDisplay(boolean seeCount) {
194 return toDisplay(getInfo().getSecondaryInfo(seeCount));
195 }
196
197 /**
198 * Update the title with the currently registered information.
199 */
200 protected void updateMeta() {
201 String main = getMainInfoDisplay();
202 String optSecondary = getSecondaryInfoDisplay(isSeeWordCount());
203
204 title.setText(main);
205 secondary.setText(optSecondary + " ");
206
207 setBackground(BookCoverImager.getBackground(isEnabled(), isSelected(),
208 isHovered()));
209
210 remove(iconCached);
211 remove(iconNotCached);
212 add(getInfo().isCached() ? iconCached : iconNotCached,
213 BorderLayout.WEST);
214 validate();
215 }
216
217 /**
218 * Make the given {@link String} display-ready (i.e., shorten it if it is
219 * too long).
220 *
221 * @param value
222 * the full value
223 *
224 * @return the display-ready value
225 */
226 private String toDisplay(String value) {
227 if (value == null)
228 value = "";
229
230 if (value.length() > MAX_DISPLAY_SIZE) {
231 value = value.substring(0, MAX_DISPLAY_SIZE - 3) + "...";
232 }
233
234 return value;
235 }
236 }