|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
|
|
package javax.swing.plaf.synth; |
|
|
|
import java.awt.*; |
|
import java.awt.event.*; |
|
import javax.swing.*; |
|
import javax.swing.plaf.*; |
|
import javax.swing.plaf.basic.BasicInternalFrameTitlePane; |
|
import java.beans.PropertyChangeListener; |
|
import java.beans.PropertyChangeEvent; |
|
import java.beans.PropertyVetoException; |
|
import sun.swing.SwingUtilities2; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
*/ |
|
class SynthInternalFrameTitlePane extends BasicInternalFrameTitlePane |
|
implements SynthUI, PropertyChangeListener { |
|
|
|
protected JPopupMenu systemPopupMenu; |
|
protected JButton menuButton; |
|
|
|
private SynthStyle style; |
|
private int titleSpacing; |
|
private int buttonSpacing; |
|
|
|
private int titleAlignment; |
|
|
|
public SynthInternalFrameTitlePane(JInternalFrame f) { |
|
super(f); |
|
} |
|
|
|
public String getUIClassID() { |
|
return "InternalFrameTitlePaneUI"; |
|
} |
|
|
|
public SynthContext getContext(JComponent c) { |
|
return getContext(c, getComponentState(c)); |
|
} |
|
|
|
public SynthContext getContext(JComponent c, int state) { |
|
return SynthContext.getContext(c, style, state); |
|
} |
|
|
|
private Region getRegion(JComponent c) { |
|
return SynthLookAndFeel.getRegion(c); |
|
} |
|
|
|
private int getComponentState(JComponent c) { |
|
if (frame != null) { |
|
if (frame.isSelected()) { |
|
return SELECTED; |
|
} |
|
} |
|
return SynthLookAndFeel.getComponentState(c); |
|
} |
|
|
|
protected void addSubComponents() { |
|
menuButton.setName("InternalFrameTitlePane.menuButton"); |
|
iconButton.setName("InternalFrameTitlePane.iconifyButton"); |
|
maxButton.setName("InternalFrameTitlePane.maximizeButton"); |
|
closeButton.setName("InternalFrameTitlePane.closeButton"); |
|
|
|
add(menuButton); |
|
add(iconButton); |
|
add(maxButton); |
|
add(closeButton); |
|
} |
|
|
|
protected void installListeners() { |
|
super.installListeners(); |
|
frame.addPropertyChangeListener(this); |
|
addPropertyChangeListener(this); |
|
} |
|
|
|
protected void uninstallListeners() { |
|
frame.removePropertyChangeListener(this); |
|
removePropertyChangeListener(this); |
|
super.uninstallListeners(); |
|
} |
|
|
|
private void updateStyle(JComponent c) { |
|
SynthContext context = getContext(this, ENABLED); |
|
SynthStyle oldStyle = style; |
|
style = SynthLookAndFeel.updateStyle(context, this); |
|
if (style != oldStyle) { |
|
maxIcon = |
|
style.getIcon(context,"InternalFrameTitlePane.maximizeIcon"); |
|
minIcon = |
|
style.getIcon(context,"InternalFrameTitlePane.minimizeIcon"); |
|
iconIcon = |
|
style.getIcon(context,"InternalFrameTitlePane.iconifyIcon"); |
|
closeIcon = |
|
style.getIcon(context,"InternalFrameTitlePane.closeIcon"); |
|
titleSpacing = style.getInt(context, |
|
"InternalFrameTitlePane.titleSpacing", 2); |
|
buttonSpacing = style.getInt(context, |
|
"InternalFrameTitlePane.buttonSpacing", 2); |
|
String alignString = (String)style.get(context, |
|
"InternalFrameTitlePane.titleAlignment"); |
|
titleAlignment = SwingConstants.LEADING; |
|
if (alignString != null) { |
|
alignString = alignString.toUpperCase(); |
|
if (alignString.equals("TRAILING")) { |
|
titleAlignment = SwingConstants.TRAILING; |
|
} |
|
else if (alignString.equals("CENTER")) { |
|
titleAlignment = SwingConstants.CENTER; |
|
} |
|
} |
|
} |
|
context.dispose(); |
|
} |
|
|
|
protected void installDefaults() { |
|
super.installDefaults(); |
|
updateStyle(this); |
|
} |
|
|
|
protected void uninstallDefaults() { |
|
SynthContext context = getContext(this, ENABLED); |
|
style.uninstallDefaults(context); |
|
context.dispose(); |
|
style = null; |
|
JInternalFrame.JDesktopIcon di = frame.getDesktopIcon(); |
|
if(di != null && di.getComponentPopupMenu() == systemPopupMenu) { |
|
|
|
di.setComponentPopupMenu(null); |
|
} |
|
super.uninstallDefaults(); |
|
} |
|
|
|
private static class JPopupMenuUIResource extends JPopupMenu implements |
|
UIResource { } |
|
|
|
protected void assembleSystemMenu() { |
|
systemPopupMenu = new JPopupMenuUIResource(); |
|
addSystemMenuItems(systemPopupMenu); |
|
enableActions(); |
|
menuButton = createNoFocusButton(); |
|
updateMenuIcon(); |
|
menuButton.addMouseListener(new MouseAdapter() { |
|
public void mousePressed(MouseEvent e) { |
|
try { |
|
frame.setSelected(true); |
|
} catch(PropertyVetoException pve) { |
|
} |
|
showSystemMenu(); |
|
} |
|
}); |
|
JPopupMenu p = frame.getComponentPopupMenu(); |
|
if (p == null || p instanceof UIResource) { |
|
frame.setComponentPopupMenu(systemPopupMenu); |
|
} |
|
if (frame.getDesktopIcon() != null) { |
|
p = frame.getDesktopIcon().getComponentPopupMenu(); |
|
if (p == null || p instanceof UIResource) { |
|
frame.getDesktopIcon().setComponentPopupMenu(systemPopupMenu); |
|
} |
|
} |
|
setInheritsPopupMenu(true); |
|
} |
|
|
|
protected void addSystemMenuItems(JPopupMenu menu) { |
|
JMenuItem mi = menu.add(restoreAction); |
|
mi.setMnemonic(getButtonMnemonic("restore")); |
|
mi = menu.add(moveAction); |
|
mi.setMnemonic(getButtonMnemonic("move")); |
|
mi = menu.add(sizeAction); |
|
mi.setMnemonic(getButtonMnemonic("size")); |
|
mi = menu.add(iconifyAction); |
|
mi.setMnemonic(getButtonMnemonic("minimize")); |
|
mi = menu.add(maximizeAction); |
|
mi.setMnemonic(getButtonMnemonic("maximize")); |
|
menu.add(new JSeparator()); |
|
mi = menu.add(closeAction); |
|
mi.setMnemonic(getButtonMnemonic("close")); |
|
} |
|
|
|
private static int getButtonMnemonic(String button) { |
|
try { |
|
return Integer.parseInt(UIManager.getString( |
|
"InternalFrameTitlePane." + button + "Button.mnemonic")); |
|
} catch (NumberFormatException e) { |
|
return -1; |
|
} |
|
} |
|
|
|
protected void showSystemMenu() { |
|
Insets insets = frame.getInsets(); |
|
if (!frame.isIcon()) { |
|
systemPopupMenu.show(frame, menuButton.getX(), getY() + getHeight()); |
|
} else { |
|
systemPopupMenu.show(menuButton, |
|
getX() - insets.left - insets.right, |
|
getY() - systemPopupMenu.getPreferredSize().height - |
|
insets.bottom - insets.top); |
|
} |
|
} |
|
|
|
|
|
public void paintComponent(Graphics g) { |
|
SynthContext context = getContext(this); |
|
SynthLookAndFeel.update(context, g); |
|
context.getPainter().paintInternalFrameTitlePaneBackground(context, |
|
g, 0, 0, getWidth(), getHeight()); |
|
paint(context, g); |
|
context.dispose(); |
|
} |
|
|
|
protected void paint(SynthContext context, Graphics g) { |
|
String title = frame.getTitle(); |
|
|
|
if (title != null) { |
|
SynthStyle style = context.getStyle(); |
|
|
|
g.setColor(style.getColor(context, ColorType.TEXT_FOREGROUND)); |
|
g.setFont(style.getFont(context)); |
|
|
|
|
|
FontMetrics fm = SwingUtilities2.getFontMetrics(frame, g); |
|
int baseline = (getHeight() + fm.getAscent() - fm.getLeading() - |
|
fm.getDescent()) / 2; |
|
JButton lastButton = null; |
|
if (frame.isIconifiable()) { |
|
lastButton = iconButton; |
|
} |
|
else if (frame.isMaximizable()) { |
|
lastButton = maxButton; |
|
} |
|
else if (frame.isClosable()) { |
|
lastButton = closeButton; |
|
} |
|
int maxX; |
|
int minX; |
|
boolean ltr = SynthLookAndFeel.isLeftToRight(frame); |
|
int titleAlignment = this.titleAlignment; |
|
if (ltr) { |
|
if (lastButton != null) { |
|
maxX = lastButton.getX() - titleSpacing; |
|
} |
|
else { |
|
maxX = frame.getWidth() - frame.getInsets().right - |
|
titleSpacing; |
|
} |
|
minX = menuButton.getX() + menuButton.getWidth() + |
|
titleSpacing; |
|
} |
|
else { |
|
if (lastButton != null) { |
|
minX = lastButton.getX() + lastButton.getWidth() + |
|
titleSpacing; |
|
} |
|
else { |
|
minX = frame.getInsets().left + titleSpacing; |
|
} |
|
maxX = menuButton.getX() - titleSpacing; |
|
if (titleAlignment == SwingConstants.LEADING) { |
|
titleAlignment = SwingConstants.TRAILING; |
|
} |
|
else if (titleAlignment == SwingConstants.TRAILING) { |
|
titleAlignment = SwingConstants.LEADING; |
|
} |
|
} |
|
String clippedTitle = getTitle(title, fm, maxX - minX); |
|
if (clippedTitle == title) { |
|
|
|
if (titleAlignment == SwingConstants.TRAILING) { |
|
minX = maxX - style.getGraphicsUtils(context). |
|
computeStringWidth(context, g.getFont(), fm, title); |
|
} |
|
else if (titleAlignment == SwingConstants.CENTER) { |
|
int width = style.getGraphicsUtils(context). |
|
computeStringWidth(context, g.getFont(), fm, title); |
|
minX = Math.max(minX, (getWidth() - width) / 2); |
|
minX = Math.min(maxX - width, minX); |
|
} |
|
} |
|
style.getGraphicsUtils(context).paintText( |
|
context, g, clippedTitle, minX, baseline - fm.getAscent(), -1); |
|
} |
|
} |
|
|
|
public void paintBorder(SynthContext context, Graphics g, int x, |
|
int y, int w, int h) { |
|
context.getPainter().paintInternalFrameTitlePaneBorder(context, |
|
g, x, y, w, h); |
|
} |
|
|
|
protected LayoutManager createLayout() { |
|
SynthContext context = getContext(this); |
|
LayoutManager lm = |
|
(LayoutManager)style.get(context, "InternalFrameTitlePane.titlePaneLayout"); |
|
context.dispose(); |
|
return (lm != null) ? lm : new SynthTitlePaneLayout(); |
|
} |
|
|
|
public void propertyChange(PropertyChangeEvent evt) { |
|
if (evt.getSource() == this) { |
|
if (SynthLookAndFeel.shouldUpdateStyle(evt)) { |
|
updateStyle(this); |
|
} |
|
} |
|
else { |
|
|
|
if (evt.getPropertyName() == JInternalFrame.FRAME_ICON_PROPERTY) { |
|
updateMenuIcon(); |
|
} |
|
} |
|
} |
|
|
|
|
|
|
|
*/ |
|
private void updateMenuIcon() { |
|
Icon frameIcon = frame.getFrameIcon(); |
|
SynthContext context = getContext(this); |
|
if (frameIcon != null) { |
|
Dimension maxSize = (Dimension)context.getStyle().get(context, |
|
"InternalFrameTitlePane.maxFrameIconSize"); |
|
int maxWidth = 16; |
|
int maxHeight = 16; |
|
if (maxSize != null) { |
|
maxWidth = maxSize.width; |
|
maxHeight = maxSize.height; |
|
} |
|
if ((frameIcon.getIconWidth() > maxWidth || |
|
frameIcon.getIconHeight() > maxHeight) && |
|
(frameIcon instanceof ImageIcon)) { |
|
frameIcon = new ImageIcon(((ImageIcon)frameIcon). |
|
getImage().getScaledInstance(maxWidth, maxHeight, |
|
Image.SCALE_SMOOTH)); |
|
} |
|
} |
|
context.dispose(); |
|
menuButton.setIcon(frameIcon); |
|
} |
|
|
|
|
|
class SynthTitlePaneLayout implements LayoutManager { |
|
public void addLayoutComponent(String name, Component c) {} |
|
public void removeLayoutComponent(Component c) {} |
|
public Dimension preferredLayoutSize(Container c) { |
|
return minimumLayoutSize(c); |
|
} |
|
|
|
public Dimension minimumLayoutSize(Container c) { |
|
SynthContext context = getContext( |
|
SynthInternalFrameTitlePane.this); |
|
int width = 0; |
|
int height = 0; |
|
|
|
int buttonCount = 0; |
|
Dimension pref; |
|
|
|
if (frame.isClosable()) { |
|
pref = closeButton.getPreferredSize(); |
|
width += pref.width; |
|
height = Math.max(pref.height, height); |
|
buttonCount++; |
|
} |
|
if (frame.isMaximizable()) { |
|
pref = maxButton.getPreferredSize(); |
|
width += pref.width; |
|
height = Math.max(pref.height, height); |
|
buttonCount++; |
|
} |
|
if (frame.isIconifiable()) { |
|
pref = iconButton.getPreferredSize(); |
|
width += pref.width; |
|
height = Math.max(pref.height, height); |
|
buttonCount++; |
|
} |
|
pref = menuButton.getPreferredSize(); |
|
width += pref.width; |
|
height = Math.max(pref.height, height); |
|
|
|
width += Math.max(0, (buttonCount - 1) * buttonSpacing); |
|
|
|
FontMetrics fm = SynthInternalFrameTitlePane.this.getFontMetrics( |
|
getFont()); |
|
SynthGraphicsUtils graphicsUtils = context.getStyle(). |
|
getGraphicsUtils(context); |
|
String frameTitle = frame.getTitle(); |
|
int title_w = frameTitle != null ? graphicsUtils. |
|
computeStringWidth(context, fm.getFont(), |
|
fm, frameTitle) : 0; |
|
int title_length = frameTitle != null ? frameTitle.length() : 0; |
|
|
|
|
|
if (title_length > 3) { |
|
int subtitle_w = graphicsUtils.computeStringWidth(context, |
|
fm.getFont(), fm, frameTitle.substring(0, 3) + "..."); |
|
width += (title_w < subtitle_w) ? title_w : subtitle_w; |
|
} else { |
|
width += title_w; |
|
} |
|
|
|
height = Math.max(fm.getHeight() + 2, height); |
|
|
|
width += titleSpacing + titleSpacing; |
|
|
|
Insets insets = getInsets(); |
|
height += insets.top + insets.bottom; |
|
width += insets.left + insets.right; |
|
context.dispose(); |
|
return new Dimension(width, height); |
|
} |
|
|
|
private int center(Component c, Insets insets, int x, |
|
boolean trailing) { |
|
Dimension pref = c.getPreferredSize(); |
|
if (trailing) { |
|
x -= pref.width; |
|
} |
|
c.setBounds(x, insets.top + |
|
(getHeight() - insets.top - insets.bottom - |
|
pref.height) / 2, pref.width, pref.height); |
|
if (pref.width > 0) { |
|
if (trailing) { |
|
return x - buttonSpacing; |
|
} |
|
return x + pref.width + buttonSpacing; |
|
} |
|
return x; |
|
} |
|
|
|
public void layoutContainer(Container c) { |
|
Insets insets = c.getInsets(); |
|
Dimension pref; |
|
|
|
if (SynthLookAndFeel.isLeftToRight(frame)) { |
|
center(menuButton, insets, insets.left, false); |
|
int x = getWidth() - insets.right; |
|
if (frame.isClosable()) { |
|
x = center(closeButton, insets, x, true); |
|
} |
|
if (frame.isMaximizable()) { |
|
x = center(maxButton, insets, x, true); |
|
} |
|
if (frame.isIconifiable()) { |
|
x = center(iconButton, insets, x, true); |
|
} |
|
} |
|
else { |
|
center(menuButton, insets, getWidth() - insets.right, |
|
true); |
|
int x = insets.left; |
|
if (frame.isClosable()) { |
|
x = center(closeButton, insets, x, false); |
|
} |
|
if (frame.isMaximizable()) { |
|
x = center(maxButton, insets, x, false); |
|
} |
|
if (frame.isIconifiable()) { |
|
x = center(iconButton, insets, x, false); |
|
} |
|
} |
|
} |
|
} |
|
|
|
private JButton createNoFocusButton() { |
|
JButton button = new JButton(); |
|
button.setFocusable(false); |
|
button.setMargin(new Insets(0,0,0,0)); |
|
return button; |
|
} |
|
} |