1 package be
.nikiroo
.fanfix_swing
.gui
.browser
;
3 import java
.awt
.BorderLayout
;
4 import java
.awt
.Component
;
5 import java
.awt
.event
.ActionEvent
;
6 import java
.awt
.event
.ActionListener
;
7 import java
.util
.ArrayList
;
11 import javax
.swing
.JTree
;
12 import javax
.swing
.SwingWorker
;
13 import javax
.swing
.event
.TreeSelectionEvent
;
14 import javax
.swing
.event
.TreeSelectionListener
;
15 import javax
.swing
.plaf
.basic
.BasicTreeUI
;
16 import javax
.swing
.tree
.DefaultMutableTreeNode
;
17 import javax
.swing
.tree
.DefaultTreeCellRenderer
;
18 import javax
.swing
.tree
.DefaultTreeModel
;
19 import javax
.swing
.tree
.TreeCellRenderer
;
20 import javax
.swing
.tree
.TreePath
;
22 import be
.nikiroo
.fanfix_swing
.gui
.SearchBar
;
23 import be
.nikiroo
.fanfix_swing
.gui
.utils
.ListenerPanel
;
24 import be
.nikiroo
.fanfix_swing
.gui
.utils
.TreeCellSpanner
;
25 import be
.nikiroo
.fanfix_swing
.gui
.utils
.TreeSnapshot
;
26 import be
.nikiroo
.fanfix_swing
.gui
.utils
.UiHelper
;
27 import be
.nikiroo
.fanfix_swing
.images
.IconGenerator
;
28 import be
.nikiroo
.fanfix_swing
.images
.IconGenerator
.Icon
;
29 import be
.nikiroo
.fanfix_swing
.images
.IconGenerator
.Size
;
31 public abstract class BasicTab
<T
> extends ListenerPanel
{
32 private int totalCount
= 0;
33 private List
<String
> selectedElements
= new ArrayList
<String
>();
35 private String baseTitle
;
36 private String listenerCommand
;
40 private DefaultMutableTreeNode root
;
41 private SearchBar searchBar
;
43 public BasicTab(int index
, String listenerCommand
) {
44 setLayout(new BorderLayout());
47 this.listenerCommand
= listenerCommand
;
49 data
= createEmptyData();
52 root
= new DefaultMutableTreeNode();
54 tree
= new JTree(root
);
55 tree
.setUI(new BasicTreeUI());
56 TreeCellSpanner spanner
= new TreeCellSpanner(tree
,
57 generateCellRenderer());
58 tree
.setCellRenderer(spanner
);
59 tree
.setRootVisible(false);
60 tree
.setShowsRootHandles(false);
62 tree
.addTreeSelectionListener(new TreeSelectionListener() {
64 public void valueChanged(TreeSelectionEvent e
) {
65 List
<String
> elements
= new ArrayList
<String
>();
66 TreePath
[] paths
= tree
.getSelectionPaths();
68 for (TreePath path
: paths
) {
69 String key
= path
.getLastPathComponent().toString();
70 elements
.add(keyToElement(key
));
74 List
<String
> selectedElements
= new ArrayList
<String
>();
75 for (String element
: elements
) {
76 if (!selectedElements
.contains(element
)) {
77 selectedElements
.add(element
);
81 BasicTab
.this.selectedElements
= selectedElements
;
83 fireActionPerformed(BasicTab
.this.listenerCommand
);
87 add(UiHelper
.scroll(tree
), BorderLayout
.CENTER
);
89 searchBar
= new SearchBar();
90 add(searchBar
, BorderLayout
.NORTH
);
91 searchBar
.addActionListener(new ActionListener() {
93 public void actionPerformed(ActionEvent e
) {
101 public void reloadData() {
102 final TreeSnapshot snapshot
= new TreeSnapshot(tree
) {
104 protected boolean isSamePath(TreePath oldPath
, TreePath newPath
) {
105 String oldString
= oldPath
.toString();
106 if (oldString
.endsWith("/]"))
107 oldString
= oldString
.substring(0, oldString
.length() - 2)
110 String newString
= newPath
.toString();
111 if (newString
.endsWith("/]"))
112 newString
= newString
.substring(0, newString
.length() - 2)
115 return oldString
.equals(newString
);
118 SwingWorker
<Map
<String
, List
<String
>>, Integer
> worker
= new SwingWorker
<Map
<String
, List
<String
>>, Integer
>() {
120 protected Map
<String
, List
<String
>> doInBackground()
127 protected void done() {
130 } catch (Exception e
) {
134 root
.removeAllChildren();
135 totalCount
= loadData(root
, data
, searchBar
.getText());
136 ((DefaultTreeModel
) tree
.getModel()).reload();
140 fireActionPerformed(listenerCommand
);
147 * The currently selected elements, or an empty list.
149 * @return the sources (cannot be NULL)
151 public List
<String
> getSelectedElements() {
152 return selectedElements
;
155 public int getTotalCount() {
159 public String
getBaseTitle() {
163 public void setBaseTitle(String baseTitle
) {
164 this.baseTitle
= baseTitle
;
167 public String
getTitle() {
168 String title
= getBaseTitle();
170 if (totalCount
> 0) {
171 int selected
= selectedElements
.size();
172 count
= " (" + (selected
> 0 ? selected
+ "/" : "") + totalCount
176 return title
+ count
;
179 public int getIndex() {
183 public void unselect() {
184 tree
.clearSelection();
187 protected boolean checkFilter(String filter
, String value
) {
188 return (filter
== null || filter
.isEmpty()
189 || value
.toLowerCase().contains(filter
.toLowerCase()));
192 protected boolean checkFilter(String filter
, List
<String
> list
) {
193 for (String value
: list
) {
194 if (checkFilter(filter
, value
))
200 protected abstract T
createEmptyData();
202 protected abstract void fillData(T data
);
204 protected abstract String
keyToElement(String key
);
206 protected abstract String
keyToDisplay(String key
);
208 protected abstract int loadData(DefaultMutableTreeNode root
, T data
,
211 private TreeCellRenderer
generateCellRenderer() {
212 DefaultTreeCellRenderer renderer
= new DefaultTreeCellRenderer() {
214 public Component
getTreeCellRendererComponent(JTree tree
,
215 Object value
, boolean selected
, boolean expanded
,
216 boolean leaf
, int row
, boolean hasFocus
) {
217 if (value
instanceof DefaultMutableTreeNode
) {
218 if (((DefaultMutableTreeNode
) value
).getLevel() > 1) {
220 setLeafIcon(IconGenerator
.get(Icon
.empty
, Size
.x4
));
222 setLeafIcon(IconGenerator
.get(Icon
.empty
, Size
.x16
));
226 String display
= value
== null ?
"" : value
.toString();
227 display
= keyToDisplay(display
);
229 return super.getTreeCellRendererComponent(tree
, display
,
230 selected
, expanded
, leaf
, row
, hasFocus
);
234 renderer
.setClosedIcon(IconGenerator
.get(Icon
.arrow_right
, Size
.x16
));
235 renderer
.setOpenIcon(IconGenerator
.get(Icon
.arrow_down
, Size
.x16
));
236 renderer
.setLeafIcon(IconGenerator
.get(Icon
.empty
, Size
.x16
));