Сопоставление координат событий мыши

Я реализовал компонент JLayer<JPanel>, который рисует увеличенное Graphics самого себя, поэтому все его нисходящие компоненты также будут увеличены. Этот JLayer применяется как ContentPane к компоненту JFrame.

Основная проблема заключается в том, что все масштабирование применяется, действительно, только к графике, а фактический размер и положение компонентов остаются прежними. Это означает, что все события мыши происходят в неправильном положении относительно того, что видит пользователь.

Я настроил его, определив GlassPane JComponent в верхней части кадра, у которого есть собственный MouseInputAdapter, который перенаправляет MouseEvent на базовые компоненты, используя SwingUtilities.getDeepestComponentAt(). Это достигается путем создания нового MouseEvent с сопоставлением координат мыши в зависимости от значения масштабирования. (получено путем изменения руководства по Как использовать RootPanes)

Этот метод явно не удовлетворяет требованиям, потому что многие события просто не могут быть запущены (например, события MOUSE_ENTERED запускаются всеми нисходящими компонентами). С другой стороны, использование переопределения LayerUI.paint() подразумевает, что у меня должно быть что-то, что переназначает все координаты мыши.

  1. Есть ли способ сопоставить координаты мыши, не нарушая внутреннюю обработку MouseEvent?

    or

  2. Есть ли другой способ увеличить растровое изображение компонентов, изменив при этом реальное положение и размер? Я как бы пробовал это, но вызов setSize() внутреннего компонента, кажется, каким-то образом вызывает LayerUi.paint() во второй раз, поэтому все, что я получаю, - это более крупная графика, отсоединенная от фактической позиции виджета.


person Schizoping    schedule 28.03.2017    source источник
comment
У старого JXLayer был отличный пример библиотеки, PBar которого больше нет в сети :( - к счастью, у меня есть копия, ссылка здесь или, если вы предпочитаете, не плавайте в беспорядке моего ответа;) - ссылка здесь. Это может дать вам некоторое представление о том, как это делалось до того, как JLayer вступил во владение   -  person MadProgrammer    schedule 29.03.2017
comment
Благодарю вас! Это именно то, что я искал! На самом деле я нашел ваш первоначальный ответ незадолго до прочтения этого комментария XD... В любом случае, это будет очень полезно... прямо сейчас я изучаю код PBar, чтобы посмотреть, смогу ли я реализовать пример масштабирования, который вы опубликовали с JLayer и LayerUI в java 7... я опубликую ответ здесь, как только закончу   -  person Schizoping    schedule 29.03.2017
comment
Это было бы ОЧЕНЬ круто!   -  person MadProgrammer    schedule 29.03.2017


Ответы (1)


Это то, что я сделал до сих пор благодаря расширениям MadProgrammer и PBar, работающим с JLayer в java 8.

TransformUI включает в себя org.pbjar.jxlayer.plaf.ext.MouseEventUI и org.pbjar.jxlayer.plaf.ext.TransformUI PBar:

package jzoom.transform;

import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.Container;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import java.util.HashSet;
import java.util.Set;

import javax.swing.JComponent;
import javax.swing.JLayer;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.plaf.LayerUI;

/**
 * 
 * This UI apply an {@link AffineTransform} to all the visible objects, and apply the inversion
 *  of the same transform to all the mouse event's coordinates
 * 
 * @author Andrea.Maracci based on the pbjar JXLayer extension
 *
 */
public class TransformUI extends LayerUI<JComponent> {
    private static final long serialVersionUID = 1L;

    private Component lastEnteredTarget, lastPressedTarget;

    private final Set<JComponent> originalDoubleBuffered = new HashSet<JComponent>();
    private AffineTransform transform = new AffineTransform();
    private JLayer<JComponent> installedLayer;
    private boolean dispatchingMode = false;

