Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
mdlaf.components.titlepane.MaterialTitlePane Maven / Gradle / Ivy
/*
* Copyright 2000-2014 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package mdlaf.components.titlepane;
import java.awt.*;
import java.awt.event.*;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.List;
import javax.accessibility.AccessibleContext;
import javax.swing.*;
import javax.swing.plaf.UIResource;
import mdlaf.components.button.MaterialButtonsComponentsUI;
import mdlaf.utils.MaterialDrawingUtils;
import mdlaf.utils.MaterialManagerListener;
import mdlaf.utils.WrapperSwingUtilities;
/**
* @author Konstantin Bulenkov this code is copyed by OpenJDK
* @author https://github.com/users/vincenzopalazzo
*/
public class MaterialTitlePane extends JComponent {
private static final int IMAGE_HEIGHT = 16;
private static final int IMAGE_WIDTH = 16;
private PropertyChangeListener myPropertyChangeListener;
private Action myCloseAction;
private Action myIconifyAction;
private Action myRestoreAction;
private Action myMaximizeAction;
private JButton myToggleButton;
private JButton myIconifyButton;
private JButton myCloseButton;
private Icon myMaximizeIcon;
private Icon myMinimizeIcon;
private Image mySystemIcon;
private MaterialHandler myWindowListener;
private Window myWindow;
private JRootPane myRootPane;
private int myState;
private Color myInactiveBackground = UIManager.getColor("Material.inactiveCaption");
private Color myInactiveForeground = UIManager.getColor("Material.inactiveCaptionText");
private Color myInactiveShadow = UIManager.getColor("Material.inactiveCaptionBorder");
private Color myActiveBackground = null;
private Color myActiveForeground = null;
private Color myActiveShadow = null;
public MaterialTitlePane(JRootPane root) {
this.myRootPane = root;
myState = -1;
myWindow = getWindow();
installSubcomponents();
determineColors();
installDefaults();
setLayout(createLayout());
}
protected void uninstall() {
uninstallListeners();
myWindow = null;
removeAll();
}
protected void installListeners() {
if (myWindow != null) {
myWindowListener = createWindowListener();
myWindow.addWindowListener(myWindowListener);
myPropertyChangeListener = createWindowPropertyChangeListener();
myWindow.addPropertyChangeListener(myPropertyChangeListener);
addMouseListener(myWindowListener);
addMouseMotionListener(myWindowListener);
myWindow.addWindowFocusListener(myWindowListener);
myWindow.addWindowListener(myWindowListener);
}
}
protected void uninstallListeners() {
if (myWindow != null) {
myWindow.removeWindowListener(myWindowListener);
myWindow.removePropertyChangeListener(myPropertyChangeListener);
myWindow.removeMouseListener(myWindowListener);
myWindow.removeMouseMotionListener(myWindowListener);
myWindow.removeWindowFocusListener(myWindowListener);
myWindow.removeWindowListener(myWindowListener);
}
}
protected MaterialHandler createWindowListener() {
if (myWindow == null) return null;
return new MaterialHandler(myWindow);
}
protected PropertyChangeListener createWindowPropertyChangeListener() {
return new PropertyChangeHandler();
}
public JRootPane getRootPane() {
return myRootPane;
}
protected int getWindowDecorationStyle() {
return getRootPane().getWindowDecorationStyle();
}
public void addNotify() {
super.addNotify();
uninstallListeners();
myWindow = SwingUtilities.getWindowAncestor(this);
if (myWindow != null) {
if (myWindow instanceof Frame) {
setState(((Frame) myWindow).getExtendedState());
} else {
setState(0);
}
setActive(myWindow.isActive());
installListeners();
updateSystemIcon();
}
}
public void removeNotify() {
super.removeNotify();
uninstallListeners();
myWindow = null;
}
protected void installSubcomponents() {
int decorationStyle = getWindowDecorationStyle();
if (decorationStyle == JRootPane.FRAME) {
createActions();
createButtons();
add(myIconifyButton);
add(myToggleButton);
add(myCloseButton);
} else if (decorationStyle == JRootPane.PLAIN_DIALOG
|| decorationStyle == JRootPane.INFORMATION_DIALOG
|| decorationStyle == JRootPane.ERROR_DIALOG
|| decorationStyle == JRootPane.COLOR_CHOOSER_DIALOG
|| decorationStyle == JRootPane.FILE_CHOOSER_DIALOG
|| decorationStyle == JRootPane.QUESTION_DIALOG
|| decorationStyle == JRootPane.WARNING_DIALOG) {
createActions();
createButtons();
initMaterialButtonClose();
myCloseButton.setFocusable(false);
myCloseButton.setVisible(true);
add(myCloseButton);
}
}
/** This is method for init style button into JDialog */
protected void initMaterialButtonClose() {
MaterialManagerListener.removeAllMaterialMouseListener(myCloseButton);
myCloseButton.setBackground(UIManager.getColor("OptionPane.errorDialog.titlePane.background"));
myCloseButton.setAction(myCloseAction);
}
protected void determineColors() {
myActiveBackground = UIManager.getColor("Material.activeCaption");
myActiveForeground = UIManager.getColor("Material.activeCaptionText");
myActiveShadow = UIManager.getColor("Material.activeCaptionBorder");
}
protected void installDefaults() {
setFont(UIManager.getFont("InternalFrame.titleFont", getLocale()));
}
protected void close() {
Window window = getWindow();
if (window != null) {
window.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING));
}
}
protected void iconify() {
Frame frame = getFrame();
if (frame != null) {
frame.setExtendedState(myState | Frame.ICONIFIED);
}
}
protected void maximize() {
Frame frame = getFrame();
if (frame != null) {
frame.setExtendedState(myState | Frame.MAXIMIZED_BOTH);
}
}
protected void restore() {
Frame frame = getFrame();
if (frame == null) {
return;
}
if ((myState & Frame.ICONIFIED) != 0) {
frame.setExtendedState(myState & ~Frame.ICONIFIED);
} else {
frame.setExtendedState(myState & ~Frame.MAXIMIZED_BOTH);
}
}
protected void createActions() {
myCloseAction = new CloseAction();
if (getWindowDecorationStyle() == JRootPane.FRAME) {
myIconifyAction = new IconifyAction();
myRestoreAction = new RestoreAction();
myMaximizeAction = new MaximizeAction();
}
}
protected JMenu createMenu() {
JMenu menu = new JMenu("");
if (getWindowDecorationStyle() == JRootPane.FRAME) {
addMenuItems(menu);
}
return menu;
}
protected void addMenuItems(JMenu menu) {
menu.add(myRestoreAction);
menu.add(myIconifyAction);
if (Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
menu.add(myMaximizeAction);
}
menu.add(new JSeparator());
menu.add(myCloseAction);
}
protected JButton createButton(String accessibleName, Icon icon, Action action) {
JButton button = new TitlePaneButton();
button.putClientProperty("paintActive", Boolean.TRUE);
button.putClientProperty(AccessibleContext.ACCESSIBLE_NAME_PROPERTY, accessibleName);
button.setAction(action);
button.setIcon(icon);
button.setBackground(myActiveBackground);
return button;
}
@Override
public void updateUI() {
super.updateUI();
if (getWindowDecorationStyle() == JRootPane.FRAME) {
myMaximizeIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
myMinimizeIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
Icon iconClose = UIManager.getIcon("InternalFrame.closeIcon");
myCloseButton.setIcon(iconClose);
myIconifyButton.setIcon(myMinimizeIcon);
myToggleButton.setIcon(myMaximizeIcon);
}
}
protected void createButtons() {
myCloseButton =
createButton("Close", UIManager.getIcon("InternalFrame.closeIcon"), myCloseAction);
if (getWindowDecorationStyle() == JRootPane.FRAME) {
myMaximizeIcon = UIManager.getIcon("InternalFrame.maximizeIcon");
myMinimizeIcon = UIManager.getIcon("InternalFrame.minimizeIcon");
myIconifyButton =
createButton("Iconify", UIManager.getIcon("InternalFrame.iconifyIcon"), myIconifyAction);
myToggleButton = createButton("Maximize", myMaximizeIcon, myRestoreAction);
}
}
protected LayoutManager createLayout() {
return new TitlePaneLayout();
}
protected void setActive(boolean active) {
myCloseButton.putClientProperty("paintActive", active);
if (getWindowDecorationStyle() == JRootPane.FRAME) {
myIconifyButton.putClientProperty("paintActive", active);
myToggleButton.putClientProperty("paintActive", active);
}
getRootPane().repaint();
}
protected void setState(int state) {
setState(state, false);
}
protected void setState(int state, boolean updateRegardless) {
Window wnd = getWindow();
if (wnd != null && getWindowDecorationStyle() == JRootPane.FRAME) {
if (myState == state && !updateRegardless) {
return;
}
Frame frame = getFrame();
if (frame != null) {
JRootPane rootPane = getRootPane();
if (((state & Frame.MAXIMIZED_BOTH) != 0)
&& (rootPane.getBorder() == null || (rootPane.getBorder() instanceof UIResource))
&& frame.isShowing()) {
rootPane.setBorder(null);
} else if ((state & Frame.MAXIMIZED_BOTH) == 0) {
// This is a croak, if state becomes bound, this can
// be nuked.
// rootPaneUI.installBorder(rootPane);
}
if (frame.isResizable()) {
if ((state & Frame.MAXIMIZED_BOTH) != 0) {
updateToggleButton(myRestoreAction, myMinimizeIcon);
myMaximizeAction.setEnabled(false);
myRestoreAction.setEnabled(true);
} else {
updateToggleButton(myMaximizeAction, myMaximizeIcon);
myMaximizeAction.setEnabled(true);
myRestoreAction.setEnabled(false);
}
if (myToggleButton.getParent() == null || myIconifyButton.getParent() == null) {
add(myToggleButton);
add(myIconifyButton);
revalidate();
repaint();
}
myToggleButton.setText(null);
} else {
myMaximizeAction.setEnabled(false);
myRestoreAction.setEnabled(false);
if (myToggleButton.getParent() != null) {
remove(myToggleButton);
revalidate();
repaint();
}
}
} else {
// Not contained in a Frame
myMaximizeAction.setEnabled(false);
myRestoreAction.setEnabled(false);
myIconifyAction.setEnabled(false);
remove(myToggleButton);
remove(myIconifyButton);
revalidate();
repaint();
}
myCloseAction.setEnabled(true);
myState = state;
}
}
protected void updateToggleButton(Action action, Icon icon) {
myToggleButton.setAction(action);
myToggleButton.setIcon(icon);
myToggleButton.setText(null);
}
protected Frame getFrame() {
Window window = getWindow();
if (window instanceof Frame) {
return (Frame) window;
}
return null;
}
protected Window getWindow() {
return myWindow;
}
protected String getTitle() {
Window w = getWindow();
if (w instanceof Frame) {
return ((Frame) w).getTitle();
} else if (w instanceof Dialog) {
return ((Dialog) w).getTitle();
}
return null;
}
protected void paintComponent(Graphics g) {
if (getFrame() != null) {
setState(getFrame().getExtendedState());
}
JRootPane rootPane = getRootPane();
Window window = getWindow();
boolean leftToRight =
(window == null)
? rootPane.getComponentOrientation().isLeftToRight()
: window.getComponentOrientation().isLeftToRight();
boolean isSelected = (window == null) ? true : window.isActive();
int width = getWidth();
int height = getHeight();
Color background;
Color foreground;
Color darkShadow;
if (isSelected) {
background = myActiveBackground;
foreground = myActiveForeground;
darkShadow = myActiveShadow;
} else {
background = myInactiveBackground;
foreground = myInactiveForeground;
darkShadow = myInactiveShadow;
}
g.setColor(background);
g.fillRect(0, 0, width, height);
g.setColor(darkShadow);
g.drawLine(0, height - 1, width, height - 1);
g.drawLine(0, 0, 0, 0);
g.drawLine(width - 1, 0, width - 1, 0);
int xOffset = leftToRight ? 5 : width - 5;
if (getWindowDecorationStyle() == JRootPane.FRAME) {
xOffset += leftToRight ? IMAGE_WIDTH + 5 : -IMAGE_WIDTH - 5;
}
String theTitle = getTitle();
if (theTitle != null) {
g = MaterialDrawingUtils.getAliasedGraphics(g);
FontMetrics fm = g.getFontMetrics(rootPane.getFont());
g.setColor(foreground);
int yOffset = ((height - fm.getHeight()) / 2) + fm.getAscent();
Rectangle rect = new Rectangle(0, 0, 0, 0);
if (myIconifyButton != null && myIconifyButton.getParent() != null) {
rect = myIconifyButton.getBounds();
}
int titleW;
if (leftToRight) {
if (rect.x == 0) {
rect.x = window.getWidth() - window.getInsets().right - 2;
}
titleW = rect.x - xOffset - 4;
theTitle =
WrapperSwingUtilities.getInstance().getClippedString(rootPane, fm, theTitle, titleW);
// theTitle = BasicGraphicsUtils.getClippedString(rootPane, fm, theTitle, titleW);
} else {
titleW = xOffset - rect.x - rect.width - 4;
theTitle =
WrapperSwingUtilities.getInstance().getClippedString(rootPane, fm, theTitle, titleW);
xOffset -= fm.stringWidth(theTitle);
}
// int titleLength = SwingUtilities2.stringWidth(rootPane, fm, theTitle);
int titleLength = fm.stringWidth(theTitle);
g.drawString(theTitle, xOffset, yOffset);
xOffset += leftToRight ? titleLength + 5 : -5;
}
}
protected class CloseAction extends AbstractAction {
public CloseAction() {
super(UIManager.getString("MaterialTitlePane.closeTitle", getLocale()));
}
public void actionPerformed(ActionEvent e) {
close();
}
}
protected class IconifyAction extends AbstractAction {
public IconifyAction() {
super(UIManager.getString("MaterialTitlePane.iconifyTitle", getLocale()));
}
public void actionPerformed(ActionEvent e) {
iconify();
}
}
protected class RestoreAction extends AbstractAction {
public RestoreAction() {
super(UIManager.getString("MaterialTitlePane.restoreTitle", getLocale()));
}
public void actionPerformed(ActionEvent e) {
restore();
}
}
protected class MaximizeAction extends AbstractAction {
public MaximizeAction() {
super(UIManager.getString("MaterialTitlePane.maximizeTitle", getLocale()));
}
public void actionPerformed(ActionEvent e) {
maximize();
}
}
protected class TitlePaneLayout implements LayoutManager {
public void addLayoutComponent(String name, Component c) {}
public void removeLayoutComponent(Component c) {}
public Dimension preferredLayoutSize(Container c) {
int height = computeHeight();
//noinspection SuspiciousNameCombination
return new Dimension(height, height);
}
public Dimension minimumLayoutSize(Container c) {
return preferredLayoutSize(c);
}
private int computeHeight() {
FontMetrics fm = myRootPane.getFontMetrics(getFont());
int fontHeight = fm.getHeight();
fontHeight += 7;
int iconHeight = 0;
if (getWindowDecorationStyle() == JRootPane.FRAME) {
iconHeight = IMAGE_HEIGHT;
}
return Math.max(fontHeight, iconHeight);
}
public void layoutContainer(Container c) {
boolean leftToRight =
(myWindow == null)
? getRootPane().getComponentOrientation().isLeftToRight()
: myWindow.getComponentOrientation().isLeftToRight();
int w = getWidth();
int x;
int y = 3;
int spacing;
int buttonHeight;
int buttonWidth;
if (myCloseButton != null && myCloseButton.getIcon() != null) {
buttonHeight = myCloseButton.getIcon().getIconHeight();
buttonWidth = myCloseButton.getIcon().getIconWidth();
} else {
buttonHeight = IMAGE_HEIGHT;
buttonWidth = IMAGE_WIDTH;
}
x = leftToRight ? w : 0;
spacing = 5;
x = leftToRight ? spacing : w - buttonWidth - spacing;
x = leftToRight ? w : 0;
spacing = 4;
x += leftToRight ? -spacing - buttonWidth : spacing;
if (myCloseButton != null) {
myCloseButton.setBounds(x, y, buttonWidth, buttonHeight);
}
if (!leftToRight) x += buttonWidth;
if (getWindowDecorationStyle() == JRootPane.FRAME) {
if (Toolkit.getDefaultToolkit().isFrameStateSupported(Frame.MAXIMIZED_BOTH)) {
if (myToggleButton.getParent() != null) {
spacing = 10;
x += leftToRight ? -spacing - buttonWidth : spacing;
myToggleButton.setBounds(x, y, buttonWidth, buttonHeight);
if (!leftToRight) {
x += buttonWidth;
}
}
}
if (myIconifyButton != null && myIconifyButton.getParent() != null) {
spacing = 2;
x += leftToRight ? -spacing - buttonWidth : spacing;
myIconifyButton.setBounds(x, y, buttonWidth, buttonHeight);
if (!leftToRight) {
x += buttonWidth;
}
}
}
}
}
protected class PropertyChangeHandler implements PropertyChangeListener {
public void propertyChange(PropertyChangeEvent pce) {
String name = pce.getPropertyName();
if ("resizable".equals(name) || "state".equals(name)) {
Frame frame = getFrame();
if (frame != null) {
setState(frame.getExtendedState(), true);
}
if ("resizable".equals(name)) {
getRootPane().repaint();
}
} else if ("title".equals(name)) {
repaint();
} else if ("componentOrientation".equals(name)) {
revalidate();
repaint();
} else if ("iconImage".equals(name)) {
updateSystemIcon();
revalidate();
repaint();
}
}
}
protected void updateSystemIcon() {
Window window = getWindow();
if (window == null) {
mySystemIcon = null;
return;
}
List icons = window.getIconImages();
assert icons != null;
if (icons.size() == 0) {
mySystemIcon = null;
} else if (icons.size() == 1) {
mySystemIcon = icons.get(0);
} else {
mySystemIcon = icons.get(0);
// TODO: find cross-platofrm replacement for this?
// mySystemIcon = SunToolkit.getScaledIconImage(icons, IMAGE_WIDTH, IMAGE_HEIGHT);
}
}
protected class MaterialHandler extends WindowAdapter
implements PropertyChangeListener, MouseListener, MouseMotionListener, ComponentListener {
private Window window;
public MaterialHandler(Window window) {
this.window = window;
}
@Override
public void propertyChange(PropertyChangeEvent e) {
/* switch( e.getPropertyName() ) {
case "title":
titleLabel.setText( getWindowTitle() );
break;
case "resizable":
if( window instanceof Frame )
frameStateChanged();
break;
case "iconImage":
updateIcon();
break;
} */
}
@Override
public void windowActivated(WindowEvent e) {
// activeChanged( true );
// repaintWindowBorder();
}
@Override
public void windowDeactivated(WindowEvent e) {
// activeChanged( false );
// repaintWindowBorder();
}
@Override
public void windowStateChanged(WindowEvent e) {
// frameStateChanged();
}
// ---- interface MouseListener ----
private Point dragOffset;
@Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e)) {
if (e.getSource() == getTitle()) {
close();
} else if (window instanceof Frame && ((Frame) window).isResizable()) {
Frame frame = (Frame) window;
if ((frame.getExtendedState() & Frame.MAXIMIZED_BOTH) != 0) restore();
else maximize();
}
}
}
@Override
public void mousePressed(MouseEvent e) {
if (window == null) return; // should newer occur
dragOffset = SwingUtilities.convertPoint(MaterialTitlePane.this, e.getPoint(), window);
}
@Override
public void mouseReleased(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mouseDragged(MouseEvent e) {
if (window == null) return; // should newer occur
if (window instanceof Frame) {
Frame frame = (Frame) window;
int state = frame.getExtendedState();
if ((state & Frame.MAXIMIZED_BOTH) != 0) {
int maximizedWidth = window.getWidth();
// restore window size, which also moves window to pre-maximized location
frame.setExtendedState(state & ~Frame.MAXIMIZED_BOTH);
// fix drag offset to ensure that window remains under mouse position
// for the case that dragging starts in the right area of the maximized window
int restoredWidth = window.getWidth();
int center = restoredWidth / 2;
if (dragOffset.x > center) {
// this is same/similar to what Windows 10 does
if (dragOffset.x > maximizedWidth - center)
dragOffset.x = restoredWidth - (maximizedWidth - dragOffset.x);
else dragOffset.x = center;
}
}
}
// compute new window location
int newX = e.getXOnScreen() - dragOffset.x;
int newY = e.getYOnScreen() - dragOffset.y;
if (newX == window.getX() && newY == window.getY()) return;
// move window
window.setLocation(newX, newY);
}
@Override
public void mouseMoved(MouseEvent e) {}
@Override
public void componentResized(ComponentEvent e) {}
@Override
public void componentShown(ComponentEvent e) {
// necessary for the case that the frame is maximized before it is shown
// frameStateChanged();
}
@Override
public void componentMoved(ComponentEvent e) {}
@Override
public void componentHidden(ComponentEvent e) {}
}
protected static class TitlePaneButton extends JButton {
public TitlePaneButton() {}
@Override
protected void init(String text, Icon icon) {
super.init(text, icon);
setUI(new TitlePaneButtonUI());
}
@Override
public void updateUI() {
super.updateUI();
setUI(new TitlePaneButtonUI());
}
private static class TitlePaneButtonUI extends MaterialButtonsComponentsUI {
@Override
public void installUI(JComponent c) {
super.installUI(c);
super.background = UIManager.getColor("Material.activeCaption");
super.defaultBackground = UIManager.getColor("Material.activeCaption");
c.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
}
@Override
protected void paintButtonPressed(Graphics g, AbstractButton b) {}
@Override
protected void paintBorderButton(Graphics graphics, JComponent b) {}
@Override
protected void paintFocus(
Graphics g,
AbstractButton b,
Rectangle viewRect,
Rectangle textRect,
Rectangle iconRect) {}
}
}
}