1. CustomSplitPaneUI之部分程式範例
public class CustomSplitPaneUI extends BasicSplitPaneUI {
private static Color BG_COLOR = Color.BLACK;
private static Color BG_SHADOW_COLOR = Color.WHITE;
private static Color ARROW_COLOR = Color.WHITE;
private static Color ARROW_BLOCK_BG_COLOR = Color.BLACK;
private static Color ARROW_BLOCK_BG_SHADOW_COLOR = Color.WHITE;
private static int ONE_TOUCH_BUTTON_SIZE = -1;
//private static final SearchSplitPaneUI cornerButtonUI = new SearchSplitPaneUI();
public CustomSplitPaneUI() {
super();
}
public static ComponentUI createUI(JComponent c) {
return new CustomSplitPaneUI();
}
public void setDividerBackground(Color bgColor, Color bgShadowColor) {
BG_COLOR = bgColor;
BG_SHADOW_COLOR = bgShadowColor;
}
public void setArrowBtnBackground(Color bgColor) {
ARROW_COLOR = bgColor;
}
public void setArrowBlockBackground(Color bgColor, Color bgShadowColor) {
ARROW_BLOCK_BG_COLOR = bgColor;
ARROW_BLOCK_BG_SHADOW_COLOR = bgShadowColor;
}
public void setOneTouchButtonSize(int size) {
// 在此範例中,OneTouchButton size 只有4種:6-9
if(size > 9)
ONE_TOUCH_BUTTON_SIZE = 9;
else if(size < 6)
ONE_TOUCH_BUTTON_SIZE = 6;
else
ONE_TOUCH_BUTTON_SIZE = size;
}
▲public func以讓使用者自行設定Divider和Arrow Button背景色與陰影色
/**
* Creates the default divider.
*/
@Override
public BasicSplitPaneDivider createDefaultDivider() {
return new CustomBasicSplitPaneDivider(this, ONE_TOUCH_BUTTON_SIZE);
}
private class CustomBasicSplitPaneDivider extends BasicSplitPaneDivider {
private int oneTouchSize, oneTouchOffset;
boolean centerOneTouchButtons;
// Arrow Block Bg 之起始位置變數
private int x1, y1;
@SuppressWarnings("unchecked")
public CustomBasicSplitPaneDivider(CustomSplitPaneUI ui, int touchBtnSize) {
super(ui);
if(touchBtnSize == -1) {
oneTouchSize = DefaultLookup.getInt(ui.getSplitPane(), ui, "SplitPane.oneTouchButtonSize", ONE_TOUCH_SIZE);
if(oneTouchSize > 9)
oneTouchSize = 9;
else if(oneTouchSize < 6)
oneTouchSize = 6;
}
else {
oneTouchSize = touchBtnSize;
}
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"));
}
▲創建CustomBasicSplitPaneDivider
@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
g.setColor(ARROW_BLOCK_BG_COLOR);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
// draw the arrow
g.setColor(ARROW_COLOR);
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.fillPolygon(xs, ys, 3); // Little trick to make the arrows of equal size 小技巧使箭頭的大小相等
}
}
// 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;
}
▲部分createRightOneTouchButton之程式–Divider和Arrow Button背景色與陰影色變更成可根據客製來設定之
@Override
public void paint(Graphics g) {
super.paint(g);
Dimension size = getSize();
// Divider bg 和 陰影色
g.setColor(BG_COLOR);
g.fillRect(1, 1, size.width - 1, size.height - 1);
g.setColor(BG_SHADOW_COLOR);
g.drawRect(0, 0, size.width, size.height);
// Arrow button bg 和 陰影色
if (orientation == JSplitPane.VERTICAL_SPLIT) {
g.setColor(ARROW_BLOCK_BG_COLOR);
g.fillRect(x1, 1, 52, size.height - 1); // Arrow Block Bg 之長度為52
g.setColor(ARROW_BLOCK_BG_SHADOW_COLOR);
g.drawRect(x1, 1, 52, size.height - 1);
}
else {
g.setColor(ARROW_BLOCK_BG_COLOR);
g.fillRect(1, y1, size.width - 1, 52); // Arrow Block Bg 之長度為52
g.setColor(ARROW_BLOCK_BG_SHADOW_COLOR);
g.drawRect(1, y1, size.width - 1, 52);
}
if (leftButton != null) {
leftButton.repaint();
}
if (rightButton != null) {
rightButton.repaint();
}
}
▲paint(Graphics g)之程式–Divider和Arrow Button背景色變更成可根據客製來設定之,並新增Arrow Button陰影色的部分
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) CustomBasicSplitPaneDivider.this.getSize().getWidth();
// 設置 Arrow Block Bg 之起始位置
x1 = width / 2 - oneTouchSize - 18;
// 設定 Left / Right Button 之位置
leftButton.setBounds(extraX - oneTouchOffset-16 + width / 2, y, blockSize * 2, blockSize);
rightButton.setBounds(extraX - oneTouchOffset-(2 + (oneTouchSize-ONE_TOUCH_SIZE) * 5) + 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) CustomBasicSplitPaneDivider.this.getSize().getHeight();
// 設置 Arrow Block Bg 之起始位置
y1 = height / 2 - oneTouchSize - 18;
// 設定 Left / Right Button 之位置
leftButton.setBounds(x, extraY - oneTouchOffset-16 + height / 2, blockSize, blockSize * 2);
rightButton.setBounds(x, extraY - oneTouchOffset-(2 + (oneTouchSize-ONE_TOUCH_SIZE) * 5) + oneTouchSize * 2 + height / 2, blockSize, blockSize * 2);
}
}
else {
leftButton.setBounds(-5, -5, 1, 1);
rightButton.setBounds(-5, -5, 1, 1);
}
}
}
▲設定DividerLayout - Arrow Block Bg之起始位置、Left / Right Button之位置
2. 主程式範例
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JSplitPane;
import javax.swing.UIManager;
import javax.swing.WindowConstants;
/**
*
* @author Elsa
*/
public class JSplitPanelDemo03 extends JPanel {
JPanel panel01, panel02;
JSplitPane splitPane;
public JSplitPanelDemo03() {
this.setLayout(new BorderLayout());
// 置頂 or 置底 按鈕 離左邊的距離 --> 因按鈕置中了,所以不需要再設置,如設定了,也不會有所變動
//UIManager.put("SplitPane.oneTouchButtonOffset", 100);
UIManager.put("SplitPaneDivider.draggingColor", new Color(214, 197, 158)); // 拖曳 Divider 時的顏色
panel01 = new JPanel();
panel02 = new JPanel();
panel01.setPreferredSize(new Dimension(400, 200));
panel01.setLayout(new BorderLayout());
panel01.add(new JButton("第一個按鈕"), BorderLayout.CENTER);
panel01.setBackground(new Color(240,235,225));
panel02.setPreferredSize(new Dimension(400, 140));
panel02.setBackground(new Color(240,235,225));
splitPane = new JSplitPane();
// 設置 上下放置 之 內容
splitPane.setLeftComponent(panel01);
splitPane.setRightComponent(panel02);
// 顯示置頂 or 置底 按鈕,同於 UIManager.put("SplitPane.centerOneTouchButtons", true);
splitPane.setOneTouchExpandable(true);
// 設置 分割之方向 (JSplitPane.VERTICAL_SPLIT / JSplitPane.HORIZONTAL_SPLIT)
splitPane.setOrientation(JSplitPane.VERTICAL_SPLIT);
// 設置 Divider 之 寬度
splitPane.setDividerSize(20);
// 設定 splitPane Divider 與 leftButton、rightButton 之背景顏色
CustomSplitPaneUI ui= new CustomSplitPaneUI();
ui.setDividerBackground(new Color(231, 220, 197), new Color(244, 240, 230));
ui.setArrowBtnBackground(Color.BLACK);
ui.setArrowBlockBackground(new Color(205, 184, 136), new Color(190, 163, 100));
ui.setOneTouchButtonSize(8); // 同於 UIManager.put("SplitPane.oneTouchButtonSize", 8); // 設定置頂 or 置底 按鈕 大小
splitPane.setUI(ui);
this.add(splitPane);
this.setPreferredSize(new Dimension(400, 240));
}
3. 執行結果
▲生成時之樣貌
▲按下置頂/底之樣貌
▲拖曳Divider時與拖曳後之樣貌
▲置頂/底按鈕最大(9)和小(6)size之樣貌
▲Horizontal Split之樣貌
[補充]
1. 如果UI樣式選擇Nimbus或Window,目前依此設定只有Window和Windows已可成功變更成使用者所重新設定之樣式與顏色。
但Nimbus置頂和置底之按鈕顏色消失了,不過其相對位置之功能還在,於後有空再去研究其是否有解決之方案。
執行結果如下所示:
▲UI樣式選擇Nimbus之樣貌
▲UI樣式選擇Window之樣貌
2. 本篇之主程式其他詳細的部分,請參考「如何客製化JSplitPanel中Divider之風格(一)」文章
3. 本篇之CustomSplitPaneUI其他詳細的程式,請參考「JSplitPane中间的Divider的外观」文章
參考網址:
http://lgh3292.iteye.com/blog/321864
留言列表