简体   繁体   中英

DraggableComponents in vertical view (Java Swing)

This is my first question on this platform so bear with here:

I'm using Java Swing to make a LayerPanel just like in Photoshop, where each child of the LayerPanel is also a Panel that represents a layer. Just like in Photoshop I'm using the mouse to move these children of the LayerPanel using the DraggableComponent class inspired by: enter image description heregable-component>.

The problem lies in re-arranging the layers in the UI. I'm unable to get the swapping of panels to work within the UI.

This is my code thus far:

The DraggableComponent:

class DraggableComponent extends JPanel implements MouseListener, MouseMotionListener {

    private LayerPanel panel;

    private volatile int screenY = 0;
    private volatile int myY = 0;

    private String name;

    public DraggableComponent(LayerPanel panel, String name) {
        setPreferredSize(new Dimension(300, 80));
        this.name = name;
        this.panel = panel;
        updateBorder(name);
        setVisible(true);

        setLayout(null);

        addMouseListener(this);
        addMouseMotionListener(this);
    }

    private void updateBorder(String name) {
        setBorder(new TitledBorder(new DropShadowBorder(), name, TitledBorder.LEADING, TitledBorder.BELOW_TOP, null, null));
    }

    private void handleLocation(int y) {
        if (y >= getParent().getHeight() - this.getHeight()) {
            setLocation(getLocation().x, getParent().getHeight() - this.getHeight());
        } else setLocation(getLocation().x, Math.max(y, 0));
    }

    @Override
    public void mousePressed(MouseEvent e) {
        screenY = e.getYOnScreen();
        myY = getY();
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        panel.handleReleased(this);
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        int deltaY = e.getYOnScreen() - screenY;

        handleLocation(myY + deltaY);
        panel.handleLocation(this);
    }

    public void rename(String name) {
        this.name = name;
        updateBorder(name);
    }
}

The LayerPanel class:

public class LayerPanel extends JPanel {

    private ArrayList<DraggableComponent> components = new ArrayList<>();
    protected int HEIGHT_PER_COMPONENT;

    public LayerPanel(int height, int amountOfComponents) {
        setPreferredSize(new Dimension(200, height));
        setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));

        for (int i = 0; i < 10; i++) {
            components.add(new DraggableComponent(this, Integer.toString(i)));
        }

        updateComponents();
    }

    public void addComponent(String name) {
        components.add(new DraggableComponent(this, name));
        updateComponents();
    }

    private void updateComponents() {
        HEIGHT_PER_COMPONENT = getHeight() / (components.size() + 1);
        removeAll();

        for (DraggableComponent c : components) {
            //c.rename(Integer.toString(components.indexOf(c)));
            add(c);
            c.setLocation(0, HEIGHT_PER_COMPONENT * components.indexOf(c));
        }
    }

    public void handleReleased(DraggableComponent component) {
        updateComponents();
    }

    public void handleLocation(DraggableComponent component) {
        final int index = components.indexOf(component);

        for (DraggableComponent nextComponent : components) {
            final int indexNext = components.indexOf(nextComponent);
            if (component.getY() >= nextComponent.getY() - HEIGHT_PER_COMPONENT / 2 && !component.equals(nextComponent)) {
                Collections.swap(components, indexNext, indexNext - 1);
                updateComponents();
            }
        }
    }

    public static void main(String[] args) {
        JFrame f = new JFrame("Layers test");

        LayerPanel panel = new LayerPanel(800, 10);

        f.add(panel);
        f.setSize(300, 800);
        f.setLocationRelativeTo(null);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setVisible(true);
    }
}

The problem lies in re-arranging the layers.

There is no need to manage this yourself.

This is controlled by the ZOrder of the components in the panel.

In your mousePressed event you can set the ZOrder of the component to 0, to make sure this component is painted last, which means it will now paint of top of all the other components on the panel.

Something like:

Container container = e.getComponent().getParent();
container.setComponentZOrder(e.getComponent(), 0);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM