From 47ec2f3b47170c0681a47336c54585d6d1793c85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E5=B2=B3?= <445798420@qq.com> Date: Tue, 24 Aug 2021 18:08:01 +0800 Subject: [PATCH] =?UTF-8?q?CHART-20373=20=20gradientBar=E7=BB=A7=E6=89=BFJ?= =?UTF-8?q?panel=E4=B9=8B=E5=90=8E=E9=87=8D=E7=BB=98=E6=9C=89=E9=97=AE?= =?UTF-8?q?=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../gradient/AbstractComponentPopBox.java | 243 ++++++++++++++++++ .../background/gradient/GradientBar.java | 3 +- 2 files changed, 244 insertions(+), 2 deletions(-) create mode 100644 designer-base/src/main/java/com/fr/design/style/background/gradient/AbstractComponentPopBox.java diff --git a/designer-base/src/main/java/com/fr/design/style/background/gradient/AbstractComponentPopBox.java b/designer-base/src/main/java/com/fr/design/style/background/gradient/AbstractComponentPopBox.java new file mode 100644 index 000000000..ef647f2bd --- /dev/null +++ b/designer-base/src/main/java/com/fr/design/style/background/gradient/AbstractComponentPopBox.java @@ -0,0 +1,243 @@ +package com.fr.design.style.background.gradient; + +import com.fr.design.layout.FRGUIPaneFactory; +import com.fr.design.style.background.BackgroundJComponent; +import com.fr.general.Background; + +import javax.swing.JComponent; +import javax.swing.JPanel; +import javax.swing.JWindow; +import javax.swing.SwingUtilities; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import java.util.ArrayList; +import java.util.List; +import java.awt.AWTEvent; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; +import java.awt.Toolkit; +import java.awt.Window; +import java.awt.event.AWTEventListener; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; + +/** + * @author Bjorn + * @version 10.0 + * Created by Bjorn on 2021-08-24 + */ +public abstract class AbstractComponentPopBox extends JComponent { + + protected BackgroundJComponent displayComponent; + + private JWindow selectPopupWindow; + private boolean isWindowEventInit = false; + private static int GAP = 2; + private static int GAP2 = 20; + + private List changeListenerList = new ArrayList(); + + MouseAdapter mouseListener = new MouseAdapter() { + public void mousePressed(MouseEvent evt) { + showPopupMenu(); + } + + + }; + + AWTEventListener awt = new AWTEventListener() { + public void eventDispatched(AWTEvent event) { + if (event instanceof MouseEvent) { + MouseEvent evt = (MouseEvent) event; + if (evt.getClickCount() > 0) { + mouseClick(evt); + } + } + } + }; + + protected void showPopupMenu() { + if (selectPopupWindow != null && selectPopupWindow.isVisible()) { + hidePopupMenu(); + return; + } + + if (!this.isEnabled()) { + return; + } + Toolkit.getDefaultToolkit().addAWTEventListener(awt, AWTEvent.MOUSE_EVENT_MASK); + + selectPopupWindow = this.getControlWindow(); + + Point convertPoint = new Point(0, 0); + + // e: 将点(0,0)从ColorSelectionPane的坐标系统转换到屏幕坐标. + SwingUtilities.convertPointToScreen(convertPoint, this); + int y = convertPoint.y + this.getSize().height; + int x = convertPoint.x; + int h = y + selectPopupWindow.getHeight(); + int width = x + selectPopupWindow.getWidth(); + Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); + if (h > screenSize.height) { + y = y - selectPopupWindow.getHeight() - GAP2;// 超过屏幕高度了 + } + + if (width > screenSize.width) { + x = screenSize.width - selectPopupWindow.getWidth(); + } + selectPopupWindow.setLocation(x, y); + + selectPopupWindow.setVisible(true); + + //wei : 为了点击别的地方下拉颜色窗口消失 + MouseAdapter parentMouseListener = new MouseAdapter() { + public void mousePressed(MouseEvent evt) { + mouseClick(evt); + } + }; + if (!this.isWindowEventInit && SwingUtilities.getAncestorOfClass(GradientBackgroundPane.class, this) != null) { + SwingUtilities.getAncestorOfClass(GradientBackgroundPane.class, this).addMouseListener(parentMouseListener); + this.isWindowEventInit = true; + } + } + + private void mouseClick(MouseEvent evt) { + Point point = new Point((int) (evt.getLocationOnScreen().getX()), (int) evt.getLocationOnScreen().getY()); + Dimension popBoxD = AbstractComponentPopBox.this.getSize(); + try { + Point popBoxP = AbstractComponentPopBox.this.getLocationOnScreen(); + Dimension popMenuD = this.getControlWindow().getSize(); + Point popMenuP = this.getControlWindow().getLocation(); + Rectangle popBoxRect = new Rectangle(popBoxP, popBoxD); + Rectangle popMenuRect = new Rectangle(popMenuP, popMenuD); + if (!popBoxRect.contains(point) && !popMenuRect.contains(point)) { + this.hidePopupMenu(); + } + } catch (Exception ignore) { + this.hidePopupMenu(); + } + } + + protected void hidePopupMenu() { + if (selectPopupWindow != null) { + selectPopupWindow.setVisible(false); + } + + selectPopupWindow = null; + Toolkit.getDefaultToolkit().removeAWTEventListener(awt); + } + + protected JWindow getControlWindow() { + //find parent. + if (this.selectPopupWindow == null) { + Window parentWindow = SwingUtilities.windowForComponent(this); + if (parentWindow != null) { + this.selectPopupWindow = new AbstractComponentPopBox.SelectControlWindow(parentWindow); + } + + selectPopupWindow.addMouseListener(new MouseAdapter() { + public void mouseExited(MouseEvent evt) { + int x = evt.getLocationOnScreen().x; + int y = evt.getLocationOnScreen().y; + + if (selectPopupWindow != null) { + double desValue = 2; + Rectangle rectangle = selectPopupWindow.getBounds(); + boolean b1 = x < rectangle.x + desValue || x >= rectangle.x + rectangle.width - desValue; + boolean b2 = y > rectangle.y + rectangle.height - desValue;//避免了鼠标下移刚进入selectPopupWindow的过程中弹出框隐藏,上移移出后由AbstractPopBox的mouseListener处理 + if (b1 || b2) { + hidePopupMenu(); + } + } + } + }); + } + + return selectPopupWindow; + } + + /** + * 添加事件 + * + * @param changeListener 事件 + */ + public void addSelectChangeListener(ChangeListener changeListener) { + this.changeListenerList.add(changeListener); + } + + /** + * 删除事件 + * + * @param changeListener 事件 + */ + public void removeSelectChangeListener(ChangeListener changeListener) { + this.changeListenerList.remove(changeListener); + } + + /** + * 响应事件 + */ + public void fireChangeListener() { + if (!changeListenerList.isEmpty()) { + ChangeEvent evt = new ChangeEvent(this); + for (int i = 0; i < changeListenerList.size(); i++) { + this.changeListenerList.get(i).stateChanged(evt); + } + } + } + + /** + * 待说明 + * + * @param background 背景 + */ + public void fireDisplayComponent(Background background) { + if (displayComponent != null) { + displayComponent.setSelfBackground(background); + } + fireChangeListener(); + this.repaint(); + } + + /** + * 初始化弹出框的面板 + * + * @param preWidth 宽度 + * @return 弹出面板 + */ + public abstract JPanel initWindowPane(double preWidth); + + private class SelectControlWindow extends JWindow { + private static final long serialVersionUID = -5776589767069105911L; + + public SelectControlWindow(Window paranet) { + super(paranet); + this.initComponents(); + } + + public void initComponents() { + JPanel defaultPane = FRGUIPaneFactory.createBorderLayout_S_Pane(); + this.setContentPane(defaultPane); + +// defaultPane.setBorder(UIManager.getBorder("PopupMenu.border")); + + if (displayComponent != null) { + defaultPane.add(initWindowPane(displayComponent.getPreferredSize().getWidth())); + } else { + defaultPane.add(initWindowPane(20)); + } + this.pack(); + } + + @Override + public void setVisible(boolean b) { + super.setVisible(b); + AbstractComponentPopBox.this.repaint(); + } + } + + protected boolean isPopupVisible() { + return selectPopupWindow == null ? false : selectPopupWindow.isVisible(); + } +} diff --git a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java index 269a68be2..e6c2e4dbd 100644 --- a/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java +++ b/designer-base/src/main/java/com/fr/design/style/background/gradient/GradientBar.java @@ -5,7 +5,6 @@ import com.fr.design.event.UIObserver; import com.fr.design.event.UIObserverListener; import com.fr.design.gui.itextfield.UINumberField; import com.fr.design.mainframe.DesignerContext; -import com.fr.design.style.AbstractPopBox; import com.fr.design.style.color.ColorCell; import com.fr.design.style.color.ColorSelectDetailPane; import com.fr.design.style.color.ColorSelectDialog; @@ -34,7 +33,7 @@ import java.awt.geom.Point2D; /** * TODO:面板缩放的功能没有考虑(就是尾值过大,导致超过界面显示的情况),原来的那个实现完全是个BUG。要缩放的情况也比较少,就干脆以后弄吧 */ -public class GradientBar extends AbstractPopBox implements UIObserver, ColorSelectable { +public class GradientBar extends AbstractComponentPopBox implements UIObserver, ColorSelectable { /** *