Search code examples
javadraggablejscrollpaneboxlayout

Java draggable JPanel within JScrollPane with boxLayout


I have (1)JPanel containing (2)JPanel with BoxLayout. (2)JPanel can contain any number of (n)JPanels with FlowLayout (no of orders). (1)JPanel is put into JScrollPane using JScrollPaneLayout. I want (n)JPanels to be draggable to switch positions of (n)JPanels, but still maintain BoxLayout. For example I have JPanel with BoxLayout and 4 JPanels, I want to insert 4th JPanel between 1st and 2nd by dragging it in between, initial 2nd JPanel would automatically be moved to 3rd spot.

I already made (n)JPanels draggable, but I can't figure out a way to get position in which they should be inserted:

private void handleDrag(final JPanel panel){
    panel.addMouseListener(new MouseAdapter() {

        @Override
        public void mousePressed(MouseEvent me) {
             panelX = me.getX();
             panelY = me.getY();
        }

        @Override
        public void mouseReleased(MouseEvent me2){

            // get position of Component

            boxPanel.add(panel, position);

            scroll.revalidate();
        }
    });

    panel.addMouseMotionListener(new MouseMotionAdapter() {

        @Override
        public void mouseDragged(MouseEvent me) {
            me.translatePoint(me.getComponent().getLocation().x - panelX, me.getComponent().getLocation().y - panelY);
            panel.setLocation(0, me.getY());
        }
    });

I want to change positions of components in JPanel using BoxLayout by dragging JPanel to position, but I want JPanel to maintain BoxLayout.


Solution

  • Code I end up using, might be helpful to someone else.

    private void handleDrag(final JPanel panel){
    
        panel.addMouseListener(new MouseAdapter() {
            @Override
            public void mousePressed(MouseEvent me) {
                 panelY = me.getY();
    
                 panelNo = rowPanel.indexOf(panel);
                 tempItem = rowPanel.get(panelNo);
    
                 tempItem.setBackground(panelActiveColor);
                 tempItem.setBorder(BorderFactory.createRaisedBevelBorder());
            }
    
            @Override
            public void mouseReleased(MouseEvent me){
    
                tempItem.setBackground(panelColor);
                tempItem.setBorder(BorderFactory.createEmptyBorder());
                scroll.revalidate();
            }
        });
    
        panel.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent me) {
                me.translatePoint(0, me.getComponent().getLocation().y - panelY);
    
                int temp;
    
                if((int) ((me.getY() - panelY) / me.getComponent().getSize().height) < 0){
                    temp = 0;
                }
                else if((int) ((me.getY() - panelY) /  me.getComponent().getSize().height) < (elementsAmount - 1)){
                    temp = (me.getY() - panelY) /  me.getComponent().getSize().height + 1;
                }
                else{
                    temp = (elementsAmount - 1);
                }
    
                rowPanel.remove(tempItem);
    
                rowPanel.add(temp, tempItem);
    
                boxPanel.add(tempItem, temp);
    
                scroll.revalidate();
            }
        });
    }