修改 JSplitPane 展开、隐藏按钮的样式位置
package com.easyfeeling.ui.skin;
import java.awt.Color;
import java.awt.Component;
import java.awt.Container;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Insets;
import java.awt.LayoutManager;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JSplitPane;
import javax.swing.UIManager;
import javax.swing.border.Border;
import javax.swing.plaf.ComponentUI;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
/**
*
* @author lgh
*/
public class SearchSplitPaneUI extends BasicSplitPaneUI {
private static final Color BG_COLOR = Color.BLACK;
private static final SearchSplitPaneUI cornerButtonUI = new SearchSplitPaneUI();
public SearchSplitPaneUI() {
super();
}
public static ComponentUI createUI(JComponent c) {
return new SearchSplitPaneUI();
}
/**
* Creates the default divider.
*/
@Override
public BasicSplitPaneDivider createDefaultDivider() {
return new MyBasicSplitPaneDivider(this);
}
private class MyBasicSplitPaneDivider extends BasicSplitPaneDivider {
private int oneTouchSize, oneTouchOffset;
boolean centerOneTouchButtons;
//center空白区域
private int x1, y1;
@SuppressWarnings("unchecked")
public MyBasicSplitPaneDivider(SearchSplitPaneUI ui) {
super(ui);
// oneTouchSize = DefaultLookup.getInt(ui.getSplitPane(), ui,
// "SplitPane.oneTouchButtonSize", ONE_TOUCH_SIZE);
// oneTouchOffset = DefaultLookup.getInt(ui.getSplitPane(), ui,
// "SplitPane.oneTouchButtonOffset", ONE_TOUCH_OFFSET);
// centerOneTouchButtons = DefaultLookup.getBoolean(ui.getSplitPane(),
// ui, "SplitPane.centerOneTouchButtons", true);
oneTouchSize = ONE_TOUCH_SIZE;
oneTouchOffset = ONE_TOUCH_OFFSET;
centerOneTouchButtons = true;
setLayout(new DividerLayout());
setBasicSplitPaneUI(ui);
orientation = splitPane.getOrientation();
setCursor((orientation == JSplitPane.HORIZONTAL_SPLIT) ? Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR) : Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
setBackground(UIManager.getColor("SplitPane.background"));
// super(ui);
// this.setBackground(BG_COLOR);
// this.setPreferredSize(getSize());
}
/**
* Creates and return an instance of JButton that can be used to
* collapse the right component in the split pane.
*/
@Override
protected JButton createRightOneTouchButton() {
JButton b = new JButton() {
public void setBorder(Border border) {
}
@Override
public void paint(Graphics g) {
if (splitPane != null) {
int[] xs = new int[3];
int[] ys = new int[3];
int blockSize;
// Fill the background first ...
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getWidth(),
this.getHeight());
// ... then draw the arrow.
if (orientation == JSplitPane.VERTICAL_SPLIT) {
blockSize = Math.min(getHeight(), oneTouchSize);
xs[0] = blockSize;
xs[1] = blockSize << 1;
xs[2] = 0;
ys[0] = blockSize;
ys[1] = ys[2] = 0;
} else {
blockSize = Math.min(getWidth(), oneTouchSize);
xs[0] = xs[2] = 0;
xs[1] = blockSize;
ys[0] = 0;
ys[1] = blockSize;
ys[2] = blockSize << 1;
}
g.setColor(BG_COLOR);
g.fillPolygon(xs, ys, 3);
}
}
// Don't want the button to participate in focus traversable.
public boolean isFocusTraversable() {
return false;
}
};
b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));
b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
b.setFocusPainted(false);
b.setBorderPainted(false);
b.setRequestFocusEnabled(false);
return b;
}
/**
* Creates and return an instance of JButton that can be used to
* collapse the left component in the split pane.
*/
protected JButton createLeftOneTouchButton() {
JButton b = new JButton() {
public void setBorder(Border b) {
}
public void paint(Graphics g) {
if (splitPane != null) {
int[] xs = new int[3];
int[] ys = new int[3];
int blockSize;
// Fill the background first ...
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getWidth(),
this.getHeight());
// ... then draw the arrow.
g.setColor(BG_COLOR);
if (orientation == JSplitPane.VERTICAL_SPLIT) {
blockSize = Math.min(getHeight(), oneTouchSize);
xs[0] = blockSize;
xs[1] = 0;
xs[2] = blockSize << 1;
ys[0] = 0;
ys[1] = ys[2] = blockSize;
g.drawPolygon(xs, ys, 3); // Little trick to make the
// arrows of equal size
} else {
blockSize = Math.min(getWidth(), oneTouchSize);
xs[0] = xs[2] = blockSize;
xs[1] = 0;
ys[0] = 0;
ys[1] = blockSize;
ys[2] = blockSize << 1;
}
g.fillPolygon(xs, ys, 3);
}
}
// Don't want the button to participate in focus traversable.
public boolean isFocusTraversable() {
return false;
}
};
b.setMinimumSize(new Dimension(oneTouchSize, oneTouchSize));
b.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
b.setFocusPainted(false);
b.setBorderPainted(false);
b.setRequestFocusEnabled(false);
return b;
}
/**
* Used to layout a <code>BasicSplitPaneDivider</code>.
* Layout for the divider
* involves appropriately moving the left/right buttons around.
* <p>
*/
protected class DividerLayout implements LayoutManager {
public void layoutContainer(Container c) {
if (leftButton != null && rightButton != null) {
if (splitPane.isOneTouchExpandable()) {
Insets insets = getInsets();
if (orientation == JSplitPane.VERTICAL_SPLIT) {
int extraX = (insets != null) ? insets.left : 0;
int blockSize = getHeight();
if (insets != null) {
blockSize -= (insets.top + insets.bottom);
blockSize = Math.max(blockSize, 0);
}
blockSize = Math.min(blockSize, oneTouchSize);
int y = (c.getSize().height - blockSize) / 2;
if (!centerOneTouchButtons) {
y = (insets != null) ? insets.top : 0;
extraX = 0;
}
int width = (int) MyBasicSplitPaneDivider.this.getSize().getWidth();
x1 = width / 2 - oneTouchSize;
leftButton.setBounds(extraX - oneTouchOffset + width / 2, y,
blockSize * 2, blockSize);
rightButton.setBounds(extraX - oneTouchOffset +
oneTouchSize * 2 + width / 2, y,
blockSize * 2, blockSize);
} else {
int extraY = (insets != null) ? insets.top : 0;
int blockSize = getWidth();
if (insets != null) {
blockSize -= (insets.left + insets.right);
blockSize = Math.max(blockSize, 0);
}
blockSize = Math.min(blockSize, oneTouchSize);
int x = (c.getSize().width - blockSize) / 2;
if (!centerOneTouchButtons) {
x = (insets != null) ? insets.left : 0;
extraY = 0;
}
int height = (int) MyBasicSplitPaneDivider.this.getSize().getHeight();
y1 = height / 2 - oneTouchSize;
leftButton.setBounds(x, extraY - oneTouchOffset + height / 2,
blockSize, blockSize * 2);
rightButton.setBounds(x, extraY - oneTouchOffset +
oneTouchSize * 2 + height / 2, blockSize,
blockSize * 2);
}
} else {
leftButton.setBounds(-5, -5, 1, 1);
rightButton.setBounds(-5, -5, 1, 1);
}
}
}
public Dimension minimumLayoutSize(Container c) {
// NOTE: This isn't really used, refer to
// BasicSplitPaneDivider.getPreferredSize for the reason.
// I leave it in hopes of having this used at some point.
if (splitPane == null) {
return new Dimension(0, 0);
}
Dimension buttonMinSize = null;
if (splitPane.isOneTouchExpandable() && leftButton != null) {
buttonMinSize = leftButton.getMinimumSize();
}
Insets insets = getInsets();
int width = getDividerSize();
int height = width;
if (orientation == JSplitPane.VERTICAL_SPLIT) {
if (buttonMinSize != null) {
int size = buttonMinSize.height;
if (insets != null) {
size += insets.top + insets.bottom;
}
height = Math.max(height, size);
}
width = 1;
} else {
if (buttonMinSize != null) {
int size = buttonMinSize.width;
if (insets != null) {
size += insets.left + insets.right;
}
width = Math.max(width, size);
}
height = 1;
}
return new Dimension(width, height);
}
public Dimension preferredLayoutSize(Container c) {
return minimumLayoutSize(c);
}
public void removeLayoutComponent(Component c) {
}
public void addLayoutComponent(String string, Component c) {
}
} // End of class BasicSplitPaneDivider.DividerLayout
}
}
相关推荐
自定义控件是C#编程中一个重要的概念,它允许开发者根据需求扩展或修改内置控件的功能和外观,以满足特定项目的需求。在本案例中,我们将深入探讨如何自定义ComboBox控件。 ComboBox控件是Windows Forms中一个非常...
本篇文章将深入探讨如何定义和优化自定义模块,以及处理自定义事件。 首先,理解FreeSwitch模块的生命周期是至关重要的。一个模块通常包括加载、初始化、运行和卸载四个阶段。在加载阶段,模块被FreeSwitch核心加载...
在QT编程中,自定义窗口是一项常见的需求,它允许开发者根据应用的需求来设计独特的界面元素和交互方式。本文将深入探讨如何在QT中创建自定义窗口,并实现自由拖动和自定义标题的功能。 首先,我们需要了解QT中的...
"C#自定义控件库"是指使用C#语言编写的、由开发者自定义的控件集合,这些控件可以扩展.NET Framework的标准控件集,为用户提供更丰富的界面元素和功能。自定义控件是软件开发中的一个重要环节,特别是在UI设计和用户...
本篇将深入探讨如何自定义FreeMarker标签,以扩展其功能并适应特定项目需求。 首先,理解FreeMarker的默认标签语法至关重要。FreeMarker使用${...}表达式来插入变量,#{...}用于输出注释,以及、等控制结构进行条件...
本教程将深入讲解如何在WinForms中自定义CheckBox控件,以满足特定的界面或功能需求。 首先,自定义CheckBox控件主要是为了扩展其默认功能,比如改变其外观、添加额外的事件处理或者提供更复杂的交互逻辑。在VS2005...
鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例鸿蒙自定义组件实例...
本主题将深入探讨如何在Spring Boot工程中通过自定义response注解、利用Java反射机制、设置自定义拦截器以及实现WebMvcConfigurer接口来实现这一目标。 首先,我们来看自定义response注解。在Spring Boot中,可以...
【vue+printJs】前端打印, 自定义字体大小, 自定义样式, 封装共享样式,开箱即用【vue+printJs】前端打印, 自定义字体大小, 自定义样式, 封装共享样式,开箱即用【vue+printJs】前端打印, 自定义字体大小, 自定义样式,...
在APICloud平台上,开发者可以利用其提供的自定义模块功能,扩展原生的API接口,以满足特定项目的需求。本文将详细解析如何进行自定义模块的开发、打包以及使用过程,结合给定的压缩包文件中的源码和截图,我们将...
本话题将深入探讨如何实现UITableViewCell的自定义,特别是实现等高的自定义。 一、UITableViewCell自定义基础 自定义UITableViewCell主要涉及以下几个方面: 1. 创建UITableViewCell子类:通过继承...
在C#编程中,自定义用户控件是提高应用程序界面美观性和功能多样性的重要手段。本教程将基于给定的"C#自定义漂亮按钮"主题,深入讲解如何利用C#和Visual Studio 2010创建一个自定义的按钮控件。我们将主要探讨以下几...
在实际的企业环境中,根据业务需求,我们可能需要对默认的CAS登录页面进行自定义,以提供更符合品牌形象或用户体验的界面。下面将详细讲解如何配置和实现CAS的自定义登录页面。 一、CAS自定义登录页面概述 CAS的...
自定义用户控件是提升应用程序功能和界面个性化的重要手段。在这个场景中,我们关注的是一个特定的自定义控件,即基于PictureBox的扩展。PictureBox是.NET Framework提供的一个标准控件,用于显示图像,而自定义用户...
在Android开发中,自定义View和自定义属性是提升应用个性化和功能扩展性的重要手段。本文将深入探讨这两个核心概念,以及如何在实际项目中应用它们。 ### 自定义View 自定义View允许开发者创建自己的视图组件,以...
在AutoCAD平台上,开发者可以利用ObjectARX(Autodesk Reactor Extension)库来创建自定义实体,这是一种基于C++的编程接口,允许程序员深入到AutoCAD的内部工作流程,实现扩展功能和定制化操作。本篇文章将详细探讨...
在C# WinForm应用开发中,自定义RadioButton控件是一种常见的需求,这通常涉及到扩展.NET Framework提供的默认RadioButton控件的功能,以满足特定的设计或交互需求。本教程将深入讲解如何在Visual Studio 2005及其更...
这个自定义键盘的实现主要涉及到UIKeyboardType的扩展以及自定义UIView的使用。 首先,我们了解iOS系统键盘的默认类型。iOS提供了多种键盘类型,如UIKeyboardTypeASCIICapable、UIKeyboardTypeNumberPad等。其中,...
在开发这些应用程序时,有时我们需要根据项目需求创建特定的用户界面元素,这正是自定义控件的作用所在。本主题将深入探讨如何在C#中自定义一个类似于系统默认`MessageBox`的控件。 `MessageBox`是.NET Framework...
在Microsoft Foundation Classes (MFC)库中,开发者可以利用自定义消息和自定义类来扩展框架的功能,以满足特定项目的需求。自定义消息是Windows消息系统的一部分,允许程序员定义自己的消息类型,而自定义类则提供...