This question already has an answer here:
paint() in java applet is called twice for no reason
(1 answer)
Closed 8 years ago.
This is my code:
public class Circles extends JApplet{
public void paint(Graphics g) {
Scanner in = new Scanner(System.in);
Random rand = new Random();
int position = rand.nextInt(200);
System.out.println(position);
}
}
and the output was:
199
152
What's happening is after it prints out the "position" variable, it jumps back and starts again. I cant figure out why it does this.
As MadProgrammer noted, you're trying to paint to a JApplet, which not only doesn't have a paint method, but is a top-level container like a JFrame and a JDialog. You don't want to paint to a top-level container. Put it in a JPanel or some lower level container that allows you to override the paintComponent method.
You do not want to put that in your paint method. Also, use the paintComponent method if you're using Swing (which you are, it's the ones with the J at the front of their names).
And make sure you call the original parent method of paintComponent with super.paintComponent(g); as your first line in the paintComponent method.
So it will look like:
public void paintComponent(Graphics g) {
super.paintComponent(g);
//anything else you want goes here
//don't get in the habit of creating Objects in here
//and don't do anything that's not event-driven
}
Don't put anything other than painting stuff in your overridden paintComponent method. You should never put user input into it and avoid creating objects because not only is there probably a better way to do it, creating objects can take a lot of time which will be terrible for a method that's called in quick, repeated succession.
You don't have control over when your application is repainted. The paintComponent/paint methods are called continuously, and your design should be based around that.
Design your GUI to be event-driven, not sequential.
Related
what does the paint method do after receiving the object created from the Graphics class as a parameter?
as for example in this code:
public class unaClase extends Applet{
public void paint(Graphics g){
g.drawRect(0, 0, 400, 200);
}
}
try to trace the source to see its code and thus be able to understand what it does, but it does not show me anything
What I want is to know what makes paint with the parameter it receives?
PD: I know that apple is dead, I just want to understand well what is happening, what it does
when I use the paint method (as in the example code), I'm technically overwriting it (unless I had used super.paint ...), and then its code would be the one I just defined; so my question is, how does paint know what to do with the parameter (Graphics) that I'm going through?
The actual term is overriding. And the first thing you would normally do is call super.paint() to the parent version. Graphics (or Graphics2D which has additional methods but needs to be cast) allows one to use those methods to draw, rotate, and in general manipulate pixels. It is handled internally using native method calls that are supported by the OS.
If you are going to paint you should do it in a JPanel and override paintComponent(Graphics g). Check out the tutorials on painting at https://docs.oracle.com/javase/tutorial/index.html
I am creating a java 2D game and have come to a point where I am thinking of creating "pop-up graphics" i.e graphics that will populate the screen when a certain event occurs. Say, you pick up a certain item, I want this item to be displayed in the middle of the screen in a box containing information about said item.
Currently I have one big paintComponent that paints all of the graphics for the game (tiles, entities, players etc (which has been done efficiently I might add)). I know that I can probably have a boolean value which checks if an item has been picked up in that method, but it feels wrong.
What I am wondering is, is there a way for items to have their own paintComponent so that when it is called, it will show say a bo for a brief period WITHOUT having a boolean value in the big paintComponent method that I currently use for everything?
Small code example (won't execute)
public class popUpGraphics extends (JComponent or JPanel or whatever works best for this scenario)
{
public popUpGraphics(){
}
#Override
protected void paintComponent(Graphics g){
//g.Draw(stuff);
}
}
and then somewhere in an event I instantiate this or somesuch.
I do not want this to override the other paintcomponent, I just want to add to it
(as if it was another layer) to the paintComponent
In short I want to know:
1. Is is possible to have brief graphics shown without including in the huge paintComponent method
2. What Swing library should be extended (JComponent, JPanel etc)
Thanks in advance!
Can somebody explain to me why this isn't working?
The error seems to be inside the Gen class but
I think it may something to do with BoxMan.
The error says cannot find symbol- variable g.
I also tried putting in ints and doubles but it gives me: Required (Java.awt.Graphics) Found(int) / (double). So how can fix this? I've looked everywhere and can't find the answer. Help a beginner!
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.WindowConstants;
import java.lang.Object.*;
public class JFrame_Test
{
public static void main (String [] args)
{
Gen Gen= new Gen (1500,1000,"A Name"); // this gives parameters for a Jframe later.
}
}
{
Gen (int size1, int size2, String title)
{
JFrame aFrame = new JFrame (title);
aFrame.setSize(size1,size2);
aFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
aFrame.setVisible(true);
//aFrame.getContentPane().add(new Canvas());
//Was trying to get it to work with a canvas
BoxMan.paint (g); // the error pops up here.
}
}
public class BoxMan
{
public Graphics2D g2;
public void paint(Graphics a )
{
g2 = (Graphics2D) g; // i even tried declaring "g" here.
g2.drawRect (10, 10, 200, 200);
}
}
Rather then repeating what Jantomedes has already said (which is all excellent), I'm going to expand on it...
Painting in AWT and Swing is done through the paint sub system. This system makes decision about what and when to paint and calls the appropriate methods to update the components on the screen.
See Painting in AWT and Swing for more details
Graphics is an abstract concept in Java and is used to standardise the concept of painting to a variety of possible outputs, including the screen, image and printers. Apart from images, you can't create your own Graphics context, you need it to be supplied by the system
Check out Perfoming Custom Painting in Swing for details
The Graphics object isn't declared anywhere. If you want to draw on your JPanel you should rather create a class extending JPanel and there add draw() method which will get an "automated" Graphics object.
Eventually you can create your own Graphics object but you didn't do that anywhere in that code. Your BoxMen class is very messy. You have to decide if you use Graphics object argument under paint() method or declare it yourself. I'm assuming you try the second one, if so, you should change the g to a (there isn't a g variable anywhere in BoxMen class). You can also get rid of the field g2 and use a local variable instead.
The error pops up because Java doesn't know what you mean by g (it isn't declared anywhere). It depends on you if you want to use the JPanel's Graphics or your own.
Edit: uses awt...
I am trying to display random numbers in an applet based maths game, and have run into an issue. Either one of two things happen depending on where I call the method:
The numbers generate and display properly, without automatically updating each frame but get drawn over by the background and artwork each frame as they're being updated at runtime, or...
The number displayed on-screen appear above the background elements but are redrawn fresh every frame.
Quick illustration:
private int setNumberOne() {
return rand.nextInt(11) + 2;
}
private int setNumberTwo() {
return rand.nextInt(11) + 2;
}
private int setAnswer() {
return setNumberTwo() * setNumberOne();
}
private void displayOutput() {
Graphics2D g2d = graphics();
int one = setNumberOne();
int ans = setAnswer();
setNumberTwo();
g2d.setColor(Color.WHITE);
g2d.drawString(one + " x ? = " + ans, 480, 480);
}
Calling this function in the initialisation method displays a static question that I can update elsewhere when specific triggers are met, however everything else gets drawn on top of it by the update event, rendering it invisible. The only way I've managed to see this working is to remove the other images from the game for testing.
Is there a way to set the "precedence" of GUI elements in an applet?
I'm currently looking at attempting to include the displayOutput() method in it's own thread, but I'm not so experienced with Java and its proving very hard to resolve.
I also tried to not allow the background to update at runtime, but the result was that the moving game objects left trails all over the screen.
What am I missing? If anyone has any suggestions as to how this can be correctly implemented, I'd be delighted to hear them.
update: "...draw in a [...] Component's paint(...) method if AWT, and use the Graphics object passed in by the JVM" -
Resolved, Thank you!
Don't use getGraphics() for your Graphics component as this will return a non-persisting object that will get drawn over with the next repaint. Instead draw in a JComponent's paintComponent(...) method if this is a Swing app (you don't say) or a Component's paint(...) method if AWT, and use the Graphics object passed in by the JVM. Mostly read the tutorials on how to draw with Java as this has been well explained there.
I'm really confused with the program flow for how the paintComponent function works within my JPanel. Ideally I'd like to have access to the Graphics object to draw stuff from other functions based on my program flow. I'm thinking along the lines of the following:
private Graphics myG;
public void paintComponent(Graphics g) {
super.paintComponent(g);
myG = g; //I want a graphics object that I can just draw with.
//Should I just initialize to myG = new Graphics(); or something?
//private Graphics myG = new Graphics(); does not seem to work
}
//this is what's getting called, where I want to call other functions that
//can use myG to draw graphics as I please
public void startPanelView() {
myG.drawRect(350, 20, 400, 300); //doesn't work
otherFunctionForGraphics(); //which will also use myG.
}
I hope I've made myself clear here. I just want to be able to do use the Graphics class as I please. Currently I can only do stuff like g.drawRect(...) inside of the paintComponent() function. This could work for my purposes but I'd like more flexibility.
Thanks.
EDIT - Alright, I understand that I should not try and reference a Graphics object outside. But how should I go about separating application logic from the paintComponent function? Right now this class is looking a little messy because I have the following:
public void paintComponent(Graphics g) {
if (flag1 == true) {
//do some graphics stuff, that I would prefer to be in another function
}
if (flag2 == true) {
//do some other graphics stuff, again, which I would prefer
//to be in another function
}
//... etc. More of these cases.
}
And basically the paintComponent function is getting stupidly long and complicated for me, so I would like to break it up in whatever ways possible.
Call repaint from your startPanelView method on the panel object. You should never act on the graphics object outside of the paint methods, nor should you maintain a reference to the graphics object for use outside of the paint method.
The others are right that you cannot keep the Graphics object as a member variable, but if the problem is that your paintComponent method is getting too long, you can still pass the Graphics Swing gives you as an argument to other methods:
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(350, 20, 400, 300);
doSomeStuff(g);
if (flag1) {
doMoreStuff(g);
} else {
doDifferentStuff(g);
}
}
I'd like to have access to the Graphics object to draw stuff from other functions based on my program flow. I'm thinking along the lines of the following:
No, you shouldn't do that in a standard Swing application as the Graphics object obtained will not persist and your drawings will disappear whenever the JVM or the operating system decide that a repaint is necessary. Consider creating Lists or other collections of objects to be drawn (such as from classes that implement Shape) and iterating through these collections in the paintComponent method. Another technique is to draw on a BufferedImage and then display it in your paintComponent method.
basic JComponent for Painting/Custom Painting/2D Graphics in Swing or for Image/ImageIcon too, is JLabel,
don't call another viod(s) or class(es) from 2D Graphics or CustomPainting, some valuable examples are here or here, search on this forum for excelent suggestions about Custom Painting and 2D Graphics