001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.etl.ui.view;
042:
043: import java.awt.BorderLayout;
044: import java.awt.Color;
045: import java.awt.Component;
046: import java.awt.Dimension;
047: import java.awt.Graphics;
048: import java.awt.Insets;
049: import java.awt.event.ActionEvent;
050: import java.awt.event.MouseEvent;
051: import java.beans.PropertyChangeListener;
052: import java.io.Serializable;
053: import javax.swing.AbstractAction;
054: import javax.swing.BoxLayout;
055: import javax.swing.Icon;
056: import javax.swing.JButton;
057: import javax.swing.JPopupMenu;
058: import javax.swing.JTabbedPane;
059: import javax.swing.JToolBar;
060: import javax.swing.UIManager;
061: import javax.swing.border.Border;
062: import javax.swing.event.ChangeEvent;
063: import javax.swing.event.ChangeListener;
064: import net.java.hulp.i18n.Logger;
065: import org.netbeans.modules.etl.logger.Localizer;
066: import org.netbeans.modules.etl.logger.LogUtil;
067: import org.netbeans.modules.sql.framework.ui.output.ETLOutputPanel;
068: import org.openide.awt.MouseUtils;
069: import org.openide.awt.TabbedPaneFactory;
070: import org.openide.util.NbBundle;
071: import org.openide.util.Utilities;
072: import org.openide.windows.TopComponent;
073: import org.openide.windows.WindowManager;
074:
075: /**
076: * Top component which displays various output panel
077: *
078: * @author Ahimanikya Satapathy
079: * @author Nithya Radhakrishnan
080: */
081: public final class ETLOutputWindowTopComponent extends TopComponent {
082:
083: private static ETLOutputWindowTopComponent instance;
084: private static final String PREFERRED_ID = "ETLOutputWindowTopComponent";
085: private JTabbedPane tabbedPane = TabbedPaneFactory
086: .createCloseButtonTabbedPane();
087: private PopupListener listener;
088: private ChangeListener listen;
089: private JPopupMenu pop;
090: private CloseListener closeL;
091: private transient boolean isVisible = false;
092: private ETLOutputPanel lastKnownSelection = null;
093: private ETLOutputPanel newSelection;
094: private JToolBar verticalBar;
095: public static final String ICON_RESOURCE = "org/netbeans/modules/sql/framework/ui/resources/images/showOutput.png"; // NOI18N
096: private static transient final Logger mLogger = LogUtil
097: .getLogger(ETLOutputWindowTopComponent.class.getName());
098: private static transient final Localizer mLoc = Localizer.get();
099:
100: private ETLOutputWindowTopComponent() {
101: initComponents();
102: setLayout(new BorderLayout());
103:
104: setFocusable(true);
105: setBackground(UIManager.getColor("text")); //NOI18N
106:
107: String nbBundle1 = mLoc.t("PRSR001: Data Integrator Output");
108: setName(Localizer.parse(nbBundle1));
109: setIcon(Utilities.loadImage(ICON_RESOURCE));
110: String nbBundle2 = mLoc.t("PRSR001: Data Integrator Output");
111: setToolTipText(Localizer.parse(nbBundle2));
112:
113: // create it but don't add it yet...
114: verticalBar = new JToolBar(JToolBar.VERTICAL);
115: verticalBar.setLayout(new BoxLayout(verticalBar,
116: BoxLayout.Y_AXIS));
117: verticalBar.setFloatable(false);
118:
119: Insets ins = verticalBar.getMargin();
120: JButton sample = new JButton();
121: sample.setBorderPainted(false);
122: sample.setOpaque(false);
123: sample.setText(null);
124: sample.setIcon(new Icon() {
125:
126: public int getIconHeight() {
127: return 16;
128: }
129:
130: public int getIconWidth() {
131: return 16;
132: }
133:
134: public void paintIcon(Component c, Graphics g, int x, int y) {
135: }
136: });
137: verticalBar.add(sample);
138: Dimension buttonPref = sample.getPreferredSize();
139: Dimension minDim = new Dimension(buttonPref.width + ins.left
140: + ins.right, buttonPref.height + ins.top + ins.bottom);
141: verticalBar.setMinimumSize(minDim);
142: verticalBar.setPreferredSize(minDim);
143: verticalBar.remove(sample);
144: verticalBar.setBorder(new VariableRightBorder(tabbedPane));
145: verticalBar.setBorderPainted(true);
146:
147: pop = new JPopupMenu();
148: pop.add(new Close());
149: pop.add(new CloseAll());
150: pop.add(new CloseAllButCurrent());
151: listener = new PopupListener();
152: closeL = new CloseListener();
153: listen = new ChangeListener() {
154:
155: public void stateChanged(ChangeEvent e) {
156: if (e.getSource() instanceof JTabbedPane) {
157: JTabbedPane jp = ((JTabbedPane) e.getSource());
158: newSelection = (ETLOutputPanel) jp
159: .getSelectedComponent();
160: fire(lastKnownSelection, newSelection);
161: }
162: }
163: };
164:
165: }
166:
167: String nbBundle1 = mLoc.t("PRSR001: Close Tab");
168: String nbBundle2 = mLoc.t("PRSR001: Close All Tabs");
169: String nbBundle3 = mLoc.t("PRSR001: Close Other Tabs");
170:
171: private class Close extends AbstractAction {
172: public Close() {
173: super (Localizer.parse(nbBundle1));
174: }
175:
176: public void actionPerformed(ActionEvent e) {
177: if (tabbedPane.getComponentCount() > 0) {
178: removePanel(tabbedPane.getSelectedComponent());
179: }
180:
181: }
182: }
183:
184: private final class CloseAll extends AbstractAction {
185:
186: public CloseAll() {
187: super (Localizer.parse(nbBundle2));
188: }
189:
190: public void actionPerformed(ActionEvent e) {
191: if (tabbedPane.getComponentCount() > 0) {
192: closeAll(tabbedPane);
193: }
194: removeAll();
195: close();
196: }
197: }
198:
199: private class CloseAllButCurrent extends AbstractAction {
200:
201: public CloseAllButCurrent() {
202: super (Localizer.parse(nbBundle3));
203: }
204:
205: public void actionPerformed(ActionEvent e) {
206: if (tabbedPane.getComponentCount() > 0) {
207: closeAllButCurrent(tabbedPane);
208: }
209: }
210: }
211:
212: void closeAllButCurrent(JTabbedPane tabs) {
213: Component current = tabs.getSelectedComponent();
214: for (Component comp : tabs.getComponents()) {
215: if (comp != current) {
216: removePanel(comp);
217: }
218: }
219: }
220:
221: void closeAll(JTabbedPane tabs) {
222: for (Component comp : tabs.getComponents()) {
223: removePanel(comp);
224: }
225: revalidate();
226: }
227:
228: private class CloseListener implements PropertyChangeListener {
229:
230: public void propertyChange(java.beans.PropertyChangeEvent evt) {
231: if (TabbedPaneFactory.PROP_CLOSE.equals(evt
232: .getPropertyName())) {
233: removePanel((Component) evt.getNewValue());
234: }
235: }
236: }
237:
238: /** This method is called from within the constructor to
239: * initialize the form.
240: * WARNING: Do NOT modify this code. The content of this method is
241: * always regenerated by the Form Editor.
242: */
243: private class PopupListener extends MouseUtils.PopupMouseAdapter {
244:
245: /**
246: * Called when the sequence of mouse events should lead to actual showing popup menu
247: */
248: @Override
249: protected void showPopup(MouseEvent e) {
250: pop.show(ETLOutputWindowTopComponent.this , e.getX(), e
251: .getY());
252: }
253: } // end of PopupListener
254:
255: // <editor-fold defaultstate="collapsed" desc=" Generated Code ">//GEN-BEGIN:initComponents
256: private void initComponents() {
257:
258: org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(
259: this );
260: this .setLayout(layout);
261: layout.setHorizontalGroup(layout.createParallelGroup(
262: org.jdesktop.layout.GroupLayout.LEADING).add(0, 400,
263: Short.MAX_VALUE));
264: layout.setVerticalGroup(layout.createParallelGroup(
265: org.jdesktop.layout.GroupLayout.LEADING).add(0, 300,
266: Short.MAX_VALUE));
267: }// </editor-fold>//GEN-END:initComponents
268:
269: // Variables declaration - do not modify//GEN-BEGIN:variables
270: // End of variables declaration//GEN-END:variables
271: /**
272: * Gets default instance. Do not use directly: reserved for *.settings files only,
273: * i.e. deserialization routines; otherwise you could get a non-deserialized instance.
274: * To obtain the singleton instance, use {@link findInstance}.
275: * @return ETLOutputWindowTopComponent defaultInstance
276: */
277:
278: public static synchronized ETLOutputWindowTopComponent getDefault() {
279: if (instance == null) {
280: instance = new ETLOutputWindowTopComponent();
281: }
282: return instance;
283: }
284:
285: /**
286: * Obtain the ETLOutputWindowTopComponent instance. Never call {@link #getDefault} directly!
287: * @return ETLOutputWindowTopComponent defaultInstance
288: */
289: public static synchronized ETLOutputWindowTopComponent findInstance() {
290: TopComponent win = WindowManager.getDefault().findTopComponent(
291: PREFERRED_ID);
292: if (win == null) {
293: mLogger
294: .infoNoloc(mLoc
295: .t(
296: "PRSR111: Cannot find {0}component. It will not be located properly in the window system.",
297: PREFERRED_ID));
298: return getDefault();
299: }
300: if (win instanceof ETLOutputWindowTopComponent) {
301: return (ETLOutputWindowTopComponent) win;
302: }
303: mLogger
304: .infoNoloc(mLoc
305: .t(
306: "PRSR112: There seem to be multiple components with the '{0} ' ID. That is a potential source of errors and unexpected behavior.",
307: PREFERRED_ID));
308: return getDefault();
309: }
310:
311: public void removePanel(Component panel) {
312: if (tabbedPane.getComponentCount() == 0) {
313: remove(panel);
314: } else {
315: tabbedPane.remove(panel);
316: if (tabbedPane.getComponentCount() == 1) {
317: Component c = tabbedPane.getSelectedComponent();
318: lastKnownSelection = (ETLOutputPanel) c;
319: tabbedPane.removeMouseListener(listener);
320: tabbedPane.removePropertyChangeListener(closeL);
321: remove(tabbedPane);
322: add(c, BorderLayout.CENTER);
323: }
324: }
325: revalidate();
326: }
327:
328: public void addPanel(Component panel) {
329: if (getComponentCount() == 0) {
330: add(panel, BorderLayout.CENTER);
331: if (panel instanceof ETLOutputPanel) {
332: lastKnownSelection = (ETLOutputPanel) panel;
333: verticalBar.removeAll();
334: JButton[] btns = ((ETLOutputPanel) panel)
335: .getVerticalToolBar();
336: for (JButton btn : btns) {
337: verticalBar.add(btn);
338: }
339: add(verticalBar, BorderLayout.WEST);
340: }
341: } else if (tabbedPane.getComponentCount() == 0
342: && lastKnownSelection != panel) {
343: Component comp = (Component) lastKnownSelection;
344: remove(comp);
345: tabbedPane.addMouseListener(listener);
346: tabbedPane.addPropertyChangeListener(closeL);
347: tabbedPane.addChangeListener(listen);
348: add(tabbedPane, BorderLayout.CENTER);
349: tabbedPane.addTab(comp.getName() + " ", null, comp, comp
350: .getName()); //NOI18N
351: tabbedPane.addTab(panel.getName() + " ", null, panel,
352: panel.getName()); //NOI18N
353: tabbedPane.setSelectedComponent(panel);
354: tabbedPane.validate();
355: } else if (lastKnownSelection != panel) {
356: tabbedPane.addTab(panel.getName() + " ", null, panel,
357: panel.getName()); //NOI18N
358: tabbedPane.setSelectedComponent(panel);
359: tabbedPane.validate();
360: }
361: if (!isVisible) {
362: isVisible = true;
363: open();
364: }
365: validate();
366: requestActive();
367: }
368:
369: @Override
370: public int getPersistenceType() {
371: return TopComponent.PERSISTENCE_ALWAYS;
372: }
373:
374: @Override
375: public void componentOpened() {
376: // TODO add custom code on component opening
377: }
378:
379: @Override
380: public void componentClosed() {
381: // TODO add custom code on component closing
382: }
383:
384: @Override
385: public Object writeReplace() {
386: return new ResolvableHelper();
387: }
388:
389: @Override
390: protected String preferredID() {
391: return PREFERRED_ID;
392: }
393:
394: static final class ResolvableHelper implements Serializable {
395:
396: private static final long serialVersionUID = 1L;
397:
398: public Object readResolve() {
399: return ETLOutputWindowTopComponent.getDefault();
400: }
401: }
402:
403: protected void fire(ETLOutputPanel formerSelection,
404: ETLOutputPanel selection) {
405: if (formerSelection != selection && selection != null) {
406: lastKnownSelection = selection;
407: setToolbarButtons(selection.getVerticalToolBar());
408: } else if (lastKnownSelection != null) {
409: setToolbarButtons(lastKnownSelection.getVerticalToolBar());
410: }
411: }
412:
413: private void setToolbarButtons(JButton[] buttons) {
414: verticalBar.removeAll();
415: for (JButton btn : buttons) {
416: if (btn != null) {
417: verticalBar.add(btn);
418: }
419: }
420: verticalBar.repaint();
421: verticalBar.validate();
422: }
423:
424: private class VariableRightBorder implements Border {
425:
426: private JTabbedPane pane;
427:
428: public VariableRightBorder(JTabbedPane pane) {
429: this .pane = pane;
430: }
431:
432: public void paintBorder(Component c, Graphics g, int x, int y,
433: int width, int height) {
434: Color old = g.getColor();
435: g.setColor(getColor());
436: g.drawLine(x + width - 1, y, x + width - 1, y + height);
437: g.setColor(old);
438: }
439:
440: public Color getColor() {
441: if (Utilities.isMac()) {
442: Color c1 = UIManager.getColor("controlShadow");
443: Color c2 = UIManager.getColor("control");
444: return new Color((c1.getRed() + c2.getRed()) / 2, (c1
445: .getGreen() + c2.getGreen()) / 2,
446: (c1.getBlue() + c2.getBlue()) / 2);
447: } else {
448: return UIManager.getColor("controlShadow");
449: }
450: }
451:
452: public Insets getBorderInsets(Component c) {
453: return new Insets(0, 0, 0, 2);
454: }
455:
456: public boolean isBorderOpaque() {
457: return true;
458: }
459: }
460: }
|