source: josm/trunk/src/org/openstreetmap/josm/gui/ExtendedDialog.java@ 1789

Last change on this file since 1789 was 1661, checked in by stoecker, 15 years ago

minor fix to dialog - patch by xeen

File size: 6.8 KB
Line 
1package org.openstreetmap.josm.gui;
2
3import java.awt.Component;
4import java.awt.Dimension;
5import java.awt.event.ActionEvent;
6import java.awt.GridBagLayout;
7import java.awt.Toolkit;
8import java.util.ArrayList;
9
10import javax.swing.AbstractAction;
11import javax.swing.Action;
12import javax.swing.JButton;
13import javax.swing.JComponent;
14import javax.swing.JDialog;
15import javax.swing.JOptionPane;
16import javax.swing.JPanel;
17import javax.swing.JScrollBar;
18import javax.swing.JScrollPane;
19import javax.swing.KeyStroke;
20
21import org.openstreetmap.josm.gui.JMultilineLabel;
22import org.openstreetmap.josm.tools.GBC;
23import org.openstreetmap.josm.tools.ImageProvider;
24
25
26public class ExtendedDialog extends JDialog {
27 private int result = 0;
28 private Component parent;
29 private final String[] bTexts;
30
31 // For easy access when inherited
32 protected Object contentConstraints = GBC.eol().anchor(GBC.CENTER).fill(GBC.HORIZONTAL).insets(5,10,5,0);
33 protected ArrayList<JButton> buttons = new ArrayList<JButton>();
34
35 /**
36 * Sets up the dialog. The first button is always the default.
37 * @param parent The parent element that will be used for position and maximum size
38 * @param title The text that will be shown in the window titlebar
39 * @param content Any component that should be show above the buttons (e.g. JLabel)
40 * @param buttonTexts The labels that will be displayed on the buttons
41 * @param buttonIcons The path to the icons that will be displayed on the buttons. Path is relative to JOSM's image directory. File extensions need to be included. If a button should not have an icon pass null.
42 */
43 public ExtendedDialog(Component parent, String title, Component content, String[] buttonTexts, String[] buttonIcons) {
44 super(JOptionPane.getFrameForComponent(parent), title, true);
45 this.parent = parent;
46 bTexts = buttonTexts;
47 setupDialog(content, buttonIcons);
48 setVisible(true);
49 }
50
51 public ExtendedDialog(Component parent, String title, Component content, String[] buttonTexts) {
52 this(parent, title, content, buttonTexts, null);
53 }
54
55 /**
56 * Sets up the dialog and displays the given message in a breakable label
57 */
58 public ExtendedDialog(Component parent, String title, String message, String[] buttonTexts, String[] buttonIcons) {
59 super(JOptionPane.getFrameForComponent(parent), title, true);
60
61 JMultilineLabel lbl = new JMultilineLabel(message);
62 // Make it not wider than 2/3 of the screen
63 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
64 lbl.setMaxWidth(Math.round(screenSize.width*2/3));
65
66 bTexts = buttonTexts;
67 setupDialog(lbl, buttonIcons);
68 setVisible(true);
69 }
70
71 public ExtendedDialog(Component parent, String title, String message, String[] buttonTexts) {
72 this(parent, title, message, buttonTexts, null);
73 }
74
75 /**
76 * Constructor that doesn't make the dialog visible immediately. Intended for when inheriting.
77 */
78 public ExtendedDialog(Component parent, String title, String[] buttonTexts, boolean modal) {
79 super(JOptionPane.getFrameForComponent(parent), title, modal);
80 bTexts = buttonTexts;
81 }
82
83 protected void setupDialog(Component content, String[] buttonIcons) {
84 setupEscListener();
85
86 JButton button;
87 JPanel buttonsPanel = new JPanel(new GridBagLayout());
88
89 for(int i=0; i < bTexts.length; i++) {
90 Action action = new AbstractAction(bTexts[i]) {
91 public void actionPerformed(ActionEvent evt) {
92 buttonAction(evt);
93 }
94 };
95
96 button = new JButton(action);
97 if(buttonIcons != null && buttonIcons[i] != null)
98 button.setIcon(ImageProvider.get(buttonIcons[i]));
99
100 if(i == 0) rootPane.setDefaultButton(button);
101 buttonsPanel.add(button, GBC.std().insets(2,2,2,2));
102 buttons.add(button);
103 }
104
105 JPanel cp = new JPanel(new GridBagLayout());
106 cp.add(content, contentConstraints);
107 cp.add(buttonsPanel, GBC.eol().anchor(GBC.CENTER).insets(5,5,5,5));
108
109 JScrollPane pane = new JScrollPane(cp);
110 pane.setBorder(null);
111 setContentPane(pane);
112
113 pack();
114
115 // Try to make it not larger than the parent window or at least not larger than 2/3 of the screen
116 Dimension d = getSize();
117 Dimension x = findMaxDialogSize();
118
119 boolean limitedInWidth = d.width > x.width;
120 boolean limitedInHeight = d.height > x.height;
121
122 if(x.width > 0 && d.width > x.width) d.width = x.width;
123 if(x.height > 0 && d.height > x.height) d.height = x.height;
124
125 // We have a vertical scrollbar and enough space to prevent a horizontal one
126 if(!limitedInWidth && limitedInHeight)
127 d.width += new JScrollBar().getPreferredSize().width;
128
129 setSize(d);
130 setLocationRelativeTo(parent);
131 }
132
133 /**
134 * @return int The selected button. The count starts with 1.
135 * A return value of 0 means the dialog has been closed otherwise.
136 */
137 public int getValue() {
138 return result;
139 }
140
141 /**
142 * This gets performed whenever a button is clicked or activated
143 * @param evt the button event
144 */
145 protected void buttonAction(ActionEvent evt) {
146 String a = evt.getActionCommand();
147 for(int i=0; i < bTexts.length; i++)
148 if(bTexts[i].equals(a)) {
149 result = i+1;
150 break;
151 }
152
153 setVisible(false);
154 }
155
156 /**
157 * Tries to find a good value of how large the dialog should be
158 * @return Dimension Size of the parent Component or 2/3 of screen size if not available
159 */
160 protected Dimension findMaxDialogSize() {
161 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
162 Dimension x = new Dimension(Math.round(screenSize.width*2/3),
163 Math.round(screenSize.height*2/3));
164 try {
165 if(parent != null)
166 x = JOptionPane.getFrameForComponent(parent).getSize();
167 } catch(NullPointerException e) { }
168 return x;
169 }
170
171 /**
172 * Makes the dialog listen to ESC keypressed
173 */
174 private void setupEscListener() {
175 Action actionListener = new AbstractAction() {
176 public void actionPerformed(ActionEvent actionEvent) {
177 // 0 means that the dialog has been closed otherwise.
178 // We need to set it to zero again, in case the dialog has been re-used
179 // and the result differs from its default value
180 result = 0;
181 setVisible(false);
182 }
183 };
184
185 rootPane.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW)
186 .put(KeyStroke.getKeyStroke("ESCAPE"), "ESCAPE");
187 rootPane.getActionMap().put("ESCAPE", actionListener);
188 }
189}
Note: See TracBrowser for help on using the repository browser.