JSplitPaneWithZeroSizeDivider.java
package com.jsql.view.swing.splitpane;
/*
* Copyright (c) 2011 Karl Tauber <karl at jformdesigner dot com>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* o Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
import com.jsql.util.LogLevelUtil;
import com.jsql.view.swing.util.UiUtil;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;
import java.awt.*;
/**
* A JSplitPane that uses a 1 pixel thin visible divider,
* but a 9 pixel wide transparent drag area.
*/
public class JSplitPaneWithZeroSizeDivider extends JSplitPane {
/**
* Log4j logger sent to view.
*/
private static final Logger LOGGER = LogManager.getRootLogger();
/**
* The size of the transparent drag area.
*/
private int dividerDragSize = 9;
/**
* The offset of the transparent drag area relative to the visible divider line.
* Positive offset moves the drag area left/top to the divider line.
* If zero then the drag area is right/bottom of the divider line.
* Useful values are in the range 0 to {@link #dividerDragSize}.
* Default is centered.
*/
private int dividerDragOffset = 0;
public JSplitPaneWithZeroSizeDivider(int orientation) {
super(orientation, true);
}
public void disableDragSize() {
this.dividerDragSize = 0;
}
public void enableDragSize() {
this.dividerDragSize = 9;
}
public int getDividerDragSize() {
return this.dividerDragSize;
}
public void setDividerDragSize(int dividerDragSize) {
this.dividerDragSize = dividerDragSize;
this.revalidate();
}
public int getDividerDragOffset() {
return this.dividerDragOffset;
}
public void setDividerDragOffset(int dividerDragOffset) {
this.dividerDragOffset = dividerDragOffset;
this.revalidate();
}
@Override
public void doLayout() {
super.doLayout();
// increase divider width or height
BasicSplitPaneDivider divider = ((BasicSplitPaneUI) this.getUI()).getDivider();
Rectangle bounds = divider.getBounds();
if (this.orientation == HORIZONTAL_SPLIT) {
bounds.x -= this.dividerDragOffset;
bounds.width = this.dividerDragSize;
} else {
bounds.y -= this.dividerDragOffset;
bounds.height = this.dividerDragSize;
}
divider.setBounds(bounds);
}
@Override
public void updateUI() {
this.setUI(new SplitPaneWithZeroSizeDividerUI());
this.revalidate();
}
private class SplitPaneWithZeroSizeDividerUI extends BasicSplitPaneUI {
@Override
public BasicSplitPaneDivider createDefaultDivider() {
return new ZeroSizeDivider(this);
}
}
private class ZeroSizeDivider extends BasicSplitPaneDivider {
public ZeroSizeDivider(BasicSplitPaneUI ui) {
super(ui);
super.setBorder(null);
this.setBackground(UiUtil.COLOR_COMPONENT_BORDER);
}
@Override
public void setBorder(Border border) {
// ignore
}
@Override
public void paint(Graphics g) {
g.setColor(this.getBackground());
if (this.orientation == HORIZONTAL_SPLIT) {
// Fix #38925: ClassCastException on drawLine()
try {
g.drawLine(
JSplitPaneWithZeroSizeDivider.this.dividerDragOffset,
0,
JSplitPaneWithZeroSizeDivider.this.dividerDragOffset,
this.getHeight() - 1
);
} catch (ClassCastException e) {
LOGGER.log(LogLevelUtil.CONSOLE_JAVA, e, e);
}
} else {
g.drawLine(
0,
JSplitPaneWithZeroSizeDivider.this.dividerDragOffset,
this.getWidth() - 1,
JSplitPaneWithZeroSizeDivider.this.dividerDragOffset
);
}
}
@Override
protected void dragDividerTo(int location) {
super.dragDividerTo(location + JSplitPaneWithZeroSizeDivider.this.dividerDragOffset);
}
@Override
protected void finishDraggingTo(int location) {
super.finishDraggingTo(location + JSplitPaneWithZeroSizeDivider.this.dividerDragOffset);
}
}
}