I have to write a program using applet it should have 3 Button line,rect,circle.Upon clicking on them the desired shape should be drawn.
I have written the following code but it is showing error that Graphics is not initialized.
What to do now?
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Drawshapes extends Applet implements ActionListener
{
Button line,rect,circle;
public void init()
{
line=new Button("Line");
rect=new Button("Rectangle");
circle=new Button("Circle");
add(line);
add(circle);
add(rect);
line.addActionListener(this);
rect.addActionListener(this);
circle.addActionListener(this);
}
public void paint(Graphics g)
{
}
public void actionPerformed(ActionEvent ae)
{
Graphics g;
if(ae.getSource()==line)
{
g.drawLine(0,100,100,10);
}
else if(ae.getSource()==rect)
{
g.drawRect(10,10,60,50);
}
else
{
g.drawOval(10,10,50,50);
}
}
}
As with all local variables, the Graphics g is required to be initialized. However, doing custom painting from the ActionListener is a bad idea. Use the Graphics object in the paint method which has been properly instantiated.
Set a flag in the ActionListener and then call repaint:
For example in ActionListener for line:
drawLine = true;
repaint();
paint:
#Override
public void paint(Graphics g) {
super.paint(g);
if (drawLine) {
g.drawLine(0, 100, 100, 10);
} else if (drawRect) {
g.drawRect(10, 10, 60, 50);
} else {
g.drawOval(10, 10, 50, 50);
}
}
You didn't initialize your Graphics reference. You can initialize it by calling the getGraphics() method that Applet inherits from Component.
Graphics g = getGraphics();
Your are calling methods from g which is not intialized as your error says : you have only declared it.
Edit : as others have said, your Graphics object is a member of Applet, and is accessible from the method getGraphics. Therefore you can call this method everytime you need it, or create a member in your DrawShapes class.
Graphics g = getGraphics();
public void actionPerformed(ActionEvent ae)
{
if(ae.getSource()==line)
{
g.drawLine(0,100,100,10);
}
// etc
}
Related
Hey guys i am trying to move a rectangle with arrow keys using keylistener in java. I got everything to work and imported everything but it is saying that the class name is not implemented in the non-abstract class "SoccerGame." I do not know what to do. I tried to make many changes to get it to work but it is still not functional. Are there any more packages I need to import or something? Hope you guys can help. Thanks.
// The "SoccerGame" class.
import java.awt.*;
import java.applet.*;
import java.awt.event.*;
public class SoccerGame extends Applet implements KeyListener
{
int x = 200, y = 200;
public void init ()
{
this.requestFocus ();
addKeyListener (this);
setSize (800, 550);
} // init method
public void paint (Graphics g)
{
g.drawRect (20, 20, 340, 340);
g.fillRect (x, y, 20, 20);
} // paint method
public void keyPressed (KeyEvent e)
{
if (e.getKeyCode()==e.VK_UP)
{
y = y-10;
}
if (e.getKeyCode()==e.VK_DOWN)
{
y = y+10;
}
if (e.getKeyCode()==e.VK_LEFT)
{
x = x-10;
}
if (e.getKeyCode()==e.VK_RIGHT)
{
x = x+10;
}
repaint ();
}
public void keyReleased (KeyEvent e)
{
}
} // SoccerGame class
The code works fine after adding the missing public void keyTyped(KeyEvent arg0) {} to avoid compilation error.
I am learning the template method and delegation now. I do not understand what interface inheritance to the newClass, and then the newClass past its inside method to NextClass.
When I ran it, MouseLintener does not work.
Could you please teach me how to fix my codes?
Thank you!
public class KiteComponent extends JComponent{
private ArrayList<Kite> kites;
private Point mousePoint;
public KiteComponent() {
kites = new ArrayList<Kite>();
ColoredCompoundShape c = new ColoredCompoundShape();
addMouseListener(new MouseAdapter(){
public void mouseClicked(MouseEvent e)
{
mousePoint = e.getLocationOnScreen();
for (Kite s: kites){
if (s.contains(mousePoint))
s.setColor(s.getColor());}
repaint();
}
});
}
public void add(Kite k){ kites.add(k);repaint();}
public void paintComponent (Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (Kite s : kites){ s.drawInColor(g2); }
}
}
s.setColor(s.getColor())
Isn't this useless, it's setting the same color it already is... If you think that this actually isn't being called, print a line in your mouseClicked method to check if it's actually being called.
Main class:
public Main() {
Frame f = new Frame();
final Panel p = f.p;
final Player player = new Player();
Timer t = new Timer(UPDATE_PERIOD, new ActionListener() {
public void actionPerformed(ActionEvent e) {
Graphics g = p.getGraphics();
p.render(g);
player.tick();
player.render(g);
g.dispose();
}
});
t.start();
}
Player render method:
public void render(Graphics g) {
g.drawImage(Images.get("player"), x, y, null);
}
The problem is, that all previous drawn images are still there. Example (when I change the drawn image's x or y):
To draw in Swing, you should not be getting the Graphics object directly from the JPanel. Instead, override the paintComponent method and use the parameter Graphics object to perform your custom drawing, with a call to the parent method to erase previous painting
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
//custom painting goes here
}
If you wish to trigger a repaint, use the method by that name on the JPanel:
p.repaint();
Rather than doing custom rendering your your timer, you should really be doing all your painting in your paintComponent method. Something like:
public void actionPerformed(ActionEvent e) {
player.tick();
p.repaint();
}
And then re-render the player and the background in paintComponent()
Painting like you currently are runs into issues when you resize the panel, etc
Try calling 'p.repaint()' in your ActionListener once you have changed the position of the Graphic.
I'm trying to figure out if the repaint method does something that we can't do ourselves.
I mean,how are these two versions different?
public class Component extends JComponent {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Rectangle r = new Rectangle(0,0,20,10);
g2.draw(r);
r.translate(5,5);
g2.draw(r);
}
}
and
public class Component extends JComponent {
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Rectangle r = new Rectangle(0,0,20,10);
g2.draw(r);
r.translate(5,5);
repaint();
}
}
The 2nd version can result in a very risky and poor animation since it can result in repaints being called repeatedly, and is something that should never be done. If you need simple animation in a Swing GUI, use a Swing Timer to drive the animation.
i.e.,
public class MyComponent extends JComponent {
private Rectangle r = new Rectangle(0,0,20,10);
public MyComponent() {
int timerDelay = 100;
new Timer(timerDelay, new ActionListener(){
public void actionPerformed(ActionEvent e) {
r.translate(5, 5);
repaint();
}
}).start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.draw(r);
}
}
The use of repaint() is to suggest to the JVM that the component needs to be painted, but it should never be called in a semi-recursive fashion within the paint or paintComponent method. An example of its use can be seen above. Note that you don't want to call the painting methods -- paint or paintComponent directly yourselves except under very unusual circumstances.
Also avoid calling a class Componenet since that name clashes with a key core Java class.
I am trying to code a simple animation like a moving circle. I have tried using getGraphics() and work with that but it's not dynamic and it's painted for just one time
So please help me and guide me to code a dynamic graphic program.
I mean for example defining a function and every time when it called, it draws a line on a label.
Here is how to make a growing rectangle:
public class MovingRectangle extends JPanel {
private Timer timer = new Timer(500, new ActionListener() {
public void actionPerformed(ActionEvent event) {
rectWidth += 100;
repaint();
}
};
private int rectWidth = 100;
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(0, 0, 100. rectWidth);
}
public void start() {
timer.start();
}
public void stop() {
timer.stop();
}
public void reset() {
rectWidth = 100;
repaint();
}
}
you should override the paintComponent(Graphic g).
This method is called every time the repaint() is called, so you should periodic calling that method.
You should also set DoubleBuffering on true: setDoubleBuffered(true)
It will prevent possible flicker of your animation