How to draw a mouth for a Smiley Face in Java - java

How do I get the mouth part of the smiley face? Do I use a polygon or oval...oval doesn't seem to make sense but I don't know?
here is my code:
import java.awt.Color;
import java.awt.Canvas;
import java.awt.Graphics;
public class HappyFace extends Canvas {
public HappyFace() {
setBackground(Color.BLACK);
}
public void paint(Graphics window) {
window.setColor(Color.YELLOW);
window.fillOval(250, 150, 350, 320);
window.setColor(Color.MAGENTA);
window.fillOval(300, 220, 90, 100);
window.fillOval(450, 220, 90, 100);
window.setColor(Color.WHITE);
window.drawOval(380, 320, 90, 100);
window.setColor(Color.GREEN);
}
}

Maybe a drawArc(...)
import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
public class FaceComponent extends JPanel
{
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawArc(100, 45, 80, 80, 0, 360);
g.setColor( Color.blue );
g.drawArc( 120, 70, 10, 10, 0, 360);
g.drawArc( 150, 70, 10, 10, 0, 360);
g.setColor( Color.magenta );
g.drawLine ( 140, 85, 140, 100 );
g.setColor( Color.red );
g.drawArc ( 110, 55, 60, 60, 0, -180 );
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(250, 250);
}
private static void createAndShowGUI()
{
JComponent face = new FaceComponent();
face.setForeground(Color.GREEN);
// face.setBackground(Color.YELLOW);
JPanel contentPane = new JPanel( new BorderLayout() );
contentPane.setBackground( Color.CYAN );
contentPane.add( face );
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane( contentPane );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

you are going to want to put an inverted arc or you will have a frowning face so you want to add
g.drawArc.invert(110, 55, 60, 60, 0, -180)
` import java.awt.*;
import java.awt.geom.*;
import java.awt.event.*;
import javax.swing.*;
public class FaceComponent extends JPanel
{
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawArc(100, 45, 80, 80, 0, 360);
g.setColor( Color.blue );
g.drawArc( 120, 70, 10, 10, 0, 360);
g.drawArc( 150, 70, 10, 10, 0, 360);
g.setColor( Color.magenta );
g.drawLine ( 140, 85, 140, 100 );
g.setColor( Color.red );
g.drawArc ( 110, 55, 60, 60, 0, -180 );
}
#Override
public Dimension getPreferredSize()
{
return new Dimension(250, 250);
}
private static void createAndShowGUI()
{
JComponent face = new FaceComponent();
face.setForeground(Color.GREEN);
// face.setBackground(Color.YELLOW);
JPanel contentPane = new JPanel( new BorderLayout() );
contentPane.setBackground( Color.CYAN );
contentPane.add( face );
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane( contentPane );
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}
`

Related

Java on Eclipse won't show the JPanel even when I add it to JFrame

These are the files. I have set JFrame to be visible, and have added JPanel to it, but still, the code only shows the window without anything in it.
import java.util.List;
import java.util.ArrayList;
import java.util.Random;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Collections;
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.setSize(350, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("My Empty Window");
frame.setVisible(true);
DrawingPanel panel = new DrawingPanel();
frame.add(panel);
frame.setVisible(true);
}
-------------DRAWINGPANEL FILE-------------------
import java.awt.Graphics;
import javax.swing.JPanel;
public class DrawingPanel extends JPanel {
public void painting(Graphics pen) {
pen.drawRect(50, 50, 20, 20);
pen.drawRect(100, 50, 40, 20);
pen.drawOval(200,50,20,20);
pen.drawOval(250, 50, 40, 20);
pen.drawString("Square", 50, 90);
pen.drawString("Rectangle", 100, 90);
pen.drawString("Cirlce", 200, 90);
pen.drawString("Oval", 250, 90);
pen.fillRect(50, 100, 20, 20);
pen.fillRect(100, 100, 40, 20);
pen.fillOval(250, 100, 20, 20);
pen.fillOval(250, 100, 40, 20);
pen.drawLine(50, 150, 300, 150);
pen.drawArc(50, 150, 200, 100, 0, 180);
pen.fillArc(100, 175, 200, 75, 90, 45);
}
}
Here's what I get after making your code runnable, fixing your JFrame method calls and fixing your drawing JPanel.
Swing applications should always start with a call to the SwingUtilities invokeLater method. This method ensures that the Swing components are created and executed on the Event Dispatch Thread.
You pack a JFrame. You set the preferred size of your drawing JPanel. This way, you know how big your drawing JPanel is, without worrying about the JFrame decorations.
Here's the complete runnable code.
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawingPanelExample implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new DrawingPanelExample());
}
#Override
public void run() {
JFrame frame = new JFrame("My Empty Window");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawingPanel panel = new DrawingPanel();
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
public DrawingPanel() {
this.setPreferredSize(new Dimension(350, 300));
}
#Override
protected void paintComponent(Graphics pen) {
super.paintComponent(pen);
pen.drawRect(50, 50, 20, 20);
pen.drawRect(100, 50, 40, 20);
pen.drawOval(200, 50, 20, 20);
pen.drawOval(250, 50, 40, 20);
pen.drawString("Square", 50, 90);
pen.drawString("Rectangle", 100, 90);
pen.drawString("Cirlce", 200, 90);
pen.drawString("Oval", 250, 90);
pen.fillRect(50, 100, 20, 20);
pen.fillRect(100, 100, 40, 20);
pen.fillOval(250, 100, 20, 20);
pen.fillOval(250, 100, 40, 20);
pen.drawLine(50, 150, 300, 150);
pen.drawArc(50, 150, 200, 100, 0, 180);
pen.fillArc(100, 175, 200, 75, 90, 45);
}
}
}
Try changing the method in DrawingPanel from painting to paint, which will get called when run. paint is a method inherited from JPanel.
Edit: As mentioned by NomadMaker, use paintComponent() not paint() here. Read this for more information.
You should override paintComponent like so:
...
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D pen = (Graphics2D) g;
...
}
Also some suggestions:
You can extending JComponent instead of JPanel (It should work both ways)
You can use setSize or setPreferredSize for your panel to fit it with your frame size.
You can only use setVisisble(true); only once after all of the configurations of your frame.
And add it to the center of the frame like so:
...
JFrame frame = new JFrame();
frame.setSize(350, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setTitle("My Empty Window");
DrawingPanel panel = new DrawingPanel();
panel.setPreferredSize(new Dimensions(350, 300));
frame.add(panel, BorderLayout.CENTER);
frame.setVisible(true);
...
On a side note:
Adding a layout manager may not be necessary and you can also replace setPreferredSize with setBounds like so:
panel.setBounds(0, 0, 350, 300);
frame.add(panel);
Where 0s are x and y coordinates respectively.

Overriding Method with MouseListener

I'm creating a Java program that uses Swing to draw a face, and then I am using MouseListener to respond to mouse clicks to make one of the eyes blink. How would I make one of the eyes blink using MouseListener? The method paint(Graphics g) can only be created once with that name, so if I want to repeat it and edit it under the MouseListener code with one of the eyes turned into a line for blinking, how would I do that?
Here is my code so far:
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Sans extends JPanel {
public void paint(Graphics g) {
super.paintComponent(g);
setSize(650, 650);
g.drawOval(110, 250, 500, 275);
g.setColor(new Color(226, 222, 217));
g.fillOval(110, 250, 500, 275);
g.drawOval(475, 300, 75, 75);
g.setColor(new Color(74, 199, 226));
g.fillOval(475, 300, 75, 75);
g.drawOval(505, 330, 15, 15);
g.setColor(new Color(0, 0, 0));
g.fillOval(505, 330, 15, 15);
g.drawOval(175, 300, 75, 75);
g.setColor(new Color(0, 0, 0));
g.fillOval(175, 300, 75, 75);
g.drawOval(205, 330, 15, 15);
g.setColor(new Color(232, 255, 243));
g.fillOval(205, 330, 15, 15);
g.drawOval(350, 375, 20, 50);
g.setColor(new Color(0, 0, 0));
g.fillOval(350, 375, 20, 50);
g.drawArc(290, 360, 150, 150, 180, 180);
g.setColor(new Color(255, 255, 255));
g.fillArc(290, 360, 150, 150, 180, 180);
}
public static void main(String[] args) {
Font font = new Font("TimesRoman", Font.PLAIN, 15);
JFrame frame = new JFrame();
Sans spook = new Sans();
frame.add(spook);
frame.setSize(750, 750);
frame.setTitle("I'VE GOTTEN A TON OF WORK DONE TODAY. A SKELE-TON.");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
public class BlinkHandler implements MouseListener {
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
}
}

Unable to load a Jbutton to JFrame

I am trying to add a button to my form to bring the user back to the previous screen. I can display the form and drawn objects but unable to get the button to display.
Any help would be greatly appreciated
public static JButton mainMenue = new JButton("Main Menue");
public static void main(String[] args)
{
//creating and setting the values for the Jframe
JFrame form = new JFrame();
Color backColour = new Color(153,153,153);
form.getContentPane().setBackground(backColour);
form.add(mainMenue);
mainMenue.setVisible(true);
mainMenue.setLocation(100,100);
form.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
form.setBounds(30, 30, 1000, 1000);
form.getContentPane().add(new Layout());
form.setVisible(true);
}
#Override
public void paint(Graphics g)
{
//creating the seating
Font titleFont = new Font("Dialog", Font.BOLD, 36);
Font subTitleFont = new Font("Dialog", Font.BOLD, 14);
Graphics2D g2 = (Graphics2D) g;
super.paint(g);
g.setColor(Color.blue);
g.drawLine(225, 60, 255, 60);
g.drawLine(340, 60, 400, 60);
g.drawLine(400, 60, 400, 135);
g.drawLine(400, 135, 650, 135);
g.drawLine(650, 135, 650, 60);
g.drawLine(650, 60, 680, 60);
g.drawLine(765, 60, 825, 60);
g.drawLine(225, 600, 450, 600);
g.drawLine(600, 600, 850, 600);

Graphics2D on JPanel and adding JPanel to JFrame

I am trying to draw on a JPanel and add it to a JFrame in my createAndShowGui method. I have tried a few different things: creating the JPanel in the createAndShowGui method, adding the drawing to the JFrame, etc... The one thing that is common, I don't see any of my graphics!
Note: I am able to get the graphics to display in a JTabbedPane but not on a JPanel, which is what I actually want them to show up on to make the code more object oriented.
Edit:
Here is the working concept self contained example:
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
public class DrawPanelMain extends JPanel {
/*
* Variables used to set the value of preferred height and width
*/
public static final double version = 0.0;
JPanel switchPanel = new JPanel();
JPanel testPanel = new JPanel();
JPanel btnPanel = new JPanel();
DrawEllipses drawEllipses = new DrawEllipses(POINT_LIST);
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
initializePointList();
createAndShowGui();
}
});
}
public static java.util.List<Point> POINT_LIST = new ArrayList<>();
/*
* This loop will initialize POINT_LIST with the set of points for drawing the ellipses.
* The for each loop initializes points for the top row and the second for loop draws the
* right triangle.
*/
public static void initializePointList() {
int ellipsePointsYCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620};
int ellipsePointsXCoordinate[] = {140, 200, 260, 320, 380, 440, 500, 560, 620, 680};
int xx = 80;
for (int aXt : ellipsePointsXCoordinate) {
POINT_LIST.add(new Point(aXt, xx));
}
for (int i = 0; i < ellipsePointsYCoordinate.length; i++) {
for (int j = i; j < ellipsePointsYCoordinate.length; j++) {
POINT_LIST.add(new Point(ellipsePointsXCoordinate[i], ellipsePointsYCoordinate[j]));
}
}
}
public DrawPanelMain() {
testPanel.setBackground(Color.RED);
switchPanel.add(drawEllipses);
setLayout(new BorderLayout());
add(switchPanel, BorderLayout.CENTER);
add(testPanel, BorderLayout.EAST);
add(btnPanel, BorderLayout.SOUTH);
getPreferredSize();
btnPanel.add(new JButton(new AddSwitchAction("Add Switch Panel")));
}
public static void createAndShowGui() {
JFrame frame = new JFrame("RF Connection Panel " + version);
frame.setLayout(new BorderLayout());
frame.add(new DrawPanelMain());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationByPlatform(false);
//frame.setLocationRelativeTo(null);
frame.pack();
frame.setVisible(true);
}
/*
* AddSwitchAction will add a new pane to the tabbedPane when the add switch button is clicked
*/
private class AddSwitchAction extends AbstractAction {
public AddSwitchAction(String name) {
super(name);
int mnemonic = (int) name.charAt(0);
putValue(MNEMONIC_KEY, mnemonic);
}
#Override
public void actionPerformed(ActionEvent e) {
int index = 0;
DrawEllipses tabComponent = new DrawEllipses(POINT_LIST);
switchPanel.add(tabComponent, index++);
}
}
}
#SuppressWarnings("serial")
class DrawEllipses extends JPanel {
private final int PREF_W = 750; //Window width
private final int PREF_H = 750; //Window height
private static final int OVAL_WIDTH = 30;
private static final Color INACTIVE_COLOR = Color.RED;
private static final Color ACTIVE_COLOR = Color.green;
private java.util.List<Point> points;
private java.util.List<Ellipse2D> ellipses = new ArrayList<>();
private Map<Ellipse2D, Color> ellipseColorMap = new HashMap<>();
/*
* This method is used to populate "ellipses" with the initialized ellipse2D dimensions
*/
public DrawEllipses(java.util.List<Point> points) {
this.points = points;
for (Point p : points) {
int x = p.x - OVAL_WIDTH / 2;
int y = p.y - OVAL_WIDTH / 2;
int w = OVAL_WIDTH;
int h = OVAL_WIDTH;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, w, h);
ellipses.add(ellipse);
ellipseColorMap.put(ellipse, INACTIVE_COLOR);
}
MyMouseAdapter mListener = new MyMouseAdapter();
addMouseListener(mListener);
addMouseMotionListener(mListener);
}
/*
* paintComponent is used to paint the ellipses
*/
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
for (Ellipse2D ellipse : ellipses) {
g2.setColor(ellipseColorMap.get(ellipse));
g2.fill(ellipse);
g2.setColor(Color.BLACK);
g2.setStroke(new BasicStroke(2));
g2.draw(ellipse);
}
/*
* Set the font characteristics, color, and draw the row labels.
*/
g.setFont(new Font("TimesRoman", Font.BOLD, 18));
g.setColor(Color.BLACK);
//Along the top row
g.drawString("External Port", 10, 50);
g.drawString("1", 135, 50);
g.drawString("2", 195, 50);
g.drawString("3", 255, 50);
g.drawString("4", 315, 50);
g.drawString("5", 375, 50);
g.drawString("6", 435, 50);
g.drawString("7", 495, 50);
g.drawString("8", 555, 50);
g.drawString("9", 615, 50);
g.drawString("10", 672, 50);
//Along the Y-axis
g.drawString("Radio 2", 40, 145);
g.drawString("3", 90, 205);
g.drawString("4", 90, 265);
g.drawString("5", 90, 325);
g.drawString("6", 90, 385);
g.drawString("7", 90, 445);
g.drawString("8", 90, 505);
g.drawString("9", 90, 565);
g.drawString("10", 90, 625);
//Along the X-Axis
g.drawString("1", 135, 670);
g.drawString("2", 195, 670);
g.drawString("3", 255, 670);
g.drawString("4", 315, 670);
g.drawString("5", 375, 670);
g.drawString("6", 435, 670);
g.drawString("7", 495, 670);
g.drawString("8", 555, 670);
g.drawString("9", 615, 670);
//Draws a 3DRect around the top row of ellipse2D objects
g2.setColor(Color.lightGray);
g2.draw3DRect(120, 60, 580, 40, true);
g2.draw3DRect(121, 61, 578, 38, true);
g2.draw3DRect(122, 62, 576, 36, true);
}
/*
* MouseAdapter is extended for mousePressed Event that detects if the x, y coordinates
* of a drawn ellipse are clicked. If the color is INACTIVE it is changed to ACTIVE and
* vice versa.
*/
private class MyMouseAdapter extends MouseAdapter {
#Override
/*
* When mousePressed event occurs, the color is toggled between ACTIVE and INACTIVE
*/
public void mousePressed(MouseEvent e) {
Color c;
for (Ellipse2D ellipse : ellipses) {
if (ellipse.contains(e.getPoint())) {
c = (ellipseColorMap.get(ellipse) == INACTIVE_COLOR) ? ACTIVE_COLOR : INACTIVE_COLOR;
ellipseColorMap.put(ellipse, c);
}
}
repaint();
}
}
/*
* This method will set the dimensions of the JFrame equal to the preferred H x W
*/
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
}
switchPanel.add(title, tabComponent);
By default a JPanel uses a FlowLayout which respects the preferred size of the component. The preferred size of your component is (0, 0) so there is nothing to paint. Also, you are using the "title" string which is incorrect (and obsolete as has already been mentioned). That string represents a constraint for the layout manager. You can't just make up a String value. In any case FlowLayout does not accept any contraints so you should just be using:
switchPanel.add(tabComponent);
I am trying to draw on a JPanel
When doing custom painting you need to override the getPreferredSize() of the panel so the layout manager can use the information. If you don't override this method then the size is (0, 0) so there is nothing to paint.
Edit:
First some general comments:
Don't hardcode sizes of the panel. Your hardcoded size of (1200 x 750) is too large for my monitor. If you want full screen then use frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
Post code that you are actually testing. As has already been mentioned your posted code doesn't even add the "switchPanel" to the frame.
You haven't updated the code to show how you override the getPreferredSize() method.
Finally, I see in your code that you add the panel dynamically to the visible GUI. In this case the general code should be:
panel.add(....);
panel.revalidate(); // to invoke the layout manager otherwise size is still (0, 0)
panel.repaint();
You are adding DrawEllipses instances to switchPanel using an obsolete method add(String,Component); you should use something like add(component, index). Also, You don't add switchPanel to anything (commented out in DrawPanelMain ctor).

