package com.vci.client.ui.swing.components;
|
|
import java.awt.BorderLayout;
|
import java.awt.Color;
|
import java.awt.Component;
|
import java.awt.Graphics;
|
import java.awt.Graphics2D;
|
import java.awt.Rectangle;
|
import java.awt.Transparency;
|
|
import javax.swing.Icon;
|
import javax.swing.JFrame;
|
import javax.swing.JTabbedPane;
|
import javax.swing.UIManager;
|
import javax.swing.event.EventListenerList;
|
|
import com.vci.client.ui.swing.VCISwingUtil;
|
//import java.awt.geom.AffineTransform;
|
//import java.util.ArrayList;
|
//import java.util.HashMap;
|
/**
|
* A JTabbedPane which has a close ('X') icon on each tab.
|
* To add a tab, use the method addTab(String, Component)
|
* To have an extra icon on each tab (e.g. like in JBuilder,
|
* showing the file type) use the method
|
* addTab(String, Component, Icon).
|
* Only clicking the 'X' closes the tab. */
|
public class JClosableTabbedPane extends JTabbedPane {
|
private static final long serialVersionUID = -5331239697810133531L;
|
private EventListenerList closeListenerList = new EventListenerList();
|
public JClosableTabbedPane() {
|
super();
|
setFont(VCISwingUtil.FONT_DEFAULT);
|
}
|
public void addTab(String title, Component component, boolean closeable) {
|
this.addTab(title, component, null, closeable);
|
}
|
public void addTab(String title, Component component, Icon extraIcon, boolean closeable) {
|
this.addTab(title, component, extraIcon, null, closeable);
|
}
|
|
public void addTab(String title, Component component, Icon extraIcon, String tip, boolean closeable) {
|
if (closeable) {
|
super.add(title, component);
|
int index = getTabCount() - 1;
|
TabTitleComponent tabComponent = new TabTitleComponent(this, component);
|
tabComponent.setTitle(title);
|
this.setTabComponentAt(index, tabComponent);
|
} else {
|
super.addTab(title, extraIcon, component, tip);
|
}
|
}
|
|
public void addCloseListener(CloseListener l){
|
this.closeListenerList.add(CloseListener.class, l);
|
}
|
|
public void removeCloseListener(CloseListener l){
|
if(l != null){
|
this.closeListenerList.remove(CloseListener.class, l);
|
}
|
}
|
private final String BEFORECLOSEING = "beforeCloseing";
|
private final String AFTERCLOSED = "afterClosed";
|
private void invokeBeforeCloseing(int index, Component tabCompt){
|
invoke(index, BEFORECLOSEING, tabCompt);
|
}
|
private void invokeAfterClosed(int index, Component tabCompt){
|
invoke(index, AFTERCLOSED, tabCompt);
|
}
|
|
private void invoke(int index, String method, Component tabCompt){
|
CloseListener[] listeners = getCloseListeners();
|
if(listeners != null){
|
for(CloseListener l : listeners){
|
CloseEvent e = new CloseEvent(this, index, tabCompt);
|
invoke(l, e, method);
|
}
|
}
|
}
|
|
private void invoke(CloseListener l, CloseEvent e, String method){
|
if(method.equalsIgnoreCase(BEFORECLOSEING)){
|
l.beforeCloseing(e);
|
} else if(method.equals(AFTERCLOSED)){
|
l.afterClosed(e);
|
}
|
}
|
|
private CloseListener[] getCloseListeners(){
|
CloseListener[] listeners = closeListenerList.getListeners(CloseListener.class);
|
return listeners;
|
}
|
|
public void removeTabAt(int index) {
|
Component tabCompt = getTabComponentAt(index);
|
invokeBeforeCloseing(index, tabCompt);
|
super.removeTabAt(index);
|
invokeAfterClosed(index, tabCompt);
|
}
|
|
public static void main(String args[]) {
|
try {
|
UIManager
|
.setLookAndFeel(VCISwingUtil.LOOK_AND_FEEL_NimbusLookAndFeel);
|
} catch (Exception e) {
|
e.printStackTrace();
|
}
|
final JClosableTabbedPane pane = new JClosableTabbedPane();
|
for (int i = 0; i < 20; i++) {
|
pane.addTab("Title " + String.valueOf(i), new VCIJPanel(), true);
|
}
|
pane.addCloseListener(new CloseListener() {
|
@Override
|
public void beforeCloseing(CloseEvent e) {
|
// TODO Auto-generated method stub
|
VCIJOptionPane.showMessage(pane, "BeforeCloseing:" + String.valueOf(e.getTabIndex()));
|
}
|
|
@Override
|
public void afterClosed(CloseEvent e) {
|
// TODO Auto-generated method stub
|
VCIJOptionPane.showMessage(pane, "AfterClosed:" + String.valueOf(e.getTabIndex()));
|
}
|
});
|
JFrame frame = new JFrame("Demo");
|
frame.getContentPane().add(pane, BorderLayout.CENTER);
|
frame.setSize(500, 300);
|
frame.setLocation(300, 200);
|
frame.setVisible(true);
|
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
}
|
|
}
|
/**
|
* The class which generates the 'X' icon for the tabs. The constructor
|
* accepts an icon which is extra to the 'X' icon, so you can have tabs
|
* like in JBuilder. This value is null if no extra icon is required.
|
*/
|
class CloseTabIcon implements Icon {
|
private int x_pos;
|
private int y_pos;
|
private int width;
|
private int height;
|
private Icon fileIcon;
|
public CloseTabIcon(Icon fileIcon) {
|
this.fileIcon = fileIcon;
|
width = 16;
|
height = 16;
|
}
|
public void paintIcon(Component c, Graphics g, int x, int y) {
|
this.x_pos = x;
|
this.y_pos = y;
|
if(g instanceof Graphics2D){
|
Graphics2D g2d = (Graphics2D)g;
|
g2d.getDeviceConfiguration().createCompatibleImage(width*2, height*2, Transparency.TRANSLUCENT);
|
}
|
Color col = g.getColor();
|
g.setColor(Color.black);
|
int y_p = y + 2;
|
g.drawLine(x + 1, y_p, x + 12, y_p);
|
g.drawLine(x + 1, y_p + 13, x + 12, y_p + 13);
|
g.drawLine(x, y_p + 1, x, y_p + 12);
|
g.drawLine(x + 13, y_p + 1, x + 13, y_p + 12);
|
g.drawLine(x + 3, y_p + 3, x + 10, y_p + 10);
|
g.drawLine(x + 3, y_p + 4, x + 9, y_p + 10);
|
g.drawLine(x + 4, y_p + 3, x + 10, y_p + 9);
|
g.drawLine(x + 10, y_p + 3, x + 3, y_p + 10);
|
g.drawLine(x + 10, y_p + 4, x + 4, y_p + 10);
|
g.drawLine(x + 9, y_p + 3, x + 3, y_p + 9);
|
g.setColor(col);
|
if (fileIcon != null) {
|
fileIcon.paintIcon(c, g, x + width, y_p);
|
}
|
}
|
public int getIconWidth() {
|
return width + (fileIcon != null ? fileIcon.getIconWidth() : 0);
|
}
|
public int getIconHeight() {
|
return height;
|
}
|
public Rectangle getBounds() {
|
return new Rectangle(x_pos, y_pos, width, height);
|
}
|
}
|