Repainting a graphic paintComponent using an ActionListener
I am struggling a bit with how to repaint a circle graphic to a different color on a button click. Further, I also have to do the same with a JColorChooser. Getting the chooser dialog to show is fairly straightforward but what do I need to add to the action listener to get the color of the circle changed?
I am kind of at a loss, though I know that the method repaint() is involved. Please have a look at my code and tell me where I am going wrong or "painting" myself into a corner. Thanks!
package P3;
// ******************************************************************
// CirclePanel.java
//
// A panel with a circle drawn in the center and buttons on the
// bottom that move the circle.
// ******************************************************************
import java.awt.*;
import java.awt.Graphics;
import javax.swing.*;
import java.awt.event.*;
public class CirclePanel extends JPanel {
public JButton btnChoice;
private JButton btnRed;
private JButton btnYellow;
private JButton btnBlue;
private final int CIRCLE_SIZE = 50;
private int x, y;
private Color c;
//---------------------------------------------------------------
// Set up circle and buttons to move it.
//---------------------------------------------------------------
public CirclePanel(int width, int height) {
// Set coordinates so circle starts in middle
x = (width / 2) - (CIRCLE_SIZE / 2);
y = (height / 2) - (CIRCLE_SIZE / 2);
//set recentering coordinates - need to find a position relative to
//center of panel and not location of circle (for position reset)
c = Color.green;
// Need a border layout to get the buttons on the bottom
this.setLayout(new BorderLayout());
// Create buttons to move the circle
JButton left = new JButton("Left");
JButton right = new JButton("Right");
JButton up = new JButton("Up");
JButton down = new JButton("Down");
JButton center = new JButton("+");
// Add listeners to the buttons
left.addActionListener(new MoveListener(-20, 0));
right.addActionListener(new MoveListener(20, 0));
up.addActionListener(new MoveListener(0, -20));
down.addActionListener(new MoveListener(0, 20));
//reset circle position to start position
//center.addActionListener(new MoveListener());
// Need a panel to put the buttons on or they'll be on top of each other.
GridBagLayout layout = new GridBagLayout();
// create GridBagConstraints object "gbc" to position the buttons we want to use
GridBagConstraints gbc = null;
//position of up button
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 0;
gbc.insets = new Insets(0, 0, 3, 0);
layout.setConstraints(up, gbc);
//position of left button
gbc = new GridBagConstraints();
gbc.gridy = 1;
gbc.insets = new Insets(0, 0, 0, 3);
layout.setConstraints(left, gbc);
//position of center button
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 1;
layout.setConstraints(center, gbc);
//position of right button
gbc = new GridBagConstraints();
gbc.gridx = 2;
gbc.gridy = 1;
gbc.insets = new Insets(0, 3, 0, 0);
layout.setConstraints(right, gbc);
//position of down button
gbc = new GridBagConstraints();
gbc.gridx = 1;
gbc.gridy = 2;
gbc.insets = new Insets(3, 0, 0, 0);
layout.setConstraints(down, gbc);
// apply GridBagLayout to a JPanel
JPanel btnPanel = new JPanel(layout);
//add the buttons to the panel
btnPanel.add(left);
btnPanel.add(right);
btnPanel.add(up);
btnPanel.add(down);
btnPanel.add(center);
//new panel with buttons to choose colors
JPanel chooserBtnPnl = new JPanel();
chooserBtnPnl.setLayout(new GridLayout(1, 4, 3, 3));
//red button
btnRed = new JButton("Red");
btnRed.setBackground(c.RED);
btnRed.addActionListener(new ColorListener(Color.RED));
//yellow button
btnYellow = new JButton("Yellow");
btnYellow.setBackground(c.YELLOW);
btnYellow.addActionListener(new ColorListener(Color.YELLOW));
//blue button
btnBlue = new JButton("Blue");
btnBlue.setBackground(c.BLUE);
btnBlue.addActionListener(new ColorListener(Color.BLUE));
//button used for choosing a color with JColorChooser
btnChoic开发者_运维技巧e = new JButton("Choose Color");
btnChoice.addActionListener(new ColorListener());
chooserBtnPnl.add(btnRed);
chooserBtnPnl.add(btnYellow);
chooserBtnPnl.add(btnBlue);
chooserBtnPnl.add(btnChoice);
// Add the chooser panel to the top of the main panel
this.add(chooserBtnPnl, "North");
// Add the button panel to the bottom of the main panel
this.add(btnPanel, "South");
}
//---------------------------------------------------------------
// Draw circle on CirclePanel
//---------------------------------------------------------------
public void paintComponent(Graphics page) {
super.paintComponent(page);
page.setColor(c);
page.fillOval(x, y, CIRCLE_SIZE, CIRCLE_SIZE);
}
//---------------------------------------------------------------
// Class to listen for button clicks that move circle.
//---------------------------------------------------------------
private class MoveListener implements ActionListener {
private int dx;
private int dy;
//---------------------------------------------------------------
// Parameters tell how to move circle at click.
//---------------------------------------------------------------
public MoveListener(int dx, int dy) {
this.dx = dx;
this.dy = dy;
}
//---------------------------------------------------------------
// Change x and y coordinates and repaint.
//---------------------------------------------------------------
public void actionPerformed(ActionEvent e) {
x += dx;
y += dy;
repaint();
}
}
private class ColorListener implements ActionListener {
private Color color;
ColorListener(){}
//tells what color to change the circle to
public ColorListener(Color c) {
this.color = c;
}
//change color and repaint
public void actionPerformed(ActionEvent e) {
JColorChooser jcc = new JColorChooser();
if (e.getSource() == btnChoice) {
jcc.showDialog(btnChoice, "Choose Circle Color", Color.BLUE);
} else {
if (e.getSource() == btnRed) {
repaint();
} else if (e.getSource() == btnYellow) {
repaint();
} else if (e.getSource() == btnBlue) {
repaint();
}
}
}
}
}
and file MoveCircle.java
package P3;
// ******************************************************************
// MoveCircle.java
//
// Uses CirclePanel to display a GUI that lets the user move
// a circle by pressing buttons.
// ******************************************************************
import java.awt.*;
import javax.swing.*;
public class MoveCircle {
public static void main(String[] args) {
JFrame frame = new JFrame("MoveCircle");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500,500);
frame.getContentPane().add(new CirclePanel(400,300));
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
}
Actually you forgot to set the new color to your field c
(the color the circle is painted) in your ColorListener. The following code should do the trick.
// change color and repaint
public void actionPerformed(ActionEvent e) {
if (e.getSource() == btnChoice) {
JColorChooser jcc = new JColorChooser();
c = jcc.showDialog(btnChoice, "Choose Circle Color", Color.BLUE);
} else {
c = this.color;
}
repaint();
}
精彩评论