📄 j2xwindowtitlebar.java
字号:
package com.ibm.j2x.swing.window;
import java.awt.Color;
import java.awt.Component;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.util.Vector;
import javax.swing.Icon;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.border.AbstractBorder;
import com.ibm.j2x.swing.event.WindowChangeEvent;
import com.ibm.j2x.swing.layout.GroupFlowLayout;
import com.ibm.j2x.swing.layout.GroupFlowLayoutConstraints;
import com.ibm.j2x.swing.util.WindowUtilities;
/**
* The J2XWindowTitleBar acts as the title bar for all J2XFrames. It provides
* multiple functions for displaying and manipulating the title bar to simulate
* a real title bar that you would find on a native frame.
* <p>The default implementation of J2XWindowTitleBar will paint itself like
* the title bar on a Windows 2000 machine and will handle its own mouse events
* that it receives from the frame's rootpane. It will also handle its own
* cursor changes. This default implementation assumes only a rectangular title bar.
* <p>Basic functions have been added to manipulate the colors, fonts, layouts,
* and buttons on the title bar. Users who wish to simply change the properties
* on the title bar without changing its shape can simply call these functions.
* <p>More advanced windows will need to subclass J2XWindowTitleBar to paint
* more complex looks and to customize where the borders are located and how they
* should behave. Subclasses should override the <code>isMouseOnBorder</code>
* function to define where the borders are on the title bar and <code>isInsideTitleBar</code>
* to define where the title bar is located.
* @author MAbernethy
*/
public class J2XWindowTitleBar extends J2XBorderComponent implements ActionListener
{
/** the instance of the title label used by the default implementation */
protected JLabel lblTitle;
/** the instance of the logo used by the default implementation */
protected JLabel lblLogo;
/** contains all the buttons on the title bar */
protected Vector vctWindowButtons = new Vector();
/** the border around the title bar */
protected Insets borderSize;
/**
* Creates an J2XWindowTitleBar that is by default:
* <br>22 pixels high
* <br>A background color of medium blue (default Windows 2000)
* <br>Has a Windows border
* <br>Displays the 3 title bar buttons on the right side
*/
public J2XWindowTitleBar()
{
super();
setPreferredSize(new Dimension(0, 22));
setBackground(new Color(106, 128, 168));
setBorder(new DefaultBorder());
setBorderSize(new Insets(2, 2, 0, 2));
GroupFlowLayout absLayout = new GroupFlowLayout();
setLayout(absLayout);
addAllWindowButtons();
}
/**
* Returns the minimum size that this title bar can be. By default
* the title bar cannot change its height.
* @return the minimum size
*/
public Dimension getMinimumSize()
{
return getPreferredSize();
}
/**
* Returns the maximum size that this title bar can be. By default
* the title bar cannot change its height.
*/
public Dimension getMaximumSize()
{
return getPreferredSize();
}
/**
* Returns the border size of the border around the title bar.
* @return the border in pixels
*/
public Insets getBorderSize()
{
return borderSize;
}
/**
* Sets the border size of the border around the title bar.
* @param borderSize the border in pixels
*/
public void setBorderSize(Insets borderSize)
{
this.borderSize = borderSize;
}
/**
* Returns whether the coordinates are inside the title bar. By default
* this returns true since the default title bar takes up the entire panel.
* <br>More advanced subclasses that don't use the entire
* panel as the title bar will override this method to return true only
* when the coordinates are within the desired title bar.
* @param x the x coordinate
* @param y the y coordinate
* @return whether the coordinates are inside the title bar
*/
protected boolean isInsideTitleBar(int x, int y)
{
return true;
}
/**
* Returns whether the coordinates are on a border of the title bar. By
* default, this returns true if the coordinates are within the border size
* defined by <code>borderSize</code> and is a rectangular shape.
* <br>More advanced subclasses will override this method to return true
* only when the coordinates lie on a border.
* @param x the x coordinates
* @param y the y coordinates
*/
protected void isMouseOnBorder(int x, int y)
{
if (y < borderSize.top)
isMouseOnBorder = true;
else if (x < borderSize.left)
isMouseOnBorder = true;
else if (x > getWidth() - borderSize.right)
isMouseOnBorder = true;
else
isMouseOnBorder = false;
}
/**
* After computing the appropriate coordinates, it tells any listeners
* that the window should be resized or moved.
* @param e the MouseEvent from the frame's rootpane
*/
public void mouseDragged(MouseEvent e)
{
if (isWindowMaximized())
return;
if (!isInsideTitleBar(e.getX(), e.getY()))
return;
WindowChangeEvent event = new WindowChangeEvent(this, e.getX(), e.getY(), e.getX()-X, e.getY()-Y, direction, true);
if (isMouseOnBorder)
fireWindowChangeEvent(WindowChangeEvent.WINDOW_RESIZED, event);
else
fireWindowChangeEvent(WindowChangeEvent.WINDOW_MOVED, event);
}
/**
* Computes the coordinates where the mouse is first pressed. Uses these
* coordinates as a basis for all mouse movements.
* @param e the MouseEvent from the frame's rootpane
*/
public void mousePressed(MouseEvent e)
{
if (isWindowMaximized())
return;
if (!isInsideTitleBar(e.getX(), e.getY()))
return;
X = e.getX();
Y = e.getY();
isMouseOnBorder(X, Y);
handleDirections(e, true);
}
/**
* Computes the coordinates where the mouse is released and tells any listeners
* that the window should stop resizing or moving.
* @param e the MouseEvent from the frame's rootpane
*/
public void mouseReleased(MouseEvent e)
{
if (isWindowMaximized())
return;
if (!isInsideTitleBar(e.getX(), e.getY()))
return;
WindowChangeEvent event = new WindowChangeEvent(this, e.getX(), e.getY(), e.getX()-X, e.getY()-Y, direction, false);
if (isMouseOnBorder)
fireWindowChangeEvent(WindowChangeEvent.WINDOW_RESIZED, event);
else
fireWindowChangeEvent(WindowChangeEvent.WINDOW_MOVED, event);
}
/**
* Computes the coordinates where the mouse enters. Only changes the cursor.
* @param e the MouseEvent from the frame's rootpane
*/
public void mouseEntered(MouseEvent e)
{
if (isWindowMaximized())
return;
if (!isInsideTitleBar(e.getX(), e.getY()))
return;
handleDirections(e, false);
}
/**
* Computes the coordinates where the mouse exits. Changes the cursor back
* to the default cursor.
* @param e the MouseEvent from the frame's rootpane
*/
public void mouseExited(MouseEvent e)
{
if (!isInsideTitleBar(e.getX(), e.getY()))
return;
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}
/**
* Computes the coordinates where the mouse moves. Only changes the cursor.
* @param e the MouseEvent from the frame's rootpane
*/
public void mouseMoved(MouseEvent e)
{
if (isWindowMaximized())
return;
if (!isInsideTitleBar(e.getX(), e.getY()))
return;
handleDirections(e, false);
}
/**
* Computes the coordinates where the mouse is clicked. Maximizes
* the window when it is double clicked.
* @param e the MouseEvent from the frame's rootpane
*/
public void mouseClicked(MouseEvent e)
{
if (!isInsideTitleBar(e.getX(), e.getY()))
return;
if (e.getClickCount() == 2 && SwingUtilities.isLeftMouseButton(e))
{
changeRestoreButton();
WindowChangeEvent event = new WindowChangeEvent();
fireWindowChangeEvent(WindowChangeEvent.WINDOW_MAXIMIZED, event);
}
}
/**
* Based on the coordinates contained in the MouseEvent, computes whether
* the mouse is over the border and draws the appropriate cursor. It also
* determines the direction which is used for window change events.
* @param e the MouseEvent from the frame's rootpane
*/
private void handleDirections(MouseEvent e, boolean changeDirection)
{
if (e.getY() < borderSize.top && e.getX() < WindowUtilities.DIAGONAL_RESIZE_SIZE)
{
setCursor(new Cursor(Cursor.NW_RESIZE_CURSOR));
if (changeDirection)
direction = WindowChangeEvent.RESIZE_NORTH_WEST;
}
else if (e.getY() < borderSize.top && e.getX() > getWidth() -WindowUtilities.DIAGONAL_RESIZE_SIZE)
{
setCursor(new Cursor(Cursor.NE_RESIZE_CURSOR));
if (changeDirection)
direction = WindowChangeEvent.RESIZE_NORTH_EAST;
}
else if (e.getY() < borderSize.top)
{
setCursor(new Cursor(Cursor.N_RESIZE_CURSOR));
if (changeDirection)
direction = WindowChangeEvent.RESIZE_NORTH;
}
if (e.getX() < borderSize.left)
{
setCursor(new Cursor(Cursor.NW_RESIZE_CURSOR));
if (changeDirection)
direction = WindowChangeEvent.RESIZE_NORTH_WEST;
}
if (e.getX() > getWidth() - borderSize.right)
{
setCursor(new Cursor(Cursor.NE_RESIZE_CURSOR));
if (changeDirection)
direction = WindowChangeEvent.RESIZE_NORTH_EAST;
}
if (e.getX() > borderSize.right && e.getX() < getWidth()-borderSize.right &&
e.getY() > borderSize.top && e.getY() < getHeight()-borderSize.bottom)
{
setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
if (changeDirection)
direction = WindowChangeEvent.RESIZE_NONE;
}
}
/**
* Captures events from the title bar buttons and fires the appropriate
* window change event to the listeners
* @param e the ActionEvent
*/
public void actionPerformed(ActionEvent e)
{
J2XWindowButton b = (J2XWindowButton)e.getSource();
if (b.getButtonType() == J2XWindowButton.MINIMIZE)
{
fireWindowChangeEvent(WindowChangeEvent.WINDOW_MINIMIZED, new WindowChangeEvent());
}
else if (b.getButtonType() == J2XWindowButton.RESTORE_MAX || b.getButtonType() == J2XWindowButton.RESTORE_MIN)
{
changeRestoreButton();
fireWindowChangeEvent(WindowChangeEvent.WINDOW_MAXIMIZED, new WindowChangeEvent());
}
else if (b.getButtonType() == J2XWindowButton.CLOSE)
{
fireWindowChangeEvent(WindowChangeEvent.WINDOW_CLOSED, new WindowChangeEvent());
}
}
/**
* Sets the restore button state as either restore maximized or restore minimized.
* @param isMaximized if the restore state is mazimized
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -