I am creating a Java program to simulate Microsoft Paint in Windows 95. There is a color palette in the bottom. Clicking any color in the palette will change the color of the painting tool like pencil. I tried to use Graphics2D to set each color for the tool according to the button clicked in the palette. I tried to add ActionListener to JButton representing the color button in the palette and then changed it to MouseListener. But my code does not work for this purpose. I am not sure whether this occurs because ActionListener/MouseListener is included in a for loop, which is then included in MouseMotionListener. Neither ActionListener nor MouseListener added to JButton works for setting color in PaintComponent in JPanel in this code. Is there a better way to rewrite this code?
This is a screenshot of Paint simulation that I created: enter image description here
My code is as follows:
paintOpen = new JFrame();
paintCanvasPanel = new JPanel() {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
this.addMouseMotionListener(new MouseMotionListener() {
public void mouseDragged(MouseEvent e) {
if (SwingUtilities.isLeftMouseButton(e)) {
Graphics2D g = (Graphics2D) getGraphics();
g.drawLine(e.getX(), e.getY(), e.getXOnScreen(), e.getYOnScreen());
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setStroke(new BasicStroke(WIDTH, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL));
for (int i = 0; i < 28; i++) {
//Neither ActionListener nor MouseListener works
paintColorButton[i].addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
for (int j = 0; j < 28; j++) {
g.setColor(paintPaletteColor[j]);
}
}
});
}
}
}
public void mouseMoved(MouseEvent e) {
}
});
}
};
paintScrollPane = new JScrollPane(paintCanvasPanel);
paintScrollPane.setBackground(white);
paintScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
paintScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
paintOpen.getContentPane().add(paintScrollPane);
paintOpen.getContentPane().setBackground(white);
paintOpen.setAlwaysOnTop(true);
paintOpen.setBounds(200, 0, 420, 600);
paintOpen.setExtendedState(JFrame.MAXIMIZED_BOTH);
paintOpen.setIconImage(paintIcon.getImage());
paintOpen.setTitle("untitled - Paint");
paintPalettePanel = new JPanel();
paintColorButton = new JButton[28];
for (int i = 0; i < 28; i++) {
paintColorButton[i] = new JButton();
paintColorButton[i].setBackground(paintPaletteColor[i]);
paintPalettePanel.add(paintColorButton[i]);
}
paintOpen.add(paintPalettePanel, BorderLayout.SOUTH);
}
I tried to change ActionListener to MouseListener, but the color still cannot be changed.
for (int i = 0; i < 28; i++) {
paintColorButton[i].addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
for (int j = 0; j < 28; j++) {
g.setColor(paintPaletteColor[j]);
}
}
});
}
I'm not sure if this is of any help, but I took your code, put things in order, removed the redundant and added the missing. I can only recommend that you take a closer look at things. Swing is event oriented and you have to remember when the mouse was moved or a button was pressed in order to be able to process this information in the paintComponent
event. In this case, repaint()
must be called in mouseDragged
so that the result is visible.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PaintPanel extends JPanel implements MouseMotionListener, ActionListener{
private Color[] paintPaletteColor = { Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY, Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED, Color.WHITE, Color.YELLOW };
private Color drawColor = Color.BLACK;
private MouseEvent e;
public static void main(String[] args) {
new PaintPanel();
}
public PaintPanel() {
addMouseMotionListener(this);
setPreferredSize(new Dimension(1024, 768));
JScrollPane paintScrollPane = new JScrollPane(this);
paintScrollPane.setBackground(Color.WHITE);
paintScrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
paintScrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
paintScrollPane.setBackground(Color.white);
JPanel paintPalettePanel = new JPanel();
// Add a button for each color defined in paintPaletteColor.
// Add more colors there for additional buttons.
for (int i = 0; i < paintPaletteColor.length; i++) {
JButton button = new JButton();
button.setBackground(paintPaletteColor[i]);
button.addActionListener(this);
paintPalettePanel.add(button);
}
JFrame paintOpen = new JFrame();
paintOpen.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
paintOpen.add(paintScrollPane);
paintOpen.add(paintPalettePanel, BorderLayout.SOUTH);
paintOpen.setIconImage(new ImageIcon("Icon.png").getImage());
paintOpen.setTitle("untitled - Paint");
paintOpen.pack();
paintOpen.setLocationRelativeTo(null);
paintOpen.setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
// A button was clicked - remember its color.
drawColor = ((JButton)e.getSource()).getBackground();
}
@Override
public void mouseDragged(MouseEvent e) {
// The mouse was dragged - remember the new position and repaint the panel.
this.e = e;
repaint();
}
@Override
public void mouseMoved(MouseEvent e) {
//
}
@Override
public void paintComponent(Graphics g) {
// triggered `repaint`, so let's go.
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(4, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_BEVEL));
g2d.setColor(drawColor);
// mouse dragged ?
if(e != null) g2d.drawLine(e.getX(), e.getY(), e.getX(), e.getY());
}
}