    /**
     * Process the mouse events and map the mouse coordinates inverting the internal affine transformation.
     * 
     * @param
     * event the event to be dispatched
     * layer the layer this LayerUI is set to
     * 
     */
    @Override
    public void eventDispatched(AWTEvent event, final JLayer<? extends JComponent> layer) {
        if (event instanceof MouseEvent) {
            MouseEvent mouseEvent = (MouseEvent) event;
            /*
             * The if discriminate between generated and original event.
             * Removing it cause a stack overflow caused by the event being redispatched to this class.
             */
            if (!dispatchingMode) {
                // Process an original mouse event
                dispatchingMode = true;
                try {
                    redispatchMouseEvent(mouseEvent, layer);
                } finally {
                    dispatchingMode = false;
                }
            } else {
                /*
                 * Process generated mouse events
                 * Added a check, because on mouse entered or exited, the cursor
                 * may be set to specific dragging cursors.
                 */
                if (MouseEvent.MOUSE_ENTERED == mouseEvent.getID() || MouseEvent.MOUSE_EXITED == mouseEvent.getID()) {
                    layer.getGlassPane().setCursor(null);
                } else {
                    Component component = mouseEvent.getComponent();
                    layer.getGlassPane().setCursor(component.getCursor());
                }
            }
        } else {
            super.eventDispatched(event, layer);
        }
        layer.repaint();
    }

    /**
     * Set the affine transformation applied to the graphics
     * @param transform the transformation
     */
    public void setTransform(AffineTransform transform) {
        if (transform != null) {
            this.transform = transform;
        }
    }

    /**
     * Return the affine transformation applied to the graphics
     * @return the transformation
     */
    public AffineTransform getTransform() {
        return transform;
    }

    /**
     * Paint the specified component {@code c} applying the transformation on it's graphic
     * 
     * @param
     * g - the Graphics context in which to paint
     * c - the component being painted
     */
    @Override
    public void paint(Graphics g, JComponent c) {
        if (g instanceof Graphics2D) {
            Graphics2D g2 = (Graphics2D) g.create();
            JLayer<? extends JComponent> l = (JLayer<? extends JComponent>) c;
            g2.transform(transform);
            paintLayer(g2, l);
            g2.dispose();
        }
    }

    /**
     * Paint the view decorated by the JLayer {@code layer} and the JLayer itself
     * 
     * @param g2
     * @param layer the layer this LayerUI is set to
     */
    private final void paintLayer(Graphics2D g2, JLayer<? extends JComponent> layer) {
        JComponent view = layer.getView();
        if (view != null) {
            if (view.getX() < 0 || view.getY() < 0) {
                setToNoDoubleBuffering(view);
                g2.translate(view.getX(), view.getY());
                view.paint(g2);
                for (JComponent jComp : originalDoubleBuffered) {
                    jComp.setDoubleBuffered(true);
                }
                originalDoubleBuffered.clear();
                return;
            }
        }
        layer.paint(g2);
    }

