close

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以讓使用者自行設定DividerArrow 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之程式–DividerArrow 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)之程式–DividerArrow 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. 執行結果

執行結果01.png

生成時之樣貌

 

執行結果02.png

執行結果03.png

▲按下置頂/之樣貌

 

執行結果04.png

執行結果05.png

▲拖曳Divider時與拖曳後之樣貌

 

執行結果07_最大size按鈕.png

執行結果06_最小size按鈕.png

 

▲置頂/底按鈕最大(9)和小(6)size之樣貌

 

執行結果_HORIZONTAL_SPLIT.png

Horizontal Split之樣貌

 

 

[補充]

1. 如果UI樣式選擇NimbusWindow,目前依此設定只有WindowWindows已可成功變更成使用者所重新設定之樣式與顏色。

Nimbus置頂和置底之按鈕顏色消失了,不過其相對位置之功能還在,於後有空再去研究其是否有解決之方案。

執行結果如下所示:

執行結果_Nimbus.png

 

 

UI樣式選擇Nimbus之樣貌

 

執行結果_Window.png

UI樣式選擇Window之樣貌

 

2. 本篇之主程式其他詳細的部分,請參考「如何客製化JSplitPanelDivider之風格()」文章

3. 本篇之CustomSplitPaneUI其他詳細的程式,請參考「JSplitPane中间的Divider的外观」文章

 

參考網址:

http://lgh3292.iteye.com/blog/321864

 

arrow
arrow
    文章標籤
    JSplitPanel Divider Arrow Button
    全站熱搜

    Elsa 發表在 痞客邦 留言(0) 人氣()