package com.explodingpixels.macwidgets;
import java.awt.BorderLayout;
import java.awt.Cursor;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.SwingUtilities;
import javax.swing.border.Border;
import com.explodingpixels.widgets.PopdownButton;
import com.explodingpixels.widgets.PopupMenuCustomizer;
public class ComponentBottomBar extends TriAreaComponent {
protected static final ImageIcon SPLITTER_HANDLE =
new ImageIcon(SourceListControlBar.class.getResource(
"/com/explodingpixels/macwidgets/images/splitter_handle.png"));
protected JSplitPane fSplitPane;
protected final JLabel fSplitterHandle = new JLabel(SPLITTER_HANDLE);
protected final SplitterHandleMouseMovementHandler fMouseListener =
new SplitterHandleMouseMovementHandler();
public ComponentBottomBar() {
super();
setBackgroundPainter(MacButtonFactory.GRADIENT_BUTTON_IMAGE_PAINTER);
getComponent().setBorder(
BorderFactory.createMatteBorder(1, 0, 0, 0,
MacButtonFactory.GRADIENT_BUTTON_BORDER_COLOR));
}
public void addComponentToLeftWithBorder(JComponent toolToAdd) {
JPanel panel = new JPanel(new BorderLayout());
panel.setOpaque(false);
panel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1,
MacButtonFactory.GRADIENT_BUTTON_BORDER_COLOR));
panel.add(toolToAdd, BorderLayout.CENTER);
super.addComponentToLeft(panel);
}
public void addComponentToCenterWithBorder(JComponent toolToAdd) {
// TODO use matteBorder when on first center item addition.
// if this is the first component being added, add a line to the left
// and right of the component.
// else add a border just to the right.
Border matteBorder = getCenterComponentCount() == 0 ? BorderFactory
.createMatteBorder(0, 1, 0, 1,
MacButtonFactory.GRADIENT_BUTTON_BORDER_COLOR)
: BorderFactory.createMatteBorder(0, 0, 0, 1,
MacButtonFactory.GRADIENT_BUTTON_BORDER_COLOR);
JPanel panel = new JPanel(new BorderLayout());
panel.setOpaque(false);
panel.setBorder(BorderFactory.createMatteBorder(0, 0, 0, 1,
MacButtonFactory.GRADIENT_BUTTON_BORDER_COLOR));
panel.add(toolToAdd, BorderLayout.CENTER);
super.addComponentToCenter(panel);
}
public void addComponentToRightWithBorder(JComponent toolToAdd) {
JPanel panel = new JPanel(new BorderLayout());
panel.setOpaque(false);
panel.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0,
MacButtonFactory.GRADIENT_BUTTON_BORDER_COLOR));
panel.add(toolToAdd, BorderLayout.CENTER);
super.addComponentToRight(panel);
}
/**
* Connects the draggable widget in this {@code ComponentBottomBar} to the divider of the
* given {@link javax.swing.JSplitPane}. Thus when the user drags the {@code ComponentBottomBar} draggable
* widget, the given {@code JSplitPane}s divider location will be adjusted.
*
* DO THIS LAST AFTER YOU ADD ALL OTHER COMPONENTS TO THE RIGHT
*
* @param splitPane the {@code JSplitPane} to connect the draggable widget to.
*/
public void installDraggableWidgetOnSplitPane(JSplitPane splitPane) {
if (splitPane == null) {
throw new IllegalArgumentException("JSplitPane cannot be null.");
}
fSplitPane = splitPane;
fSplitterHandle.addMouseListener(fMouseListener);
fSplitterHandle.addMouseMotionListener(fMouseListener);
addComponentToRight(fSplitterHandle);
fSplitterHandle.setCursor(Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
}
/**
* Add a new pop-down style button. The given {@link com.explodingpixels.widgets.PopupMenuCustomizer} will be called just
* prior to each showing of the menu.
*
* @param icon the icon to use in the pop-down menu.
* @param popupMenuCustomizer the {@code PopupMenuCustomizer} to be called just prior to showing
* the menu.
*/
public PopdownButton createAndAddPopdownButton(Icon icon, PopupMenuCustomizer popupMenuCustomizer) {
PopdownButton button = MacButtonFactory.createGradientPopdownButton(
icon, popupMenuCustomizer);
initBottomBarButton(button.getComponent());
addComponentToLeft(button.getComponent());
return button;
}
/**
* Adds a new button with the given icon. The given {@link java.awt.event.ActionListener} will be called when
* the button is pressed.
*
* @param icon the icon to use for the button.
* @param actionListener the {@code ActionListener} to call when the button is pressed.
*/
public JComponent createAndAddButton(Icon icon, ActionListener actionListener) {
JComponent button = MacButtonFactory.createGradientButton(icon, actionListener);
initBottomBarButton(button);
addComponentToLeft(button);
return button;
}
static void initBottomBarButton(JComponent component) {
component.setBorder(BorderFactory.createEmptyBorder());
}
/**
* Hides the resize handle.
*/
public void hideResizeHandle() {
fSplitterHandle.setVisible(false);
}
// Mouse handler for splitter control widget. /////////////////////////////////////////////////
protected class SplitterHandleMouseMovementHandler extends MouseAdapter
implements MouseMotionListener {
private int fDelta;
@Override
public void mousePressed(MouseEvent e) {
MouseEvent convertedEvent =
SwingUtilities.convertMouseEvent(fSplitterHandle, e, fSplitPane);
fDelta = fSplitPane.getDividerLocation() - convertedEvent.getPoint().x;
}
// MouseMotionListener implementation /////////////////////////////////////////////////////
public void mouseDragged(MouseEvent e) {
MouseEvent convertedEvent =
SwingUtilities.convertMouseEvent(fSplitterHandle, e, fSplitPane);
int newLocation = convertedEvent.getPoint().x + fDelta;
// bound newLocation between the minimum and maximum divider locations.
int boundedNewLocation = Math.max(fSplitPane.getMinimumDividerLocation(),
Math.min(newLocation, fSplitPane.getMaximumDividerLocation()));
fSplitPane.setDividerLocation(boundedNewLocation);
}
public void mouseMoved(MouseEvent e) {
}
}
}