forked from fanruan/design
kuangshuai
3 years ago
9 changed files with 517 additions and 40 deletions
@ -0,0 +1,31 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import java.awt.event.MouseWheelEvent; |
||||||
|
import java.awt.event.MouseWheelListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Starryi |
||||||
|
* @version 1.0 |
||||||
|
* Created by Starryi on 2021/9/23 |
||||||
|
*/ |
||||||
|
public class DesignerScaleMouseWheelHandler implements MouseWheelListener { |
||||||
|
private final ScalePane scalePane; |
||||||
|
private final int step; |
||||||
|
|
||||||
|
public DesignerScaleMouseWheelHandler(ScalePane scalePane, int step) { |
||||||
|
this.scalePane = scalePane; |
||||||
|
this.step = step; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) { |
||||||
|
int dir = e.getWheelRotation(); |
||||||
|
JFormSliderPane slidePane = this.scalePane.getSlidePane(); |
||||||
|
int old_resolution = slidePane.getShowValue(); |
||||||
|
slidePane.setShowValue(old_resolution - (dir * step)); |
||||||
|
} |
||||||
|
|
||||||
|
public interface ScalePane { |
||||||
|
JFormSliderPane getSlidePane(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,279 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import javax.swing.JScrollBar; |
||||||
|
import javax.swing.JViewport; |
||||||
|
import javax.swing.Scrollable; |
||||||
|
import javax.swing.SwingConstants; |
||||||
|
import java.awt.Component; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.event.MouseWheelEvent; |
||||||
|
import java.awt.event.MouseWheelListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* 实现设计器面板的触摸板滚动移动交互 https://work.fineres.com/browse/REPORT-55989
|
||||||
|
* |
||||||
|
* mouseWheelMoved 的具体实现来自 |
||||||
|
* @link {javax.swing.plaf.basic.BasicScrollPaneUI.Handler#mouseWheelMoved} |
||||||
|
* scrollByUnits 的具体实现来自 |
||||||
|
* @link {javax.swing.plaf.basic.BasicScrollPaneUI#scrollByUnits} |
||||||
|
* scrollByBlock 的具体实现来自 |
||||||
|
* @link {javax.swing.plaf.basic.BasicScrollPaneUI#scrollByBlock} |
||||||
|
*/ |
||||||
|
public class DesignerTranslateMouseWheelHandler implements MouseWheelListener { |
||||||
|
private final ScrollPane scrollpane; |
||||||
|
|
||||||
|
public DesignerTranslateMouseWheelHandler(ScrollPane scrollpane) { |
||||||
|
this.scrollpane = scrollpane; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) { |
||||||
|
if (scrollpane.isWheelScrollingEnabled() && |
||||||
|
e.getWheelRotation() != 0) { |
||||||
|
JScrollBar toScroll = scrollpane.getVerticalScrollBar(); |
||||||
|
int direction = e.getWheelRotation() < 0 ? -1 : 1; |
||||||
|
int orientation = SwingConstants.VERTICAL; |
||||||
|
|
||||||
|
// find which scrollbar to scroll, or return if none
|
||||||
|
if (toScroll == null || !toScroll.isVisible() |
||||||
|
|| e.isShiftDown()) { |
||||||
|
toScroll = scrollpane.getHorizontalScrollBar(); |
||||||
|
if (toScroll == null || !toScroll.isVisible()) { |
||||||
|
return; |
||||||
|
} |
||||||
|
orientation = SwingConstants.HORIZONTAL; |
||||||
|
} |
||||||
|
|
||||||
|
e.consume(); |
||||||
|
|
||||||
|
if (e.getScrollType() == MouseWheelEvent.WHEEL_UNIT_SCROLL) { |
||||||
|
JViewport vp = scrollpane.getViewport(); |
||||||
|
if (vp == null) { return; } |
||||||
|
Component comp = vp.getView(); |
||||||
|
int units = Math.abs(e.getUnitsToScroll()); |
||||||
|
|
||||||
|
// When the scrolling speed is set to maximum, it's possible
|
||||||
|
// for a single wheel click to scroll by more units than
|
||||||
|
// will fit in the visible area. This makes it
|
||||||
|
// hard/impossible to get to certain parts of the scrolling
|
||||||
|
// Component with the wheel. To make for more accurate
|
||||||
|
// low-speed scrolling, we limit scrolling to the block
|
||||||
|
// increment if the wheel was only rotated one click.
|
||||||
|
boolean limitScroll = Math.abs(e.getWheelRotation()) == 1; |
||||||
|
|
||||||
|
// Check if we should use the visibleRect trick
|
||||||
|
Object fastWheelScroll = toScroll.getClientProperty( |
||||||
|
"JScrollBar.fastWheelScrolling"); |
||||||
|
if (Boolean.TRUE == fastWheelScroll && |
||||||
|
comp instanceof Scrollable) { |
||||||
|
// 5078454: Under maximum acceleration, we may scroll
|
||||||
|
// by many 100s of units in ~1 second.
|
||||||
|
//
|
||||||
|
// BasicScrollBarUI.scrollByUnits() can bog down the EDT
|
||||||
|
// with repaints in this situation. However, the
|
||||||
|
// Scrollable interface allows us to pass in an
|
||||||
|
// arbitrary visibleRect. This allows us to accurately
|
||||||
|
// calculate the total scroll amount, and then update
|
||||||
|
// the GUI once. This technique provides much faster
|
||||||
|
// accelerated wheel scrolling.
|
||||||
|
Scrollable scrollComp = (Scrollable) comp; |
||||||
|
Rectangle viewRect = vp.getViewRect(); |
||||||
|
int startingX = viewRect.x; |
||||||
|
boolean leftToRight = |
||||||
|
comp.getComponentOrientation().isLeftToRight(); |
||||||
|
int scrollMin = toScroll.getMinimum(); |
||||||
|
int scrollMax = toScroll.getMaximum() - |
||||||
|
toScroll.getModel().getExtent(); |
||||||
|
|
||||||
|
if (limitScroll) { |
||||||
|
int blockIncr = |
||||||
|
scrollComp.getScrollableBlockIncrement(viewRect, |
||||||
|
orientation, |
||||||
|
direction); |
||||||
|
if (direction < 0) { |
||||||
|
scrollMin = Math.max(scrollMin, |
||||||
|
toScroll.getValue() - blockIncr); |
||||||
|
} |
||||||
|
else { |
||||||
|
scrollMax = Math.min(scrollMax, |
||||||
|
toScroll.getValue() + blockIncr); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (int i = 0; i < units; i++) { |
||||||
|
int unitIncr = |
||||||
|
scrollComp.getScrollableUnitIncrement(viewRect, |
||||||
|
orientation, direction); |
||||||
|
// Modify the visible rect for the next unit, and
|
||||||
|
// check to see if we're at the end already.
|
||||||
|
if (orientation == SwingConstants.VERTICAL) { |
||||||
|
if (direction < 0) { |
||||||
|
viewRect.y -= unitIncr; |
||||||
|
if (viewRect.y <= scrollMin) { |
||||||
|
viewRect.y = scrollMin; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
else { // (direction > 0
|
||||||
|
viewRect.y += unitIncr; |
||||||
|
if (viewRect.y >= scrollMax) { |
||||||
|
viewRect.y = scrollMax; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
// Scroll left
|
||||||
|
if ((leftToRight && direction < 0) || |
||||||
|
(!leftToRight && direction > 0)) { |
||||||
|
viewRect.x -= unitIncr; |
||||||
|
if (leftToRight) { |
||||||
|
if (viewRect.x < scrollMin) { |
||||||
|
viewRect.x = scrollMin; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// Scroll right
|
||||||
|
else if ((leftToRight && direction > 0) || |
||||||
|
(!leftToRight && direction < 0)) { |
||||||
|
viewRect.x += unitIncr; |
||||||
|
if (leftToRight) { |
||||||
|
if (viewRect.x > scrollMax) { |
||||||
|
viewRect.x = scrollMax; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
assert false : "Non-sensical ComponentOrientation / scroll direction"; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
// Set the final view position on the ScrollBar
|
||||||
|
if (orientation == SwingConstants.VERTICAL) { |
||||||
|
toScroll.setValue(viewRect.y); |
||||||
|
} |
||||||
|
else { |
||||||
|
if (leftToRight) { |
||||||
|
toScroll.setValue(viewRect.x); |
||||||
|
} |
||||||
|
else { |
||||||
|
// rightToLeft scrollbars are oriented with
|
||||||
|
// minValue on the right and maxValue on the
|
||||||
|
// left.
|
||||||
|
int newPos = toScroll.getValue() - |
||||||
|
(viewRect.x - startingX); |
||||||
|
if (newPos < scrollMin) { |
||||||
|
newPos = scrollMin; |
||||||
|
} |
||||||
|
else if (newPos > scrollMax) { |
||||||
|
newPos = scrollMax; |
||||||
|
} |
||||||
|
toScroll.setValue(newPos); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
else { |
||||||
|
// Viewport's view is not a Scrollable, or fast wheel
|
||||||
|
// scrolling is not enabled.
|
||||||
|
scrollByUnits(toScroll, direction, |
||||||
|
units, limitScroll); |
||||||
|
} |
||||||
|
} |
||||||
|
else if (e.getScrollType() == |
||||||
|
MouseWheelEvent.WHEEL_BLOCK_SCROLL) { |
||||||
|
scrollByBlock(toScroll, direction); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* Method for scrolling by a unit increment. |
||||||
|
* Added for mouse wheel scrolling support, RFE 4202656. |
||||||
|
* |
||||||
|
* If limitByBlock is set to true, the scrollbar will scroll at least 1 |
||||||
|
* unit increment, but will not scroll farther than the block increment. |
||||||
|
* See BasicScrollPaneUI.Handler.mouseWheelMoved(). |
||||||
|
*/ |
||||||
|
static void scrollByUnits(JScrollBar scrollbar, int direction, |
||||||
|
int units, boolean limitToBlock) { |
||||||
|
// This method is called from BasicScrollPaneUI to implement wheel
|
||||||
|
// scrolling, as well as from scrollByUnit().
|
||||||
|
int delta; |
||||||
|
int limit = -1; |
||||||
|
|
||||||
|
if (limitToBlock) { |
||||||
|
if (direction < 0) { |
||||||
|
limit = scrollbar.getValue() - |
||||||
|
scrollbar.getBlockIncrement(direction); |
||||||
|
} |
||||||
|
else { |
||||||
|
limit = scrollbar.getValue() + |
||||||
|
scrollbar.getBlockIncrement(direction); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
for (int i=0; i<units; i++) { |
||||||
|
if (direction > 0) { |
||||||
|
delta = scrollbar.getUnitIncrement(direction); |
||||||
|
} |
||||||
|
else { |
||||||
|
delta = -scrollbar.getUnitIncrement(direction); |
||||||
|
} |
||||||
|
|
||||||
|
int oldValue = scrollbar.getValue(); |
||||||
|
int newValue = oldValue + delta; |
||||||
|
|
||||||
|
// Check for overflow.
|
||||||
|
if (delta > 0 && newValue < oldValue) { |
||||||
|
newValue = scrollbar.getMaximum(); |
||||||
|
} |
||||||
|
else if (delta < 0 && newValue > oldValue) { |
||||||
|
newValue = scrollbar.getMinimum(); |
||||||
|
} |
||||||
|
if (oldValue == newValue) { |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
if (limitToBlock && i > 0) { |
||||||
|
assert limit != -1; |
||||||
|
if ((direction < 0 && newValue < limit) || |
||||||
|
(direction > 0 && newValue > limit)) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
scrollbar.setValue(newValue); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
/* |
||||||
|
* Method for scrolling by a block increment. |
||||||
|
* Added for mouse wheel scrolling support, RFE 4202656. |
||||||
|
*/ |
||||||
|
static void scrollByBlock(JScrollBar scrollbar, int direction) { |
||||||
|
// This method is called from BasicScrollPaneUI to implement wheel
|
||||||
|
// scrolling, and also from scrollByBlock().
|
||||||
|
int oldValue = scrollbar.getValue(); |
||||||
|
int blockIncrement = scrollbar.getBlockIncrement(direction); |
||||||
|
int delta = blockIncrement * ((direction > 0) ? +1 : -1); |
||||||
|
int newValue = oldValue + delta; |
||||||
|
|
||||||
|
// Check for overflow.
|
||||||
|
if (delta > 0 && newValue < oldValue) { |
||||||
|
newValue = scrollbar.getMaximum(); |
||||||
|
} |
||||||
|
else if (delta < 0 && newValue > oldValue) { |
||||||
|
newValue = scrollbar.getMinimum(); |
||||||
|
} |
||||||
|
|
||||||
|
scrollbar.setValue(newValue); |
||||||
|
} |
||||||
|
|
||||||
|
public interface ScrollPane { |
||||||
|
boolean isWheelScrollingEnabled(); |
||||||
|
JScrollBar getVerticalScrollBar(); |
||||||
|
JScrollBar getHorizontalScrollBar(); |
||||||
|
JViewport getViewport(); |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.common.inputevent.InputEventBaseOnOS; |
||||||
|
|
||||||
|
import javax.swing.JScrollBar; |
||||||
|
import javax.swing.JViewport; |
||||||
|
import java.awt.event.MouseWheelEvent; |
||||||
|
import java.awt.event.MouseWheelListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Starryi |
||||||
|
* @version 1.0 |
||||||
|
* Created by Starryi on 2021/9/24 |
||||||
|
*/ |
||||||
|
public class FormAreaMouseWheelHandler implements MouseWheelListener { |
||||||
|
private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; |
||||||
|
private final DesignerScaleMouseWheelHandler scaleMouseWheelHandler; |
||||||
|
|
||||||
|
public FormAreaMouseWheelHandler(FormArea formArea) { |
||||||
|
translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new FormAreaScrollPaneAdapter(formArea)); |
||||||
|
scaleMouseWheelHandler = new DesignerScaleMouseWheelHandler(new FormAreaScalePaneAdapter(formArea), FormArea.SHOWVALMIN); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) { |
||||||
|
if (InputEventBaseOnOS.isControlDown(e)) { |
||||||
|
scaleMouseWheelHandler.mouseWheelMoved(e); |
||||||
|
} else { |
||||||
|
translateMouseWheelHandler.mouseWheelMoved(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class FormAreaScalePaneAdapter implements DesignerScaleMouseWheelHandler.ScalePane { |
||||||
|
private final FormArea formArea; |
||||||
|
|
||||||
|
public FormAreaScalePaneAdapter(FormArea formArea) { |
||||||
|
this.formArea = formArea; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JFormSliderPane getSlidePane() { |
||||||
|
return formArea.getSlidePane(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class FormAreaScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { |
||||||
|
private final FormArea formArea; |
||||||
|
private final JViewport viewport; |
||||||
|
|
||||||
|
public FormAreaScrollPaneAdapter(FormArea formArea) { |
||||||
|
this.formArea = formArea; |
||||||
|
this.viewport = new JViewport(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isWheelScrollingEnabled() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JScrollBar getVerticalScrollBar() { |
||||||
|
return formArea.getVerticalScrollBar(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JScrollBar getHorizontalScrollBar() { |
||||||
|
return formArea.getHorizontalScrollBar(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JViewport getViewport() { |
||||||
|
return this.viewport; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
@ -0,0 +1,75 @@ |
|||||||
|
package com.fr.design.mainframe; |
||||||
|
|
||||||
|
import com.fr.common.inputevent.InputEventBaseOnOS; |
||||||
|
|
||||||
|
import javax.swing.JScrollBar; |
||||||
|
import javax.swing.JViewport; |
||||||
|
import java.awt.event.MouseWheelEvent; |
||||||
|
import java.awt.event.MouseWheelListener; |
||||||
|
|
||||||
|
/** |
||||||
|
* @author Starryi |
||||||
|
* @version 1.0 |
||||||
|
* Created by Starryi on 2021/9/24 |
||||||
|
*/ |
||||||
|
public class ReportComponentCompositeMouseWheelHandler implements MouseWheelListener { |
||||||
|
private final DesignerTranslateMouseWheelHandler translateMouseWheelHandler; |
||||||
|
private final DesignerScaleMouseWheelHandler scaleMouseWheelHandler; |
||||||
|
|
||||||
|
public ReportComponentCompositeMouseWheelHandler(ReportComponentComposite componentComposite) { |
||||||
|
translateMouseWheelHandler = new DesignerTranslateMouseWheelHandler(new ScrollPaneAdapter(componentComposite)); |
||||||
|
scaleMouseWheelHandler = new DesignerScaleMouseWheelHandler(new ScalePaneAdapter(componentComposite), ReportComponentComposite.DIR); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseWheelMoved(MouseWheelEvent e) { |
||||||
|
if (InputEventBaseOnOS.isControlDown(e)) { |
||||||
|
scaleMouseWheelHandler.mouseWheelMoved(e); |
||||||
|
} else { |
||||||
|
translateMouseWheelHandler.mouseWheelMoved(e); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class ScrollPaneAdapter implements DesignerTranslateMouseWheelHandler.ScrollPane { |
||||||
|
private final ReportComponentComposite componentComposite; |
||||||
|
private JViewport viewport; |
||||||
|
|
||||||
|
public ScrollPaneAdapter(ReportComponentComposite componentComposite) { |
||||||
|
this.componentComposite = componentComposite; |
||||||
|
this.viewport = new JViewport(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public boolean isWheelScrollingEnabled() { |
||||||
|
return true; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JScrollBar getVerticalScrollBar() { |
||||||
|
return componentComposite.getEditingReportComponent().getVerticalScrollBar(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JScrollBar getHorizontalScrollBar() { |
||||||
|
return componentComposite.getEditingReportComponent().getHorizontalScrollBar(); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JViewport getViewport() { |
||||||
|
return viewport; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
private static class ScalePaneAdapter implements DesignerScaleMouseWheelHandler.ScalePane { |
||||||
|
private final ReportComponentComposite componentComposite; |
||||||
|
|
||||||
|
public ScalePaneAdapter(ReportComponentComposite componentComposite) { |
||||||
|
this.componentComposite = componentComposite; |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public JFormSliderPane getSlidePane() { |
||||||
|
return componentComposite.getjSliderContainer(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue