Draw circle to the screen - java

import javax.swing.*;
import java.awt.*;
public class Drag extends JFrame {
Drag(){
setSize(500,400);
setTitle("Drag");
setVisible(true);
}
public void paint(Graphics g){
super.paint(g);
g.setColor(Color.RED);
g.fillOval(0,0,30,30);
}
public static void main(String args[]){
Drag frame1 = new Drag();
}
}
I don't know where did i get wrong, but it just didn't create a circle to the screen for some reason

The JFrame coordinates begin at the top left corner of the window created with the y axis going down. To see your circle at the center of this window try
g.fillOval(this.getWidth()/2,this.getHeight()/2,30,30);

Not 100% sure but by any chance is it because you're instantiating a JFrame outside of the event dispatch thread?
I can't test because I'm on my phone but if you want to you can try replacing mains code with this :
EventQueue.invokeLater(new Runnable () {
public void run () {
new Drag ()
}
});

Related

JFrame window coordinates in error

When one plots points on the JFrame, one naturally assumes that (0,0) corresponds the the top-left pixel available below the tab, and that (Max_x, Max_y) corresponds to the bottom-right pixel in the Frame. However it seems that the (0,0) actually is hidden in the area where the tab is. For instance, if I write the following code to draw a diagonal line between the top-left corner and the bottom-right corner,
import java.awt.Graphics;
import javax.swing.JFrame;
public class Test extends JFrame{
public Test() {
setSize(960, 960);
setTitle("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
Test t = new Test();
}
public void paint(Graphics g) {
g.drawLine(0, 0, 960, 960);
}
}
I get the following
And as we can see, the top-left of the line is obscured. How do I rectify this?
- In particular, how do I calculate the pixel-coordinate of the uppermost pixel below the tab?
- More generally, is it possible to display a JFrame without a tab in the first place, thereby removing the problem?
Probably because you're drawing directly on the JFrame which is a top-level window and I don't think it supports custom painting in a predictable manner, at least the behaviour seems quite erratic like you've described in your question.
Typically you'd use a JPanel and place it in the JFrame, like so:
import java.awt.*;
import javax.swing.*;
public class Main extends JFrame {
public Main() {
setSize(960, 960);
setTitle("Test");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setContentPane(new JPanelTest());
}
public static void main(String[] args) {
Main t = new Main();
}
class JPanelTest extends JPanel {
public void paint(Graphics g) {
g.drawLine(0, 0, this.getWidth(), this.getHeight());
}
}
}
Output:

Add animation to netbeans-generated jFrame

I'm new to java and I'm trying to add an animation to a jFrame that I created using the Netbeans design editor. The idea is that there will be a background image and the animation will play on top of it. I'd also like to have other components that start out hidden and are displayed on top of the finished animation.
After some research on stackoverflow, I managed to create the animation I wanted. However, I can't figure out how to implement it into the Netbeans-generated jFrame I've created. As mainly a python user, all this method and class business is still a little confusing to me.
Here's my code for the animation:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class AnimationTest extends JPanel{
int height = 1;
AnimationTest() {
setPreferredSize(new Dimension(1000,618));
ActionListener al = (ActionEvent ae) -> {
repaint();
if(height < 190) {
height ++;
}
};
Timer timer = new Timer(10,al);
timer.start();
}
public void paintComponent(Graphics g) {
Color c = (Color.BLACK);
g.setColor(c);
g.fillRect(0, 309 - height, 1000, 2*height);
}
public static void main(String[] args){
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JFrame window = new JFrame("");
window.getContentPane().add(new AnimationTest());
createWindow(window);
}
});
}
public static void createWindow(JFrame window){
window.pack();
window.setLocationByPlatform(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setVisible(true);
}
}
UPDATE: I tried replacing new JFrame with new AnimationFrame (the JFrame form I made using netbeans). Now the JFrame works but the JPanel isn't added (or isn't displayed). What is the right way to add the JPanel?

Java: How to draw in a canvas?

