001: package com.xoetrope.carousel.langed;
002:
003: import com.xoetrope.carousel.build.BuildProperties;
004: import java.awt.BasicStroke;
005: import java.awt.Color;
006: import java.awt.Component;
007: import java.awt.Graphics;
008: import java.awt.Graphics2D;
009: import java.awt.Point;
010: import java.awt.Rectangle;
011: import java.awt.RenderingHints;
012: import java.awt.Window;
013: import java.awt.event.ActionEvent;
014: import java.awt.event.ActionListener;
015: import java.awt.event.ComponentAdapter;
016: import java.awt.event.ComponentEvent;
017: import java.awt.event.MouseEvent;
018: import java.awt.event.MouseListener;
019: import java.awt.event.WindowEvent;
020: import java.awt.event.WindowListener;
021: import java.lang.reflect.Method;
022: import javax.swing.ButtonGroup;
023: import javax.swing.JComboBox;
024: import javax.swing.JFrame;
025: import javax.swing.JLayeredPane;
026: import javax.swing.JPanel;
027: import javax.swing.JTabbedPane;
028: import javax.swing.SwingUtilities;
029: import javax.swing.plaf.TabbedPaneUI;
030: import net.xoetrope.editor.project.XEditorProject;
031: import net.xoetrope.swing.XApplet;
032: import net.xoetrope.swing.XLabel;
033: import net.xoetrope.swing.XPanel;
034: import net.xoetrope.swing.XRadioButton;
035:
036: /**
037: * <p> Copyright (c) Xoetrope Ltd., 2001-2006, This software is licensed under
038: * the GNU Public License (GPL), please see license.txt for more details. If
039: * you make commercial use of this software you must purchase a commercial
040: * license from Xoetrope.</p>
041: */
042: public class TranslationPane extends JPanel implements MouseListener,
043: ActionListener, WindowListener {
044: private XApplet applet;
045: private JFrame frame, optionFrame;
046: private XEditorProject editorProject;
047: private JLayeredPane layerPane;
048: private TranslationPopUp transPopUp;
049: private Component selected, contentPane;
050: private Rectangle selBounds;
051: private String text;
052: private EdLangMgr langMgr;
053: private EdLanguage currentLang, transLang;
054: private XRadioButton onBtn, offBtn;
055: private JComboBox currentSelect, transSelect;
056: private boolean popUpVisible = false, blockListener = false;
057:
058: /**
059: * Constructor which creates a new instance of the translation pane
060: * and adds it to the project frame.
061: */
062: public TranslationPane(XEditorProject p) {
063: editorProject = p;
064: applet = (XApplet) editorProject.getApplet();
065:
066: /*
067: * Switch off the focus traversal policy for the Applet. Stack overflow
068: * exceptions are thrown if the applet is launched with this set to true.
069: */
070: applet.setFocusTraversalPolicyProvider(false);
071:
072: setLayout(null);
073: setOpaque(false);
074: addMouseListener(this );
075:
076: layerPane = applet.getLayeredPane();
077: layerPane.add(this , -1);
078:
079: transPopUp = new TranslationPopUp(editorProject, this );
080: transPopUp.setVisible(false);
081: layerPane.add(transPopUp, 0);
082:
083: contentPane = (Component) applet.getContentPaneEx();
084:
085: setBounds(layerPane.getBounds());
086: setVisible(true);
087:
088: layerPane.addComponentListener(new ComponentAdapter() {
089: public void componentResized(ComponentEvent evt) {
090: setBounds(layerPane.getBounds());
091: layerPane.repaint();
092: }
093: });
094:
095: frame = (JFrame) editorProject.getAppFrame();
096: setupLangMgr(editorProject);
097: setupOptionWindow();
098: addWindowListeners();
099: }
100:
101: /**
102: * Create and show the option window, which will provide run-time options
103: * for using the translation pane.
104: */
105: public void setupOptionWindow() {
106: optionFrame = new JFrame("Options");
107: optionFrame.setLayout(null);
108: optionFrame.setResizable(false);
109: optionFrame.setAlwaysOnTop(true);
110:
111: JPanel optionPanel = new JPanel();
112: optionPanel.setBackground(Color.white);
113: optionPanel.setLayout(null);
114: optionPanel.setBounds(0, 0, 200, 185);
115:
116: XPanel panel1 = new XPanel();
117: panel1.setBackground(Color.white);
118: panel1.setBounds(10, 10, 177, 50);
119: panel1.setAttribute("border", "1");
120: optionPanel.add(panel1);
121:
122: XLabel label1 = new XLabel();
123: label1.setText("Translation Pane");
124: label1.setBounds(5, 3, 100, 15);
125: panel1.add(label1);
126:
127: XLabel radLabel1 = new XLabel();
128: radLabel1.setText("On");
129: radLabel1.setBounds(60, 24, 20, 20);
130: panel1.add(radLabel1);
131:
132: XLabel radLabel2 = new XLabel();
133: radLabel2.setText("Off");
134: radLabel2.setBounds(125, 24, 20, 20);
135: panel1.add(radLabel2);
136:
137: onBtn = new XRadioButton();
138: onBtn.setBackground(Color.white);
139: onBtn.setBounds(30, 20, 20, 20);
140: onBtn.setSelected(true);
141: onBtn.addActionListener(this );
142: panel1.add(onBtn);
143:
144: offBtn = new XRadioButton();
145: offBtn.setBackground(Color.white);
146: offBtn.setBounds(100, 20, 20, 20);
147: offBtn.addActionListener(this );
148: panel1.add(offBtn);
149:
150: ButtonGroup group = new ButtonGroup();
151: group.add(onBtn);
152: group.add(offBtn);
153:
154: XPanel panel2 = new XPanel();
155: panel2.setBackground(Color.white);
156: panel2.setBounds(10, 70, 177, 80);
157: panel2.setAttribute("border", "1");
158: optionPanel.add(panel2);
159:
160: XLabel label2 = new XLabel();
161: label2.setText("Select Languages");
162: label2.setBounds(5, 3, 150, 15);
163: panel2.add(label2);
164:
165: XLabel label3 = new XLabel();
166: label3.setText("Current:");
167: label3.setAlignment((int) XLabel.RIGHT_ALIGNMENT);
168: label3.setBounds(5, 28, 60, 50);
169: panel2.add(label3);
170:
171: XLabel label4 = new XLabel();
172: label4.setText("Translation:");
173: label4.setAlignment((int) XLabel.RIGHT_ALIGNMENT);
174: label4.setBounds(5, 53, 60, 50);
175: panel2.add(label4);
176:
177: currentSelect = new JComboBox();
178: currentSelect.setBounds(70, 25, 100, 20);
179: currentSelect.addActionListener(this );
180: panel2.add(currentSelect);
181:
182: transSelect = new JComboBox();
183: transSelect.setBounds(70, 50, 100, 20);
184: transSelect.addActionListener(this );
185: panel2.add(transSelect);
186:
187: int numLangs = langMgr.getNumLangs();
188: for (int i = 0; i < numLangs; i++) {
189: EdLanguage lang = langMgr.getLangFromList(i);
190: String code = lang.getLangCode().toLowerCase();
191: currentSelect.addItem(lang.getLangName());
192: transSelect.addItem(lang.getLangName());
193: }
194:
195: optionFrame.add(optionPanel);
196: optionFrame.setBounds((frame.getX() + frame.getWidth() - 200),
197: (frame.getY() + 5), 200, 185);
198: optionFrame.setVisible(true);
199: }
200:
201: /**
202: * Handles painting for this component.
203: * @param g the delagate <CODE>Graphics</CODE> instance.
204: */
205: public void paintComponent(Graphics g) {
206: super .paintComponent(g);
207:
208: if (selected != null) {
209: Graphics2D g2d = (Graphics2D) g;
210: g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
211: RenderingHints.VALUE_ANTIALIAS_ON);
212: g2d.setColor(new Color(0, 148, 255));
213: g2d.setStroke(new BasicStroke(2.0F));
214: g2d.draw(selBounds);
215: g2d.dispose();
216: }
217: }
218:
219: /**
220: * Get a component and a particular co-ordinate
221: * @param p <CODE>Point</CODE> specifying the co-ordinate of the component
222: * @return the selected component
223: */
224: public Rectangle getComponentBoundsAt(Point point) {
225: Component comp = SwingUtilities.getDeepestComponentAt(
226: contentPane, point.x, point.y);
227: Point p = SwingUtilities.convertPoint(comp.getParent(), comp
228: .getLocation(), this );
229: Rectangle r1 = new Rectangle(p.x, p.y, comp.getWidth(), comp
230: .getHeight());
231:
232: Rectangle selRect = null;
233: if (comp instanceof JTabbedPane) {
234: JTabbedPane tabPane = (JTabbedPane) comp;
235: Point tabPoint = SwingUtilities.convertPoint(this , point,
236: tabPane);
237: TabbedPaneUI tabUI = tabPane.getUI();
238: int t = tabUI.tabForCoordinate(tabPane, tabPoint.x,
239: tabPoint.y);
240: text = tabPane.getTitleAt(t);
241:
242: Rectangle r2 = tabUI.getTabBounds(tabPane, t);
243: selRect = new Rectangle((r1.x + r2.x), (r1.y + r2.y),
244: r2.width, r2.height);
245: selected = tabPane;
246: } else {
247: boolean textComp = false;
248: Method[] methods = comp.getClass().getMethods();
249: for (int i = 0; i < methods.length; i++) {
250: String methodName = methods[i].getName();
251: if (methodName.equals("getText")
252: || methodName.equals("getContent")) {
253: text = getComponentText(comp, methodName);
254: if (text != null && !text.equals("")) {
255: selRect = r1;
256: selected = comp;
257: break;
258: }
259: }
260: }
261: }
262:
263: if (text != null) {
264: return selRect;
265: } else
266: return null;
267: }
268:
269: /**
270: * Get the text displayed in a particular component
271: * @param c the <CODE>Component</CODE> dislaying text info
272: * @return the text <CODE>String</CODE>
273: */
274: public String getComponentText(Component c, String methodName) {
275: try {
276: Method method = c.getClass().getMethod(methodName,
277: new Class[0]);
278: String s = (String) method.invoke(c, new Object[0]);
279: return s;
280: } catch (Exception ex) {
281: if (BuildProperties.DEBUG)
282: ex.printStackTrace();
283: return null;
284: }
285: }
286:
287: /**
288: * Listen for mouse pressed events
289: * @param e the fired <CODE>MouseEvent</CODE>
290: */
291: public void mousePressed(MouseEvent e) {
292: Rectangle r = getComponentBoundsAt(e.getPoint());
293: if (r != null) {
294: selBounds = r;
295: int x = 0, y = 0;
296: int selX = selBounds.x;
297: int selY = selBounds.y;
298: int selW = selBounds.width;
299: int selH = selBounds.height;
300: int popUpW = transPopUp.getWidth();
301: int popUpH = transPopUp.getHeight();
302:
303: if ((selX + selW + popUpW + 12) > getWidth()) {
304: x = selX - (popUpW + 12);
305: if (x < 0)
306: x = (selX + selW) - popUpW;
307: } else
308: x = selX + selW + 12;
309:
310: if ((selY + popUpH) > getHeight()) {
311: y = (selY - popUpH) + selH;
312: if (y < 0)
313: y = (selY + selH) - popUpH;
314: } else
315: y = selY;
316:
317: transPopUp.setInfoItems(
318: selected.getClass().getSimpleName(), selected
319: .getName());
320: transPopUp.resetTextFields();
321: transPopUp.setLocation(x, y);
322: String selectedLang = transPopUp.showMatchingStrings(text);
323:
324: if (selectedLang != null) {
325: blockListener = true;
326: currentSelect.setSelectedItem(selectedLang);
327: blockListener = false;
328: }
329:
330: if (!popUpVisible) {
331: transPopUp.setVisible(true);
332: }
333:
334: repaint();
335: }
336: }
337:
338: /**
339: * Listen for mouse clicked events
340: * @param e the fired <CODE>MouseEvent</CODE>
341: */
342: public void mouseClicked(MouseEvent e) {
343: if (e.getClickCount() == 2) {
344: transPopUp.setTransFocus();
345: }
346: }
347:
348: /**
349: * Setup the language manager
350: * @param project the current project
351: */
352: public void setupLangMgr(XEditorProject project) {
353: langMgr = (EdLangMgr) project.getObject("LanguageManager");
354:
355: if (langMgr == null) {
356: langMgr = new EdLangMgr(false, project
357: .getUrl("LanguageList.properties"));
358: project.setObject("LanguageManager", langMgr);
359: }
360:
361: if (langMgr != null) {
362: currentLang = langMgr.getCurrentLang();
363: }
364: }
365:
366: /**
367: * Listen for button press events
368: * @param e the fired <CODE>ActionEvent</CODE>
369: */
370: public void actionPerformed(ActionEvent e) {
371: if ((!blockListener) && ((e.getSource() == currentSelect))) {
372: currentLang = langMgr.getLang((String) currentSelect
373: .getSelectedItem());
374: transPopUp.updateCurrentLang(currentLang);
375: } else if ((!blockListener) && ((e.getSource() == transSelect))) {
376: transLang = langMgr.getLang((String) transSelect
377: .getSelectedItem());
378: transPopUp.updateTransLang(currentLang);
379: } else {
380: if (onBtn.isSelected()) {
381: setVisible(true);
382: repaint();
383: } else {
384: setVisible(false);
385: resetSelectedComp();
386: transPopUp.setVisible(false);
387: }
388: }
389: }
390:
391: /**
392: * Set the selected current language
393: * @param str <CODE>String</CODE> specifying the language
394: */
395: public void setSelectedCurrentLang(String str) {
396: blockListener = true;
397: currentSelect.setSelectedItem(str);
398: blockListener = false;
399: }
400:
401: /**
402: * Reset the selected component
403: */
404: public void resetSelectedComp() {
405: selected = null;
406: selBounds = null;
407: popUpVisible = false;
408: }
409:
410: /**
411: * Add the window listeners to the main and option windows
412: */
413: public void addWindowListeners() {
414: Window window = editorProject.getAppWindow();
415: window.removeWindowListener(window
416: .getListeners(WindowListener.class)[0]);
417: window.addWindowListener(this );
418: optionFrame.addWindowListener(this );
419: }
420:
421: /**
422: * Detects window closing events
423: * @param e the window event
424: */
425: public void windowClosing(WindowEvent e) {
426: frame.dispose();
427: optionFrame.dispose();
428: }
429:
430: /**
431: * Template method, unused at present
432: * @param e the window event
433: */
434: public void windowActivated(WindowEvent e) {
435: }
436:
437: /**
438: * Template method, unused at present
439: * @param e the window event
440: */
441: public void windowClosed(WindowEvent e) {
442: }
443:
444: /**
445: * Template method, unused at present
446: * @param e the window event
447: */
448: public void windowDeactivated(WindowEvent e) {
449: }
450:
451: /**
452: * Template method, unused at present
453: * @param e the window event
454: */
455: public void windowDeiconified(WindowEvent e) {
456: }
457:
458: /**
459: * Template method, unused at present
460: * @param e the window event
461: */
462: public void windowIconified(WindowEvent e) {
463: }
464:
465: /**
466: * Template method, unused at present
467: * @param e the window event
468: */
469: public void windowOpened(WindowEvent e) {
470: }
471:
472: /**
473: * Template method, unused at present
474: * @param e the window event
475: */
476: public void mouseEntered(MouseEvent e) {
477: }
478:
479: /**
480: * Template method, unused at present
481: * @param e the window event
482: */
483: public void mouseReleased(MouseEvent e) {
484: }
485:
486: /**
487: * Template method, unused at present
488: * @param e the window event
489: */
490: public void mouseExited(MouseEvent e) {
491: }
492: }
|