You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
430 lines
13 KiB
430 lines
13 KiB
package com.fr.design.gui.icontainer; |
|
|
|
|
|
import com.fr.design.base.mode.DesignModeContext; |
|
import com.fr.design.constants.UIConstants; |
|
import com.fr.design.gui.ibutton.UIButton; |
|
import com.fr.design.mainframe.DesignerContext; |
|
import com.fr.design.utils.SvgDrawUtils; |
|
import com.fr.design.utils.gui.GUICoreUtils; |
|
|
|
import javax.swing.JComponent; |
|
import javax.swing.JFrame; |
|
import javax.swing.JPanel; |
|
import java.awt.BorderLayout; |
|
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.Image; |
|
import java.awt.LayoutManager; |
|
import java.awt.event.MouseAdapter; |
|
import java.awt.event.MouseEvent; |
|
import java.awt.event.MouseMotionListener; |
|
import java.awt.Point; |
|
|
|
/** |
|
* Created by plough on 2017/7/7. |
|
*/ |
|
public class UIEastResizableContainer extends JPanel { |
|
private static final long serialVersionUID = 1854340560790476907L; |
|
public static final int MAX_CONTAINER_WIDTH = 825; |
|
public static final int INIT_CONTAINER_WIDTH = 380; |
|
public static final int MIN_CONTAINER_WIDTH = 150; |
|
|
|
private int containerWidth = 240; |
|
private int preferredWidth = 240; |
|
private int topToolPaneHeight = 25; |
|
private int leftPaneWidth = 40; |
|
private static final int RESIZE_RANGE = 8; |
|
private Cursor westResizeCursor = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR); |
|
|
|
private JComponent leftPane; |
|
private JComponent rightPane; |
|
|
|
// private HorizotalToolPane horizontToolPane; |
|
private TopToolPane topToolPane; |
|
|
|
|
|
private static final int ARROW_MARGIN = 15; |
|
private static final int ARROW_RANGE = 35; |
|
|
|
// private boolean isRightPaneVisible = true; |
|
|
|
public UIEastResizableContainer() { |
|
this(new JPanel(), new JPanel()); |
|
} |
|
|
|
/** |
|
* 设置面板宽度 |
|
* |
|
* @param width |
|
*/ |
|
public void setContainerWidth(int width) { |
|
this.containerWidth = width; |
|
this.preferredWidth = width; |
|
} |
|
|
|
public boolean isRightPaneVisible() { |
|
return containerWidth > leftPaneWidth; |
|
} |
|
|
|
|
|
// public void setRightPaneVisible(boolean isVisible){ |
|
// this.isRightPaneVisible = isVisible; |
|
// } |
|
|
|
private void setPreferredWidth(int width) { |
|
this.preferredWidth = width; |
|
} |
|
|
|
public UIEastResizableContainer(JComponent leftPane, JComponent rightPane) { |
|
setBackground(UIConstants.PROPERTY_PANE_BACKGROUND); |
|
this.leftPane = leftPane; |
|
this.rightPane = rightPane; |
|
|
|
this.topToolPane = new TopToolPane(); |
|
topToolPane.setBackground(UIConstants.PROPERTY_PANE_BACKGROUND); |
|
|
|
setLayout(containerLayout); |
|
add(topToolPane); |
|
add(leftPane); |
|
add(rightPane); |
|
} |
|
|
|
public static void main(String... args) { |
|
JFrame jf = new JFrame("test"); |
|
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
|
JPanel content = (JPanel) jf.getContentPane(); |
|
content.setLayout(new BorderLayout()); |
|
|
|
JPanel leftPane = new JPanel(); |
|
leftPane.setBackground(Color.yellow); |
|
JPanel rightPane = new JPanel(); |
|
rightPane.setBackground(Color.green); |
|
|
|
UIButton b1, b2; |
|
b1 = new UIButton("b1"); |
|
b2 = new UIButton("b2"); |
|
b1.setPreferredSize(new Dimension(40, 40)); |
|
b2.setPreferredSize(new Dimension(40, 40)); |
|
leftPane.add(b1); |
|
leftPane.add(b2); |
|
|
|
|
|
UIEastResizableContainer bb = new UIEastResizableContainer(leftPane, rightPane); |
|
|
|
JPanel cc = new JPanel(); |
|
cc.setBackground(Color.WHITE); |
|
|
|
content.add(bb, BorderLayout.EAST); |
|
content.add(cc, BorderLayout.CENTER); |
|
GUICoreUtils.centerWindow(jf); |
|
jf.setSize(500, 500); |
|
jf.setVisible(true); |
|
} |
|
|
|
/** |
|
* 将面板设置成最佳的宽度 |
|
*/ |
|
public void setWindow2PreferWidth() { |
|
if (containerWidth == leftPaneWidth) { |
|
containerWidth = preferredWidth; |
|
refreshContainer(); |
|
} |
|
} |
|
|
|
/** |
|
* 得到容器的宽度 |
|
* |
|
* @return |
|
*/ |
|
public int getContainerWidth() { |
|
return this.containerWidth; |
|
} |
|
|
|
/** |
|
* 设置关闭设计器前最后一次面板的宽度 |
|
* |
|
* @param containerWidth |
|
*/ |
|
public void setLastContainerWidth(int containerWidth) { |
|
if (containerWidth == leftPaneWidth) { |
|
this.containerWidth = containerWidth; |
|
} |
|
// 忽略其他情况 |
|
} |
|
|
|
private LayoutManager containerLayout = new LayoutManager() { |
|
|
|
@Override |
|
public void removeLayoutComponent(Component comp) { |
|
// TODO Auto-generated method stub |
|
|
|
} |
|
|
|
@Override |
|
public Dimension preferredLayoutSize(Container parent) { |
|
return parent.getPreferredSize(); |
|
} |
|
|
|
@Override |
|
public Dimension minimumLayoutSize(Container parent) { |
|
return null; |
|
} |
|
|
|
@Override |
|
public void layoutContainer(Container parent) { |
|
if (topToolPane == null || rightPane == null) { |
|
return; |
|
} |
|
|
|
// topToolPane.setBounds(0, 0, containerWidth, topToolPaneHeight);//0,0,10,462 |
|
topToolPane.setBounds(0, 0, leftPaneWidth, topToolPaneHeight);//0,0,10,462 |
|
leftPane.setBounds(0, topToolPaneHeight, leftPaneWidth, getHeight() - topToolPaneHeight); |
|
|
|
// parameterPane.setBounds(20, 0, 230, getParameterPaneHeight());//10,0,230,462 |
|
rightPane.setBounds(leftPaneWidth, 0, containerWidth - leftPaneWidth, getHeight());//20,0,230,0 |
|
} |
|
|
|
@Override |
|
public void addLayoutComponent(String name, Component comp) { |
|
// do nothing |
|
} |
|
}; |
|
|
|
@Override |
|
/** |
|
* 得到最佳大小 |
|
*/ |
|
public Dimension getPreferredSize() { |
|
return new Dimension(containerWidth, 400); |
|
} |
|
|
|
/** |
|
* 替换左子面板 |
|
* |
|
* @param pane 面板 |
|
*/ |
|
public void replaceLeftPane(JComponent pane) { |
|
remove(pane); |
|
remove(this.leftPane); |
|
add(this.leftPane = pane); |
|
refreshContainer(); |
|
} |
|
|
|
|
|
/** |
|
* 替换右子面板 |
|
* |
|
* @param pane 面板 |
|
*/ |
|
public void replaceRightPane(JComponent pane) { |
|
remove(pane); |
|
remove(this.rightPane); |
|
add(this.rightPane = pane); |
|
refreshContainer(); |
|
} |
|
|
|
/** |
|
* 得到左子面板 |
|
* |
|
* @return |
|
*/ |
|
public JComponent getLeftPane() { |
|
return this.leftPane; |
|
} |
|
|
|
/** |
|
* 得到右子面板 |
|
* |
|
* @return |
|
*/ |
|
public JComponent getRightPane() { |
|
return this.rightPane; |
|
} |
|
|
|
private void refreshContainer() { |
|
validate(); |
|
repaint(); |
|
revalidate(); |
|
} |
|
|
|
/** |
|
* 伸缩右子面板时,触发此方法 |
|
*/ |
|
public void onResize() { |
|
refreshContainer(); |
|
if (DesignModeContext.isAuthorityEditing()) { |
|
DesignerContext.getDesignerFrame().doResize(); |
|
} |
|
} |
|
|
|
public void showContainer() { |
|
if (containerWidth != leftPaneWidth) { |
|
return; |
|
} |
|
containerWidth = preferredWidth; |
|
onResize(); |
|
} |
|
|
|
public void hideContainer() { |
|
if (containerWidth == leftPaneWidth) { |
|
return; |
|
} |
|
setPreferredWidth(containerWidth); |
|
containerWidth = leftPaneWidth; |
|
onResize(); |
|
} |
|
|
|
private class TopToolPane extends JPanel { |
|
private int model = UIConstants.MODEL_NORMAL; |
|
private Point mouseDownCompCoords; |
|
|
|
public TopToolPane() { |
|
super(); |
|
addMouseMotionListener(new MouseMotionListener() { |
|
|
|
@Override |
|
public void mouseMoved(MouseEvent e) { |
|
if (e.getX() <= RESIZE_RANGE) { |
|
setCursor(westResizeCursor); |
|
} else { |
|
setCursor(Cursor.getDefaultCursor()); |
|
model = UIConstants.MODEL_NORMAL; |
|
} |
|
refreshContainer(); |
|
} |
|
|
|
@Override |
|
public void mouseDragged(MouseEvent e) { |
|
if (mouseDownCompCoords != null && getCursor().equals(westResizeCursor)) { |
|
Point currCoords = e.getLocationOnScreen(); |
|
int newWidth = containerWidth - (currCoords.x - mouseDownCompCoords.x); |
|
if (newWidth >= MIN_CONTAINER_WIDTH && newWidth <= MAX_CONTAINER_WIDTH) { |
|
containerWidth = newWidth; |
|
mouseDownCompCoords = currCoords; |
|
refreshContainer(); |
|
} |
|
} |
|
} |
|
}); |
|
addMouseListener(new MouseAdapter() { |
|
|
|
@Override |
|
public void mouseClicked(MouseEvent e) { |
|
if (e.getX() <= ARROW_RANGE) { |
|
if (containerWidth == leftPaneWidth) { |
|
showContainer(); |
|
} else { |
|
hideContainer(); |
|
} |
|
} |
|
} |
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
model = UIConstants.MODEL_NORMAL; |
|
if (e.getX() <= RESIZE_RANGE) { |
|
mouseDownCompCoords = e.getLocationOnScreen(); |
|
} |
|
refreshContainer(); |
|
} |
|
|
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
mouseDownCompCoords = null; |
|
} |
|
}); |
|
} |
|
|
|
@Override |
|
public void paint(Graphics g) { |
|
Image button; |
|
if (containerWidth == leftPaneWidth) { |
|
if (model == UIConstants.MODEL_NORMAL) { |
|
button = UIConstants.DRAG_LEFT_NORMAL; |
|
} else { |
|
button = UIConstants.DRAG_LEFT_PRESS; |
|
} |
|
} else { |
|
if (model == UIConstants.MODEL_NORMAL) { |
|
button = UIConstants.DRAG_RIGHT_NORMAL; |
|
} else { |
|
button = UIConstants.DRAG_RIGHT_PRESS; |
|
} |
|
} |
|
SvgDrawUtils.doDrawSVG(g, () -> SvgDrawUtils.drawImage(g, button, 10, 7, null)); |
|
} |
|
} |
|
|
|
/** |
|
* This inner class handles mouse events for resizing the container |
|
* by dragging the left edge of the right pane. |
|
*/ |
|
public class ResizeListener extends MouseAdapter implements MouseMotionListener { |
|
|
|
// Stores the point where the mouse was initially pressed |
|
private Point mouseDownCompCoords; |
|
|
|
/** |
|
* This method is called when the mouse is moved within the component. |
|
* It changes the cursor to indicate that resizing is possible. |
|
* |
|
* @param e The MouseEvent. |
|
*/ |
|
@Override |
|
public void mouseMoved(MouseEvent e) { |
|
if (e.getX() <= RESIZE_RANGE) { |
|
setCursor(westResizeCursor); |
|
} else { |
|
setCursor(Cursor.getDefaultCursor()); |
|
} |
|
} |
|
|
|
/** |
|
* This method is called when the mouse is pressed near the left edge. |
|
* If within the resize area, the mouse position is stored for dragging. |
|
* |
|
* @param e The MouseEvent. |
|
*/ |
|
@Override |
|
public void mousePressed(MouseEvent e) { |
|
if (e.getX() <= RESIZE_RANGE) { |
|
mouseDownCompCoords = e.getLocationOnScreen(); |
|
} |
|
} |
|
|
|
/** |
|
* This method is called when the mouse is dragged after being pressed |
|
* near the left edge. It adjusts the container width based on drag distance. |
|
* |
|
* @param e The MouseEvent. |
|
*/ |
|
@Override |
|
public void mouseDragged(MouseEvent e) { |
|
if (mouseDownCompCoords != null && getCursor().equals(westResizeCursor)) { |
|
Point currCoords = e.getLocationOnScreen(); |
|
int newWidth = containerWidth - (currCoords.x - mouseDownCompCoords.x); |
|
// Update container width within allowed range |
|
if (newWidth >= MIN_CONTAINER_WIDTH && newWidth <= MAX_CONTAINER_WIDTH) { |
|
containerWidth = newWidth; |
|
mouseDownCompCoords = currCoords; |
|
refreshContainer(); |
|
} |
|
} |
|
} |
|
|
|
/** |
|
* This method is called when the mouse button is released. |
|
* It clears the stored starting point for dragging. |
|
* |
|
* @param e The MouseEvent. |
|
*/ |
|
@Override |
|
public void mouseReleased(MouseEvent e) { |
|
mouseDownCompCoords = null; |
|
} |
|
} |
|
} |