package timeflow.app.ui;
|
|
import javax.swing.*;
|
import javax.swing.event.ChangeListener;
|
|
import java.awt.*;
|
import java.awt.event.*;
|
import java.util.*;
|
|
// custom JTabbedPane-like thing.
|
public class LinkTabPane extends JPanel {
|
|
ArrayList<String> tabNames=new ArrayList<String>();
|
HashMap<String, JComponent> tabMap=new HashMap<String, JComponent>();
|
String currentName;
|
CardLayout cards=new CardLayout();
|
JPanel center=new JPanel();
|
LinkTop top=new LinkTop();
|
|
public LinkTabPane()
|
{
|
setBackground(Color.white);
|
setLayout(new BorderLayout());
|
add(top, BorderLayout.NORTH);
|
add(center, BorderLayout.CENTER);
|
center.setLayout(cards);
|
top.addMouseListener(new MouseAdapter() {
|
@Override
|
public void mousePressed(MouseEvent e) {
|
String s=top.getName(e.getX());
|
if (s!=null)
|
{
|
String old=currentName;
|
setCurrentName(s);
|
firePropertyChange("tab", old, s);
|
}
|
}});
|
}
|
|
public String getTitleAt(int i)
|
{
|
return tabNames.get(i);
|
}
|
|
public void setSelectedIndex(int i)
|
{
|
setCurrentName(getTitleAt(i));
|
}
|
|
public void addTab(JComponent component, String name, boolean left)
|
{
|
tabNames.add(name);
|
tabMap.put(name, component);
|
center.add(component, name);
|
top.addName(name, left);
|
repaint();
|
if (currentName==null)
|
currentName=name;
|
}
|
|
public String getCurrentName()
|
{
|
return currentName;
|
}
|
|
public void setCurrentName(final String currentName)
|
{
|
this.currentName=currentName;
|
top.repaint();
|
SwingUtilities.invokeLater(new Runnable() {public void run() {cards.show(center, currentName);}});
|
|
}
|
|
class LinkTop extends JPanel
|
{
|
int left, right;
|
ArrayList<HotLink> leftHots=new ArrayList<HotLink>();
|
ArrayList<HotLink> rightHots=new ArrayList<HotLink>();
|
Font font=new Font("Verdana", Font.PLAIN, 14);
|
FontMetrics fm=getFontMetrics(font);
|
|
LinkTop()
|
{
|
setLayout(new FlowLayout(FlowLayout.LEFT));
|
setBackground(new Color(220,220,220));
|
}
|
|
public void paintComponent(Graphics g1)
|
{
|
int w=getSize().width, h=getSize().height;
|
Graphics2D g=(Graphics2D)g1;
|
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
|
g.setColor(getBackground());
|
g.fillRect(0,0,w,h);
|
g.setColor(Color.gray);
|
for (int i=0; i<2; i++)
|
{
|
g.drawLine(0,i,w,i);
|
g.drawLine(0,h-1-i,w,h-1-i);
|
}
|
|
for (HotLink hot: leftHots)
|
{
|
draw(g, hot, h, 0);
|
}
|
|
for (HotLink hot: rightHots)
|
{
|
draw(g, hot, h, w);
|
}
|
|
for (int i=0; i<leftHots.size(); i++)
|
{
|
|
if (i<leftHots.size()-1)
|
{
|
HotLink hot=leftHots.get(i);
|
for (int j=0; j<1; j++)
|
g.drawLine(hot.x+hot.width-1-j, 7, hot.x+hot.width-1-j, h-7);
|
}
|
}
|
|
for (int i=0; i<rightHots.size(); i++)
|
{
|
|
if (i<rightHots.size()-1)
|
{
|
HotLink hot=rightHots.get(i);
|
for (int j=0; j<1; j++)
|
g.drawLine(hot.x+w-1-j, 7, hot.x+w-1-j, h-7);
|
}
|
}
|
}
|
|
void draw(Graphics g, HotLink hot, int h, int dx)
|
{
|
int x=hot.x+dx;
|
if (hot.s.equals(currentName))
|
{
|
g.setColor(Color.lightGray);
|
g.fillRect(x,2,hot.width,h-4);
|
g.setColor(Color.gray);
|
g.drawLine(x-1, 0, x-1, h);
|
g.drawLine(x+hot.width-1, 0, x+hot.width-1, h);
|
}
|
g.setColor(Color.darkGray);
|
g.setFont(font);
|
int sw=fm.stringWidth(hot.s);
|
g.drawString(hot.s, x+(hot.width-sw)/2, h-10);
|
|
}
|
|
String getName(int x)
|
{
|
for (HotLink h: leftHots)
|
{
|
if (h.x<=x && h.x+h.width>x)
|
return h.s;
|
}
|
for (HotLink h: rightHots)
|
{
|
int w=getSize().width;
|
if (h.x+w<=x && h.x+h.width+w>x)
|
return h.s;
|
}
|
|
if (leftHots.size()>0)
|
return leftHots.get(leftHots.size()-1).s;
|
if (rightHots.size()>0)
|
return rightHots.get(0).s;
|
return null;
|
}
|
|
void addName(String name, boolean leftward)
|
{
|
if (leftward)
|
{
|
int x=right;
|
int w=fm.stringWidth(name)+24;
|
leftHots.add(new HotLink(name, x, 0, w, 30));
|
right+=w;
|
}
|
else
|
{
|
int x=left;
|
int w=fm.stringWidth(name)+24;
|
rightHots.add(new HotLink(name, x-w, 0, w, 30));
|
left-=w;
|
}
|
}
|
|
class HotLink extends Rectangle
|
{
|
String s;
|
HotLink(String s, int x, int y, int w, int h)
|
{
|
super(x,y,w,h);
|
this.s=s;
|
}
|
}
|
|
public Dimension getPreferredSize()
|
{
|
return new Dimension(30,30);
|
}
|
}
|
|
}
|