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.
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.
I created a class called Test, most likely where I went wrong.
import javax.swing.JPanel;
import java.awt.*;
public class Test extends JPanel {
Graphics grap;
public void sun()
{
super.paintComponent(grap);
grap.setColor(Color.YELLOW);
grap.fillOval(0,0,20,20);
}
}
As you can see I want to paint a yellow "Oval" in the top left corner of the panel using a method but I did not use a PaintComponent method. Now I try to implement it in my Paint component method which is in a class called Painting.
//import...;
public class Painting extends JPanel{
protected void paintComponent(Graphics g)
{
Test test = new Test();
test.sun();
}
And now i created a main window that will create a panel and display the yellow oval.
//import...
public class main extends JFrame{
public static main(String [] args){
JFrame window = new JFrame();
window.add(new Painting());
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setSize(100,100);
window.setLocationRelativeTo(null);
window.setVisible(true);
}
}
But this does not work. I have a feeling that it is the sun method in test. How would I get this to work? I have looked in all the java books and cant find anything that can help.
Please note that I do not what to add parameters to the method.
Thank You
Tom.
Few points to be noted here:
Never call super.paintComponent by yourself except within the overriden paintComponent method itself.
If you want to do some Graphics activities then override the paintComponent method and draw graphics over there
When you are overriding paintComponent method then the first statement within the method should be super.paintComponent(g).
Now, going by all above points your code should now be like this:
public class Test extends JPanel {
public void paintComponent(Graphics grap)
{
super.paintComponent(grap);
grap.setColor(Color.YELLOW);
grap.fillOval(0,0,20,20);
}
}
And your Painting class should be like this:
public class Painting extends JPanel{
Test test;
public Painting()
{
test = new Test();
setLayout(new BorderLayout());
add(test);
}
}
If i want to draw 50 ovals on different places then i would have a problem with extensive code
Then you would keep a List of the ovals that you want to paint. See Custom Painting Approaches which paints a bunch of Rectangles on a panel. All the code does is loop through the ArrayList to paint the Rectangle. Only a couple of lines of code are required.
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);
...
}
I'm trying to completely disable all painting and refreshing on a portion of a JFrame. I got the desired effect on the entire JFrame by simply overriding public void paint(Graphics) like so:
import javax.swing.*;
class Test extends JFrame {
Test () {
setBounds(20,20, 100,100);
setVisible(true);
}
//This disables all painting and refreshing ON A JFRAME.
//Just doing this on a JPanel doesn't work.
public void paint (Graphics g) {}
public static void main (String[] args)
{ new Test(); }
}
I want this same effect, but only on a particular region of the JFrame. I want to be able to add GUI components like normal to the rest of the frame. I've tried disabling double buffering (using JPanel's constructor) and overriding the following methods (extending both JPanel and JComponent) like so:
public class DontRefresh extends JComponent/JPanel {
public void paint (Graphics g) {}
public void paintComponent (Graphics g) {}
public void repaint () {}
public void update (Graphics g) {}
public void updateUI () {}
}
and i also tried disabling refresh via:
DontRefresh component = new DontRefresh();
RepaintManager.currentManager(component).markCompletelyClean(component);
but nothing worked.
Well, without knowing exactly what you're doing I would recommend you have a "filler panel" (just a JPanel you don't do anything with) in the space you don't want anything to appear and then have other panels for everything else.
So say you have a JFrame. If you wanted the top right corner to never display anything, you could fill the JFrame with 4 JPanels, one in each corner (or 3 with one on the left, one in the top right corner and one in the bottom right corner). Then put all you swing components in the other panels. I don't know if this will accomplish your purpose, but I'm not totally certain what you're purpose is, so that's the best I can do :) I hope it helps!