Drawn images do not stay on screen - java

I am drawing onto a JPanel using getGraphics and the drawLine and fillOval commands but it is very temperamental when running the program. However, when I debug it it draws every time.
draw.drawPoints(drawing.getGraphics(), xCoord, yCoord);
Calls:
public void drawPoints (Graphics g, int x, int y){
g.setColor(Color.red);
g.fillOval(x, y, 5, 5);
}
edit: It wont always draw. Most of the time is stays blank.

I am drawing onto a JPanel using getGraphics
You should not draw stuff on the JPanel by getting a Graphics object from drawing.getGraphics().
Instead, you should override the paintComponent(Graphics g) method and do your painting there.
A simple example to get you started:
container.add(new JPanel() {
public void paintComponent(Graphics g) {
drawPoints(g, xCoord, yCoord);
}
});

You need to do that every time the object is repainted.

Related

JLabel not showing when called in paint method

I have the following code:
public class Canvas extends JPanel{
JLabel label = new JLabel();
public void init()
{
label.setSize(100, 100);
label.setLocation(10, 10);
label.setText("lalallaalal");
this.add(label);
}
#Override
public void paint(Graphics g) {
super.paint(g);
paintRoad(g);
paintBorders(g);
paintEnemies(g, enemies);
paintPlayer(g);
}
I want the label to be redrawn every time the JPanel is repainted, but when I put this.add(label) at the end of paint method it doesn't show the label.
Any idea why?
paint() invokes paintComponent(). It's better to override paintComponent instead of paint.
protected void paintComponent(Graphics g)
A Closer Look at the Paint Mechanism
Instead of using the JLabel, try using the drawString(String str, int X, int y) method in the paint method.
public void paint(Graphics g){
g.drawString(label.getText(), 110, 110);
}

Rectangle2D, borders go missing?

Helo guys,
my problem is that sometimes if my Rectangle2D gets a big width or height its bottom,left border splits and no longer makes a continous border and if I even make it wider the border goes smaller and smaller, like if there were a limitation of how long a rectangles border can be... It is really confusing and so far I have not found the solution :S I put there a link to a picture so you can see for yourself.
new Rectangle2D.Double(mojrectangle.getUpperleftPointmojRectangle().getX(), mojrectangle.getUpperleftPointmojRectangle().getY(),1000,1000)
repaint();
thanks for your help..
BTW I have the same problem with Arc2D if it gets really big
UPDATE: I removed from the function the setStroke command and now it draws it correctly, but in the future I will need to set the Rectangles stroke so it leaves me sad.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2=(Graphics2D)g;
//g2.setStroke(stroke);
g2.draw(rectangle);
}
Here I put an example code of my project, please try it with g2.setStroke(selectedstroke)- it wont work, and without it...I hope I explained myself clear .
package com.awtgraphicsdemo;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import javax.swing.JComboBox;
public class AWTgraphicsdemo extends Frame {
final float dash[] = {10.0f};
final float solid[] = {1000.0f}; // these must be in an Array
float lineWidth[]={2.0f,4.0f,6.0f,8.0f,10.0f}; // width of the drawing line
String[] lineWidthString={"2.0","4.0","6.0","8.0","10.0"};
JComboBox strokecombobox=new JComboBox(lineWidthString);
BasicStroke selectedStroke = new BasicStroke(lineWidth[0],BasicStroke.CAP_BUTT,BasicStroke.JOIN_MITER, 10.0f, solid, 0.0f);
public AWTgraphicsdemo(){
super("Java AWT Examples");
prepareGUI();
}
public static void main(String[] args){
AWTgraphicsdemo awtGraphicsDemo = new AWTgraphicsdemo();
awtGraphicsDemo.setVisible(true);
}
private void prepareGUI(){
setSize(400,400);
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent windowEvent){
System.exit(0);
}
});
}
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(selectedStroke);
g2.draw (new Rectangle2D.Double(10, 10, 1000, 900));
Font font = new Font("Serif", Font.PLAIN, 24);
g2.setFont(font);
g.drawString("Welcome to TutorialsPoint", 50, 70);
g2.drawString("Rectangle2D.Rectangle", 100, 120);
}
}
Helo again,
I figured out my problem, it was in the properties of stroke,so after some lenght of the compoment the stroke got activated which made changed to the drawn shape.By modifying the strokes solid array I was able the get the result I wanted.
Thank you for your help and suggestions :)
Take Care
Better to:
Not override paint(...) in top level windows (as MadProgrammer states) since this also changes painting of borders and child components -- a dangerous thing to do.
Instead override paintComponent(...) of a JPanel (again as MadProgrammer states) and place that JPanel into your top level window.
Don't set the Stroke of the Graphics object passed into your painting method, but rather a copy of the Graphics object so not to have side effects down the road.
e.g.,
public class MyPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g.create();
g2.setStroke(....);
// do drawing with g2 here
g2.dispose();
}
}

