001: package com.xoetrope.swing.tabs;
002:
003: import java.awt.BasicStroke;
004: import java.awt.Color;
005: import java.awt.Component;
006: import java.awt.Dimension;
007: import java.awt.FlowLayout;
008: import java.awt.Font;
009: import java.awt.Graphics;
010: import java.awt.Graphics2D;
011: import java.awt.event.ActionEvent;
012: import java.awt.event.ActionListener;
013: import java.awt.event.MouseAdapter;
014: import java.awt.event.MouseEvent;
015: import java.awt.event.MouseListener;
016: import javax.swing.AbstractButton;
017: import javax.swing.BorderFactory;
018: import javax.swing.JButton;
019: import javax.swing.JLabel;
020: import javax.swing.JPanel;
021: import javax.swing.JTabbedPane;
022: import javax.swing.plaf.basic.BasicButtonUI;
023: import net.xoetrope.xui.XProject;
024: import net.xoetrope.xui.style.XStyle;
025:
026: /**
027: * Component to be used as tabComponent;
028: * Contains a JLabel to show the text and
029: * a JButton to close the tab it belongs to
030: */
031: public class WrappingTabComponent extends JPanel {
032: private final JTabbedPane pane;
033: private JButton closeBtn;
034: private JLabel label;
035:
036: private XProject currentProject;
037:
038: public WrappingTabComponent(XProject project, JTabbedPane pane,
039: boolean canClose) {
040: //unset default FlowLayout' gaps
041: super (new FlowLayout(FlowLayout.LEFT, 0, 0));
042:
043: currentProject = project;
044: if (pane == null)
045: throw new NullPointerException("TabbedPane is null");
046:
047: this .pane = pane;
048: setOpaque(false);
049:
050: XStyle wrappedStyle = currentProject.getStyleManager()
051: .getStyle("wrappedTabs");
052: Font font = currentProject.getStyleManager().getFont(
053: "wrappedTabs");
054:
055: //make JLabel read titles from JTabbedPane
056: label = new JLabel();
057: label.setFont(font);
058: label.setForeground(wrappedStyle
059: .getStyleAsColor(XStyle.COLOR_FORE));
060: add(label);
061:
062: if (canClose) {
063: //add more space between the label and the button
064: label
065: .setBorder(BorderFactory.createEmptyBorder(0, 0, 0,
066: 5));
067:
068: //tab button
069: closeBtn = new TabButton();
070: add(closeBtn);
071: }
072:
073: // add more space to the top of the component
074: setBorder(BorderFactory.createEmptyBorder(2, 0, 0, 0));
075: }
076:
077: public void paintChildren(Graphics g) {
078: label.setText(pane.getTitleAt(pane.indexOfTabComponent(this )));
079:
080: super .paintChildren(g);
081: }
082:
083: private class TabButton extends JButton implements ActionListener {
084: public TabButton() {
085: int size = 17;
086: setPreferredSize(new Dimension(size, size));
087: setToolTipText("close this tab");
088:
089: //Make the button looks the same for all Laf's
090: setUI(new BasicButtonUI());
091:
092: //Make it transparent
093: setContentAreaFilled(false);
094:
095: //No need to be focusable
096: setFocusable(false);
097: setBorder(BorderFactory.createEtchedBorder());
098: setBorderPainted(false);
099:
100: //Making nice rollover effect
101: //we use the same listener for all buttons
102: addMouseListener(buttonMouseListener);
103: setRolloverEnabled(true);
104:
105: //Close the proper tab by clicking the button
106: addActionListener(this );
107: }
108:
109: public void actionPerformed(ActionEvent e) {
110: int i = pane.indexOfTabComponent(WrappingTabComponent.this );
111: if (i != -1)
112: pane.remove(i);
113: }
114:
115: //we don't want to update UI for this button
116: public void updateUI() {
117: }
118:
119: //paint the cross
120: protected void paintComponent(Graphics g) {
121: super .paintComponent(g);
122: Graphics2D g2 = (Graphics2D) g.create();
123:
124: // Shift the image for pressed buttons
125: if (getModel().isPressed())
126: g2.translate(1, 1);
127:
128: g2.setStroke(new BasicStroke(2));
129: g2.setColor(Color.BLACK);
130: if (getModel().isRollover())
131: g2.setColor(Color.RED);
132:
133: int delta = 6;
134: g2.drawLine(delta, delta, getWidth() - delta - 1,
135: getHeight() - delta - 1);
136: g2.drawLine(getWidth() - delta - 1, delta, delta,
137: getHeight() - delta - 1);
138: g2.dispose();
139: }
140: }
141:
142: private final static MouseListener buttonMouseListener = new MouseAdapter() {
143: public void mouseEntered(MouseEvent e) {
144: Component component = e.getComponent();
145: if (component instanceof AbstractButton) {
146: AbstractButton button = (AbstractButton) component;
147: button.setBorderPainted(true);
148: }
149: }
150:
151: public void mouseExited(MouseEvent e) {
152: Component component = e.getComponent();
153: if (component instanceof AbstractButton) {
154: AbstractButton button = (AbstractButton) component;
155: button.setBorderPainted(false);
156: }
157: }
158: };
159: }
|