/* Copyright (C) 2005-2011 Fabio Riccardi */
package com.lightcrafts.ui.layout;
import com.lightcrafts.ui.LightZoneSkin;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
import javax.swing.border.EmptyBorder;
import javax.swing.border.CompoundBorder;
import javax.swing.*;
import java.util.prefs.Preferences;
import java.util.prefs.PreferenceChangeListener;
import java.util.prefs.PreferenceChangeEvent;
import java.awt.*;
/**
* A standard border for toolbar controls with a fixed style and a preference
* listener so that the borders can be toggled on and off globally.
* <p>
* If you just call JComponent.setBorder() with one of these, it will work,
* but it will not update when the global preference changes. Use
* setBorder() instead.
*/
public class ToggleTitleBorder
extends CompoundBorder implements PreferenceChangeListener
{
/**
* Set the border on the given component to a ToggleTitledBorder that
* will update dynamically when the global preference changes.
*/
public static void setBorder(JComponent comp, String title) {
ToggleTitleBorder border = new ToggleTitleBorder(comp, title);
Prefs.addPreferenceChangeListener(border);
comp.setBorder(border);
}
/**
* Reset the border on the given component, removing its global
* preference change listener and restoring its original border.
*/
public static void unsetBorder(JComponent comp) {
Border border = comp.getBorder();
if (border instanceof ToggleTitleBorder) {
ToggleTitleBorder ttborder = (ToggleTitleBorder) border;
Prefs.removePreferenceChangeListener(ttborder);
comp.setBorder(ttborder.original);
}
}
/**
* Remove borders recursively on this container and all of its descendants.
*/
public static void unsetAllBorders(JComponent comp) {
unsetBorder(comp);
Component[] children = comp.getComponents();
for (Component child : children) {
if (child instanceof JComponent) {
unsetAllBorders((JComponent) child);
}
}
}
public static void setShowBorders(boolean show) {
Prefs.putBoolean(ShowBordersKey, show);
}
public static boolean isShowBorders() {
return Prefs.getBoolean(ShowBordersKey, true);
}
private final static Preferences Prefs = Preferences.userRoot().node(
"/com/lightcrafts/ui/layout"
);
private final static String ShowBordersKey = "ShowToggleTitleBorders";
static class PlaceholderBorder extends EmptyBorder {
ToggleTitleBorder ttb;
PlaceholderBorder(ToggleTitleBorder ttb, Insets insets) {
super(insets);
this.ttb = ttb;
}
}
private static final RenderingHints aliasingRenderHints;
static {
aliasingRenderHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON
);
aliasingRenderHints.put(
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON
);
aliasingRenderHints.put(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY
);
}
static class LZTitleBorder extends TitledBorder {
ToggleTitleBorder ttb;
LZTitleBorder(ToggleTitleBorder ttb, String title) {
super(BorderFactory.createEmptyBorder(), title);
// super(BorderFactory.createLineBorder(Color.gray), title);
this.ttb = ttb;
titleColor = LightZoneSkin.Colors.LabelForeground;
}
// On Windows text aliasing is off for some reason...
public void paintBorder(Component jComponent, Graphics graphics, int x, int y, int width, int height) {
Graphics2D g = (Graphics2D) graphics;
g.setRenderingHints(aliasingRenderHints);
super.paintBorder(jComponent, graphics, x, y, width, height);
}
}
// The component that receives the border
private JComponent comp;
// The Border that actually displays the title
private LZTitleBorder title;
// A Border to replace the title Border when it is hidden
private PlaceholderBorder placeholder;
// The original Border of the component
private Border original;
private ToggleTitleBorder(JComponent comp, String text) {
this.comp = comp;
title = new LZTitleBorder(this, text);
title.setTitleJustification(TitledBorder.CENTER);
title.setTitlePosition(TitledBorder.BOTTOM);
Insets insets = getBorderInsets(comp);
insets.top = 0;
insets.bottom = 0;
placeholder = new PlaceholderBorder(this, insets);
original = comp.getBorder();
insideBorder = original;
outsideBorder = isShowBorders() ? title : placeholder;
}
public void preferenceChange(PreferenceChangeEvent evt) {
boolean show = isShowBorders();
if (show) {
outsideBorder = title;
}
else {
outsideBorder = placeholder;
}
comp.revalidate();
comp.repaint();
}
}