5

I am currently trying to develop a basic pixel editor application to build up my programming experience with Java. I am designing it so the user has several colour options on, they click on an option and then they can drag over the cells in the grid and they change colour (like a typical image editor, but with a sort of snap on to each grid cell)

Any idea of what Java component, if any, is able to implement this type of grid in Java?

I had thought of each cell being a JButton, but this seemed terribly inefficient and I don't think it would be possible to change the colour of each cell(button) with out individually clicking on each one.

Any help appreciated.

wiggles
  • 499
  • 6
  • 16
  • 1
    You might want to check this link out.. The basic concepts are always important and very helpful. http://java.sun.com/docs/books/tutorial/uiswing/ – Erkan Haspulat May 24 '10 at 22:47
  • Hey any progress on your pixel editor? I am attempting to create one myself. Do you have it up on GIT hub or any other public repo? – Jose Mar 24 '12 at 15:30
  • Sorry Jose, I got rid of it a while back I'm afraid :( – wiggles Mar 24 '12 at 19:29

2 Answers2

9

More than a few hundred components is awkward. One easy way to get big pixels is to use drawImage() and scale the mouse coordinates as shown here and here. Here's a simple example.

screenshot

import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;

/** @see http://stackoverflow.com/questions/2900801 */
public class Grid extends JPanel implements MouseMotionListener {

    private final BufferedImage img;
    private int imgW, imgH, paneW, paneH;

    public Grid(String name) {
        super(true);
        Icon icon = UIManager.getIcon(name);
        imgW = icon.getIconWidth();
        imgH = icon.getIconHeight();
        this.setPreferredSize(new Dimension(imgW * 10, imgH * 10));
        img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2d = (Graphics2D) img.getGraphics();
        icon.paintIcon(null, g2d, 0, 0);
        g2d.dispose();
        this.addMouseMotionListener(this);
    }

    @Override
    protected void paintComponent(Graphics g) {
        paneW = this.getWidth();
        paneH = this.getHeight();
        g.drawImage(img, 0, 0, paneW, paneH, null);
    }

    @Override
    public void mouseMoved(MouseEvent e) {
        Point p = e.getPoint();
        int x = p.x * imgW / paneW;
        int y = p.y * imgH / paneH;
        int c = img.getRGB(x, y);
        this.setToolTipText(x + "," + y + ": "
            + String.format("%08X", c));
    }

    @Override
    public void mouseDragged(MouseEvent e) {
    }

    private static void create() {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(new Grid("Tree.closedIcon"));
        f.pack();
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                create();
            }
        });
    }
}
trashgod
  • 203,806
  • 29
  • 246
  • 1,045
  • 1
    Marginally acceptable example of using [`setPreferredSize()`](http://stackoverflow.com/q/7229226/230513). :-) – trashgod Jan 05 '13 at 10:22
2

An option is to use a large Canvas, and intercept events on it. Draw whatever you need to in the paint(g) method.

Chris Dennett
  • 22,412
  • 8
  • 58
  • 84