draw graphics outside of paint method

private void draw_shape() {
Graphics g = getGraphics();
g.drawLine(0, 0, 100, 100);
repaint();
}
In paint method only those graphics are drawn which is a part of paint method because of which
I wanted to draw shapes outside of paint method.
This code draws the line but it immediately disappeares, I don't understand why this is happening. please help
This doens't work because you are getting the current Graphics outside of the Swing repaint thread. Basically:
you get the current Graphics
you draw something on it
then you call repaint() that will call the paint() of the component thus discarding all you did
To make it work you should override the paint (paintComponent for Swing) method of your object:
#Override
public void paint(Graphics g) {
super.paint(g); // if you have children to the component
g.drawLine(..)
}
and then just call repaint() when something has been modified.
The line disappears because Swing (or AWT) will call paint(Graphics) or paintComponent(Graphics g) in order to pain the component.
What you need to do is to put your drawing logic on the paint(Graphics) or paintComponent(Graphics g) method. The latter is more advisable.
If you really need to draw things using another method, store an image as a class field and draw this image on the paint or paintComponent methods.
Because the paint method also paints stuff. You should not draw graphics outside the paint method. You should instead override the paint method, like this:
#Override public void paint (Graphics g) {
super.paint(g);
g.drawLine(0, 0, 100, 100);
}
Thanks for the help found the answer
BufferedImage image = (BufferedImage) createImage(300, 300);
image.getGraphics().drawLine(0, 0, 300, 300);
jLabel1.setIcon( new ImageIcon(image ));

In Java, repaint() doesn't call paintcomponent()

For a homework assignment I have to make a Java program that draws a red circle on a jframe when clicking a "start" button. When clicking the button, the method setSmallCircle is called. This does work, but inside this method I'm making a calling repaint(), but this doesn't seem to call the paintComponent method.
This is my code so far:
import java.awt.*;
import javax.swing.*;
class ReactionPanel extends JPanel {
Color color;
int size;
public void paintComponent(Graphics g){
System.out.println("paintcomp 1");
super.paintComponent(g);
System.out.println("paintcomp 2");
g.setColor(color);
g.fillOval(200, 200, size, size);
}
public void setSmallCircle(Color c){
color = c;
size = 10;
System.out.println("drawing");
repaint();
System.out.println("repaint called");
}
}
The method setSmallCircle(Color.red) is called by some other class. Does anyone know why the "repaint()" isn't drawing a red circle?
Any update to the painting of swing component should be inside EDT (eevent dispatch thread). However while experimenting following portion:
public void paintComponent(Graphics g){
System.out.println("paintcomp 1");
super.paintComponent(g);
g.setColor(color);
System.out.println(color); // print color as null
g.fillOval(20, 20, size, size); // printing size as 0
System.out.println(size);
}
updating color and size in setSmallCircle() is not taking effect !! paintComponent seems to keep using the old value, instead of updated value.

Problems with setting JPanel's colour

Here's my canvas class extending JPanel:
package start;
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Board extends JPanel
{
private static final long serialVersionUID = 1L;
public Board() {}
public void paintComponent(Graphics g)
{
int width = getWidth();
int height = getHeight();
this.setBackground(Color.green);
g.setColor(Color.black);
g.drawOval(0, 0, width, height);
}
}
Here's the method where I'm calling it:
private static void createAndShowGUI()
{
JFrame frame = new JFrame("Hello");
frame.setPreferredSize(new Dimension(700, 700));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Board b = new Board();
frame.getContentPane().add(b);
frame.pack();
frame.setVisible(true);
}
But this shows the oval on the default colour. I also tried without the this., and then tried setting the colour of b, and setting the colour inside the constructor, but none of these worked. What's wrong?
EDIT: Sorry for not making thing clear, my goal was to display a thin black oval on a green background.
In the paintComponent method you do not have to use setBackground to change the colour of the JPanel. That should be done outside of paintComponent. paintComponent will probably use the colour of the background before you change it.
There are a number of things you can try. One, is to set the colour in the constructor and then call the super class' paintComponent first like this:
public Board() {
this.setBackground(Color.GREEN);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
g.setColor(Color.BLACK);
g.drawOval(0, 0, width, height);
}
Also note the color constants are all upper case. i.e. BLACK or GREEN.
If you want to change the background colour dynamically then you can do so in the event handler such as mouseEntered or actionPerformed etc.
While the code does not exactly make clear what's your intent i try to fix some issues:
If you want a green background, do as #vincent told you. YOu should see a black oval in green background. The "super.paintComponent" will fill its area with the components background automatically if the panel is opaque.
If you want a green oval on white background, maybe with black border
public void paintComponent(Graphics g)
{
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval(0, 0, width, height);
g.setColor(Color.BLACK);
g.drawOval(0, 0, width, height);
}
EDIT
i forgot super

Categories

Resources