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("");
217 _trackpointsLabel.setText(I18nManager.getText("details.track.points") + ": "
218 + _track.getNumPoints());
219 int numFiles = _trackInfo.getFileInfo().getNumFiles();
222 _filenameLabel.setText(I18nManager.getText("details.track.file") + ": "
223 + _trackInfo.getFileInfo().getFilename());
225 else if (numFiles > 1)
227 _filenameLabel.setText(I18nManager.getText("details.track.numfiles") + ": " + numFiles);
229 else _filenameLabel.setText("");
232 // Update scroller settings
233 int currentPointIndex = _trackInfo.getSelection().getCurrentPointIndex();
234 _ignoreScrollEvents = true;
235 if (_track == null || _track.getNumPoints() < 2)
237 // careful to avoid event loops here
238 // _scroller.setValue(0);
239 _scroller.setEnabled(false);
243 _scroller.setMaximum(_track.getNumPoints() -1 + SCROLLBAR_INTERVAL);
244 if (currentPointIndex >= 0)
245 _scroller.setValue(currentPointIndex);
246 _scroller.setEnabled(true);
248 _ignoreScrollEvents = false;
250 // update waypoints and photos if necessary
252 (DataSubscriber.DATA_ADDED_OR_REMOVED | DataSubscriber.DATA_EDITED | DataSubscriber.WAYPOINTS_MODIFIED)) > 0)
254 _waypointListModel.fireChanged();
257 (DataSubscriber.DATA_ADDED_OR_REMOVED | DataSubscriber.DATA_EDITED | DataSubscriber.PHOTOS_MODIFIED)) > 0)
259 _photoListModel.fireChanged();
260 _audioListModel.fireChanged();
262 // Deselect selected waypoint if selected point has since changed
263 if (_waypointList.getSelectedIndex() >= 0)
265 if (_trackInfo.getCurrentPoint() == null
266 || _waypointList.getSelectedIndex() >= _waypointListModel.getSize()
267 || !_waypointListModel.getWaypoint(_waypointList.getSelectedIndex()).equals(_trackInfo.getCurrentPoint()))
269 // point is selected in list but different from current point - deselect
270 _waypointList.clearSelection();
273 // Hide photo list if no photos loaded, same for audio
274 redrawLists(_photoListModel.getSize() > 0, _audioListModel.getSize() > 0);
276 // Make sure correct photo is selected
277 if (_photoListModel.getSize() > 0)
279 int photoIndex = _trackInfo.getSelection().getCurrentPhotoIndex();
280 int listSelection = _photoList.getSelectedIndex();
281 // Change listbox selection if indexes not equal
282 if (listSelection != photoIndex)
284 if (photoIndex < 0) {
285 _photoList.clearSelection();
288 _photoList.setSelectedIndex(photoIndex);
292 // Same for audio clips
293 if (_audioListModel.getSize() > 0)
295 int audioIndex = _trackInfo.getSelection().getCurrentAudioIndex();
296 int listSelection = _audioList.getSelectedIndex();
297 // Change listbox selection if indexes not equal
298 if (listSelection != audioIndex)
300 if (audioIndex < 0) {
301 _audioList.clearSelection();
304 _audioList.setSelectedIndex(audioIndex);
311 * Make one of the three list panels
312 * @param inNameKey key for heading text
313 * @param inList list object
314 * @return panel object
316 private static JPanel makeListPanel(String inNameKey, JList<String> inList)
318 JPanel panel = new JPanel();
319 panel.setLayout(new BorderLayout());
320 panel.add(new JLabel(I18nManager.getText(inNameKey)), BorderLayout.NORTH);
321 inList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
322 panel.add(new JScrollPane(inList), BorderLayout.CENTER);
327 * Redraw the list panels in the display according to which ones should be shown
328 * @param inShowPhotos true to show photo list
329 * @param inShowAudio true to show audio list
331 private void redrawLists(boolean inShowPhotos, boolean inShowAudio)
333 // exit if same as last time
334 int panels = 1 + (inShowPhotos?2:0) + (inShowAudio?4:0);
335 if (panels == _visiblePanels) return;
336 _visiblePanels = panels;
337 // remove all panels and re-add them
338 _listsPanel.removeAll();
339 _listsPanel.setLayout(new GridLayout(0, 1));
340 _listsPanel.add(_waypointListPanel);
342 _listsPanel.add(_photoListPanel);
345 _listsPanel.add(_audioListPanel);
347 _listsPanel.invalidate();
348 _listsPanel.getParent().validate();