source: josm/trunk/src/org/openstreetmap/josm/gui/dialogs/MapPaintDialog.java@ 5538

Last change on this file since 5538 was 5538, checked in by bastiK, 12 years ago

move window switch listener to Main class, because it is needed in a plugin

  • Property svn:eol-style set to native
File size: 26.3 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.dialogs;
3
4import static org.openstreetmap.josm.tools.I18n.tr;
5import static org.openstreetmap.josm.tools.I18n.trn;
6
7import java.awt.Component;
8import java.awt.Dimension;
9import java.awt.Font;
10import java.awt.GridBagLayout;
11import java.awt.Insets;
12import java.awt.Point;
13import java.awt.Rectangle;
14import java.awt.Window;
15import java.awt.event.ActionEvent;
16import java.awt.event.ActionListener;
17import java.awt.event.KeyEvent;
18import java.awt.event.MouseEvent;
19import java.awt.event.WindowAdapter;
20import java.awt.event.WindowEvent;
21import java.io.BufferedInputStream;
22import java.io.BufferedOutputStream;
23import java.io.BufferedReader;
24import java.io.File;
25import java.io.FileOutputStream;
26import java.io.IOException;
27import java.io.InputStream;
28import java.io.InputStreamReader;
29import java.util.ArrayList;
30import java.util.Arrays;
31import java.util.List;
32
33import javax.swing.AbstractAction;
34import javax.swing.DefaultButtonModel;
35import javax.swing.DefaultListSelectionModel;
36import javax.swing.JCheckBox;
37import javax.swing.JFileChooser;
38import javax.swing.JLabel;
39import javax.swing.JPanel;
40import javax.swing.JPopupMenu;
41import javax.swing.JScrollPane;
42import javax.swing.JTabbedPane;
43import javax.swing.JTable;
44import javax.swing.JTextArea;
45import javax.swing.JViewport;
46import javax.swing.ListSelectionModel;
47import javax.swing.SingleSelectionModel;
48import javax.swing.SwingConstants;
49import javax.swing.SwingUtilities;
50import javax.swing.UIManager;
51import javax.swing.border.EmptyBorder;
52import javax.swing.event.ChangeEvent;
53import javax.swing.event.ChangeListener;
54import javax.swing.event.ListSelectionEvent;
55import javax.swing.event.ListSelectionListener;
56import javax.swing.table.AbstractTableModel;
57import javax.swing.table.DefaultTableCellRenderer;
58import javax.swing.table.TableCellRenderer;
59import javax.swing.table.TableModel;
60
61import org.openstreetmap.josm.Main;
62import org.openstreetmap.josm.gui.ExtendedDialog;
63import org.openstreetmap.josm.gui.PleaseWaitRunnable;
64import org.openstreetmap.josm.gui.SideButton;
65import org.openstreetmap.josm.gui.mappaint.MapPaintStyles;
66import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.MapPaintStyleLoader;
67import org.openstreetmap.josm.gui.mappaint.MapPaintStyles.MapPaintSylesUpdateListener;
68import org.openstreetmap.josm.gui.mappaint.StyleSource;
69import org.openstreetmap.josm.gui.preferences.PreferenceDialog;
70import org.openstreetmap.josm.gui.preferences.SourceEntry;
71import org.openstreetmap.josm.gui.widgets.HtmlPanel;
72import org.openstreetmap.josm.gui.widgets.JFileChooserManager;
73import org.openstreetmap.josm.gui.widgets.PopupMenuLauncher;
74import org.openstreetmap.josm.tools.GBC;
75import org.openstreetmap.josm.tools.ImageProvider;
76import org.openstreetmap.josm.tools.InputMapUtils;
77import org.openstreetmap.josm.tools.Shortcut;
78import org.openstreetmap.josm.tools.Utils;
79
80public class MapPaintDialog extends ToggleDialog implements Main.WindowSwitchListener {
81
82 protected StylesTable tblStyles;
83 protected StylesModel model;
84 protected DefaultListSelectionModel selectionModel;
85
86 protected OnOffAction onoffAction;
87 protected ReloadAction reloadAction;
88 protected MoveUpDownAction upAction;
89 protected MoveUpDownAction downAction;
90 protected JCheckBox cbWireframe;
91
92 public MapPaintDialog() {
93 super(tr("Map Paint Styles"), "mapstyle", tr("configure the map painting style"),
94 Shortcut.registerShortcut("subwindow:mappaint", tr("Toggle: {0}", tr("MapPaint")),
95 KeyEvent.VK_M, Shortcut.ALT_SHIFT), 150);
96 build();
97 }
98
99 protected void build() {
100 model = new StylesModel();
101
102 cbWireframe = new JCheckBox();
103 JLabel wfLabel = new JLabel(tr("Wireframe View"), ImageProvider.get("dialogs/mappaint", "wireframe_small"), JLabel.HORIZONTAL);
104 wfLabel.setFont(wfLabel.getFont().deriveFont(Font.PLAIN));
105
106 cbWireframe.setModel(new DefaultButtonModel() {
107 @Override
108 public void setSelected(boolean b) {
109 super.setSelected(b);
110 tblStyles.setEnabled(!b);
111 onoffAction.updateEnabledState();
112 upAction.updateEnabledState();
113 downAction.updateEnabledState();
114 }
115 });
116 cbWireframe.addActionListener(new ActionListener() {
117 public void actionPerformed(ActionEvent e) {
118 Main.main.menu.wireFrameToggleAction.actionPerformed(null);
119 }
120 });
121 cbWireframe.setBorder(new EmptyBorder(new Insets(1,1,1,1)));
122
123 tblStyles = new StylesTable(model);
124 tblStyles.setSelectionModel(selectionModel= new DefaultListSelectionModel());
125 tblStyles.addMouseListener(new PopupMenuHandler());
126 tblStyles.putClientProperty("terminateEditOnFocusLost", true);
127 tblStyles.setBackground(UIManager.getColor("Panel.background"));
128 tblStyles.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
129 tblStyles.setTableHeader(null);
130 tblStyles.getColumnModel().getColumn(0).setMaxWidth(1);
131 tblStyles.getColumnModel().getColumn(0).setResizable(false);
132 tblStyles.getColumnModel().getColumn(0).setCellRenderer(new MyCheckBoxRenderer());
133 tblStyles.getColumnModel().getColumn(1).setCellRenderer(new StyleSourceRenderer());
134 tblStyles.setShowGrid(false);
135 tblStyles.setIntercellSpacing(new Dimension(0, 0));
136
137 JPanel p = new JPanel(new GridBagLayout());
138 p.add(cbWireframe, GBC.std(0, 0));
139 p.add(wfLabel, GBC.std(1, 0).weight(1, 0));
140 p.add(tblStyles, GBC.std(0, 1).span(2).fill());
141
142 reloadAction = new ReloadAction();
143 onoffAction = new OnOffAction();
144 upAction = new MoveUpDownAction(false);
145 downAction = new MoveUpDownAction(true);
146 selectionModel.addListSelectionListener(onoffAction);
147 selectionModel.addListSelectionListener(reloadAction);
148 selectionModel.addListSelectionListener(upAction);
149 selectionModel.addListSelectionListener(downAction);
150
151 // Toggle style on Enter and Spacebar
152 InputMapUtils.addEnterAction(tblStyles, onoffAction);
153 InputMapUtils.addSpacebarAction(tblStyles, onoffAction);
154
155 createLayout(p, true, Arrays.asList(new SideButton[] {
156 new SideButton(onoffAction, false),
157 new SideButton(upAction, false),
158 new SideButton(downAction, false),
159 new SideButton(new LaunchMapPaintPreferencesAction(), false)
160 }));
161 }
162
163 protected static class StylesTable extends JTable {
164
165 public StylesTable(TableModel dm) {
166 super(dm);
167 }
168
169 public void scrollToVisible(int row, int col) {
170 if (!(getParent() instanceof JViewport))
171 return;
172 JViewport viewport = (JViewport) getParent();
173 Rectangle rect = getCellRect(row, col, true);
174 Point pt = viewport.getViewPosition();
175 rect.setLocation(rect.x - pt.x, rect.y - pt.y);
176 viewport.scrollRectToVisible(rect);
177 }
178 }
179
180 @Override
181 public void toOtherApplication() {
182 // nothing
183 }
184
185 @Override
186 public void fromOtherApplication() {
187 // Reload local styles when they have been changed in an external editor.
188 // Checks file modification time.
189 List<StyleSource> toReload = new ArrayList<StyleSource>();
190 for (StyleSource s : MapPaintStyles.getStyles().getStyleSources()) {
191 if (s.isLocal()) {
192 File f = new File(s.url);
193 long mtime = f.lastModified();
194 if (mtime > s.getLastMTime()) {
195 toReload.add(s);
196 s.setLastMTime(mtime);
197 }
198 }
199 }
200 if (!toReload.isEmpty()) {
201 System.out.println(trn("Reloading {0} map style.", "Reloading {0} map styles.", toReload.size(), toReload.size()));
202 Main.worker.submit(new MapPaintStyleLoader(toReload));
203 }
204 }
205
206 @Override
207 public void showNotify() {
208 MapPaintStyles.addMapPaintSylesUpdateListener(model);
209 Main.main.menu.wireFrameToggleAction.addButtonModel(cbWireframe.getModel());
210 if (Main.pref.getBoolean("mappaint.auto_reload_local_styles", true)) {
211 Main.addWindowSwitchListener(this);
212 }
213 }
214
215 @Override
216 public void hideNotify() {
217 Main.main.menu.wireFrameToggleAction.removeButtonModel(cbWireframe.getModel());
218 MapPaintStyles.removeMapPaintSylesUpdateListener(model);
219 if (Main.pref.getBoolean("mappaint.auto_reload_local_styles", true)) {
220 Main.removeWindowSwitchListener(this);
221 }
222 }
223
224 protected class StylesModel extends AbstractTableModel implements MapPaintSylesUpdateListener {
225
226 List<StyleSource> data = new ArrayList<StyleSource>();
227
228 public StylesModel() {
229 data = new ArrayList<StyleSource>(MapPaintStyles.getStyles().getStyleSources());
230 }
231
232 private StyleSource getRow(int i) {
233 return data.get(i);
234 }
235
236 @Override
237 public int getColumnCount() {
238 return 2;
239 }
240
241 @Override
242 public int getRowCount() {
243 return data.size();
244 }
245
246 @Override
247 public Object getValueAt(int row, int column) {
248 if (column == 0)
249 return getRow(row).active;
250 else
251 return getRow(row);
252 }
253
254 @Override
255 public boolean isCellEditable(int row, int column) {
256 return column == 0;
257 }
258
259 Class<?>[] columnClasses = {Boolean.class, StyleSource.class};
260
261 @Override
262 public Class<?> getColumnClass(int column) {
263 return columnClasses[column];
264 }
265
266 @Override
267 public void setValueAt(Object aValue, int row, int column) {
268 if (row < 0 || row >= getRowCount() || aValue == null)
269 return;
270 if (column == 0) {
271 MapPaintStyles.toggleStyleActive(row);
272 }
273 }
274
275 /**
276 * Make sure the first of the selected entry is visible in the
277 * views of this model.
278 */
279 public void ensureSelectedIsVisible() {
280 int index = selectionModel.getMinSelectionIndex();
281 if (index < 0) return;
282 if (index >= getRowCount()) return;
283 tblStyles.scrollToVisible(index, 0);
284 tblStyles.repaint();
285 }
286
287 /**
288 * MapPaintSylesUpdateListener interface
289 */
290
291 @Override
292 public void mapPaintStylesUpdated() {
293 data = new ArrayList<StyleSource>(MapPaintStyles.getStyles().getStyleSources());
294 fireTableDataChanged();
295 tblStyles.repaint();
296 }
297
298 @Override
299 public void mapPaintStyleEntryUpdated(int idx) {
300 data = new ArrayList<StyleSource>(MapPaintStyles.getStyles().getStyleSources());
301 fireTableRowsUpdated(idx, idx);
302 tblStyles.repaint();
303 }
304 }
305
306 private class MyCheckBoxRenderer extends JCheckBox implements TableCellRenderer {
307
308 public MyCheckBoxRenderer() {
309 setHorizontalAlignment(SwingConstants.CENTER);
310 setVerticalAlignment(SwingConstants.CENTER);
311 }
312
313 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,int row,int column) {
314 if (value == null)
315 return this;
316 boolean b = (Boolean) value;
317 setSelected(b);
318 setEnabled(!cbWireframe.isSelected());
319 return this;
320 }
321 }
322
323 private class StyleSourceRenderer extends DefaultTableCellRenderer {
324 @Override
325 public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
326 if (value == null)
327 return this;
328 StyleSource s = (StyleSource) value;
329 JLabel label = (JLabel)super.getTableCellRendererComponent(table,
330 s.getDisplayString(), isSelected, hasFocus, row, column);
331 label.setIcon(s.getIcon());
332 label.setToolTipText(s.getToolTipText());
333 label.setEnabled(!cbWireframe.isSelected());
334 return label;
335 }
336 }
337
338 protected class OnOffAction extends AbstractAction implements ListSelectionListener {
339 public OnOffAction() {
340 putValue(NAME, tr("On/Off"));
341 putValue(SHORT_DESCRIPTION, tr("Turn selected styles on or off"));
342 putValue(SMALL_ICON, ImageProvider.get("apply"));
343 updateEnabledState();
344 }
345
346 protected void updateEnabledState() {
347 setEnabled(!cbWireframe.isSelected() && tblStyles.getSelectedRowCount() > 0);
348 }
349
350 @Override
351 public void valueChanged(ListSelectionEvent e) {
352 updateEnabledState();
353 }
354
355 @Override
356 public void actionPerformed(ActionEvent e) {
357 int[] pos = tblStyles.getSelectedRows();
358 MapPaintStyles.toggleStyleActive(pos);
359 selectionModel.clearSelection();
360 for (int p: pos) {
361 selectionModel.addSelectionInterval(p, p);
362 }
363 }
364 }
365
366 /**
367 * The action to move down the currently selected entries in the list.
368 */
369 protected class MoveUpDownAction extends AbstractAction implements ListSelectionListener {
370
371 final int increment;
372
373 public MoveUpDownAction(boolean isDown) {
374 increment = isDown ? 1 : -1;
375 putValue(NAME, isDown?tr("Down"):tr("Up"));
376 putValue(SMALL_ICON, isDown ? ImageProvider.get("dialogs", "down") : ImageProvider.get("dialogs", "up"));
377 putValue(SHORT_DESCRIPTION, isDown ? tr("Move the selected entry one row down.") : tr("Move the selected entry one row up."));
378 updateEnabledState();
379 }
380
381 public void updateEnabledState() {
382 int[] sel = tblStyles.getSelectedRows();
383 setEnabled(!cbWireframe.isSelected() && MapPaintStyles.canMoveStyles(sel, increment));
384 }
385
386 @Override
387 public void actionPerformed(ActionEvent e) {
388 int[] sel = tblStyles.getSelectedRows();
389 MapPaintStyles.moveStyles(sel, increment);
390
391 selectionModel.clearSelection();
392 for (int row: sel) {
393 selectionModel.addSelectionInterval(row + increment, row + increment);
394 }
395 model.ensureSelectedIsVisible();
396 }
397
398 public void valueChanged(ListSelectionEvent e) {
399 updateEnabledState();
400 }
401 }
402
403 /**
404 * Opens preferences window and selects the mappaint tab.
405 */
406 public static class LaunchMapPaintPreferencesAction extends AbstractAction {
407 public LaunchMapPaintPreferencesAction() {
408 putValue(NAME, tr("Preferences"));
409 putValue(SMALL_ICON, ImageProvider.get("dialogs", "mappaintpreference"));
410 }
411
412 @Override
413 public void actionPerformed(ActionEvent e) {
414 final PreferenceDialog p =new PreferenceDialog(Main.parent);
415 p.selectMapPaintPreferenceTab();
416 p.setVisible(true);
417 }
418 }
419
420 protected class ReloadAction extends AbstractAction implements ListSelectionListener {
421 public ReloadAction() {
422 putValue(NAME, tr("Reload from file"));
423 putValue(SHORT_DESCRIPTION, tr("reload selected styles from file"));
424 putValue(SMALL_ICON, ImageProvider.get("dialogs", "refresh"));
425 setEnabled(getEnabledState());
426 }
427
428 protected boolean getEnabledState() {
429 if (cbWireframe.isSelected())
430 return false;
431 int[] pos = tblStyles.getSelectedRows();
432 if (pos.length == 0)
433 return false;
434 for (int i : pos) {
435 if (!model.getRow(i).isLocal())
436 return false;
437 }
438 return true;
439 }
440
441 @Override
442 public void valueChanged(ListSelectionEvent e) {
443 setEnabled(getEnabledState());
444 }
445
446 @Override
447 public void actionPerformed(ActionEvent e) {
448 final int[] rows = tblStyles.getSelectedRows();
449 MapPaintStyles.reloadStyles(rows);
450 Main.worker.submit(new Runnable() {
451 @Override
452 public void run() {
453 SwingUtilities.invokeLater(new Runnable() {
454 @Override
455 public void run() {
456 selectionModel.clearSelection();
457 for (int r: rows) {
458 selectionModel.addSelectionInterval(r, r);
459 }
460 }
461 });
462
463 }
464 });
465 }
466 }
467
468 protected class SaveAsAction extends AbstractAction {
469
470 public SaveAsAction() {
471 putValue(NAME, tr("Save as..."));
472 putValue(SHORT_DESCRIPTION, tr("Save a copy of this Style to file and add it to the list"));
473 putValue(SMALL_ICON, ImageProvider.get("copy"));
474 setEnabled(tblStyles.getSelectedRows().length == 1);
475 }
476
477 @Override
478 public void actionPerformed(ActionEvent e) {
479 int sel = tblStyles.getSelectionModel().getLeadSelectionIndex();
480 if (sel < 0 || sel >= model.getRowCount())
481 return;
482 final StyleSource s = model.getRow(sel);
483
484 JFileChooserManager fcm = new JFileChooserManager(false, "mappaint.clone-style.lastDirectory", System.getProperty("user.home"));
485 String suggestion = fcm.getInitialDirectory() + File.separator + s.getFileNamePart();
486 fcm.createFileChooser().getFileChooser().setSelectedFile(new File(suggestion));
487 JFileChooser fc = fcm.openFileChooser();
488 if (fc == null)
489 return;
490 Main.worker.submit(new SaveToFileTask(s, fc.getSelectedFile()));
491 }
492
493 private class SaveToFileTask extends PleaseWaitRunnable {
494 private StyleSource s;
495 private File file;
496
497 private boolean canceled;
498 private boolean error;
499
500 public SaveToFileTask(StyleSource s, File file) {
501 super(tr("Reloading style sources"));
502 this.s = s;
503 this.file = file;
504 }
505
506 @Override
507 protected void cancel() {
508 canceled = true;
509 }
510
511 @Override
512 protected void realRun() {
513 getProgressMonitor().indeterminateSubTask(
514 tr("Save style ''{0}'' as ''{1}''", s.getDisplayString(), file.getPath()));
515 BufferedInputStream bis = null;
516 BufferedOutputStream bos = null;
517 try {
518 bis = new BufferedInputStream(s.getSourceInputStream());
519 bos = new BufferedOutputStream(new FileOutputStream(file));
520 byte[] buffer = new byte[4096];
521 int length;
522 while ((length = bis.read(buffer)) > -1 && !canceled) {
523 bos.write(buffer, 0, length);
524 }
525 } catch (IOException e) {
526 error = true;
527 } finally {
528 Utils.close(bis);
529 Utils.close(bos);
530 }
531 }
532
533 @Override
534 protected void finish() {
535 SwingUtilities.invokeLater(new Runnable() {
536 @Override
537 public void run() {
538 if (!error && !canceled) {
539 SourceEntry se = new SourceEntry(s);
540 se.url = file.getPath();
541 MapPaintStyles.addStyle(se);
542 tblStyles.getSelectionModel().setSelectionInterval(model.getRowCount() - 1 , model.getRowCount() - 1);
543 model.ensureSelectedIsVisible();
544 }
545 }
546 });
547 }
548 }
549 }
550
551 protected class InfoAction extends AbstractAction {
552
553 boolean errorsTabLoaded;
554 boolean sourceTabLoaded;
555
556 public InfoAction() {
557 putValue(NAME, tr("Info"));
558 putValue(SHORT_DESCRIPTION, tr("view meta information, error log and source definition"));
559 putValue(SMALL_ICON, ImageProvider.get("info"));
560 setEnabled(tblStyles.getSelectedRows().length == 1);
561 }
562
563 @Override
564 public void actionPerformed(ActionEvent e) {
565 int sel = tblStyles.getSelectionModel().getLeadSelectionIndex();
566 if (sel < 0 || sel >= model.getRowCount())
567 return;
568 final StyleSource s = model.getRow(sel);
569 ExtendedDialog info = new ExtendedDialog(Main.parent, tr("Map Style info"), new String[] {tr("Close")});
570 info.setPreferredSize(new Dimension(600, 400));
571 info.setButtonIcons(new String[] {"ok.png"});
572
573 final JTabbedPane tabs = new JTabbedPane();
574
575 tabs.add("Info", buildInfoPanel(s));
576 JLabel lblInfo = new JLabel(tr("Info"));
577 lblInfo.setFont(lblInfo.getFont().deriveFont(Font.PLAIN));
578 tabs.setTabComponentAt(0, lblInfo);
579
580 final JPanel pErrors = new JPanel(new GridBagLayout());
581 tabs.add("Errors", pErrors);
582 JLabel lblErrors;
583 if (s.getErrors().isEmpty()) {
584 lblErrors = new JLabel(tr("Errors"));
585 lblErrors.setFont(lblInfo.getFont().deriveFont(Font.PLAIN));
586 lblErrors.setEnabled(false);
587 tabs.setTabComponentAt(1, lblErrors);
588 tabs.setEnabledAt(1, false);
589 } else {
590 lblErrors = new JLabel(tr("Errors"), ImageProvider.get("misc", "error"), JLabel.HORIZONTAL);
591 tabs.setTabComponentAt(1, lblErrors);
592 }
593
594 final JPanel pSource = new JPanel(new GridBagLayout());
595 tabs.addTab("Source", pSource);
596 JLabel lblSource = new JLabel(tr("Source"));
597 lblSource.setFont(lblSource.getFont().deriveFont(Font.PLAIN));
598 tabs.setTabComponentAt(2, lblSource);
599
600 tabs.getModel().addChangeListener(new ChangeListener() {
601 @Override
602 public void stateChanged(ChangeEvent e) {
603 if (!errorsTabLoaded && ((SingleSelectionModel) e.getSource()).getSelectedIndex() == 1) {
604 errorsTabLoaded = true;
605 buildErrorsPanel(s, pErrors);
606 }
607 if (!sourceTabLoaded && ((SingleSelectionModel) e.getSource()).getSelectedIndex() == 2) {
608 sourceTabLoaded = true;
609 buildSourcePanel(s, pSource);
610 }
611 }
612 });
613 info.setContent(tabs, false);
614 info.showDialog();
615 }
616
617 private JPanel buildInfoPanel(StyleSource s) {
618 JPanel p = new JPanel(new GridBagLayout());
619 StringBuilder text = new StringBuilder("<table cellpadding=3>");
620 text.append(tableRow(tr("Title:"), s.getDisplayString()));
621 if (s.url.startsWith("http://")) {
622 text.append(tableRow(tr("URL:"), s.url));
623 } else if (s.url.startsWith("resource://")) {
624 text.append(tableRow(tr("Built-in Style, internal path:"), s.url));
625 } else {
626 text.append(tableRow(tr("Path:"), s.url));
627 }
628 if (s.icon != null) {
629 text.append(tableRow(tr("Icon:"), s.icon));
630 }
631 if (s.getBackgroundColorOverride() != null) {
632 text.append(tableRow(tr("Background:"), Utils.toString(s.getBackgroundColorOverride())));
633 }
634 text.append(tableRow(tr("Style is currently active?"), s.active ? tr("Yes") : tr("No")));
635 text.append("</table>");
636 p.add(new JScrollPane(new HtmlPanel(text.toString())), GBC.eol().fill(GBC.BOTH));
637 return p;
638 }
639
640 private String tableRow(String firstColumn, String secondColumn) {
641 return "<tr><td><b>" + firstColumn + "</b></td><td>" + secondColumn + "</td></tr>";
642 }
643
644 private void buildSourcePanel(StyleSource s, JPanel p) {
645 JTextArea txtSource = new JTextArea();
646 txtSource.setFont(new Font("Monospaced", txtSource.getFont().getStyle(), txtSource.getFont().getSize()));
647 txtSource.setEditable(false);
648 p.add(new JScrollPane(txtSource), GBC.std().fill());
649
650 InputStream is = null;
651 try {
652 is = s.getSourceInputStream();
653 BufferedReader reader = new BufferedReader(new InputStreamReader(is));
654 String line;
655 while ((line = reader.readLine()) != null) {
656 txtSource.append(line + "\n");
657 }
658 } catch (IOException ex) {
659 txtSource.append("<ERROR: failed to read file!>");
660 } finally {
661 Utils.close(is);
662 }
663 }
664
665 private void buildErrorsPanel(StyleSource s, JPanel p) {
666 JTextArea txtErrors = new JTextArea();
667 txtErrors.setFont(new Font("Monospaced", txtErrors.getFont().getStyle(), txtErrors.getFont().getSize()));
668 txtErrors.setEditable(false);
669 p.add(new JScrollPane(txtErrors), GBC.std().fill());
670 for (Throwable t : s.getErrors()) {
671 txtErrors.append(t.toString() + "\n");
672 }
673 }
674 }
675
676 class PopupMenuHandler extends PopupMenuLauncher {
677 @Override
678 public void launch(MouseEvent evt) {
679 if (cbWireframe.isSelected())
680 return;
681 Point p = evt.getPoint();
682 int index = tblStyles.rowAtPoint(p);
683 if (index < 0) return;
684 if (!tblStyles.getCellRect(index, 1, false).contains(evt.getPoint()))
685 return;
686 if (!tblStyles.isRowSelected(index)) {
687 tblStyles.setRowSelectionInterval(index, index);
688 }
689 MapPaintPopup menu = new MapPaintPopup();
690 menu.show(tblStyles, p.x, p.y);
691 }
692 }
693
694 public class MapPaintPopup extends JPopupMenu {
695 public MapPaintPopup() {
696 add(reloadAction);
697 add(new SaveAsAction());
698 addSeparator();
699 add(new InfoAction());
700 }
701 }
702}
Note: See TracBrowser for help on using the repository browser.