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

Last change on this file since 7033 was 7033, checked in by Don-vip, 10 years ago

see #8465 - global use of try-with-resources, according to

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