001: /*
002: * (C) Copyright IBM Corp. 1998-2005. All Rights Reserved.
003: *
004: * The program is provided "as is" without any warranty express or
005: * implied, including the warranty of non-infringement and the implied
006: * warranties of merchantibility and fitness for a particular purpose.
007: * IBM will not be liable for any damages suffered by you as a result
008: * of using the Program. In no event will IBM be liable for any
009: * special, indirect or consequential damages or lost profits even if
010: * IBM has been advised of the possibility of their occurrence. IBM
011: * will not be liable for any third party claims against you.
012: */
013: package com.ibm.richtext.swingui;
014:
015: import java.util.Hashtable;
016:
017: import javax.swing.Box;
018: import javax.swing.BorderFactory;
019: import javax.swing.BoxLayout;
020: import javax.swing.JDialog;
021: import javax.swing.JPanel;
022: import javax.swing.JScrollPane;
023: import javax.swing.JButton;
024: import javax.swing.JList;
025: import javax.swing.JLabel;
026: import javax.swing.ListSelectionModel;
027:
028: import javax.swing.event.ListSelectionEvent;
029: import javax.swing.event.ListSelectionListener;
030:
031: import java.awt.BorderLayout;
032: import java.awt.Container;
033: import java.awt.Dimension;
034: import java.awt.Frame;
035: import java.awt.FlowLayout;
036:
037: import java.awt.event.ActionEvent;
038: import java.awt.event.ActionListener;
039: import java.awt.event.MouseEvent;
040: import java.awt.event.MouseAdapter;
041: import java.awt.event.WindowEvent;
042: import java.awt.event.WindowAdapter;
043:
044: import com.ibm.richtext.textlayout.attributes.AttributeSet;
045: import com.ibm.richtext.styledtext.MConstText;
046: import com.ibm.richtext.styledtext.StyleModifier;
047: import com.ibm.richtext.textpanel.MTextPanel;
048: import com.ibm.richtext.uiimpl.MenuItemSet;
049:
050: import com.ibm.richtext.uiimpl.resources.FrameResources;
051: import com.ibm.richtext.uiimpl.ResourceUtils;
052:
053: /**
054: * Simple dialog that sets an attribute.
055: */
056: final class JObjectDialog extends JDialog {
057:
058: static final String COPYRIGHT = "(C) Copyright IBM Corp. 1998-1999 - All Rights Reserved";
059:
060: private final MTextPanel fTextPanel;
061: private final Object fKey;
062: private boolean fCharacter;
063: private Hashtable fNameToValueMap;
064:
065: private final JButton fOKButton;
066: private final JButton fCancelButton;
067: private final JList fItems;
068:
069: /**
070: * Construct a new JObjectDialog.
071: * @param parent the dialog's parent frame
072: * @param title the dialogs title
073: * @param message the message displayed next to the input box
074: */
075: JObjectDialog(Frame parent, String title, String message,
076: MTextPanel textPanel, Object key, boolean character,
077: String[] names, Object[] values) {
078:
079: super (parent, title, false);
080:
081: setupMap(names, values);
082:
083: Dimension size = new Dimension(250, 200);
084:
085: fTextPanel = textPanel;
086: fKey = key;
087: fCharacter = character;
088:
089: fItems = new JList(names);
090: fItems
091: .setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
092:
093: fItems.addMouseListener(new MouseAdapter() {
094: public void mouseClicked(MouseEvent e) {
095: if (e.getClickCount() == 2) {
096: closeWindow(true);
097: }
098: }
099: });
100:
101: JScrollPane listScroller = new JScrollPane(fItems);
102: listScroller.setPreferredSize(size);
103: listScroller.setPreferredSize(size);
104: listScroller.setAlignmentX(LEFT_ALIGNMENT);
105:
106: JLabel label = new JLabel(message);
107: label.setLabelFor(fItems);
108:
109: JPanel itemPanel = new JPanel();
110: itemPanel.add(label);
111: itemPanel.add(Box.createRigidArea(new Dimension(0, 5)));
112: itemPanel.add(listScroller);
113: itemPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10,
114: 10));
115:
116: itemPanel.setLayout(new BoxLayout(itemPanel, BoxLayout.Y_AXIS));
117:
118: fCancelButton = new JButton(ResourceUtils
119: .getResourceString(FrameResources.CANCEL));
120: fOKButton = new JButton(ResourceUtils
121: .getResourceString(FrameResources.OK));
122:
123: JPanel buttonPanel = new JPanel();
124: buttonPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 5, 5));
125: buttonPanel.add(fCancelButton);
126: buttonPanel.add(fOKButton);
127:
128: Container content = getContentPane();
129: content.add(itemPanel, BorderLayout.CENTER);
130: content.add(buttonPanel, BorderLayout.SOUTH);
131:
132: pack();
133:
134: addWindowListener(new WindowAdapter() {
135: public void windowClosing(WindowEvent e) {
136: closeWindow(false);
137: }
138: });
139:
140: ActionListener listener = new ActionListener() {
141: public void actionPerformed(ActionEvent e) {
142:
143: Object source = e.getSource();
144: if (source == fOKButton) {
145: closeWindow(true);
146: } else if (source == fCancelButton) {
147: closeWindow(false);
148: }
149: }
150: };
151:
152: fOKButton.addActionListener(listener);
153: fCancelButton.addActionListener(listener);
154:
155: selectStyles(values);
156: }
157:
158: private void setupMap(String[] names, Object[] values) {
159:
160: if (names.length != values.length) {
161: throw new IllegalArgumentException(
162: "Must have same number of names and values.");
163: }
164:
165: fNameToValueMap = new Hashtable(names.length);
166:
167: for (int i = 0; i < names.length; i++) {
168: if (values[i] != null) {
169: fNameToValueMap.put(names[i], values[i]);
170: }
171: }
172:
173: }
174:
175: private void closeWindow(boolean sendAction) {
176:
177: setVisible(false);
178:
179: if (sendAction
180: && fItems.getMinSelectionIndex() != fItems
181: .getMaxSelectionIndex()) {
182: sendAction = false;
183: }
184:
185: if (sendAction) {
186: Object value = fNameToValueMap.get(fItems
187: .getSelectedValue());
188: sendAction(value);
189: }
190: dispose();
191: }
192:
193: /**
194: * Handle the user input
195: * @param value The value object
196: */
197: private void sendAction(Object value) {
198:
199: StyleModifier modifier;
200: if (value != null) {
201: modifier = StyleModifier.createAddModifier(fKey, value);
202: } else {
203: AttributeSet set = new AttributeSet(fKey);
204: modifier = StyleModifier.createRemoveModifier(set);
205: }
206:
207: if (fCharacter == MenuItemSet.CHARACTER) {
208: fTextPanel.modifyCharacterStyleOnSelection(modifier);
209: } else {
210: fTextPanel.modifyParagraphStyleOnSelection(modifier);
211: }
212: }
213:
214: private void selectValue(Object value, Object[] values) {
215:
216: for (int i = 0; i < values.length; i++) {
217:
218: if ((value != null && value.equals(values[i]))
219: || (value == null && values[i] == null)) {
220: fItems.addSelectionInterval(i, i);
221: fItems.ensureIndexIsVisible(i);
222: return;
223: }
224: }
225: }
226:
227: private void selectStyles(Object[] values) {
228:
229: Object value;
230:
231: if (fCharacter) {
232: value = fTextPanel.getCharacterStyleOverSelection(fKey);
233: } else {
234: value = fTextPanel.getParagraphStyleOverSelection(fKey);
235: }
236:
237: if (value != MTextPanel.MULTIPLE_VALUES) {
238: selectValue(value, values);
239: } else {
240: fOKButton.setEnabled(false);
241:
242: int selLimit = fTextPanel.getSelectionEnd();
243: MConstText text = fTextPanel.getText();
244: for (int runStart = fTextPanel.getSelectionStart(); runStart <= selLimit; runStart = fCharacter ? text
245: .characterStyleLimit(runStart)
246: : text.paragraphLimit(runStart)) {
247:
248: Object runVal;
249: if (fCharacter) {
250: runVal = text.characterStyleAt(runStart).get(fKey);
251: } else {
252: runVal = text.paragraphStyleAt(runStart).get(fKey);
253: }
254: if (runVal == null) {
255: runVal = fTextPanel.getDefaultValues().get(fKey);
256: }
257:
258: selectValue(runVal, values);
259: if (runStart == text.length()) {
260: break;
261: }
262: }
263: }
264:
265: fItems.addListSelectionListener(new ListSelectionListener() {
266: public void valueChanged(ListSelectionEvent e) {
267: fItems
268: .setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
269: fOKButton.setEnabled(true);
270: fItems.removeListSelectionListener(this);
271: }
272: });
273: }
274: }
|