package tripane;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Insets;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JSplitPane;
import javax.swing.OverlayLayout;
@SuppressWarnings("serial")
public class TriPane extends JComponent {
private enum SideEnum {
Left,
Right,
}
private final int DIVIDER_WIDTH = 2;
private final int COLLAPSED_WIDTH = 1;
private final int EXPAND_WIDTH = 250;
private final int TOGGLE_BUTTON_SIZE = 20;
private final int MAX_WINDOW_WIDTH = 10000; // use some high value
private static final boolean USE_ANIMATION = true;
private JSplitPane m_jSplitPane_left = null;
private JSplitPane m_jSplitPane_right = null;
private JComponent m_holder = null;
private JButton m_jButton_toggleLeft = null;
private JButton m_jButton_toggleRight = null;
private boolean m_initialized = false;
//###########################################################################
/**
* Constructor
*/
public TriPane() {
m_jSplitPane_left = new JSplitPane();
m_jSplitPane_left.setDividerSize(DIVIDER_WIDTH);
m_jSplitPane_left.setResizeWeight(0);
m_jSplitPane_right = new JSplitPane();
m_jSplitPane_right.setDividerSize(DIVIDER_WIDTH);
m_jSplitPane_right.setResizeWeight(1);
m_jButton_toggleLeft = createToggleButton(SideEnum.Left);
m_jButton_toggleRight = createToggleButton(SideEnum.Right);
m_jSplitPane_left.addPropertyChangeListener("dividerLocation", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if(Integer.parseInt( evt.getNewValue().toString() ) == COLLAPSED_WIDTH) {
m_jButton_toggleLeft.setText(TO_THE_RIGHT);
} else {
m_jButton_toggleLeft.setText(TO_THE_LEFT);
}
}
});
m_jSplitPane_right.addPropertyChangeListener("dividerLocation", new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if( isAlmostEqual( Integer.parseInt(evt.getNewValue().toString()), m_jSplitPane_right.getSize().width) ) {
m_jButton_toggleRight.setText(TO_THE_LEFT);
} else {
m_jButton_toggleRight.setText(TO_THE_RIGHT);
}
}
});
this.addComponentListener(new ComponentListener() {
public void componentMoved(ComponentEvent arg0) {}
public void componentHidden(ComponentEvent arg0) {}
public void componentShown(ComponentEvent arg0) {}
public void componentResized(ComponentEvent arg0) {
// because componentShown() event did not occur in my tests
if(!m_initialized) {
setLeftToggleState(true);
setRightToggleState(true);
m_initialized = true;
} else {
/*
if(m_jSplitPane_right.getWidth() < 2*EXPAND_WIDTH) {
setLeftToggleState(false);
} else {
if(m_jSplitPane_right.getWidth() < 3*EXPAND_WIDTH) {
setRightToggleState(false);
} else {
setRightToggleState(getRightToggleState());
}
}
*/
}
}
});
// +----------------------------------------+------------+
// | +------------+-----------------------+ | |
// | | | | | |
// | | | | | |
// | | | | | |
// | | | | | |
// | | | | | |
// | | | | | |
// | | | | | |
// | | | | | |
// | | | | | |
// | +------------+-----------------------+ | |
// +----------------------------------------+------------+
m_jSplitPane_right.setLeftComponent(m_jSplitPane_left);
this.setLayout( new BorderLayout() );
this.add(m_jSplitPane_right, BorderLayout.CENTER);
}
//###########################################################################
public void setLeftComponent(Component leftComponent) {
m_jSplitPane_left.setLeftComponent(leftComponent);
}
public Component getLeftComponent() {
return m_jSplitPane_left.getLeftComponent();
}
//---------------------------------------------------------------------------
public void setCenterComponent(Component centerComponent) {
m_holder = (JComponent)centerComponent;
//important! - otherwise project preview cannot be placed correctly in overlay mode
m_holder.setAlignmentX(1.0f);
m_holder.setAlignmentY(1.0f);
m_holder.setLayout( new OverlayLayout(m_holder) );
addToggleButtons(m_holder);
m_jSplitPane_left.setRightComponent(m_holder);
}
public Component getCenterComponent() {
return m_jSplitPane_right.getLeftComponent();
}
//---------------------------------------------------------------------------
public void setRightComponent(Component rightComponent) {
m_jSplitPane_right.setRightComponent(rightComponent);
}
public Component getRightComponent() {
return m_jSplitPane_right.getRightComponent();
}
//###########################################################################
final String TO_THE_RIGHT = ">";
final String TO_THE_LEFT = "<";
public boolean getLeftToggleState() {
return m_jButton_toggleLeft.getText().equals(TO_THE_LEFT);
}
public boolean getRightToggleState() {
return m_jButton_toggleRight.getText().equals(TO_THE_RIGHT);
}
public void setLeftToggleState(boolean enable) {
if(enable) {
//slide(m_jSplitPane_left, COLLAPSED_WIDTH, EXPAND_WIDTH);
m_jSplitPane_left.setDividerLocation(EXPAND_WIDTH);
} else {
m_jSplitPane_left.setDividerLocation(COLLAPSED_WIDTH);
}
}
public void setRightToggleState(boolean enable) {
if(enable) {
m_jSplitPane_right.setDividerLocation(m_jSplitPane_right.getSize().width - EXPAND_WIDTH);
} else {
m_jSplitPane_right.setDividerLocation(m_jSplitPane_right.getSize().width);
}
}
public void toggleLeftPane() {
setLeftToggleState( !getLeftToggleState() );
}
public void toggleRightPane() {
setRightToggleState( !getRightToggleState() );
}
public void addToggleButtons(JComponent toPlaceOn) {
JComponent holder = new JLabel();
// use MaximumSize in OverlayLayout!
holder.setMaximumSize( new Dimension(MAX_WINDOW_WIDTH, TOGGLE_BUTTON_SIZE) );
holder.setAlignmentX(0.0f);
holder.setAlignmentY(0.0f);
holder.setLayout( new BorderLayout() );
holder.add(m_jButton_toggleLeft, BorderLayout.WEST);
holder.add(m_jButton_toggleRight, BorderLayout.EAST);
toPlaceOn.setAlignmentX(1.0f);
toPlaceOn.setAlignmentY(1.0f);
toPlaceOn.setLayout( new OverlayLayout(toPlaceOn) );
toPlaceOn.add(holder);
}
public JButton createToggleButton(final SideEnum side) {
JButton button = new JButton();
button.setAlignmentX(0.0f);
button.setAlignmentY(0.0f);
button.setPreferredSize( new Dimension(TOGGLE_BUTTON_SIZE, TOGGLE_BUTTON_SIZE) );
button.setMargin( new Insets(0,0,0,0) );
button.setFont( new Font("Dialog", Font.BOLD, 12) );
button.setText(TO_THE_LEFT);
button.setOpaque(false);
button.addMouseListener( new MouseListener() {
@Override public void mouseClicked(MouseEvent e) {}
@Override public void mousePressed(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent arg0) {
((JButton)arg0.getSource()).setOpaque(true);
}
@Override
public void mouseExited(MouseEvent arg0) {
((JButton)arg0.getSource()).setOpaque(false);
}
@Override
public void mouseReleased(MouseEvent e) {
switch(side) {
case Left: ((TriPane)m_jSplitPane_left.getParent().getParent()).toggleLeftPane(); break;
case Right: ((TriPane)m_jSplitPane_right.getParent()).toggleRightPane(); break;
}
}
});
return button;
}
//###########################################################################
// not used - did not work as expected...
static void slide(JSplitPane splitPane, int from, int to) {
if(USE_ANIMATION) {
for(int i=from; i<to; i+=(to-from)/10) {
System.out.println(i);
splitPane.setDividerLocation(i);
try { Thread.sleep(10); } catch (InterruptedException e) {}
}
}
splitPane.setDividerLocation(to);
}
//---------------------------------------------------------------------------
static boolean isAlmostEqual(int value1, int value2, int tolerance) {
return (value1 >= value2-tolerance && value1 <= value2+tolerance);
}
static boolean isAlmostEqual(int value1, int value2) {
return isAlmostEqual(value1, value2, 10);
}
/**
* Demo
* @param args
*/
public static void main(String[] args) {
JLabel jl1 = new JLabel("Left");
JLabel jl2 = new JLabel("Center");
JLabel jl3 = new JLabel("Right");
JButton jb1 = new JButton("Left");
JButton jb2 = new JButton("Center");
JButton jb3 = new JButton("Right");
JFrame win = new JFrame();
TriPane tri = new TriPane();
if(true) {
tri.setLeftComponent(jl1);
tri.setCenterComponent(jl2);
tri.setRightComponent(jl3);
} else {
tri.setLeftComponent(jb1);
tri.setCenterComponent(jb2);
tri.setRightComponent(jb3);
}
win.add(tri);
win.setSize(800, 600);
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setVisible(true);
}
}