Related
i need some help with this code.
I already have the functions of paint the objects and clear the objects from the window but how i can make that when i make a resize or when i minimize the windows the objects doesn't disappear?
This is the code i have at the moment:
public class miClass implements ActionListener{
JFrame ventana;
JPanel panel;
JButton p,c;
Graphics g;
Image img;
Font font1,font2,font3;
public miClass(){
ventana = new JFrame("Aplicacion.");
p = new JButton("P");
c = new JButton("C");
panel = new JPanel();
ventana.setLayout(null);
ventana.setBounds(100,100,600,600);
ventana.getContentPane().add(panel);
ventana.add(p);
p.addActionListener(this);
c.addActionListener(this);
p.setBounds(20,20,120,45);
ventana.add(c);
c.setBounds(200,20,120,45);
ventana.setFocusable(true);
ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ventana.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
g = ventana.getGraphics();
Toolkit tool = Toolkit.getDefaultToolkit();
img = tool.getImage("prueba.png");
g.drawImage(img,0,100,null);
font1 = new Font("Helvetica",Font.PLAIN,22);
g.setFont(font1);
g.drawString("Hola", 100, 300);
font2 = new Font("TimesRoman",Font.BOLD,20);
g.setFont(font2);
g.drawString("Mundo", 100, 340);
font3 = new Font("Courier",Font.BOLD+Font.ITALIC,25);
g.setFont(font3);
g.drawString("WASAAAA!", 100, 400);
g.setColor(Color.green);
g.drawOval(300, 200, 150, 100);
g.setColor(Color.red);
g.drawArc(200, 400, 250, 64, 135, 46);
g.setColor(Color.blue);
g.drawLine(400, 200, 150, 100);
g.setColor(Color.magenta);
g.drawRect(300, 250, 160, 50);
g.setColor(Color.cyan);
g.fillRect(100,400,20,240);
g.setColor(Color.lightGray);
g.fillOval(100,340,14,30);
if(e.getSource() == c){ //Clean all objects on the window//
g.clearRect(0,100,900,800);
}
}
public static void main(String args[]){
miClass GUI = new miClass();
}
}
Your frame is reset to its initial state when it is resized, and your code only redraws it when a button is clicked, not when it is resized. The paintComponent method on any subclass of Component is called after the parent frame is resized, so you can fix this issue by overriding that method.
package SO;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class miClass implements ActionListener {
JFrame ventana;
JPanel panel;
JButton p, c;
Graphics g;
Image img;
Font font1, font2, font3;
public miClass() {
ventana = new JFrame("Aplicacion.");
p = new JButton("P");
c = new JButton("C");
panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
// your stuff
font1 = new Font("Helvetica", Font.PLAIN, 22);
g.setFont(font1);
g.drawString("THIS GETS REDRAWN", 100, 300);
}
};
panel.setSize(400, 400);
ventana.setLayout(null);
ventana.setBounds(100, 100, 600, 600);
ventana.getContentPane().add(panel);
ventana.add(p);
p.addActionListener(this);
c.addActionListener(this);
p.setBounds(20, 20, 120, 45);
ventana.add(c);
c.setBounds(200, 20, 120, 45);
ventana.setFocusable(true);
ventana.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ventana.setVisible(true);
}
public void actionPerformed(ActionEvent e) {
g = panel.getGraphics();
Toolkit tool = Toolkit.getDefaultToolkit();
img = tool.getImage("prueba.png");
g.drawImage(img, 0, 100, null);
font1 = new Font("Helvetica", Font.PLAIN, 22);
g.setFont(font1);
g.drawString("Hola", 100, 300);
font2 = new Font("TimesRoman", Font.BOLD, 20);
g.setFont(font2);
g.drawString("Mundo", 100, 340);
font3 = new Font("Courier", Font.BOLD + Font.ITALIC, 25);
g.setFont(font3);
g.drawString("WASAAAA!", 100, 400);
g.setColor(Color.green);
g.drawOval(300, 200, 150, 100);
g.setColor(Color.red);
g.drawArc(200, 400, 250, 64, 135, 46);
g.setColor(Color.blue);
g.drawLine(400, 200, 150, 100);
g.setColor(Color.magenta);
g.drawRect(300, 250, 160, 50);
g.setColor(Color.cyan);
g.fillRect(100, 400, 20, 240);
g.setColor(Color.lightGray);
g.fillOval(100, 340, 14, 30);
if (e.getSource() == c) { // Clean all objects on the window//
g.clearRect(0, 100, 900, 800);
}
}
public static void main(String args[]) {
miClass GUI = new miClass();
}
}
package easteregg;
import java.awt.Graphics;
import javax.swing.JComponent;
import javax.swing.JFrame;
class MyCanvas extends JComponent {
public void paint(Graphics g) {
g.drawOval (100, 20, 110, 160);
}
}
public class EasterEgg {
public static void main(String[] a) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 300);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}
my problem is i dont know how to put lines inside the oval
i want to make a easterEgg please help me
i have modified the paint method to draw one pattern please check the below code
public void paint(Graphics g) {
g.drawOval (100, 20, 110, 160);
g.drawLine(120, 40, 140, 60);
g.drawLine(140, 60, 150, 40);
g.drawLine(150, 40, 170, 60);
g.drawLine(170, 60, 190,40);
}
and the output is
this is just a hint to draw lines but better to create one method which will draw that pattern form one end to other end of the oval
I'm having trouble with my buttons. I know they're working because I've tested them out by exiting the problem through System.exit. Here is what my output looks like:
http://imgur.com/Ks7mIFa
When I click the close button, the handle on the switch should redraw to the other side and the close button should change to open. When I click the open button, it should do the opposite. However, the buttons aren't doing anything. What am I doing wrong?
public class ProgrammingAssignment2 {
public static void main(String[] args) {
boolean ison = false;
// Objects
Circuit circuitObject = new Circuit();
Controller controllerObject = new Controller();
Draw drawObject = new Draw();
AllListeners listenerObject = new AllListeners();
drawObject.window();
circuitObject.buttons(drawObject, ison);
controllerObject.openFile("Programming Assignment 2 Data.txt", drawObject);
}
}
Class circuit just creates the buttons
import javax.swing.JButton;
public class Circuit {
public void buttons(Draw drawObject, boolean ison) {
AllListeners listenerObject = new AllListeners();
if (ison == true) {
JButton openButton = new JButton("Close");
openButton.addActionListener(listenerObject);
openButton.setBounds(200, 100, 50, 20);
drawObject.add(openButton);
} else if (ison == false) {
JButton closeButton = new JButton("Open");
closeButton.addActionListener(listenerObject);
closeButton.setBounds(50, 100, 50, 20);
drawObject.add(closeButton);
}
}
}
Draw class does most of the work. It creates all the graphics and reads in a text file that has the titles of each object(like switch and lightbulb).
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.JFrame;
import java.awt.Graphics;
public class Draw extends JFrame {
private String[] line = new String[5];
private int counter = 0;
private boolean ison;
public void window() {
setSize(500, 500);
setTitle("Programming Assignment 2");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public void readFile(String filename) {
counter = 1;
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader(filename));
for (int i = 0; i < 4; i++) {
line[i] = br.readLine();
}
} catch (FileNotFoundException e) {
String error = "File was not found";
System.out.println(error.toString());
System.out.println("or could not be opened.");
} catch (IOException e) {
System.out.println("Error reading from file.");
} finally {
try {
br.close();
} catch (IOException e) {
System.out.println("Error closing file.");
}
}
}
public void paint(Graphics g) {
Circuit circuitObject = new Circuit();
super.paint(g);
if (ison == true) {
turnon(g);
circuitObject.buttons(this, ison);
} else {
turnoff(g);
}
}
public void setisOn() {
ison = true;
}
public void setisOff() {
ison = false;
}
public void turnoff(Graphics g) {
// Title
g.drawString(line[0], 150, 40);
//Switch
g.drawString(line[2], 130, 190);
g.drawRect(100, 150, 100, 20);
g.drawOval(115, 155, 10, 10);
g.drawOval(175, 155, 10, 10);
g.drawArc(140, 140, 20, 20, 180, -180);
//off switch
g.drawLine(160, 150, 182, 133);
g.drawLine(157, 142, 173, 128);
g.drawLine(173, 128, 182, 133);
//Power Supply
g.drawString(line[1], 50, 420);
g.drawRect(50, 320, 50, 80);
g.drawLine(50, 320, 70, 290);
g.drawLine(100, 320, 120, 290);
g.drawLine(70, 290, 120, 290);
g.drawLine(120, 370, 120, 290);
g.drawLine(120, 370, 100, 400);
//plus
g.drawLine(94, 310, 100, 310);
g.drawLine(97, 307, 97, 313);
// minus
g.drawLine(100, 300, 107, 300);
// pliers
g.drawRect(70, 305, 5, 10);
g.drawRect(90, 288, 5, 10);
//lightbulb
g.drawString(line[3], 400, 250);
g.drawRect(400, 200, 20, 20);
g.drawOval(395, 170, 30, 30);
// pliers
g.drawRect(400, 220, 5, 10);
g.drawRect(415, 220, 5, 10);
// plus wire to switch
g.drawLine(72, 305, 120, 160);
//bulb to switch
g.drawLine(180, 160, 400, 230);
//bulb to minus
g.drawLine(90, 290, 420, 230);
}
public void turnon(Graphics g) {
// Title
g.drawString(line[0], 150, 40);
//Switch
g.drawString(line[2], 130, 190);
g.drawRect(100, 150, 100, 20);
g.drawOval(115, 155, 10, 10);
g.drawOval(175, 155, 10, 10);
g.drawArc(140, 140, 20, 20, 180, -180);
//on switch
g.drawLine(140, 150, 122, 133);
g.drawLine(143, 142, 129, 128);
g.drawLine(122, 133, 129, 128);
//Power Supply
g.drawString(line[1], 50, 420);
g.drawRect(50, 320, 50, 80);
g.drawLine(50, 320, 70, 290);
g.drawLine(100, 320, 120, 290);
g.drawLine(70, 290, 120, 290);
g.drawLine(120, 370, 120, 290);
g.drawLine(120, 370, 100, 400);
//plus
g.drawLine(94, 310, 100, 310);
g.drawLine(97, 307, 97, 313);
// minus
g.drawLine(100, 300, 107, 300);
// pliers
g.drawRect(70, 305, 5, 10);
g.drawRect(90, 288, 5, 10);
//lightbulb
g.drawString(line[3], 400, 250);
g.drawRect(400, 200, 20, 20);
g.drawOval(395, 170, 30, 30);
// pliers
g.drawRect(400, 220, 5, 10);
g.drawRect(415, 220, 5, 10);
// plus wire to switch
g.drawLine(72, 305, 120, 160);
//bulb to switch
g.drawLine(180, 160, 400, 230);
//bulb to minus
g.drawLine(90, 290, 420, 230);
}
}
Controller doesn't do much right.
public class Controller {
public void openFile(String filename, Draw drawObject) {
drawObject.readFile(filename);
}
}
And this is the actionlisterner class
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
public class AllListeners implements ActionListener {
public void actionPerformed(ActionEvent e) {
Circuit circuitObject = new Circuit();
Draw drawObject = new Draw();
String buttonString = e.getActionCommand();
if (buttonString.equals("Close")) {
drawObject.setisOn();
drawObject.repaint();
} else if (buttonString.equals("Open")) {
drawObject.setisOff();
drawObject.repaint();
} else {
System.out.println("Unexpected error.");
}
}
}
You've got lots of major problems with this code including:
Drawing directly within a JFrame's paint method, something fraught with problems as you risk messing up the JFrame's own complicated painting.
Placing program logic within a painting method, a method you don't have full control over when or if it fires, and one that you shouldn't slow down
Placing component creation code within a painting method.
Trying to add multiple JButtons willy nilly rather than changing the state of an existing component.
Creating multiple Circuit objects.
Trying to use absolute positioning via setBounds(...) to place a component in a container that uses BorderLayout.
I suggest that you
Start over and scrap this code.
Draw only in a JPanel's paintComponent method, just as the tutorials will tell you to do.
Create your buttons once and only once and add them to your GUI.
Get all program logic out of the painting (here paintComponent) method, and all object state changing outside of that method as they are for painting and painting only.
Instead the logic should belong to the controller, and which should be notified of the button push.
So consider having the button push notify the control what was pushed,
the control changes the state of the program (changes variables)
and then it calls repaint so that the paintComponent method can use those variables to change its drawing.
Also, avoid using setBounds and null layouts if at all possible, and instead use layout managers/borders/nested JPanels to help you place your components.
I am trying to make a triangle out of a sloop can a made in the graphics panel but I cant seem to get the code to work right. this is what I have so far.
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
public class PyramidSoupCans {
/**
* #param args
*/
public static void main(String[] args) {
DrawingPanel panel = new DrawingPanel(800, 800);
panel.setBackground(new Color(219, 204, 186));
Graphics g = panel.getGraphics();
for(int i=1;i<=10;i++){
for(int j=1;j<=10-i; j++){
System.out.print(" ");
}
for (int k=1;k<=2 * i-1;k++){
draw_can( g, i, k);
}
System.out.println();
}}
public static void draw_can(Graphics g, int x, int y){
int sizeX = 225;
int sizeY = 340;
int cornerX = 37;
int cornerY = 80;
g.setColor(new Color(138, 138, 138));
g.fillRoundRect(cornerX, 246, sizeX, 180, 150, 45);
g.setColor(new Color(243, 243, 243));
g.fillRoundRect(cornerX, cornerY, sizeX, sizeY, 150, 45);
g.setColor(new Color(162,22,5));
g.fillRoundRect(cornerX, 70, sizeX, 190, 150, 45);
g.setColor(new Color(138, 138, 138));
g.fillOval(cornerX, 65, sizeX, 45);
g.setColor(Color.white);
g.setFont(new Font("Serif",Font.BOLD+Font.ITALIC,45));
g.drawString("Campbell's",45,150);
g.setFont(new Font("SanSerif",Font.BOLD,20));
g.drawString("CONDENSED",85,200);
g.setColor(new Color(162,22,5));
g.setFont(new Font("SanSerif",Font.BOLD,40));
g.drawString("TOMATO",60,360);
g.setFont(new Font("Serif",Font.BOLD,40));
g.setColor(new Color(157, 131, 82));
g.fillOval(113, 223, 70, 70);
g.drawString("SOUP",95,410);
}}
I am trying to make a triangle out of a sloop can a made in the graphics panel but I cant seem to get the code to work right. this is what I have so far.
That's all. Thanks
I wasn't able to make a triangle, but I did get the soup can to draw.
I made lots of changes to your code. I did keep your class name, PyramidSoupCans.
The important changes include.
I decided to use Swing components, since you named a DrawingPanel that you didn't include as part of your code.
You always start a Swing application with a call to the SwingUtilities invokeLater method. This ensures that the Swing components are created and updated on the Event Dispatch thread.
I created a drawing panel from a JPanel, and put the JPanel in a JFrame with some basic decorations.
I put your drawing code in the place where Swing provides a Graphics object to draw on. You should always override the JPanel paintComponent method when you want to draw on a Swing GUI.
Here's the code:
package com.ggl.testing;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class PyramidSoupCans implements Runnable {
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new PyramidSoupCans());
}
#Override
public void run() {
frame = new JFrame("Pyramid Soup Cans");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawingPanel panel = new DrawingPanel(300, 500);
frame.add(panel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = -4147433638611078320L;
public DrawingPanel(int width, int height) {
this.setPreferredSize(new Dimension(width, height));
this.setBackground(new Color(219, 204, 186));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int sizeX = 225;
int sizeY = 340;
int cornerX = 37;
int cornerY = 80;
g.setColor(new Color(138, 138, 138));
g.fillRoundRect(cornerX, 246, sizeX, 180, 150, 45);
g.setColor(new Color(243, 243, 243));
g.fillRoundRect(cornerX, cornerY, sizeX, sizeY, 150, 45);
g.setColor(new Color(162, 22, 5));
g.fillRoundRect(cornerX, 70, sizeX, 190, 150, 45);
g.setColor(new Color(138, 138, 138));
g.fillOval(cornerX, 65, sizeX, 45);
g.setColor(Color.white);
g.setFont(new Font("Serif", Font.BOLD + Font.ITALIC, 45));
g.drawString("Campbell's", 45, 150);
g.setFont(new Font("SanSerif", Font.BOLD, 20));
g.drawString("CONDENSED", 85, 200);
g.setColor(new Color(162, 22, 5));
g.setFont(new Font("SanSerif", Font.BOLD, 40));
g.drawString("TOMATO", 60, 360);
g.setFont(new Font("Serif", Font.BOLD, 40));
g.setColor(new Color(157, 131, 82));
g.fillOval(113, 223, 70, 70);
g.drawString("SOUP", 95, 410);
}
}
}
I am creating a Towers of Hanoi game and have sucedded in printing the shapes with a time delay (that part of the code has been removed while I try to get all the ovals where they are supposed to be) I am wondering how I would go about removing the circle. As you can see I have tried the clearRect(); method but that doesn't work. Is there a way I can set if the method is visible on JPanel since each circle has its own method? I think that would be the easiest way but if anyone has a better idea go for it! Thanks for any help and I have attached my code
package towersofhanoi;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.Object;
/*g.fillOval(60 = horizontal distance , 540= vertical distance, 400 = width, 60 = height) */
public class TowersOfHanoi extends JPanel {
private int clock = 0;
private Color circles = new Color(176, 56, 251);
public static void main(String[] args) {
// Print the shapes and frame
TowersOfHanoi drawRectangle = new TowersOfHanoi();
JFrame frame = new JFrame("Towers of Hanoi");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(drawRectangle);
frame.setSize(1250, 800);
frame.setVisible(true);
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
drawRectangle.nextFrame();
drawRectangle.repaint();
}
});
timer.setRepeats(true);
timer.start();
}
public void nextFrame() {
clock++;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
frame1(g);
frame2(g);
frame3(g);
frame4(g);
frame5(g);
frame6(g);
frame7(g);
frame8(g);
frame9(g);
}
private Color frame1(Graphics g) {
Color pegs = new Color(251, 129, 56);
g.setColor(pegs);
// peg 1
g.fillRect(250, 300, 25, 450);
// peg 2
g.fillRect(600, 300, 25, 450);
// peg 3
g.fillRect(950, 300, 25, 450);
// bottom
g.fillRect(200, 700, 825, 50);
// create a color for circles
// cirle 7 (Labeled from bottom to top)
g.setColor(circles);
g.fillOval(60, 640, 400, 60);
g.setColor(Color.BLACK);
g.drawOval(60, 640, 400, 60);
return circles;
}
private void frame2(Graphics g) {
// circle 6
g.setColor(circles);
g.fillOval(85, 580, 350, 60);
g.setColor(Color.BLACK);
g.drawOval(85, 580, 350, 60);
}
private void frame3(Graphics g) {
// circle 5
g.setColor(circles);
g.fillOval(110, 520, 300, 60);
g.setColor(Color.BLACK);
g.drawOval(110, 520, 300, 60);
}
private void frame4(Graphics g) {
// circle 4
g.setColor(circles);
g.fillOval(135, 465, 250, 55);
g.setColor(Color.BLACK);
g.drawOval(135, 465, 250, 55);
}
private void frame5(Graphics g) {
// circle 3
g.setColor(circles);
g.fillOval(160, 420, 200, 45);
g.setColor(Color.BLACK);
g.drawOval(160, 420, 200, 45);
}
private void frame6(Graphics g) {
// circle 2
g.setColor(circles);
g.fillOval(185, 380, 150, 40);
g.setColor(Color.BLACK);
g.drawOval(185, 380, 150, 40);
}
private void frame7(Graphics g) {
// circle 1
g.setColor(circles);
g.fillOval(210, 345, 100, 35);
g.setColor(Color.BLACK);
g.drawOval(210, 345, 100, 35);
}
public void frame8(Graphics g) {
g.clearRect(210, 345, 100, 35);
g.setColor(circles);
g.fillOval(560, 665, 100, 35);
g.setColor(Color.BLACK);
g.drawOval(560, 665, 100, 35);
}
public void frame9(Graphics g) {
g.clearRect(185, 380, 150, 40);
g.setColor(circles);
g.fillOval(890, 660, 150, 40);
g.setColor(Color.BLACK);
g.drawOval(890, 660, 150, 40);
}
}
I am wondering how I would go about removing the circle.
The super.paintComponent(...) will clear the painting on the panel so that is all the is needed.
As you can see I have tried the clearRect();
It is not needed (see my comment above), but then you invoke the fillOval(...) and drawOval(...) methods again so the painting is redone. So the code is doing exactly as you asked it to do.
Is there a way I can set if the method is visible on JPanel
You need a Boolean indicator telling the paint method what to do. Something like:
if (paintOval1)
frame1(g);
if (paintOval2)
frame2(g);
Of course that is approach is very brute force and not a very good approach if for say you have 100 circles to paint. The code become too big.
So, instead you should create a custom class that contains four properties (x, y, width, height, isPainted). Then you create an instance of this class for each circle and add the class to an ArrayList. Something like:
ArrayList<CustomClass> circles = new ArrayList<CustomClass>();
circles.add( new CustomClass(60, 640, 400, 60, true) );
circles.add( new CustomClass(85, 580, 350, 60, true) );
Then in the paintCompnent() method your code becomes simpler:
for (CustomClass circle: circles.get)
{
if (circle.isPainted())
{
g.setColor(...);
g.fillOval(circle.getX(), circle,getY(), circle.getWidth(), circle.getHeight());
...
}
}
Finally you would need a method to change the state of painting a circle. Something like:
pubic void setCirclePainted(int circle, Boolean isPainted)
{
CustomClass circle = circles.get(circle);
circle.setPainted( isPainted );
}
So the key for you is to create your "CustomClass" and give it a proper name. Then you need to implement all the getter/setter methods of the class so you can access the properties of the class.
I actually found that the easiest way for me to understand and do was to use else and else if statements to display the shape based on time. Thanks for the other suggestions though!
public void paintComponent(Graphics g) {
super.paintComponent(g);
frame1(g);
frame2(g);
frame3(g);
frame4(g);
if (clock<= 5) {
frame5(g);
}
else if(clock >= 6) {
frame9(g);
}
frame6(g);
frame7(g);
frame8(g);
}