Как определить что произошел клик по изображению нарисованному при помощи drawImage

140
25 декабря 2020, 07:20

Есть элемент созданный с помощью drawImage и какого-либо изображения. Хотелось бы узнать, как можно реализовать удаление элемента по клику на нём?

Это то же самое, что, допустим, удалить изображение при щелчке на нём. Спасибо.

Answer 1

Вот, я собрал пример, как в по ссылке в комментарии...

Каждому изображению присваивается цветовой идентификатор и создается дополнительная картинка-буфер в памяти, в которой каждое изображение представлено областью закрашенной в цвет-идентификатор. по клику берем цвет и по нему определяем что за картинка была под мышкой.

При таком подходе технически возможно обработать клик по картинкам с прозрачностью, при этом цветом идентификатором в пикинг буфере не надо красить полностью прозрачные пиксели, это слегка сложнее и в этом примере я не стал так делать.

public class PickingExample { 
     
        static class Elem extends Point { 
            Image img; 
            Elem() throws IOException { 
                this.img =  ImageIO.read(new File("./1.gif")); 
                this.x = (int) (Math.random()*300); 
                this.y = (int) (Math.random()*200); 
            } 
        } 
     
        public static void main(String[] args) throws IOException { 
            Map<Color, Elem> elements = new HashMap<>(); 
            for (int i = 0; i < 12; i++) 
                elements.put(new Color( i, 0, 0), new Elem()); 
            BufferedImage pickingBuffer = new BufferedImage(400, 300, BufferedImage.TYPE_INT_ARGB); 
            JFrame f = new JFrame(); 
            f.setLayout(new BorderLayout()); 
            JComponent comp = new JComponent() { 
                @Override 
                protected void paintComponent(Graphics g) { 
                    Graphics pick = pickingBuffer.getGraphics(); 
                    for (Color pickColor : elements.keySet()) { 
                        Elem element = elements.get(pickColor); 
                        pick.setColor(pickColor); 
                        pick.fillRect(element.x, element.y, element.img.getWidth(null), element.img.getHeight(null)); 
                        g.drawImage(element.img, element.x, element.y, element.img.getWidth(null), element.img.getHeight(null), null); 
                    } 
                    pick.dispose(); 
                } 
            }; 
            f.add(comp, BorderLayout.CENTER); 
            f.setSize(400, 300); 
            f.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 
            f.setLocationRelativeTo(null); 
            f.setVisible(true); 
            comp.addMouseListener(new MouseAdapter() { 
                @Override 
                public void mousePressed(MouseEvent e) { 
                    elements.remove(new Color(pickingBuffer.getRGB(e.getX(), e.getY()))); 
                    f.repaint(); 
                } 
            }); 
        } 
    }

PS: такой же фокус применяю и в некоторых случаях в 3д приложениях, для тех же самых целей, тут тоже создается картинка-буфер и специальный шейдер, который так же кодирует объекты по цветам.

в этих ответах использован тот же прием:

https://ru.stackoverflow.com/a/988105/188366

https://ru.stackoverflow.com/a/962780/188366

Answer 2

Боюсь что никак.

После вызова drawImage изображение уже преобразовано в байты и отрисовано. Java не запоминает ни какое это было изображение ни где оно было нарисовано.

Так что часть работы придется сделать самому:

Один вариант: запоминать координаты, в которых были нарисованы изображения, обрабатывать щелчок, находить пересечение и перерисовывать эту область. Отдельно обрабатывать случаи «накладок» одного изображения поверх другого.

Второй вариант: вместо того чтобы отрисовывать изображения на графике реализовать их в виде отдельных компонентов. Компонент можно написать целиком самописный, либо использовать встроенные (посмотрите как добавить JLabel с картинкой здесь: How to add an image to a JPanel?).

Преимущество второго подхода в том, что отслеживание щелчка мыши и накладок Swing сделает сам.

READ ALSO
Не понимаю работу (Math.random())

Не понимаю работу (Math.random())

Не понимаю как отрабатывает Mathrandom() и что он генерирует и умножает на surnameLength например

130
Помогите разобраться с protected?

Помогите разобраться с protected?

Во время подготовки к экзамену OCA по Боярскому, встретил пример на стр178 Он касается модификатора доступа protected и звучит примерно так, что...

145
Что значит ошибка: reached end of file while parsing }

Что значит ошибка: reached end of file while parsing }

Вот здесь похожий вопросОтвет кроется в вашем методе main(){} как уже подметил @Grundy

347
Получить отдельные параметры даты объекта Date

Получить отдельные параметры даты объекта Date

На клиенте в браузере получаю дату:

128