Browse Source

REPORT-55989 mac的触控板左右滑动时,设计器的设计主体面板是上下滚动的

【问题原因】
1. 移植JScrollPane的触摸板滚轮交互逻辑到表单布局和报表网格面板中
2. 复用表单和报表的滚轮处理逻辑, 表单和报表各自实现所需的接口即可

【改动思路】
同上
research/11.0
Starryi 3 years ago
parent
commit
a4f08dcb02
  1. 31
      designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java
  2. 279
      designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java
  3. 31
      designer-form/src/main/java/com/fr/design/mainframe/FormArea.java
  4. 75
      designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java
  5. 17
      designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java
  6. 75
      designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java

31
designer-form/src/main/java/com/fr/design/mainframe/DesignerScaleMouseWheelHandler.java

@ -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();
}
}

279
designer-form/src/main/java/com/fr/design/mainframe/DesignerTranslateMouseWheelHandler.java

@ -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();
}
}

31
designer-form/src/main/java/com/fr/design/mainframe/FormArea.java

@ -74,8 +74,8 @@ public class FormArea extends JComponent implements ScrollRulerComponent {
private static final String SCALE_MINUS_COMMAND = "scale_minus";
public static final double DEFAULT_SLIDER = 100.0;
private static final int ROTATIONS = 50;
private static final int SHOWVALMAX = 400;
private static final int SHOWVALMIN = 10;
public static final int SHOWVALMAX = 400;
public static final int SHOWVALMIN = 10;
private static final int RESIZE_PANE_GAP = 8;
private static final int MOBILE_ONLY_WIDTH = 375;
private static final int MOBILE_ONLY_HEIGHT = 560;
@ -132,10 +132,24 @@ public class FormArea extends JComponent implements ScrollRulerComponent {
addFormRuler();
}
this.setFocusTraversalKeysEnabled(false);
this.designer.addMouseWheelListener(showValSpinnerMouseWheelListener);
this.designer.addMouseWheelListener(new FormAreaMouseWheelHandler(this));
registerShortCutKey();
}
public FormScrollBar getVerticalScrollBar() {
return verScrollBar;
}
public FormScrollBar getHorizontalScrollBar() {
return horScrollBar;
}
public JFormSliderPane getSlidePane() {
return slidePane;
}
/**
* 注册缩放快捷键
* mac: command + command -
@ -169,17 +183,6 @@ public class FormArea extends JComponent implements ScrollRulerComponent {
widthPane.setEnabled(!formMobileAttr.isMobileOnly());
}
MouseWheelListener showValSpinnerMouseWheelListener = new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (InputEventBaseOnOS.isControlDown(e)) {
int dir = e.getWheelRotation();
int old_resolution = slidePane.getShowValue();
slidePane.setShowValue(old_resolution - (dir * SHOWVALMIN));
}
}
};
private UIButton createFixLayoutSwitchButton(){
UIButton button = new UIButton(com.fr.design.i18n.Toolkit.i18nText("Fine-Design_Form_Layout_No_Fix_Layout"));
button.setIcon(IOUtils.readIcon("/com/fr/base/images/share/filter_combo.png"));

75
designer-form/src/main/java/com/fr/design/mainframe/FormAreaMouseWheelHandler.java

@ -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;
}
}
}

17
designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentComposite.java

@ -34,7 +34,7 @@ public class ReportComponentComposite extends JComponent implements RemoveListen
private static final int MAX = 400;
private static final int HUND = 100;
private static final int MIN = 10;
private static final int DIR = 10;
public static final int DIR = 10;
private JWorkBook parent;
private UIModeControlContainer parentContainer = null;
@ -66,17 +66,6 @@ public class ReportComponentComposite extends JComponent implements RemoveListen
jSliderContainer.addValueChangeListener(showValSpinnerChangeListener);
}
MouseWheelListener showValSpinnerMouseWheelListener = new MouseWheelListener() {
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (InputEventBaseOnOS.isControlDown(e)) {
int dir = e.getWheelRotation();
int old_resolution = jSliderContainer.getShowValue();
jSliderContainer.setShowValue(old_resolution - (dir * DIR));
}
}
};
ChangeListener showValSpinnerChangeListener = new ChangeListener() {
@Override
public void stateChanged(ChangeEvent e) {
@ -130,12 +119,12 @@ public class ReportComponentComposite extends JComponent implements RemoveListen
}
if (centerCardPane.editingComponet.elementCasePane == null) {
centerCardPane.getPolyDezi().polyArea.addMouseWheelListener(showValSpinnerMouseWheelListener);
centerCardPane.getPolyDezi().polyArea.addMouseWheelListener(new ReportComponentCompositeMouseWheelHandler(this));
return;
}
Grid grid = centerCardPane.editingComponet.elementCasePane.getGrid();
this.centerCardPane.editingComponet.elementCasePane.getGrid().addMouseWheelListener(showValSpinnerMouseWheelListener);
this.centerCardPane.editingComponet.elementCasePane.getGrid().addMouseWheelListener(new ReportComponentCompositeMouseWheelHandler(this));
if (!grid.hasFocus() && grid.isRequestFocusEnabled()) {
grid.requestFocus();

75
designer-realize/src/main/java/com/fr/design/mainframe/ReportComponentCompositeMouseWheelHandler.java

@ -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…
Cancel
Save