Как поменять местами значки на кнопках, расположенных в GridLayout, с помощью перетаскивания? - PullRequest
1 голос
/ 15 апреля 2019

Я пытаюсь создать своего рода головоломку, в которой я загрузил изображение в сетку 5x5, обрезал изображение и назначил каждую обрезанную часть в виде значка для 25 кнопок, расположенных в одном шаблоне.Я хочу иметь возможность перетаскивать указатель мыши с одной кнопки на другую и менять местами значки на этих двух кнопках.

Я пытался использовать несколько методов MouseListener и MouseMotionListener, но пока ничего не получалось.

import java.awt.*;
import java.awt.event.*;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;
import java.awt.Component;

import javax.swing.*;
//import java.awt.image.*;
public class ImageMove {
    JFrame jf;
    JButton[][] grid;
    JLabel test;
    public static void main(String[] args) {
        ImageMove ob = new ImageMove();
        ob.start();
    }
    public void start() {
        jf = new JFrame();
        JPanel gridPanel = new JPanel();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);      
        ImageIcon img = new ImageIcon("download.jpg");
        Image temp1= img.getImage();
        img=new ImageIcon(temp1.getScaledInstance(500, 500, Image.SCALE_SMOOTH));
        Image img1 = img.getImage();

        gridPanel.setLayout(new GridLayout (5,5));
        grid = new JButton[5][5];
        for(int y=0;y<5;y++) {
            for(int x=0; x<5; x++) {
                Image image = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(img1.getSource(), new CropImageFilter(x * 500 / 5, y * 500 / 5, 100, 100)));
                ImageIcon icon = new ImageIcon(image);
                JButton temp = new JButton(icon);
                temp.setTransferHandler(new TransferHandler("icon"));
                temp.addMouseMotionListener(new DragMouseAdapter());
                grid[x][y]=temp;                
                gridPanel.add(grid[x][y]);
            }
        }
        test= new JLabel();
        jf.getContentPane().add(BorderLayout.NORTH, test);
        jf.add(gridPanel);
        jf.pack();
        jf.setSize(500, 500);
        jf.setVisible(true);
    }
    class DragMouseAdapter extends MouseAdapter{
        private int x, y;
        public void mouseDragged(MouseEvent e) {
            final int x0=MouseInfo.getPointerInfo().getLocation().x;
            final int y0=MouseInfo.getPointerInfo().getLocation().y;
            x=x0;
            y=y0;
            JButton c = (JButton) e.getSource();
            TransferHandler handler = c.getTransferHandler();
            handler.exportAsDrag(c, e, TransferHandler.COPY);

            }
        public void mouseReleased(MouseEvent e) {
            JButton c = (JButton) e.getSource();
            Icon icon = c.getIcon();
            grid[((int)(x/100))][((int)(y/100))].setIcon(icon);

        }

    }


}

В настоящее время программа копирует значок с первой кнопки на вторую кнопку,т.е. он заменяет иконку второй кнопки на первую, но первая кнопка остается прежней.Я ожидаю полностью поменять эти две иконки.Метод MouseDragged в конце выполняет описанное поведение, но MouseReleased, похоже, вообще ничего не делает.

Любая помощь очень ценится.

1 Ответ

0 голосов
/ 15 апреля 2019

Это очень просто.Вам просто нужно где-то сохранить кнопку источника перетаскивания, и при ее замене заменить ее значок старым значком кнопки перетаскивания.

import java.awt.BorderLayout;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.datatransfer.Transferable;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.CropImageFilter;
import java.awt.image.FilteredImageSource;

import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.TransferHandler;

//import java.awt.image.*;
public class ImageMove {
    JFrame jf;

    JButton[][] grid;

    JLabel test;

    JButton dragSource; // here we save drag source component

    public static void main(String[] args) {
        ImageMove ob = new ImageMove();
        ob.start();
    }

    public void start() {
        jf = new JFrame();
        JPanel gridPanel = new JPanel();
        jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        ImageIcon img = new ImageIcon("download.jpg");
        Image temp1 = img.getImage();
        img = new ImageIcon(temp1.getScaledInstance(500, 500, Image.SCALE_SMOOTH));
        Image img1 = img.getImage();

        gridPanel.setLayout(new GridLayout(5, 5));
        grid = new JButton[5][5];
        for (int y = 0; y < 5; y++) {
            for (int x = 0; x < 5; x++) {
                Image image = Toolkit.getDefaultToolkit()
                        .createImage(new FilteredImageSource(img1.getSource(), new CropImageFilter(x * 500 / 5, y * 500 / 5, 100, 100)));
                ImageIcon icon = new ImageIcon(image);
                JButton temp = new JButton(icon);
                // use own extension of TransferHandler
                temp.setTransferHandler(new MyTransferHandler("icon"));
                // start drag on mouse pressed event.
                temp.addMouseListener(new DragMouseAdapter());
                grid[x][y] = temp;
                gridPanel.add(grid[x][y]);
            }
        }
        test = new JLabel();
        jf.getContentPane().add(BorderLayout.NORTH, test);
        jf.add(gridPanel);
        jf.pack();
        jf.setSize(500, 500);
        jf.setVisible(true);
    }

    class DragMouseAdapter extends MouseAdapter {

        @Override
        public void mousePressed(MouseEvent e) {
            JButton c = (JButton) e.getSource();
            dragSource = c;
            TransferHandler handler = c.getTransferHandler();
            handler.exportAsDrag(c, e, TransferHandler.COPY);
        }

    }

    private class MyTransferHandler extends TransferHandler {
        public MyTransferHandler(String property) {
            super(property);
        }

        @Override
        public boolean importData(JComponent comp, Transferable t) {
            Icon targetIcon = ((JButton) comp).getIcon();
            boolean result = super.importData(comp, t);
            if (dragSource != null) {
                dragSource.setIcon(targetIcon);
                dragSource = null;
            }
            return result;
        }
    }

}
...