    /**
     * Disable the double buffering for the {@code component} and for all of it's children
     * 
     * @param component
     */
    private void setToNoDoubleBuffering(Component component) {
        if (component instanceof JComponent) {
            JComponent jComp = (JComponent) component;
            if (jComp.isDoubleBuffered()) {
                originalDoubleBuffered.add(jComp);
                jComp.setDoubleBuffered(false);
            }
        }
        if (component instanceof Container) {
            Container container = (Container) component;
            for (int index = 0; index < container.getComponentCount(); index++) {
                setToNoDoubleBuffering(container.getComponent(index));
            }
        }
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void uninstallUI(JComponent component) {
        if (!(component instanceof JLayer<?>)) {
            throw new IllegalArgumentException(
                    this.getClass().getName() + " invalid class, must be a JLayer component");
        }
        JLayer<JComponent> jlayer = (JLayer<JComponent>) component;
        jlayer.setLayerEventMask(0);
        super.uninstallUI(component);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void installUI(JComponent component) throws IllegalStateException {
        super.installUI(component);
        if (installedLayer != null) {
            throw new IllegalStateException(this.getClass().getName() + " cannot be shared between multiple layers");
        }
        if (!(component instanceof JLayer<?>)) {
            throw new IllegalArgumentException(
                    this.getClass().getName() + " invalid class, must be a JLayer component");
        }
        // component.getClass().getDeclaringClass();
        installedLayer = (JLayer<JComponent>) component;
        installedLayer.setLayerEventMask(AWTEvent.MOUSE_EVENT_MASK | AWTEvent.MOUSE_MOTION_EVENT_MASK
                | AWTEvent.MOUSE_WHEEL_EVENT_MASK | AWTEvent.KEY_EVENT_MASK | AWTEvent.FOCUS_EVENT_MASK);
    }

    /**
     * Process the mouse events and map the mouse coordinates inverting the internal affine transformation.
     * It consume the original event, calculates the mapped mouse coordinates and find the real target of the mouse event.
     * It than create a new event with the correct informations in it and redispatch it to the target event
     * 
     * @param originalEvent the event to be dispatched
     * @param layer the layer this LayerUI is set to
     */
    private void redispatchMouseEvent(MouseEvent originalEvent, JLayer<? extends JComponent> layer) {
        if (layer.getView() != null) {
            if (originalEvent.getComponent() != layer.getGlassPane()) {
                originalEvent.consume();
            }
            MouseEvent newEvent = null;

            Point realPoint = calculateTargetPoint(layer, originalEvent);
            Component realTarget = getTarget(layer, realPoint);

            // Component realTarget =
            // SwingUtilities.getDeepestComponentAt(layer.getView(),
            // realPoint.x, realPoint.y);

            if (realTarget != null) {
                //System.out.println(realTarget.getClass().getName());
                realTarget = getListeningComponent(originalEvent, realTarget);
            }

            switch (originalEvent.getID()) {
            case MouseEvent.MOUSE_PRESSED:
                newEvent = transformMouseEvent(layer, originalEvent, realTarget, realPoint);
                if (newEvent != null) {
                    lastPressedTarget = newEvent.getComponent();
                }
                break;
            case MouseEvent.MOUSE_RELEASED:
                newEvent = transformMouseEvent(layer, originalEvent, lastPressedTarget, realPoint);
                lastPressedTarget = null;
                break;
            case MouseEvent.MOUSE_CLICKED:
                newEvent = transformMouseEvent(layer, originalEvent, realTarget, realPoint);
                lastPressedTarget = null;
                break;
            case MouseEvent.MOUSE_MOVED:
                newEvent = transformMouseEvent(layer, originalEvent, realTarget, realPoint);
                generateEnterExitEvents(layer, originalEvent, realTarget, realPoint);
                break;
            case MouseEvent.MOUSE_ENTERED:
                generateEnterExitEvents(layer, originalEvent, realTarget, realPoint);
                break;
            case MouseEvent.MOUSE_EXITED:
                generateEnterExitEvents(layer, originalEvent, realTarget, realPoint);
                break;
            case MouseEvent.MOUSE_DRAGGED:
                newEvent = transformMouseEvent(layer, originalEvent, lastPressedTarget, realPoint);
                generateEnterExitEvents(layer, originalEvent, realTarget, realPoint);
                break;
            case (MouseEvent.MOUSE_WHEEL):
                // redispatchMouseWheelEvent((MouseWheelEvent) originalEvent,
                // realTarget, realPoint);
                newEvent = transformMouseWheelEvent(layer, (MouseWheelEvent) originalEvent, realTarget, realPoint);
                break;/**/
            }
            dispatchMouseEvent(newEvent);
        }
    }

    /**
     * Apply the inverse transformation to {@code point}
     * 
     * @param layer the layer this LayerUI is set to
     * @param point the starting point
     * @return the transformed point
     */
    private Point transformPoint(JLayer<? extends JComponent> layer, Point point) {
        if (transform != null) {
            try {
                transform.inverseTransform(point, point);
            } catch (NoninvertibleTransformException e) {
                e.printStackTrace();
            }
        }
        return point;
    }

    /**
     * Find the deepest component in the AWT hierarchy
     * 
     * @param layer  the layer to which this UI is installed
     * @param targetPoint the point in layer's coordinates
     * @return the component in the specified point
     */
    private Component getTarget(JLayer<? extends JComponent> layer, Point targetPoint) {
        Component view = layer.getView();
        if (view == null) {
            return null;
        } else {
            Point viewPoint = SwingUtilities.convertPoint(layer, targetPoint, view);
            return SwingUtilities.getDeepestComponentAt(view, viewPoint.x, viewPoint.y);
        }
    }

    /**
     * Convert the {@code mouseEvent}'s coordinates to the {@code layer}'s space
     * @param layer the layer this LayerUI is set to
     * @param mouseEvent the original mouse event
     * @return the {@code mouseEvent}'s point transformed to the {@code layer}'s coordinate space
     */
    private Point calculateTargetPoint(JLayer<? extends JComponent> layer,
            MouseEvent mouseEvent) {
        Point point = mouseEvent.getPoint();
        //SwingUtilities.convertPointToScreen(point, mouseEvent.getComponent());
        //SwingUtilities.convertPointFromScreen(point, layer);
        point = SwingUtilities.convertPoint(mouseEvent.getComponent(), point, layer);
        return transformPoint(layer, point);

        }

    private MouseEvent transformMouseEvent(JLayer<? extends JComponent> layer, MouseEvent mouseEvent, Component target, Point realPoint) {
        return transformMouseEvent( layer, mouseEvent, target, realPoint, mouseEvent.getID());
    }

    /**
     * Create the new event to being dispatched
     */
    private MouseEvent transformMouseEvent(JLayer<? extends JComponent> layer, MouseEvent mouseEvent, Component target, Point targetPoint, int id) {
        if (target == null) {
            return null;
        } else {
            Point newPoint = SwingUtilities.convertPoint(layer, targetPoint, target);
            return new MouseEvent(target, //
                    id, //
                    mouseEvent.getWhen(), //
                    mouseEvent.getModifiers(), //
                    newPoint.x, //
                    newPoint.y, //
                    mouseEvent.getClickCount(), //
                    mouseEvent.isPopupTrigger(), //
                    mouseEvent.getButton());
        }
    }

    /**
     * Create the new mouse wheel event to being dispached
     */
    private MouseWheelEvent transformMouseWheelEvent( JLayer<? extends JComponent> layer, MouseWheelEvent mouseWheelEvent, Component target,
            Point targetPoint) {
        if (target == null) {
            return null;
        } else {
            Point newPoint = SwingUtilities.convertPoint(layer, targetPoint, target);
            return new MouseWheelEvent(target, //
                    mouseWheelEvent.getID(), //
                    mouseWheelEvent.getWhen(), //
                    mouseWheelEvent.getModifiers(), //
                    newPoint.x, //
                    newPoint.y, //
                    mouseWheelEvent.getClickCount(), //
                    mouseWheelEvent.isPopupTrigger(), //
                    mouseWheelEvent.getScrollType(), //
                    mouseWheelEvent.getScrollAmount(), //
                    mouseWheelEvent.getWheelRotation() //
            );
        }
    }

    /**
     * dispatch the {@code mouseEvent}
     * @param mouseEvent the event to be dispatched
     */
    private void dispatchMouseEvent(MouseEvent mouseEvent) {
        if (mouseEvent != null) {
            Component target = mouseEvent.getComponent();
            target.dispatchEvent(mouseEvent);
        }
    }

    /**
     * Get the listening component associated to the {@code component}'s {@code event}
     */
    private Component getListeningComponent(MouseEvent event, Component component) {
        switch (event.getID()) {
        case (MouseEvent.MOUSE_CLICKED):
        case (MouseEvent.MOUSE_ENTERED):
        case (MouseEvent.MOUSE_EXITED):
        case (MouseEvent.MOUSE_PRESSED):
        case (MouseEvent.MOUSE_RELEASED):
            return getMouseListeningComponent(component);
        case (MouseEvent.MOUSE_DRAGGED):
        case (MouseEvent.MOUSE_MOVED):
            return getMouseMotionListeningComponent(component);
        case (MouseEvent.MOUSE_WHEEL):
            return getMouseWheelListeningComponent(component);
        }
        return null;
    }

    /**
     * Cycles through the {@code component}'s parents to find the {@link Component} with associated {@link MouseListener}
     */
    private Component getMouseListeningComponent(Component component) {
        if (component.getMouseListeners().length > 0) {
            return component;
        } else {
            Container parent = component.getParent();
            if (parent != null) {
                return getMouseListeningComponent(parent);
            } else {
                return null;
            }
        }
    }

    /**
     * Cycles through the {@code component}'s parents to find the {@link Component} with associated {@link MouseMotionListener}
     */
    private Component getMouseMotionListeningComponent(Component component) {
        /*
         * Mouse motion events may result in MOUSE_ENTERED and MOUSE_EXITED.
         * 
         * Therefore, components with MouseListeners registered should be
         * returned as well.
         */
        if (component.getMouseMotionListeners().length > 0 || component.getMouseListeners().length > 0) {
            return component;
        } else {
            Container parent = component.getParent();
            if (parent != null) {
                return getMouseMotionListeningComponent(parent);
            } else {
                return null;
            }
        }
    }

    /**
     * Cycles through the {@code component}'s parents to find the {@link Component} with associated {@link MouseWheelListener}
     */
    private Component getMouseWheelListeningComponent(Component component) {
        if (component.getMouseWheelListeners().length > 0) {
            return component;
        } else {
            Container parent = component.getParent();
            if (parent != null) {
                return getMouseWheelListeningComponent(parent);
            } else {
                return null;
            }
        }
    }

    /**
     * Generate a {@code MOUSE_ENTERED} and {@code MOUSE_EXITED} event when the target component is changed
     */
    private void generateEnterExitEvents( JLayer<? extends JComponent> layer,MouseEvent originalEvent, Component newTarget, Point realPoint) {
        if (lastEnteredTarget != newTarget) {
            dispatchMouseEvent(
                    transformMouseEvent(layer, originalEvent, lastEnteredTarget, realPoint, MouseEvent.MOUSE_EXITED));
            lastEnteredTarget = newTarget;
            //System.out.println("Last " + lastEnteredTarget.getClass().getName());
            dispatchMouseEvent(
                    transformMouseEvent(layer, originalEvent, lastEnteredTarget, realPoint, MouseEvent.MOUSE_ENTERED));
        }
    }
}

ZoomPanel – это JPanel, которые включают JLayer с TransformUI в нем. JLayer содержит JPanel с SpringLayout, в котором ограничения обновляются с помощью коэффициента масштабирования для правильного размещения компонентов (JXLayer имел свой собственный LayoutManager, но в JLayer вы не можете его установить)

package jzoom.transform;

import ...

public class ZoomPanel extends JPanel {

    private static final long serialVersionUID = 1L;

    private AffineTransform transform;
    private TransformUI layerUI;
    private JLayer<JComponent> layer;

    private SpringLayout layout;
    private JPanel springPanel;

    private Container view = null;

    public ZoomPanel() {
        this(null);
    }

    public ZoomPanel(Container view) {

        setLayout(new BorderLayout());

        this.view = view;
        transform = new AffineTransform();

        layout = new SpringLayout();
        springPanel = new JPanel(layout);
        if (view != null) {
            updateConstraints();
            springPanel.add(view);
        }

        layerUI = new TransformUI();
        layerUI.setTransform(transform);
        layer = new JLayer<JComponent>(springPanel, layerUI);

        super.add(layer);

    }

    private void updateConstraints() {
        Spring width = layout.getConstraint(SpringLayout.WIDTH, springPanel);
        Spring height = layout.getConstraint(SpringLayout.HEIGHT, springPanel);

        SpringLayout.Constraints constraints = layout.getConstraints(view);
        constraints.setX(Spring.constant(0));
        constraints.setY(Spring.constant(0));
        constraints.setWidth(Spring.scale(width, (float) (1 / transform.getScaleX())));
        constraints.setHeight(Spring.scale(height, (float) (1 / transform.getScaleX())));
    }

    public void setView(Container view) {
        if (this.view != null) {
            throw new IllegalStateException(
                    this.getClass().getName() + " cannot be shared between multiple containers");
        }

        if (view != null) {
            this.view = view;
            updateConstraints();
            springPanel.add(view);
        } else {
            throw new IllegalArgumentException("Can't set a null view");
        }
    }

    public double getScale() {
        return transform.getScaleX();
    }

    public void zoomIn() {
        setScale(transform.getScaleX() + 0.1);
    }

    public void zoomOut() {
        setScale(transform.getScaleX() - 0.1);
    }

    public void setScale(double scale) {
        if (!(scale < 1)) {
            transform.setToIdentity();
            transform.scale(scale, scale);
            updateConstraints();
            springPanel.updateUI();
        }
    }

    protected Component addToView(Component comp, Object constraints, int index) {
        if (view != null) {
            view.add(comp, constraints, index);
            return comp;
        }

        if (comp instanceof Container) {
            setView((Container) comp);
            return view;
        }

        throw new IllegalStateException("You need to add or set a Container view before adding Components");
    }

    @Override
    public Component add(Component comp) {
        // TODO Auto-generated method stub
        return addToView(comp, null, this.getComponentCount());
    }

    @Override
    public Component add(Component comp, int index) {
        // TODO Auto-generated method stub
        return addToView(comp, null, index);
    }

    @Override
    public void add(Component comp, Object constraints) {
        // TODO Auto-generated method stub
        addToView(comp, constraints, this.getComponentCount());
    }

    @Override
    public void add(Component comp, Object constraints, int index) {
        // TODO Auto-generated method stub
        addToView(comp, constraints, index);
    }

    private void inspectView(Container view) {
        PrintStream ps = null;
        try {
            ps = new PrintStream("C:\\Users\\andrea.maracci\\Documents\\sicraReflectionTemp.txt");
            inspectView(view, 0, ps);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (ps != null) {
                ps.close();
            }
        }
    }

    private static void inspectView(Component component, Integer level, PrintStream ps) {
        for (Integer i = 0; i < level; i++) {
            ps.print("\t");
        }
        ps.print(level + ")");
        ps.println("Inspecting " + component.getClass().getName());

        int accessibleCount = 0;
        if (component.getAccessibleContext() != null) {
            accessibleCount = component.getAccessibleContext().getAccessibleChildrenCount();
            if (accessibleCount > 0) {
                ps.println("*********************************************ACCESSIBLE CONTEXT*********************************************");
                for (int i = 0; i < accessibleCount; i++) {
                    ps.println(i + ") " + component.getAccessibleContext().getAccessibleChild(i).getClass().getName());
                }
                ps.println("************************************************************************************************************");
            }
        }

        if (component instanceof JComponent) {
            JComponent jComponent = ((JComponent)component);

            if (jComponent.getComponentCount() > 0) {
                Component[] children = jComponent.getComponents();
                for (Component child : children) {
                    inspectView(child, ++level, ps);
                }
            }
        }
        --level;
    }
}

А вот и ужасная тестовая программа

package jzoom.test;

import ...

public class TestFinal {
    public static void main(String[] args) {
        new TestFinal();
    }

    public TestFinal() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (InstantiationException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                } catch (UnsupportedLookAndFeelException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new BorderLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setMinimumSize(new Dimension(400,500));
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private JLayer<JComponent> layer;
        private TransformUI layerUI;
        private JPanel content;
        private AffineTransform transform = new AffineTransform();
        private ZoomPanel zoomPanel;

        public TestPane() {

            content = new JPanel(new GridBagLayout());
            // content = new JPanel(new XYLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridy = 0;
            gbc.weighty = 0;
            gbc.weightx = 0;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            JLabel label = new JLabel("Hello");
            JTextField field = new JTextField("World", 20);

            content.add(label, gbc);
            gbc.weightx = 1;
            content.add(field, gbc);
            // content.add(label, new XYConstraints(50, 20, 50, 22));
            // content.add(field, new XYConstraints(100, 20, 200, 22));

            gbc.gridy++;
            gbc.gridwidth = 2;

            final JSlider slider = new JSlider(100, 200);
            slider.setValue(100);
            slider.addChangeListener(new ChangeListener() {

                @Override
                public void stateChanged(ChangeEvent e) {
                    int value = slider.getValue();
                    double scale = value / 100d;
                    zoomPanel.setScale(scale);
                }
            });
            content.add(slider, gbc);
            // content.add(slider, new XYConstraints(75, 50, 200, 50));

            gbc.gridy++;
            gbc.gridwidth = 2;
            gbc.weighty = 1;
            gbc.fill = GridBagConstraints.BOTH;
            JTextArea textArea = new JTextArea();
            textArea.setEditable(true);
            textArea.setText(
                    "pollofritto\npalma\npalmipedone\ncaccoletta\namammata\na\nasd\nasdgfag\nasdafa\nasdfasf\nadsfasdf\nadfadsf\nadsfdasf\nasdfdas\npollofritto\npalma\npalmipedone\ncaccoletta\namammata\na\nasd\nasdgfag\nasdafa\nasdfasf\nadsfasdf\nadfadsf\nadsfdasf\nasdfdas");
            // textArea.setPreferredSize(new Dimensions());
            JScrollPane scrollPane = new JScrollPane(textArea);
            scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
            scrollPane.setPreferredSize(new Dimension(200, 75));
            content.add(scrollPane, gbc);

            gbc.gridy++;
            gbc.gridwidth = 2;
            gbc.weighty = 0;
            gbc.weightx = 1;
            gbc.fill = GridBagConstraints.HORIZONTAL;
            String[] petStrings = { "Bird", "Cat", "Dog", "Rabbit", "Pig" };
            JComboBox petList = new JComboBox(petStrings);
            content.add(petList, gbc);

            JButton zoomIn = new JButton("Zoom In");
            // zoomIn.addMouseListener(new ZoomMouseListener());
            zoomIn.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    // System.out.println("FIRST");
                    // layerUI.zoomIn();

                    //double zoom = transform.getScaleX();
                    //transform.setToIdentity();
                    //transform.scale(zoom + 0.1, zoom + 0.1);
                    zoomPanel.zoomIn();

                    // jLayer.repaint();
                }
            });

            JButton zoomOut = new JButton("Zoom Out");
            zoomOut.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    zoomPanel.zoomOut();

                    //double zoom = transform.getScaleX();
                    //transform.setToIdentity();
                    //transform.scale(zoom - 0.1, zoom - 0.1);
                    // jLayer.repaint();
                }
            });
            gbc.gridy++;
            gbc.gridx = 0;
            gbc.gridwidth = 0;
            gbc.anchor = GridBagConstraints.LINE_END;

            // content.add(zoomOut, new XYConstraints(50, 120, 100, 25));
            // content.add(zoomIn, new XYConstraints(170, 120, 100, 25));

            JPanel button = new JPanel();
            button.setLayout(new BoxLayout(button, BoxLayout.LINE_AXIS));
            button.add(zoomOut);
            button.add(zoomIn);
            gbc.fill = GridBagConstraints.NONE;
            content.add(button, gbc);

            setLayout(new BorderLayout());
            setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

            zoomPanel = new ZoomPanel();
            zoomPanel.setView(content);
            add(zoomPanel);
        }
    }
}
person Schizoping    schedule 05.04.2017
comment
Пришлось удалить импорт, потому что сообщение было слишком длинным - person Schizoping; 05.04.2017
comment
Я решил поиграть с этим и обнаружил, что приведенный выше код для ZoomPanel использует JXLayer, а TransformUI основан на LayerUI Java 8. Итак, чтобы заставить этот код работать, мне нужно было изменить ZoomPanel для использования JLayer. - person Enwired; 15.04.2017
comment
Спасибо за предупреждение! Я напортачил с кодом, потому что сделал версии для Java 6 и Java 7/8. Я отредактирую этот пост и перепроверю его как можно скорее. - person Schizoping; 20.04.2017