📄 paneui.java
字号:
/*
* Copyright (C) 2004 NNL Technology AB
* Visit www.infonode.net for information about InfoNode(R)
* products and how to contact NNL Technology AB.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston,
* MA 02111-1307, USA.
*/
// $Id: PaneUI.java,v 1.20 2005/12/04 13:46:05 jesper Exp $
package net.infonode.tabbedpanel.theme.internal.laftheme;
import net.infonode.gui.InsetsUtil;
import net.infonode.gui.draggable.DraggableComponentBox;
import net.infonode.tabbedpanel.Tab;
import net.infonode.tabbedpanel.TabbedPanel;
import net.infonode.tabbedpanel.TabbedPanelContentPanel;
import net.infonode.util.Direction;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.awt.image.FilteredImageSource;
import java.awt.image.RGBImageFilter;
public class PaneUI {
private static final boolean PAINT_TAB_AREA = true;
private static final boolean PAINT_CONTENT_AREA = true;
private static final boolean PAINT_TAB = true;
private static final boolean TEXT_ICON_GAP_COMPENSATE = true;
private static final int DEFAULT_SELECTED_INDEX = 3;
private static final int DEFAULT_TAB_COUNT = 7;
private static final int EXTRA_SIZE = 2;
private static final String EMPTY_STRING = "";
// Order is IMPORTANT!!!
private static final Direction[] DIRECTIONS = new Direction[]{Direction.UP, Direction.LEFT, Direction.DOWN, Direction.RIGHT};
private Insets[] areaInsets = new Insets[DIRECTIONS.length];
private Insets[] normalInsets = new Insets[DIRECTIONS.length];
private Insets[] selectedInsets = new Insets[DIRECTIONS.length];
private Insets[] adjustedContentInsets = new Insets[DIRECTIONS.length];
private Insets[] adjustedContentInsetsTabAreaHidden = new Insets[DIRECTIONS.length];
private Insets[] contentInsets = new Insets[DIRECTIONS.length];
private Dimension[] minimumSizes = new Dimension[DIRECTIONS.length];
private Dimension[] tabMinimumSizes = new Dimension[DIRECTIONS.length];
private int[] spacings = new int[DIRECTIONS.length];
private int[] raiseds = new int[DIRECTIONS.length];
private Insets[] tabInsets = new Insets[DIRECTIONS.length];
private Color[] contentTabAreaBorderColors = new Color[DIRECTIONS.length];
private boolean[] swapWidthHeights = new boolean[DIRECTIONS.length];
private boolean tabAreaNotVisibleFix = false;
private int scrollOffset = 0;
private int textIconGap;
private PaneUIListener listener;
private static ComponentCache componentCache = new ComponentCache();
private PaneHandler paneHandler = new PaneHandler(new PaneHandlerListener() {
public void updating() {
setEnabled(false);
listener.updating();
}
public void updated() {
doInit();
setEnabled(true);
listener.updated();
}
});
private Tab hoveredTab;
private TabData tabData = new TabData();
private boolean tabAreaOpaque;
private boolean contentOpaque;
private boolean opaque;
private boolean tabAreaComponentsOpaque;
private boolean enabled = true;
public PaneUI(final PaneUIListener listener) {
this.listener = listener;
}
public void init() {
paneHandler.update();
}
private void doInit() {
initPreCommonValues();
for (int i = 0; i < DIRECTIONS.length; i++) {
PanePainter pane = paneHandler.getPainter(DIRECTIONS[i]);
initValues(pane, i, DIRECTIONS[i]);
reset(pane);
}
initPostCommonValues();
}
public void dispose() {
enabled = false;
paneHandler.dispose();
}
public void setEnabled(final boolean enabled) {
this.enabled = enabled;
}
private void initPreCommonValues() {
{
// Hack for some look and feels
tabAreaNotVisibleFix = UIManager.getLookAndFeel().getClass().getName().indexOf(".WindowsLookAndFeel") > -1;
}
{
// Icon text gap
textIconGap = UIManager.getInt("TabbedPane.textIconGap");
if (textIconGap <= 0)
textIconGap = 4;
}
{
// Opaque
opaque = paneHandler.getPainter(Direction.UP).isOpaque();
Boolean contentOp = (Boolean) UIManager.get("TabbedPane.contentOpaque");
if (contentOp == null)
contentOpaque = opaque;
else
contentOpaque = contentOp.booleanValue();
tabAreaOpaque = opaque;
tabAreaComponentsOpaque = false;
}
}
private void initPostCommonValues() {
{
// Scroll offset
for (int i = 0; i < DIRECTIONS.length; i++)
scrollOffset = Math.max(scrollOffset, Math.max(minimumSizes[i].width, minimumSizes[i].height));
}
}
private void initValues(PanePainter pane, int index, Direction direction) {
estimateSwappedTabDirection(pane, index, direction);
reset(pane);
pane.setSize(1000, 1000);
boolean upDown = !direction.isHorizontal();
for (int i = 0; i < DEFAULT_TAB_COUNT; i++) {
pane.addTab(EMPTY_STRING, getComponent());
}
pane.setSelectedIndex(DEFAULT_SELECTED_INDEX);
pane.doValidation();
{
// Tab insets if any from UImanager
Insets insets = UIManager.getInsets("TabbedPane.tabInsets");
if (insets == null)
insets = new Insets(0, 0, 0, 0);
if (!upDown)
tabInsets[index] = new Insets(0, insets.left, 0, insets.right);
else
tabInsets[index] = InsetsUtil.EMPTY_INSETS;
}
{
// Raised
Rectangle bounds = pane.getBoundsAt(0);
Rectangle bounds2 = pane.getBoundsAt(pane.getSelectedIndex());
if (direction == Direction.UP)
raiseds[index] = Math.max(0, bounds.y - bounds2.y);
else if (direction == Direction.LEFT)
raiseds[index] = Math.max(0, bounds.x - bounds2.x);
else if (direction == Direction.DOWN)
raiseds[index] = raiseds[getDirectionIndex(Direction.UP)];
else
raiseds[index] = raiseds[getDirectionIndex(Direction.LEFT)];
}
{
// Spacing
Insets normal = getCalculatedInsets(pane, 0, false, direction);
Insets selected = getCalculatedInsets(pane, 0, true, direction);
if (upDown)
spacings[index] = normal.left + normal.right - selected.left - selected.right;
else
spacings[index] = normal.top + normal.bottom - selected.top - selected.bottom;
}
{
// Normal insets
normalInsets[index] = getCalculatedInsets(pane, 0, false, direction);
}
{
// Selected insets
Insets insets = getCalculatedInsets(pane, 0, true, direction);
int spacing = spacings[index];
int spaceFirst = spacing / 2;
int spaceAfter = spacing / 2 + spacing % 2;
if (direction == Direction.UP) {
insets.bottom = normalInsets[index].bottom;
insets.top = normalInsets[index].top;
insets.left += spaceFirst;
insets.right += spaceAfter;
}
else if (direction == Direction.LEFT) {
insets.right = normalInsets[index].right;
insets.left = normalInsets[index].left;
insets.top += spaceFirst;
insets.bottom += spaceAfter;
}
else if (direction == Direction.RIGHT) {
insets.right = normalInsets[index].right;
insets.left = normalInsets[index].left;
insets.top += spaceFirst;
insets.bottom += spaceAfter;
}
else {
insets.bottom = normalInsets[index].bottom;
insets.top = normalInsets[index].top;
insets.left += spaceFirst;
insets.right += spaceAfter;
}
selectedInsets[index] = insets;
}
{
// Content insets
JPanel c = new JPanel();
pane.addTab(EMPTY_STRING, c);
pane.setSelectedIndex(pane.getTabCount() - 1);
pane.doValidation();
Point l = SwingUtilities.convertPoint(c.getParent(), c.getLocation(), pane);
Rectangle bounds = pane.getBoundsAt(0);
int top = 0;
int left = 0;
int bottom = 0;
int right = 0;
if (direction == Direction.UP) {
top = l.y - bounds.height - bounds.y;
left = l.x;
bottom = pane.getHeight() - l.y - c.getHeight();
right = pane.getWidth() - l.x - c.getWidth();
}
else if (direction == Direction.DOWN) {
top = l.y;
left = l.x;
bottom = pane.getHeight() - c.getHeight() - l.y - (pane.getHeight() - bounds.y);
right = pane.getWidth() - l.x - c.getWidth();
}
else if (direction == Direction.LEFT) {
top = l.y;
left = l.x - bounds.width - bounds.x;
bottom = pane.getHeight() - l.y - c.getHeight();
right = pane.getWidth() - l.x - c.getWidth();
}
else {
top = l.y;
left = l.x;
bottom = pane.getHeight() - l.y - c.getHeight();
right = pane.getWidth() - c.getWidth() - l.x - (pane.getWidth() - bounds.x);
}
contentInsets[index] = new Insets(top, left, bottom, right);
Insets i = contentInsets[0];
Insets i2 = InsetsUtil.rotate(direction.getNextCW(), i);
Insets adjustedInsets = InsetsUtil.max(i, i2);
adjustedContentInsets[index] = adjustedInsets;
adjustedContentInsetsTabAreaHidden[index] = new Insets(
direction == Direction.UP ? adjustedInsets.left : adjustedInsets.top,
direction == Direction.LEFT ?
adjustedInsets.top : adjustedInsets.left, direction == Direction.DOWN ? adjustedInsets.right
: adjustedInsets.bottom, direction == Direction.RIGHT ?
adjustedInsets.bottom :
adjustedInsets.right);
pane.removeTabAt(pane.getTabCount() - 1);
pane.setSelectedIndex(DEFAULT_SELECTED_INDEX);
pane.doValidation();
}
{
// Minimum sizes
Rectangle bounds = pane.getBoundsAt(DEFAULT_SELECTED_INDEX);
tabMinimumSizes[index] = new Dimension(bounds.width, bounds.height);
minimumSizes[index] = new Dimension(bounds.width - tabInsets[index].left - tabInsets[index].right, bounds.height
- tabInsets[index].top - tabInsets[index].bottom);
}
calculateAreaInsets(pane, index, direction);
estimateContentTabAreaBorderColor(pane, index, direction);
}
private void calculateAreaInsets(PanePainter pane, int index, Direction direction) {
{
// Area insets
pane.setSelectedIndex(0);
Rectangle selectedBounds = pane.getBoundsAt(0);
pane.setSelectedIndex(DEFAULT_SELECTED_INDEX);
Rectangle normalBounds = pane.getBoundsAt(0);
int left = 0;
int top = 0;
int bottom = 0;
int right = 0;
if (direction == Direction.UP) {
left = Math.min(selectedBounds.x, normalBounds.x);
top = Math.min(selectedBounds.y, normalBounds.y);
bottom = 0;
// right = left;
}
else if (direction == Direction.DOWN) {
left = Math.min(selectedBounds.x, normalBounds.x);
top = 0;
bottom = pane.getHeight() - Math.max(selectedBounds.y + selectedBounds.height,
normalBounds.y + normalBounds.height);
// right = left;
}
else if (direction == Direction.LEFT) {
top = Math.min(selectedBounds.y, normalBounds.y);
left = Math.min(selectedBounds.x, normalBounds.x);
right = 0;
// bottom = top;
}
else {
top = Math.min(selectedBounds.y, normalBounds.y);
left = 0;
right = pane.getWidth() - Math.max(selectedBounds.x + selectedBounds.width,
normalBounds.x + normalBounds.width);
// bottom = top;
}
Dimension size = pane.getSize();
reset(pane);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -