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
, generateCellRenderer());
57 tree
.setCellRenderer(spanner
);
58 tree
.setRootVisible(false);
59 tree
.setShowsRootHandles(false);
61 tree
.addTreeSelectionListener(new TreeSelectionListener() {
63 public void valueChanged(TreeSelectionEvent e
) {
64 List
<String
> elements
= new ArrayList
<String
>();
65 TreePath
[] paths
= tree
.getSelectionPaths();
67 for (TreePath path
: paths
) {
68 String key
= path
.getLastPathComponent().toString();
69 elements
.add(keyToElement(key
));
73 List
<String
> selectedElements
= new ArrayList
<String
>();
74 for (String element
: elements
) {
75 if (!selectedElements
.contains(element
)) {
76 selectedElements
.add(element
);
80 BasicTab
.this.selectedElements
= selectedElements
;
82 fireActionPerformed(BasicTab
.this.listenerCommand
);
86 add(UiHelper
.scroll(tree
), BorderLayout
.CENTER
);
88 searchBar
= new SearchBar();
89 add(searchBar
, BorderLayout
.NORTH
);
90 searchBar
.addActionListener(new ActionListener() {
92 public void actionPerformed(ActionEvent e
) {
100 public void reloadData() {
101 final TreeSnapshot snapshot
= new TreeSnapshot(tree
) {
103 protected boolean isSamePath(TreePath oldPath
, TreePath newPath
) {
104 String oldString
= oldPath
.toString();
105 if (oldString
.endsWith("/]"))
106 oldString
= oldString
.substring(0, oldString
.length() - 2) + "]";
108 String newString
= newPath
.toString();
109 if (newString
.endsWith("/]"))
110 newString
= newString
.substring(0, newString
.length() - 2) + "]";
112 return oldString
.equals(newString
);
115 SwingWorker
<Map
<String
, List
<String
>>, Integer
> worker
= new SwingWorker
<Map
<String
, List
<String
>>, Integer
>() {
117 protected Map
<String
, List
<String
>> doInBackground() throws Exception
{
123 protected void done() {
126 } catch (Exception e
) {
130 root
.removeAllChildren();
131 totalCount
= loadData(root
, data
, searchBar
.getText());
132 ((DefaultTreeModel
) tree
.getModel()).reload();
136 fireActionPerformed(listenerCommand
);
143 * The currently selected elements, or an empty list.
145 * @return the sources (cannot be NULL)
147 public List
<String
> getSelectedElements() {
148 return selectedElements
;
151 public int getTotalCount() {
155 public String
getBaseTitle() {
159 public void setBaseTitle(String baseTitle
) {
160 this.baseTitle
= baseTitle
;
163 public String
getTitle() {
164 String title
= getBaseTitle();
166 if (totalCount
> 0) {
167 int selected
= selectedElements
.size();
168 count
= " (" + (selected
> 0 ? selected
+ "/" : "") + totalCount
+ ")";
171 return title
+ count
;
174 public int getIndex() {
178 public void unselect() {
179 tree
.clearSelection();
182 protected boolean checkFilter(String filter
, String value
) {
183 return (filter
== null || filter
.isEmpty() || value
.toLowerCase().contains(filter
.toLowerCase()));
186 protected boolean checkFilter(String filter
, List
<String
> list
) {
187 for (String value
: list
) {
188 if (checkFilter(filter
, value
))
194 protected abstract T
createEmptyData();
196 protected abstract void fillData(T data
);
198 protected abstract String
keyToElement(String key
);
200 protected abstract String
keyToDisplay(String key
);
202 protected abstract int loadData(DefaultMutableTreeNode root
, T data
, String filter
);
204 private TreeCellRenderer
generateCellRenderer() {
205 DefaultTreeCellRenderer renderer
= new DefaultTreeCellRenderer() {
207 public Component
getTreeCellRendererComponent(JTree tree
, Object value
, boolean selected
, boolean expanded
,
208 boolean leaf
, int row
, boolean hasFocus
) {
209 if (value
instanceof DefaultMutableTreeNode
) {
210 if (((DefaultMutableTreeNode
) value
).getLevel() > 1) {
212 setLeafIcon(IconGenerator
.get(Icon
.empty
, Size
.x4
));
214 setLeafIcon(IconGenerator
.get(Icon
.empty
, Size
.x16
));
218 String display
= value
== null ?
"" : value
.toString();
219 display
= keyToDisplay(display
);
221 return super.getTreeCellRendererComponent(tree
, display
, selected
, expanded
, leaf
, row
, hasFocus
);
225 renderer
.setClosedIcon(IconGenerator
.get(Icon
.arrow_right
, Size
.x16
));
226 renderer
.setOpenIcon(IconGenerator
.get(Icon
.arrow_down
, Size
.x16
));
227 renderer
.setLeafIcon(IconGenerator
.get(Icon
.empty
, Size
.x16
));