package com.tail;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.AbstractAction;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import com.tail.ui.TailButtonUI;
public class HeadPanel extends JComponent {
private static final long serialVersionUID = 6001973725994078371L;
private Color BACKGROUND_1 = new Color(226,223,239);
private Color BACKGROUND_2 = new Color(209,220,231);
private static final Icon EMPTY_ICON = new ImageIcon(HeadPanel.class.getResource("/com/tail/ui/previous.png"));
private static final int TAB_INSET_X = 4;
private static final int TAB_ICON_GAP = 3;
private List<HeadTab> tabs;
private JPanel toolbar;
private JButton previousButton;
private JButton nextButton;
private int selectedTab=-1;
private int overTab = -1;
private int offset =0;
public HeadPanel() {
super();
tabs = new ArrayList<HeadTab>();
setLayout(new BorderLayout());
toolbar = initToolBar();
add(toolbar, BorderLayout.EAST);
setFont(UIManager.getDefaults().getFont("TabbedPane.font").deriveFont(Font.PLAIN));
setSelectedTab(-1);
this.addMouseListener(new MouseAdapter(){
@Override
public void mousePressed(MouseEvent e) {
int tab =findTab(e);
if (tab!=-1){
setSelectedTab(tab);
}
}
public void mouseExited(MouseEvent e) {
setOverTab(-1);
}
});
this.addMouseMotionListener(new MouseAdapter(){
@Override
public void mouseMoved(MouseEvent e) {
int oldOverTab = overTab;
overTab = findTab(e);
if (overTab!=oldOverTab){
HeadPanel.this.repaint();
}
}
});
addTab("ctc_client.xml");
addTab("cctc.xml");
addTab("rpc_server.xml");
}
private JPanel initToolBar (){
JPanel toolbar = new JPanel(new FlowLayout(FlowLayout.CENTER, 2, 2));
//toolbar.setBorder(BorderFactory.createLineBorder(Color.GRAY));
toolbar.setOpaque(false);
previousButton = new JButton();
previousButton.setUI(new TailButtonUI());
previousButton.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
selectedTab--;
setSelectedTab(selectedTab);
}
});
previousButton.setIcon(new ImageIcon(HeadPanel.class.getResource("/com/tail/ui/previous.png")));
nextButton = new JButton();
nextButton.setUI(new TailButtonUI());
nextButton.setAction(new AbstractAction() {
@Override
public void actionPerformed(ActionEvent e) {
selectedTab++;
setSelectedTab(selectedTab);
}
});
nextButton.setIcon(new ImageIcon(HeadPanel.class.getResource("/com/tail/ui/next.png")));
toolbar.add(previousButton);
toolbar.add(nextButton);
return toolbar;
}
@Override
protected void paintComponent(Graphics g) {
paintTabs(g);
}
private int findTab(MouseEvent e){
if (!tabs.isEmpty()){
int x= e.getX()+offset;
for (int i = 0; i<tabs.size(); i++){
HeadTab tab = tabs.get(i);
if ((x >= tab.getX()) && x<(tab.getX()+tab.getWidth())){
return i;
}
}
}
return -1;
}
public void addTab(String title){
HeadTab tab = new HeadTab();
tab.setText(title);
tab.setWidth(getPreferredSize(title, EMPTY_ICON).width+2*TAB_INSET_X);
if (tabs.isEmpty()){
tab.setX(0);
}else{
HeadTab lastTab = tabs.get(tabs.size()-1);
tab.setX(lastTab.getX()+lastTab.getWidth()-1);
}
tabs.add(tab);
setSelectedTab(tabs.size()-1);
}
private void setSelectedTab(int i) {
selectedTab = i;
if (i==-1){
previousButton.setEnabled(true);
nextButton.setEnabled(true);
}else{
previousButton.setEnabled(i>0);
nextButton.setEnabled(i<(tabs.size()-1));
}
this.repaint();
}
private void setOverTab(int i){
int oldOverTab = overTab;
if (oldOverTab!=i){
overTab = i;
this.repaint();
}
}
private void recalculateOffsetIfNeccesary(int availableWidth){
HeadTab tab = tabs.get(selectedTab);
int maxTabX = tab.getX()+tab.getWidth()-1;
int maxAvailableX = offset+availableWidth-1;
if (maxTabX>maxAvailableX){
offset += (maxTabX-maxAvailableX);
if (selectedTab!=(tabs.size()-1)){
offset += 10;
}
} else if (offset>tab.getX()){
offset -= (offset-tab.getX());
if (selectedTab!=0){
offset -= 10;
}
}
}
private void paintTabs(Graphics g){
int availableWidth = this.getWidth()-toolbar.getWidth();
recalculateOffsetIfNeccesary(availableWidth);
Graphics2D g2 = (Graphics2D) g;
FontMetrics fm = this.getFontMetrics(getFont());
Shape oldClip = g.getClip();
Rectangle tabClip = new Rectangle(0, 0, availableWidth, this.getHeight());
g.setClip(tabClip);
for (int i=0; i<tabs.size(); i++){
HeadTab tab = tabs.get(i);
int x = tab.getX()-offset;
if (tab.getX() >= offset
|| offset<(tab.getX()+tab.getWidth())){
if (i==selectedTab){
g.setColor(Color.GRAY);
g.drawLine(x, 0, x+tab.getWidth()-1, 0);
g.drawLine(x, 0, x, getHeight()-1);
g.drawLine(x+tab.getWidth()-1, 0, x+tab.getWidth()-1, getHeight()-1);
g.drawLine(x,getHeight()-1, 0, getHeight()-1);
g.setClip(oldClip);
g.drawLine(x+tab.getWidth()-1, getHeight()-1, getWidth()-1, getHeight()-1);
g.setClip(tabClip);
}else{
if (i==overTab){
g.setColor(Color.LIGHT_GRAY.brighter());
}else{
g.setColor(Color.LIGHT_GRAY);
}
g.fillRect(x+2, 2, tab.getWidth()-4, getHeight()-4);
g.setColor(Color.GRAY);
g.drawRect(tab.getX()-offset, 0, tab.getWidth()-1, this.getHeight()-1);
}
Rectangle iconR = new Rectangle();
Rectangle textR = new Rectangle();
Rectangle rectR = new Rectangle(tab.getX()-offset+1,1,tab.getWidth(), getHeight()-2);
g.setColor(Color.GRAY.brighter());
SwingUtilities.layoutCompoundLabel(fm, tab.getText(), tab.getIcon(),
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.RIGHT,
rectR,
iconR,
textR, TAB_ICON_GAP);
tab.getIcon().paintIcon(this, g, iconR.x, iconR.y);
g.setColor(Color.BLACK);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB);
g.drawString(tab.getText(), textR.x, textR.y+fm.getAscent());
}
}
g.setClip(oldClip);
}
public Dimension getPreferredSize(String text, Icon icon)
{
FontMetrics fm = this.getFontMetrics(getFont());
Rectangle iconR = new Rectangle();
Rectangle textR = new Rectangle();
Rectangle viewR = new Rectangle();
iconR.x = iconR.y = iconR.width = iconR.height = 0;
textR.x = textR.y = textR.width = textR.height = 0;
viewR.x = 0;
viewR.y = 0;
viewR.width = viewR.height = Short.MAX_VALUE;
SwingUtilities.layoutCompoundLabel(fm, text, icon,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.CENTER,
SwingConstants.RIGHT,
viewR, iconR, textR, TAB_ICON_GAP);
int x1 = Math.min(iconR.x, textR.x);
int x2 = Math.max(iconR.x + iconR.width, textR.x + textR.width);
int y1 = Math.min(iconR.y, textR.y);
int y2 = Math.max(iconR.y + iconR.height, textR.y + textR.height);
Dimension rv = new Dimension(x2 - x1, y2 - y1);
return rv;
}
private class HeadTab {
private String text;
private int width;
private int x;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public Icon getIcon() {
return EMPTY_ICON;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
}