I'm new to Java and I want to make a simple game where there are squares in a simple grid (something between a snake and a labyrinth). The number of squares doesn't change, only their color does.
I already programmed the objects I need for the game. Now I want to display the game.
I know how to create a JFrame, a JPanel and a JButton, which I will need, but I don't understand how to draw in a canvas.
I made a test class:
import javax.swing.*;
import java.awt.*;
public class Test extends Canvas {
public static void main (String[] arg) {
JFrame f=new JFrame();
f.setTitle("Title");
f.setSize(400,500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
JPanel pan=new JPanel(new FlowLayout());
pan.add(new JButton("hey"));
Test canvas=new Test();
Graphics g=canvas.getGraphics();
canvas.paint(g);
pan.add(canvas);
f.setContentPane(pan);
}
public Test() {
setBackground (Color.green);
setSize(300,300);
setVisible(true);
}
public void paint(Graphics g) {
Color c = g.getColor();
g.setColor(Color.RED);
g.fillRect(10,10,80,80);
g.setColor(Color.BLUE);
g.fillRect(150,50,80,80);
g.setColor(c);
}
}
When I run this, a windows is created, with the correct title , size and button, but there isn't anything else (no green background, no red or blue rectangle), and an error is detected :
Exception in thread "main" java.lang.NullPointerException
at Test.paint(Test.java:25)
at Test.main(Test.java:15)
What am I doing wrong ? Is there a better way to draw these squares ?
Thanks !
Comment these two lines
//Graphics g=canvas.getGraphics();
//canvas.paint(g);
And change the paint method as follows.
#Override
public void paint(Graphics g) {
super.paint(g);
Rest is all fine. Hope it helps you to progress.

Resizing only way to repaint JFrame . repaint(); seems to not work

Im currently trying to make my first game and i am having trouble getting the repaint() method to work. I have checked my keyListeners and have confirmed that they are working a ok! The ship that i have created moves but only if i forcibly resize the window by dragging on the sides. If anyone has any tips i would be very greatful!
If you need any more information feel free to ask!
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class Main extends Canvas implements KeyListener{
public static Ship playerShip = new Ship(150,450,"F5S4-Recovered.png");
public int numberOfEnemies = 0;
public static void createFrame(){
Window frame1 = new Window();
final JPanel pane = new JPanel(){
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.BLACK);
g.fillRect(0, 0, 1000, 1000);
g.drawImage(playerShip.image, playerShip.xPos1, playerShip.yPos1, this);
}
};
frame1.add(pane);
}
public void keyTyped(KeyEvent e){System.out.println("KeyTyped");}
public void keyPressed(KeyEvent e){
switch(e.getKeyCode())
{
case KeyEvent.VK_LEFT :
playerShip.xPos1-=2;
break;
case KeyEvent.VK_RIGHT:
playerShip.xPos1+=2;
break;
}
repaint();
}
public void keyReleased(KeyEvent e){}
public static void main(String args[]){
createFrame();
}
}
Window class ----------------------------------------------------------
import javax.swing.*;
public class Window extends JFrame{
public Window()
{
setTitle("Space Game");
setSize(800,800);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addKeyListener(new Main());
setVisible(true);
}
}
Your call to repaint() is repainting the class Canvas, but the painting is done on the JPanel pane. The resizing causes an automatic repaint of the panel. So to fix you want to pane.repaint(), but you can't do that unless you put the panel as a class member, so you can access it from the listener method. Right now, it's currently locally scoped in the createFrame() method.
Also, you should probably add the listener to the panel instead, and not even extend Canvas, since you're not even using it
Other Notes:
Look into using Key Bindings instead of low-level KeyListener
Swing apps should be run from the Event Dispatch Thread (EDT). You can do so by simply wrapping the code in your main in a SwingUtilities.invokeLate(..). See more at Initial Threads
Again, I'll just add, Don't extends Canvas

Animated drawing of a successively complex image in Java

I am trying to draw an image on a JPanel that requires thousands of calculations, and I want to animate the progression of the drawing. I.e., instead of doing all 100K iterations of drawing in one go, and then repainting the JPanel, I want to repaint after each iteration, then pause for a fraction of a second, so the user sees the image gradually appearing. However, each refresh of the JPanel erases previous drawings, so my method doesn't work. How can I do this without replicating all (1..N-1) calculations on the Nth iteration?
Consider this example: I want "snow" to gradually appear on the screen. However, this code will only show the 100,000th "snowflake" as all previous ones get erased each time repaint() is called.
import javax.swing.*;
import java.awt.*;
import java.util.Random;
class spanel extends JPanel{
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawLine(snow.x, snow.y, snow.x, snow.y);
}
}
class snow extends Thread {
static int x,y;
Random r = new Random();
public void run(){
JFrame sboard = new JFrame();
sboard.setSize(600,600);
sboard.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
spanel mypanel = new spanel();
sboard.add(mypanel);
sboard.setVisible(true);
for (int i=0;i<100000;i++){
x=r.nextInt(600);
y=r.nextInt(600);
sboard.repaint();
try {
snow.sleep((long)10);
} catch (InterruptedException e) {};
}
}
}
public class SnowAnim {
public static void main(String[] args) {
(new snow()).start();
}
}
Custom Painting Approaches shows how to draw on a BufferedImage. There are also plenty of other examples in the forum.
Also, when doing animation you should use a Swing Timer to schedule the animation.
How can I do this without replicating all (1..N-1) calculations on the Nth iteration?
Add them to a BufferedImage as seen in this example.
You should probably do your painting on a buffer, then draw the current state of the buffer in paintComponent();
You could also skip the call to super.paintComponent(g);, but then you would have to worry about other elements getting visually "stuck" in your panel.
Thanks all! I figured it out. BufferedImage solves it. For the record, here is my updated code. It also implements camickr's suggestion to use a Swing timer instead of a thread to schedule the animation. I also made some aesthetic changes to make the output look more like snow :-) Thanks again!
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.util.Random;
import java.awt.event.*;
class spanel extends JPanel{
int x,y,rad,i;
static Random r = new Random();
BufferedImage image;
Graphics2D g2d;
Timer timer;
spanel(){
image = new BufferedImage(600, 600, BufferedImage.TYPE_INT_ARGB);
g2d = (Graphics2D)image.getGraphics();
setBackground(Color.black);
g2d.setColor(Color.white);
i=0;
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
iterate();
}
};
timer = new Timer(10, listener);
timer.start();
}
public void iterate(){
x=r.nextInt(600);
y=r.nextInt(600);
rad=r.nextInt(5)+5;
g2d.fillOval(x, y, rad, rad);
repaint();
i++;
if (i==1000){timer.stop();}
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawImage(image,0,0,null);
}
}
public class SnowAnim {
public static void main(String[] args) {
JFrame sboard = new JFrame();
sboard.setSize(600,600);
sboard.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
spanel mypanel = new spanel();
sboard.add(mypanel);
sboard.setVisible(true);
}
}

Categories

Resources