Как создать JPanel с двумя изображениями, где при наведении курсора мыши отображается только часть изображения ниже?

Я пытаюсь создать панель кнопок, на которой нажатая кнопка становится «разного цвета»; показать фоновое изображение. p.s. Мне нужен только этот подход (с 2 изображениями), а не что-то еще. Спасибо !

Eg:

public class TestPane extends JPanel {      

        private BufferedImage   imgUnclicked;
        private BufferedImage   imgClicked;
        private Point           mousePoint;

        public TestPane() {
            try {
                imgUnclicked = ImageIO.read(new File("C:\\Users\\Me\\Desktop\\tmp\\Uncolored.png"));
                imgClicked = ImageIO.read(new File("C:\\Users\\Me\\Desktop\\tmp\\Colored.png"));
            } catch (IOException ex) {
                Logger.getLogger(Spotlight.class.getName()).log(Level.SEVERE, null, ex);
            }

            addMouseMotionListener(new MouseAdapter() {
                @Override
                public void mouseClicked(MouseEvent e) {
                    mousePoint = e.getPoint();
                    repaint();
                }
            });
        }
    }
    @Override
    protected void paintComponent(Graphics g) {
        //Draw imgClicked
        //Draw imgUnclicked with some rectangular area around mouse click subtracted
    }
}

person sarathrami    schedule 06.09.2013    source источник
comment
Чтобы быстрее получить помощь, опубликуйте SSCCE.   -  person Andrew Thompson    schedule 06.09.2013


Ответы (3)


Не нужно изобретать велосипед. Вместо этого используйте JToggleButton (соответствующим образом настроенный). Кнопка будет реагировать как на мышь, так и ввод с клавиатуры.

import java.awt.*;
import java.net.*;
import javax.imageio.ImageIO;
import javax.swing.*;

class ChangeImageOnClick {

    public static void main(String[] args) throws Exception {
        URL url1 = new URL("http://i.stack.imgur.com/gJmeJ.png");
        final Image img1 = ImageIO.read(url1);
        URL url2 = new URL("http://i.stack.imgur.com/wCF8S.png");
        final Image img2 = ImageIO.read(url2);
        Runnable r = new Runnable() {

            @Override
            public void run() {
                JToggleButton btn = new JToggleButton("Click me!");
                btn.setIcon(new ImageIcon(img1));
                btn.setSelectedIcon(new ImageIcon(img2));

                btn.setContentAreaFilled(false);
                btn.setBorderPainted(false);

                JOptionPane.showMessageDialog(null, btn);
            }
        };
        SwingUtilities.invokeLater(r);
    }
}
person Andrew Thompson    schedule 06.09.2013

Другая идея. По сути, загрузите изображение в JLabel, установите Layout метки и добавьте к нему два непрозрачных компонента.

Используя простой MouseListener, вы можете сделать компонент невидимым или прозрачным в зависимости от ваших потребностей...

введите здесь описание изображениявведите здесь описание изображения

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class HideAndShow {

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

    public HideAndShow() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        public TestPane() {
            setLayout(new BorderLayout());
            try {
                BufferedImage img = ImageIO.read(new File("/Users/swhitehead/Dropbox/MegaTokyo/Haibane_Miho___Take_2_by_garrbage.png"));
                JLabel label = new JLabel(new ImageIcon(img.getScaledInstance(-1, 200, Image.SCALE_SMOOTH)));
                add(label);

                label.setLayout(new GridLayout(2, 1));

                JPanel top = new JPanel();
                top.add(new JLabel("Top"));
                JPanel bottom = new JPanel();
                bottom.add(new JLabel("Bottom"));

                MouseAdapter ma = new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent e) {
                        ((JPanel)e.getComponent()).setOpaque(false);
                        repaint();
                    }
                };

                top.addMouseListener(ma);
                bottom.addMouseListener(ma);

                label.add(top);
                label.add(bottom);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }
}
person MadProgrammer    schedule 06.09.2013

Добавьте ActionListener к своей кнопке и вызовите setIcon с помощью imgClicked.

Что-то вроде этого:

    JButton btn = new JButton();
    btn.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            btn.setIcon(imgClicked);
        }
    });
person BetaRide    schedule 06.09.2013
comment
setIcon() масштабирует фоновое изображение до размера кнопки. В этом случае и передний план, и фон одинаковы, за исключением того, что один фон окрашен, а другой нет. Вот почему мне нужно какое-то решение, например, вычитание площади для изображений. - person sarathrami; 06.09.2013