2

考虑我有以下代码:

public LSUIEditingPanel(LSView view) {
    super();
    parent     = view;
    controller = view.getController();

    LayoutManager overlay = new OverlayLayout(this);

    setLayout(overlay);
    scribbleArea = new LSScribblePanel();
    scribbleArea.setOpaque(false);
    add(scribbleArea);
    viewArea = new LSCanvasViewport(view);
    add(viewArea);
    setAutoscrolls(true);
    drawListener = new SVGEditorDrawMouseAdaptor();

}

其中 scribbleArea 和 viewArea 都是自定义 JPanel。它们都是添加到主面板的子面板。

现在我想这样做,以便我可以将 MouseEvent 注册到父面板本身,这就是我可以对面板进行平移,因为父面板将在实例化后嵌入到 JScrollPane 中。

这是执行拖动的代码段:

public class LSPanMouseAdapter extends MouseAdapter {

/**
 * Panning pivot point
 */
private final Point panPoint = new Point();

/**
 * {@inheritDoc}<p>
 * Set pan starting point to be the point where the mouse currently located, and change the
 * current cursor to <code>HAND_CURSOR</code>.
 */
@Override
public void mousePressed(MouseEvent event) {
    JViewport  viewport  = (JViewport) event.getSource();
    JComponent component = (JComponent) viewport.getView();

    panPoint.setLocation(event.getPoint());
    component.setCursor(new Cursor(Cursor.HAND_CURSOR));
}

/**
 * {@inheritDoc}<p>
 * Reset cursor to <code>DEFAULT_CURSOR</code>.
 */
@Override
public void mouseReleased(MouseEvent event) {
    JViewport  viewport  = (JViewport) event.getSource();
    JComponent component = (JComponent) viewport.getView();

    component.setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
}

/**
 * {@inheritDoc}<p>
 * Get the current viewport of the canvas and move the viewable area respective to the
 * event cursor location.
 */
@Override
public void mouseDragged(MouseEvent event) {
    JViewport  viewport     = (JViewport) event.getSource();
    JComponent component    = (JComponent) viewport.getView();
    Point      currentPoint = event.getPoint();
    Point      viewPoint    = viewport.getViewPosition();

    viewPoint.translate(panPoint.x - currentPoint.x, panPoint.y - currentPoint.y);
    component.scrollRectToVisible(new Rectangle(viewPoint, viewport.getSize()));
    panPoint.setLocation(currentPoint);
}
}

我已尝试注册该事件,但父面板没有触发该事件,关于我应该如何执行此操作的任何建议?

4

1 回答 1

2

请参阅下面的示例,该示例显示了如何进行某种视口拖动。鼠标侦听器附加到视口视图并在拖动鼠标时修改视口位置。为了计算鼠标的正确“偏移”,鼠标位置在鼠标被拖动时被转换为视口坐标。

import java.awt.Component;
import java.awt.Cursor;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JScrollPane;
import javax.swing.JViewport;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class TestDragViewPortView {
    public static class MouseDragger extends MouseAdapter {
        private Point startPoint;
        private Component draggedObject;
        private JViewport viewport;

        @Override
        public void mousePressed(MouseEvent e) {
            draggedObject = (Component) e.getSource();
            viewport = (JViewport) SwingUtilities.getAncestorOfClass(JViewport.class, draggedObject);
            if (viewport != null) {
                startPoint = SwingUtilities.convertPoint(draggedObject, e.getPoint(), viewport);
                draggedObject.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
            }
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            if (viewport == null) {
                return;
            }
            Point location = SwingUtilities.convertPoint(draggedObject, e.getPoint(), viewport);
            Point newPosition = viewport.getViewPosition();
            newPosition.translate(startPoint.x - location.x, startPoint.y - location.y);
            newPosition.x = Math.min(newPosition.x, draggedObject.getWidth() - viewport.getExtentSize().width);
            newPosition.y = Math.min(newPosition.y, draggedObject.getHeight() - viewport.getExtentSize().height);
            newPosition.x = Math.max(newPosition.x, 0);
            newPosition.y = Math.max(newPosition.y, 0);
            viewport.setViewPosition(newPosition);
            startPoint = location;
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            draggedObject.setCursor(Cursor.getDefaultCursor());
            startPoint = null;
            draggedObject = null;
            viewport = null;
        }

        public void makeDraggable(Component component) {
            component.addMouseListener(this);
            component.addMouseMotionListener(this);
        }

    }

    private JFrame frame;

    protected void initUI() throws MalformedURLException {
        frame = new JFrame(TestDragViewPortView.class.getSimpleName());
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JLabel background = new JLabel(new ImageIcon(new URL("http://blogs.dirteam.com/photos/sanderberkouwer/images/2157/original.aspx")));
        JScrollPane scrollPane = new JScrollPane(background);
        new MouseDragger().makeDraggable(background);
        frame.add(scrollPane);
        frame.pack();
        frame.setSize(frame.getWidth() / 2, frame.getHeight() / 2);
        frame.setVisible(true);
    }

    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException,
            UnsupportedLookAndFeelException {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
        SwingUtilities.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    new TestDragViewPortView().initUI();
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
    }
}
于 2013-05-06T12:56:38.847 回答