Okay, so I'm trying to make a smiley face program, when it first starts up it's supposed to show the default smiley face(this part works and it's great I guess)
But then it should give you two buttons to pick from the smile and the frown buttons which should redraw the faces to show one smiling or frowning but it doesn't work for some reason.
I've been reading about graphics and I know you're not supposed to call them from outside the paint() method so I changed my code accordingly and I can tell the buttons are working because I make them print out something each time but the actual redrawing isn't working. I've tried using repaint() and revalidate() as well. For some reason if you use repaint() it repaints more and more each time which is odd, but maybe it's supposed to behave that way?
Can someone please take a look at the code and let me know what you think is the problem or where I should be looking for a solution I've used java for a while but I never use graphics :/ I've read your supposed to use setVisible/setSize(or pack()) at the end and that actually helped with some issues I had earlier but I don't get what to do when you want to draw multiple things most examples only show drawing one thing.
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class JSmileFacePanel2 extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JButton smile = new JButton("SMILE");
JButton frown = new JButton("FROWN");
public JSmileFacePanel2() {
setLayout(new FlowLayout());
setTitle("JSmileFace-V2: Jose M. Tobar");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(frown);
add(smile);
setSize(800, 800);
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
//by default should show smiling
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
smile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("SMILE BUTTON CLICKED");
drawSmile(g);
}
});
frown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("FROWN BUTTON CLICKED");
drawFrown(g);
}
});
}
public void drawSmile(Graphics g) {
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
repaint();
}
public void drawFrown(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
repaint();
}
public static void main(String[] args) {
JSmileFacePanel2 js = new JSmileFacePanel2();
}
}
You are still calling painting methods outside the paint
method, because the actionPerformed
methods different methods than the paint
method. It doesn't matter that they are textually inside it, it's still a different method.
Also, you are repeatedly adding the action listeners every time that there is a repaint event, which will slow your application down to a halt and it will not repaint correctly either.
So, check whether you should smile or frown inside the paint
method and add the action listeners inside the constructor.
The code then becomes:
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class JSmileFacePanel2 extends JFrame {
private static final long serialVersionUID = 1L;
// by default should show smiling
private boolean doSmile = true;
JButton smile = new JButton("SMILE");
JButton frown = new JButton("FROWN");
public JSmileFacePanel2() {
setLayout(new FlowLayout());
setTitle("JSmileFace-V2: Jose M. Tobar");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(frown);
add(smile);
smile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("SMILE BUTTON CLICKED");
doSmile = true;
repaint();
}
});
frown.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("FROWN BUTTON CLICKED");
doSmile = false;
repaint();
}
});
setSize(800, 800);
setVisible(true);
}
public void paint(final Graphics g) {
super.paint(g);
if (doSmile) {
drawSmile(g);
} else {
drawFrown(g);
}
}
public void drawSmile(Graphics g) {
g.setColor(Color.YELLOW);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
}
public void drawFrown(Graphics g) {
g.setColor(Color.WHITE);
g.fillOval(200, 200, 500, 500);
g.setColor(Color.BLUE);
g.fillOval(300, 360, 50, 50);
g.setColor(Color.BLUE);
g.fillOval(600, 360, 50, 50);
g.drawArc(400, 400, 100, 40, 180, 185);
}
public static void main(String[] args) {
JSmileFacePanel2 js = new JSmileFacePanel2();
}
}