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

Last change on this file since 3940 was 3940, checked in by bastiK, 13 years ago

fixed #6032 - Keystroke shift alt pressed A is already assigned to org.openstreetmap.josm.gui.dialogs.ToggleDialog$ToggleDialogAction

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