why when i add a for loop my jframe turns black?

I am trying to make a flashing light in my jframe by creating a list of the colors and then cycling through them with a for loop and then repainting. but when I add a for loop to my code the whole thing bugs out and I get a black screen and it frezzes. Why is this happening?
public class bb {
static Color colors[] = {Color.ORANGE, Color.GRAY};
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(400, 525);
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
JButton smallerButton = new JButton("Flash");
JButton largerButton = new JButton("Steady");
JPanel southPanel = new JPanel();
southPanel.add(smallerButton);
southPanel.add(largerButton);
frame.add(southPanel, BorderLayout.SOUTH);
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(180, 110, 10, 30);
g.drawRect(180, 140, 9, 30);
g.fillRect(180, 170, 10, 30);
g.drawRect(180, 200, 9, 30);
g.fillRect(180, 230, 10, 30);
g.drawRect(180, 260, 9, 30);
g.fillRect(180, 290, 10, 30);
g.drawRect(180, 310, 9, 30);
g.fillRect(180, 340, 10, 30);
int i = 0;
g.setColor(colors[i]);
for(i=0; i <= colors.length; i++){
g.fillOval(160, 70, 50, 50);
if (i ==colors.length){
i=0;
}
frame.repaint();
}
smallerButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String action = e.getActionCommand();
if (action.equals("Flash")){
}
}
});
}
};
frame.add(panel);
frame.validate();
}
}
This statement resets your loop index to 0 causing it to loop indefinitely blocking the EDT
if (i == colors.length) {
i = 0;
}
since you exceed the last array index in the for statement.
Take a look at using a Swing Timer to achieve this functionality.

Categories