3 import java.awt.BorderLayout;
4 import java.awt.Component;
5 import java.awt.Dimension;
7 import java.awt.GridLayout;
8 import java.awt.event.AdjustmentEvent;
9 import java.awt.event.AdjustmentListener;
11 import javax.swing.BorderFactory;
12 import javax.swing.Box;
13 import javax.swing.BoxLayout;
14 import javax.swing.JLabel;
15 import javax.swing.JList;
16 import javax.swing.JPanel;
17 import javax.swing.JScrollBar;
18 import javax.swing.JScrollPane;
19 import javax.swing.ListSelectionModel;
20 import javax.swing.border.EtchedBorder;
21 import javax.swing.event.ListSelectionEvent;
22 import javax.swing.event.ListSelectionListener;
24 import tim.prune.DataSubscriber;
25 import tim.prune.I18nManager;
26 import tim.prune.data.TrackInfo;
29 * Class to allow selection of points and photos
30 * as a visual component
32 public class SelectorDisplay extends GenericDisplay
35 private JLabel _trackpointsLabel = null;
36 private JLabel _filenameLabel = null;
38 private JScrollBar _scroller = null;
39 private boolean _ignoreScrollEvents = false;
41 // Panel containing lists
42 private JPanel _listsPanel = null;
43 private int _visiblePanels = 1;
45 private JPanel _waypointListPanel = null;
46 private JList<String> _waypointList = null;
47 private WaypointListModel _waypointListModel = null;
49 private JPanel _photoListPanel = null;
50 private JList<String> _photoList = null;
51 private MediaListModel _photoListModel = null;
53 private JPanel _audioListPanel = null;
54 private JList<String> _audioList = null;
55 private MediaListModel _audioListModel = null;
58 private static final int SCROLLBAR_INTERVAL = 50;
59 // number of rows in lists
60 private static final int NUM_LIST_ENTRIES = 7;
65 * @param inTrackInfo Track info object
67 public SelectorDisplay(TrackInfo inTrackInfo)
70 setLayout(new BorderLayout());
72 JPanel mainPanel = new JPanel();
73 mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS));
74 mainPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
76 // Track details panel
77 JPanel trackDetailsPanel = new JPanel();
78 trackDetailsPanel.setLayout(new BoxLayout(trackDetailsPanel, BoxLayout.Y_AXIS));
79 trackDetailsPanel.setBorder(BorderFactory.createCompoundBorder(
80 BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3))
82 JLabel trackDetailsLabel = new JLabel(I18nManager.getText("details.trackdetails"));
83 Font biggerFont = trackDetailsLabel.getFont();
84 biggerFont = biggerFont.deriveFont(Font.BOLD, biggerFont.getSize2D() + 2.0f);
85 trackDetailsLabel.setFont(biggerFont);
86 trackDetailsPanel.add(trackDetailsLabel);
87 _trackpointsLabel = new JLabel(I18nManager.getText("details.notrack"));
88 trackDetailsPanel.add(_trackpointsLabel);
89 _filenameLabel = new JLabel("");
90 _filenameLabel.setMinimumSize(new Dimension(120, 10));
91 trackDetailsPanel.add(_filenameLabel);
94 _scroller = new JScrollBar(JScrollBar.HORIZONTAL, 0, SCROLLBAR_INTERVAL, 0, 100);
95 _scroller.addAdjustmentListener(new AdjustmentListener() {
96 public void adjustmentValueChanged(AdjustmentEvent e) {
97 selectPoint(e.getValue());
100 _scroller.setEnabled(false);
102 // Add panel for waypoints / photos
103 _listsPanel = new JPanel();
104 _listsPanel.setLayout(new GridLayout(0, 1));
105 _listsPanel.setBorder(BorderFactory.createCompoundBorder(
106 BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), BorderFactory.createEmptyBorder(3, 3, 3, 3))
108 _waypointListModel = new WaypointListModel(_trackInfo.getTrack());
109 _waypointList = new JList<String>(_waypointListModel);
110 _waypointList.setVisibleRowCount(NUM_LIST_ENTRIES);
111 _waypointList.addListSelectionListener(new ListSelectionListener() {
112 public void valueChanged(ListSelectionEvent e)
114 if (!e.getValueIsAdjusting()) selectWaypoint(_waypointList.getSelectedIndex());
117 _waypointListPanel = makeListPanel("details.lists.waypoints", _waypointList);
118 _listsPanel.add(_waypointListPanel);
120 _photoListModel = new MediaListModel(_trackInfo.getPhotoList());
121 _photoList = new JList<String>(_photoListModel);
122 _photoList.setVisibleRowCount(NUM_LIST_ENTRIES);
123 _photoList.addListSelectionListener(new ListSelectionListener() {
124 public void valueChanged(ListSelectionEvent e)
126 if (!e.getValueIsAdjusting()) {
127 selectPhoto(_photoList.getSelectedIndex());
130 _photoListPanel = makeListPanel("details.lists.photos", _photoList);
131 // don't add photo list (because there aren't any photos yet)
133 // List for audio clips
134 _audioListModel = new MediaListModel(_trackInfo.getAudioList());
135 _audioList = new JList<String>(_audioListModel);
136 _audioList.addListSelectionListener(new ListSelectionListener() {
137 public void valueChanged(ListSelectionEvent e)
139 if (!e.getValueIsAdjusting()) {
140 selectAudio(_audioList.getSelectedIndex());
143 _audioListPanel = makeListPanel("details.lists.audio", _audioList);
144 // don't add audio list either
145 _listsPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
147 // add the controls to the main panel
148 mainPanel.add(trackDetailsPanel);
149 mainPanel.add(Box.createVerticalStrut(5));
150 mainPanel.add(_scroller);
151 mainPanel.add(Box.createVerticalStrut(5));
153 // add the main panel at the top
154 add(mainPanel, BorderLayout.NORTH);
155 // and lists in the centre
156 add(_listsPanel, BorderLayout.CENTER);
157 // set preferred width to be small
158 setPreferredSize(new Dimension(100, 100));
163 * Select the specified point
164 * @param inValue value to select
166 private void selectPoint(int inValue)
168 if (_track != null && !_ignoreScrollEvents) {
169 _trackInfo.selectPoint(inValue);
175 * Select the specified photo
176 * @param inPhotoIndex index of selected photo
178 private void selectPhoto(int inPhotoIndex)
180 _trackInfo.selectPhoto(inPhotoIndex);
184 * Select the specified audio clip
185 * @param inIndex index of selected audio clip
187 private void selectAudio(int inIndex)
189 _trackInfo.selectAudio(inIndex);
193 * Select the specified waypoint
194 * @param inWaypointIndex index of selected waypoint
196 private void selectWaypoint(int inWaypointIndex)
198 if (inWaypointIndex >= 0) {
199 _trackInfo.selectPoint(_waypointListModel.getWaypoint(inWaypointIndex));
205 * Notification that Track has been updated
207 public void dataUpdated(byte inUpdateType)
210 if (_track == null || _track.getNumPoints() <= 0)
212 _trackpointsLabel.setText(I18nManager.getText("details.notrack"));
213 _filenameLabel.setText("");
214 _filenameLabel.setToolTipText("");
218 _trackpointsLabel.setText(I18nManager.getText("details.track.points") + ": "
219 + _track.getNumPoints());
220 int numFiles = _trackInfo.getFileInfo().getNumFiles();
223 final String filenameString = _trackInfo.getFileInfo().getFilename();
224 _filenameLabel.setText(I18nManager.getText("details.track.file") + ": "
226 _filenameLabel.setToolTipText(filenameString);
228 else if (numFiles > 1)
230 final String labelText = I18nManager.getText("details.track.numfiles") + ": " + numFiles;
231 _filenameLabel.setText(labelText);
232 _filenameLabel.setToolTipText(labelText);
236 _filenameLabel.setText("");
237 _filenameLabel.setToolTipText("");
241 // Update scroller settings
242 int currentPointIndex = _trackInfo.getSelection().getCurrentPointIndex();
243 _ignoreScrollEvents = true;
244 if (_track == null || _track.getNumPoints() < 2)
246 // careful to avoid event loops here
247 // _scroller.setValue(0);
248 _scroller.setEnabled(false);
252 _scroller.setMaximum(_track.getNumPoints() -1 + SCROLLBAR_INTERVAL);
253 if (currentPointIndex >= 0)
254 _scroller.setValue(currentPointIndex);
255 _scroller.setEnabled(true);
257 _ignoreScrollEvents = false;
259 // update waypoints and photos if necessary
261 (DataSubscriber.DATA_ADDED_OR_REMOVED | DataSubscriber.DATA_EDITED | DataSubscriber.WAYPOINTS_MODIFIED)) > 0)
263 _waypointListModel.fireChanged();
266 (DataSubscriber.DATA_ADDED_OR_REMOVED | DataSubscriber.DATA_EDITED | DataSubscriber.PHOTOS_MODIFIED)) > 0)
268 _photoListModel.fireChanged();
269 _audioListModel.fireChanged();
271 // Deselect selected waypoint if selected point has since changed
272 if (_waypointList.getSelectedIndex() >= 0)
274 if (_trackInfo.getCurrentPoint() == null
275 || _waypointList.getSelectedIndex() >= _waypointListModel.getSize()
276 || !_waypointListModel.getWaypoint(_waypointList.getSelectedIndex()).equals(_trackInfo.getCurrentPoint()))
278 // point is selected in list but different from current point - deselect
279 _waypointList.clearSelection();
282 // Hide photo list if no photos loaded, same for audio
283 redrawLists(_photoListModel.getSize() > 0, _audioListModel.getSize() > 0);
285 // Make sure correct photo is selected
286 if (_photoListModel.getSize() > 0)
288 int photoIndex = _trackInfo.getSelection().getCurrentPhotoIndex();
289 int listSelection = _photoList.getSelectedIndex();
290 // Change listbox selection if indexes not equal
291 if (listSelection != photoIndex)
293 if (photoIndex < 0) {
294 _photoList.clearSelection();
297 _photoList.setSelectedIndex(photoIndex);
301 // Same for audio clips
302 if (_audioListModel.getSize() > 0)
304 int audioIndex = _trackInfo.getSelection().getCurrentAudioIndex();
305 int listSelection = _audioList.getSelectedIndex();
306 // Change listbox selection if indexes not equal
307 if (listSelection != audioIndex)
309 if (audioIndex < 0) {
310 _audioList.clearSelection();
313 _audioList.setSelectedIndex(audioIndex);
320 * Make one of the three list panels
321 * @param inNameKey key for heading text
322 * @param inList list object
323 * @return panel object
325 private static JPanel makeListPanel(String inNameKey, JList<String> inList)
327 JPanel panel = new JPanel();
328 panel.setLayout(new BorderLayout());
329 panel.add(new JLabel(I18nManager.getText(inNameKey)), BorderLayout.NORTH);
330 inList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
331 panel.add(new JScrollPane(inList), BorderLayout.CENTER);
336 * Redraw the list panels in the display according to which ones should be shown
337 * @param inShowPhotos true to show photo list
338 * @param inShowAudio true to show audio list
340 private void redrawLists(boolean inShowPhotos, boolean inShowAudio)
342 // exit if same as last time
343 int panels = 1 + (inShowPhotos?2:0) + (inShowAudio?4:0);
344 if (panels == _visiblePanels) return;
345 _visiblePanels = panels;
346 // remove all panels and re-add them
347 _listsPanel.removeAll();
348 _listsPanel.setLayout(new GridLayout(0, 1));
349 _listsPanel.add(_waypointListPanel);
351 _listsPanel.add(_photoListPanel);
354 _listsPanel.add(_audioListPanel);
356 _listsPanel.invalidate();
357 _listsPanel.getParent().validate();