1

I am writing a program with a bouncing DVD logo but I have one issue: I want this logo to change color but it is not working. The logo is supposed to change color when it hits an edge. I know that tint() exists for JavaScript.

Is there something similar for Java?

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;

public class MyPanel extends JPanel implements ActionListener{

    final int PANEL_WIDTH = 500;
    final int PANEL_HEIGHT = 500;
    Image dvd;
    Timer timer;
    int xVelocity = 1;
    int yVelocity = 1;
    int x = 0;
    int y = 0;

    int r = (int)(Math.random() * 255);
    int g = (int)(Math.random() * 255);
    int b = (int)(Math.random() * 255);

    MyPanel(){
        this.setPreferredSize(new Dimension(PANEL_WIDTH, PANEL_HEIGHT));
        this.setBackground(Color.BLACK);
        dvd = new ImageIcon("dvdlogo-01.png").getImage();
        timer = new Timer(10, this);
        timer.start();

    }

    public void paint(Graphics g){
        super.paint(g); // paint background
        Graphics2D gr = (Graphics2D) g;
        gr.drawImage(dvd, x, y,null );

        
    }


    public void actionPerformed(ActionEvent e){

        if(x >= PANEL_WIDTH - dvd.getWidth(null) || x < 0){
            xVelocity = xVelocity * -1;
        }
        x = x + xVelocity;

        if(y >= PANEL_HEIGHT - dvd.getHeight(null) || y < 0){
            yVelocity = yVelocity * -1;
        }
        y = y + yVelocity;
        repaint();

    }
}

enter image description here

andrewJames
  • 19,570
  • 8
  • 19
  • 51
  • For [example](https://stackoverflow.com/questions/14225518/tinting-image-in-java-improvement/14225857#14225857); [a bit more brute force](https://stackoverflow.com/questions/71304272/changing-icon-color-in-java/71305300#71305300) – MadProgrammer Dec 10 '22 at 23:14

1 Answers1

0

No, Swing does not contain a native "tint" feature, but you can create one (with a bit of effort).

So, based on Tinting Image in Java improvement, you can do something like this...

enter image description here

This example makes use of a MouseListener and will display the tinted image for 1 second, but you get the idea

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;

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

    public Main() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    JFrame frame = new JFrame();
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                } catch (IOException ex) {
                    Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }

    public class TestPane extends JPanel {

        private BufferedImage masterImage;
        private BufferedImage paintImage;
        private BufferedImage tintedImage;

        public TestPane() throws IOException {
            masterImage = ImageIO.read(getClass().getResource("/images/DVDLogo.png"));
            paintImage = masterImage;
            tintedImage = ImageUtils.generateMask(masterImage, Color.YELLOW, 1f);

            addMouseListener(new MouseAdapter() {
                private Timer timer = new Timer(1000, new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        paintImage = masterImage;
                        repaint();
                    }
                });

                @Override
                public void mouseClicked(MouseEvent e) {
                    if (timer != null) {
                        timer.stop();
                    }
                    paintImage = tintedImage;
                    repaint();
                    timer.start();
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(paintImage.getWidth() + 100, paintImage.getHeight() + 100);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g.create();
            int x = (getWidth() - paintImage.getWidth()) / 2;
            int y = (getHeight() - paintImage.getHeight()) / 2;
            g2d.drawImage(paintImage, x, y, this);
            g2d.dispose();
        }

    }

    public class ImageUtils {
        public static BufferedImage generateMask(BufferedImage imgSource, Color color, float alpha) {
            int imgWidth = imgSource.getWidth();
            int imgHeight = imgSource.getHeight();

            BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight, Transparency.TRANSLUCENT);
            Graphics2D g2 = imgMask.createGraphics();
            applyQualityRenderingHints(g2);

            g2.drawImage(imgSource, 0, 0, null);
            g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha));
            g2.setColor(color);

            g2.fillRect(0, 0, imgSource.getWidth(), imgSource.getHeight());
            g2.dispose();

            return imgMask;
        }

        public static GraphicsConfiguration getGraphicsConfiguration() {
            return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
        }

        public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
            BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
            image.coerceData(true);
            return image;
        }

        public static void applyQualityRenderingHints(Graphics2D g2d) {
            g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
            g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
            g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
            g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
        }

        public BufferedImage tint(BufferedImage master, BufferedImage tint) {
            int imgWidth = master.getWidth();
            int imgHeight = master.getHeight();

            BufferedImage tinted = createCompatibleImage(imgWidth, imgHeight, Transparency.TRANSLUCENT);
            Graphics2D g2 = tinted.createGraphics();
            applyQualityRenderingHints(g2);
            g2.drawImage(master, 0, 0, null);
            g2.drawImage(tint, 0, 0, null);
            g2.dispose();

            return tinted;
        }
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366