import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JApplet;
import javax.swing.Timer;
public class CountingSheep extends JApplet
{
private Image sheepImage;
private Image backgroundImage;
private GameBoard gameBoard;
private scoreBoard scoreBoard;
public void init()
{
loadImages();
gameBoard = new GameBoard(sheepImage, backgroundImage);
scoreBoard = new scoreBoard();
getContentPane().add(gameBoard);
getContentPane().add(scoreBoard);
}
public void loadImages()
{
sheepImage = getImage(getDocumentBase(), "sheep.png");
backgroundImage = getImage(getDocumentBase(), "bg.jpg");
}
}
The program works correctly when nothing but the GameBoard class is added to the JApplet, however, when I try to add the ScoreBoard class, both Panel classes do not show on the Applet. I'm guessing this is now down to positioning? Any ideas?
EDIT: Gone back to the previously asked question Hovercraft, and found it was due to the layout of the contentPane and the order at with the components were added.
Some suggestions:
Don't draw in the paint method of a JApplet as that is a top-level window and should not be drawn directly on. Instead draw in the paintComponent(Graphics g) method of a JPanel or other JComponent, and then add that JPanel to the JApplet's contentPane.
Similar to his advice about the super call, your first method call in this method should be the super.paintComponent(g); which will refresh the JPanel's graphics.
The flicker is from your drawing directly in the JApplet's paint method. If you do as I suggest, you'll take advantage of Swing's use of double buffering.
Since this is a Swing application, you should avoid using KeyListeners and instead use Key Bindings.
Don't get the Graphics object of a component by calling `getGraphics(). The Graphics object obtained will be short-lived and thus will not persist after any repaint.
The code you've posted above is somewhat confusing to me. What are you trying to do with it? You've added components to the JApplet, and these components should handle their own graphics, and then you're painting on the JApplet as well. What kind of behavior exactly are you trying to achieve?
In your paint method, make sure to call super.paint(g) since it is a method inherited from Container, a superclass of JApplet.
#Override
public void paint(Graphics g)
{
super.paint(g);
...
}
Related
So, I've taken an AP class on java, and in the class, we never really went over repaint(), and how to properly use it. I've also searched through the internet, and I personally have not found any answers on the standard way of calling repaint(). Are we supposed to call the repaint() method from the main class like the following?
import java.awt.*;
import javax.swing.*;
public class RepaintExample{
public static void main(String[] args){
JFrame frame = new JFrame();
JComponent component = new JComponent();
frame.add(component);
frame.repaint();
}
}
Or would I call the JComponent.repaint() Like this
import java.awt.*;
import javax.swing.*;
public class RepaintExample{
public static void main(String[] args){
JFrame frame = new JFrame();
JComponent component = new JComponent();
frame.add(component);
component.repaint();
}
}
Or, are both approaches wrong, and JComponent.repaint() should be called from the paintComponent as shown here:
import java.awt.*;
import javax.swing.*;
public class ComponentRepaintExample extends JComponent{
public void paintComponent(Graphics g){
//Draw stuff
for(int i = 0; i < 10; i++){
//Draw stuff
this.repaint();
}
}
}
It is quite possible that all three approaches are wrong. Any help figuring out how to properly use the repaint() method is appreciated. The whole topic is very shrouded to me, so I apologize if any terminology I use is incorrect. All thanks in advance.
Why do you think you need to call repaint()?
The repaint() method is invoked by a Swing component automatically when a property of the component is changed.
For example if you have a JLabel and you invoke setText(...) or setIcon(...), then those methods will automatically invoke repaint().
You would NEVER invoke repaint() from a painting method.
If you are doing custom painting, then your code should be structured like any other Swing component. That is you create getter/setter methods for your custom components to change properties of the component. In the setter method you invoke repaint().
i have an assignment to make a simple drawing application using swing and mouse listener. the application has to have three classes, one that contains Main, one that contains the frame, and the last one that makes the drawing. The teacher gave us a source code we're supposed to use to complete the assignment and it looks like this:
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
public class Drawsome extends JFrame implements MouseMotionListener {
public Drawsome(){
setSize(300,400);
setForeground(Color.black);
show();;
addMouseMotionListener(this);
}
public void mouseDragged(MouseEvent evt) {
start = end;
end = new Point(evt.getX(),evt.getY());
repaint();
}
public void mouseMoved(MouseEvent evt) {
end = null;
}
public void paint(Graphics g) {
if (start!=null && end!=null)
g.drawLine(start.x, start.y, end.x, end.y);
}
public void update(Graphics g) {
paint(g);
}
Point start=null;
Point end=null;
}
now this work perfectly, but since we have to make the frame in another class i tried to do this:
import java.awt.Color;
import javax.swing.JFrame;
public class MainWindow extends JFrame {
public MainWindow() {
setSize(300,400);
setForeground(Color.black);
show();;
}
}
import java.awt.*;
import java.awt.event.*;
import javax.swing.JFrame;
public class Drawsome extends JFrame implements MouseMotionListener {
public Drawsome(){
MainWindow mainwindow = new MainWindow();
addMouseMotionListener(this);
} (rest is the same as the previous code)
i'll get a frame, but the rest doesn't work, i dont' understand what i'm doing wrong, and would greatly appreciate a push in the right direction
Your teacher's source code is terrible since you should never be drawing within the paint method or within a JFrame, plus his/her paint override doesn't call the super's method, breaking the painting chain. They don't appear to know what they're doing.
Having said that, your main driver should not extend JFrame nor should you try to create a JFrame of it or even an instance of it. Instead, in this class's main method, create an instance of the terrible drawing class.
Note that I don't understand this requirement:
and the last one that makes the drawing.
Please post the exact requirements.
If this were my application, I'd
Do my drawing within a JPanel, and not a JFrame
Do it within the JPanel's paintComponent method, not the paint method.
Be sure to call the super's paintComponent method within my JPanel's paintComponent method override.
Then place my JPanel within a JFrame to display it.
I would not have my GUI class implement the MouseListener but rather would use a nested inner class for this.
Im working with eclipse.
My Code:
import javax.swing.JApplet;
import java.awt.*;
public class Einstein extends JApplet
{
public void pain(Graphics page)
{
page.drawRect(60,60,40,40); // Square
page.drawString("Out of clutter, find simplicity. " , 110, 70);
}
}
The rectangle and text does not shown in the applet.
what could be the problem?
public void pain(Graphics page) - interesting choice of naming...
I believe the method you're looking for is paint
#Override
public void paint(Graphics g) {
super.paint(g);
//...
}
Make sure you call super.paint before performing any custom painting, otherwise you could end up with a bunch of nasty paint artefacts.
Having said that. Consider using a custom component, extending from JPanel for example, and override it's paintComponent method instead, then add this component to your applet.
You gain the benefit of the double buffering support of Swing for free and the freedom to move you component to another container, like a JFrame or other container for example, making it far more re-usable
When I run this code in Eclipse I get a the string and line printing in a new windows, but instead of a blank window it simply is a screenshot of my current window, set to the size I declare.
http://i.imgur.com/nWFN9YJ.png
Any suggestions on what I'm doing wrong?
import java.awt.Graphics;
import javax.swing.JFrame;
public class EmptyFrame2 extends JFrame
{
public static void main(String args[])
{
EmptyFrame2 JF=new EmptyFrame2();
JF.setSize(1000,500);
JF.setVisible(true);
}
public void paint(Graphics g)
{
g.drawString("Hello",50,50);
//g.drawLine(50-2, 50+2, 50+70, 50+2);
}
If this is too vague let me know and I'll change it or add whatever else you need.
Avoid overriding paint of top level components
Avoid breaking the paint chain, making super you call super.paintXxx
Override paintComponent of something like JPanel instead
See Performing Custom Painting
Try adding super.paint(g) to your paint() method.
I have created a testing version to simplify the problem that I'm having for you guys:
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Test extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
JLabel l = new JLabel("hello");
JPanel cp;
public Test(){
setContentPane(cp = new JPanel());
cp.add(l);
setSize(200, 200);
setVisible(true);
}
public void paint(Graphics g){
//do absolutely nothing
}
}
When you start up the program, you get to see a perfectly blank window. However, if you remove the paint method, the JLabel shows up! (I've had to search for this bug for ages, really). Now, how can I enable a window to both use graphics and regularly draw components?
Thanks in advance
1) You should not override paint(..) of JFrame, unless you have a specific purpose for that.
The correct method of drawing in Swing is to:
Add a JPanel to JFrame
in JPanel, override paintComponent(..) and getPreferredSize() to return correct Dimensions which fit our drawing.
NB dont forget to call super.paintComponent(g) as first call in overridden paintComponent method as to honor the paint chain
See this answer of mine which has a few examples for you.
Also do not extend JFrame unnecessarilly.
Dont call setSize on JFrame rather use a correct LayoutManager and/or override getPreferredSize() - usually done on a JPanel when we are drawing directly or the JPanel will have no size if no components are added, if they are it will only be as big as it needs to fit the components and not the image.
and than call pack() on JFrame before setting it visible.
And just incase have a look Concurrency in Swing especially Event-Dispatch-Thread