I want to draw some balls and interact with them, but when I run my program I see my balls staying still and i get java.lang.NullPointerException error. Can u tell me what I'm doing wrong?
Main class:
public class Main extends JPanel {
// creating big ball
Big big = new Big(this);
// creating small balls
Small small_list = new Small(40);
// method for moving big ball
private void moveBig() throws InterruptedException{
big.move();
}
// same but small balls
private void moveSmall() throws InterruptedException{
// ERROR
small_list.move();
}
// paiting
#Override
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
big.paint(g2d);
big.paintLine(g2d);
small_list.paint(g2d);
}
public static void main(String[] args) throws InterruptedException {
// TODO code application logic here
JFrame window = new JFrame("test");
Main main = new Main();
window.add(main);
window.setSize(500,500);
window.setVisible(true);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while(true){
main.moveBig();
// ERROR
main.moveSmall();
main.repaint();
Thread.sleep(15);
}
}
}
Big ball class:
public class Big {
// coordinates of first apperence
int x = 200;
int y = 200;
int upAnddown = 1;
int leftAndright = 1;
private static final int sizeOfbig = 30;
// list to draw a line after ball
private List<Point> listofpoints = new ArrayList<>();
private Main main;
public Big(Main main){
this.main=main;
}
void move() throws InterruptedException{
if (x+upAnddown < 5) {
upAnddown=1;
}
if (x+upAnddown > main.getWidth()-14) {
upAnddown=-1;
}
if (y+leftAndright < 5) {
leftAndright=1;
}
if (y+leftAndright > main.getHeight()-14) {
leftAndright=-1;
}
(...)
Small ball class:
public class Small {
int x = 20;
int y=20;
private static final int sizeOfSmall = 10;
int upAnddown = 1;
int leftAndright = 1;
private Main main;
public Small(Main main){
this.main=main;
}
public Small(int j){
ArrayList<Small> my_array = new ArrayList<Small>(j);
for (int i = 0; i < my_array.size(); i++) {
i=j;
my_array.add(new Small(i));
}
}
void move() throws InterruptedException{
//////////////////////////////////////
if (x+upAnddown < 0) {
upAnddown=1;
}
// ERROR
if (x+upAnddown > main.getWidth()-30) {
upAnddown=-1;
}
if (y+leftAndright < 0) {
leftAndright=1;
}
if (y+leftAndright > main.getHeight()-30) {
leftAndright=-1;
}
(...)
ERROR:
Exception in thread "main" java.lang.NullPointerException
at test2.Small.move(Small.java:56)
at test2.Main.moveSmall(Main.java:34)
at test2.Main.main(Main.java:67)
The while(true) will take all UI thread time. You need to put it in a thread to avoid that.
That's why balls stay still.
new Thread(new Runnable(){
public void run(){
while(true) {
main.moveBig();
main.moveSmall();
main.repaint();
Thread.sleep(15);
}
}
}).Start();
The NullPointerException may be related to this issue, I'm not sure. I don't see anything else that could raise it.
Related
Concurrent writing elements into the ConcurrentHashMap admits element. Requirements: writing must be done in different threads. Is there way to use advantages of the ConcurrentHashMap and do writing without blocking and sleeping?
Is there good code for iterator that accessed from different treads. Or is there other good variant to keep ieratian looking on the effectively-final requirement?
public class Task3v2 {
public static void main(String[] args) {
System.out.println("ConcurrentHashMap : "+timeIt(new ConcurrentHashMap<Integer, String>()));
}
static Iterator<Integer> integerIterator;
static {createIterator();}
private static void createIterator() {
integerIterator=
Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList()).iterator();
}
public static double timer(Runnable block) {
long start = System.nanoTime();
try {
block.run();
} finally {
long end = System.nanoTime();
return(end - start);
}
}
public static double timeIt(Map<Integer, String> map){
return timer(
()->{
new Thread(()->{
fillMap(map);
System.out.println("invoked");
readMap(map);
}).start();
});
}
private static void fillMap(Map<Integer, String> map){
int[] index = new int[1];
String[] tmp = new String[1];
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0; i< 100; i++){
index[0] = i;
tmp[0] = "Name"+i;
new Thread(()->{
int a = integerIterator.next();
System.out.println("a :"+a);
map.put(a,"Name"+a);
}
).start();
}
}
private static void readMap(Map<Integer, String> map){
int[] index2 = new int[1];
for(int i = 0; i< 100; i++){
index2[0]=i;
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(()->{
System.out.println("map.get(index2[0]) :"+map.get(index2[0]));
}).start();
}
}
}
Finally the map must pass following tests:
public class Task3Test {
static ConcurrentHashMap<Integer, String> map;
#BeforeClass
public static void fillMap(){
map = new ConcurrentHashMap<>();
timeIt(map);
}
#Test
public void elementPresenceTest(){
//GIVEN
//map;
//WHEN
List<Integer> actualPresenceList = Stream.iterate(0, i -> i + 1).limit(100)
.filter(n->(map.entrySet().stream().map(Map.Entry::getKey)
.anyMatch(m->(n.equals(m))))).collect(Collectors.toList());
actualPresenceList.forEach(System.out::println);
System.out.println("size"+actualPresenceList.size());
//THEN
List<Integer>expectedPresenceList = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toList());
assertThat(actualPresenceList, Matchers.contains(expectedPresenceList));
}
#Test
public void elementAmountTest() {
assertThat(map.entrySet(), Matchers.hasSize(100));
}
}
Iterator is not acceptable for concurrency. Solution is:
static Queue integerQueue = Stream.iterate(0, i -> i + 1).limit(100).collect(Collectors.toCollection(LinkedBlockingQueue::new));
There is needed to keep sleeping for the readMap() method to provide time for the writing method. If there is needed to keep any data structure on adding new elements in concurrency environment, it should be used queue instead of map.
how can i block the put method when cache reloading is being called.
Example: These are dummy classes not the actual.
Caching class
public class Class1 {
private static Map<Integer, Integer> map = new HashMap<>();
public Class1() {
for (int i = 0; i < 20; i++) {
map.put(i, ++i);
}
}
public void reload() throws InterruptedException {
Map<Integer, Integer> exist = map;
System.out.println("are you waiting ");
System.out.println("waiting over");
map = new HashMap<>();
for (Map.Entry<Integer, Integer> entry : exist.entrySet()) {
map.put(entry.getKey(), entry.getValue());
}
for (int i = 100; i < 120; i++) {
map.put(i, ++i);
}
}
public Map<Integer, Integer> getMap() {
return map;
}
}
Class initializing the cache
public class Class2 {
private static Class1 cache = new Class1();;
public Class1 getCache() {
return cache;
}
public void reload() throws InterruptedException {
cache.reload();
}
}
class using the cache
package com.diaryreaders.corejava.algorithms.dp;
public class Class3 {
public static void main(String[] args) {
final Class2 klass = new Class2();
Runnable runn1 = new Runnable() {
#Override
public void run() {
int i = 50, j = 50;
while (i < 100) {
System.out.println("I am stuck due to lock");
klass.getCache().getMap().put(i++, j++);
System.out.println(klass.getCache().getMap());
}
}
};
Runnable runn2 = new Runnable() {
#Override
public void run() {
try {
System.out.println("Calling reloading");
klass.reload();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
Thread t1 = new Thread(runn1);
Thread t2 = new Thread(runn2);
t1.start();
t2.start();
}
}
As thread t2 is calling reloading, t1 should be blocked i.e cache put method be blocked till reloading completes
I have some problem. I am learning to program games and I want to try to program some game on my own. But I hit a snag just at beginning. I have 2 classes. The main class (call Frame) is only for create game frame:
public class Frame extends JFrame{
/**
*
*/
private static final long serialVersionUID = 1L;
Game game;
public Frame() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
game = new Game();
this.add(game.canvas);
this.pack();
this.setResizable(false);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Frame().setVisible(true);;
}
});
}
}
It goes correctly. But I have created a second class (call Game), that is supposed to provide game loop:
public class Game implements Runnable{
public Canvas canvas;
Thread thread;
BufferStrategy bs;
Graphics g;
//Variables for game loop
private int fps, timePerTick;
double now, lastTime;
private double delta;
Game(){
initVariables();
canvas = new Canvas();
canvas.setPreferredSize(new Dimension(300, 300));
}
private void initVariables(){
//create and start thread
thread = new Thread(this);
thread.start();
}
private void tick(){
}
private void render(){
bs = canvas.getBufferStrategy();
if (bs == null){
canvas.createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.drawRect(0, 0, 50, 50);
bs.show();
g.dispose();
}
private void initRun(){
delta = 0;
lastTime = System.nanoTime();
fps = 30;
timePerTick = 1000000000/fps;
}
#Override
public void run() {
initRun();
int timer=0;
int ticks=0;
while(true){
now = System.nanoTime();
delta += (now - lastTime) / timePerTick;
timer += (now - lastTime);
lastTime = now;
if(delta>=1){
tick();
render();
delta--;
ticks++;
}
if (timer>1000000000){
System.out.println("FPS: "+ticks);
timer = ticks = 0;
}
}
}
}
The problem was in value of variable call FPS. When I set FPS in method call initRun() to 10, everything goes correctly. (simply thanks to method run() program wrote "FPS: 60" every second, and in frame was draw a rectangle).
But when I set FPS to (for example) 30, there was the problem. There was exception call "Exception in thread "Thread-1" java.lang.IllegalStateException: Component must have a valid peer" in render() method, concretely at instruction "canvas.createBufferStrategy(3);".
(image of exception)
What can I do? Where is problem? I am not good in speaking english, so I don't understand this Exception and I don't know, what I can do...Please help me! Thanks.
I've tried with code below. please guide me where i am wrong??? The desired output is like..
m(delay)e(delay)s(delay)s(delay)a(delay)g(delay)e.
import java.util.*;
import java.applet.*;
import java.awt.*;
/*<applet code="MessageWithDelay" width=400 height=200>
</applet>*/
public class MessageWithDelay extends Applet implements Runnable {
Thread t;
//char msg[] ={"m","e","s","s","a","g","e"};
String str = "message";
Graphics bufferg;
Image buffer;
int counter=0,x=str.length(),i=0;;
public void init() {
//initializa the thread
t = new Thread(this);
t.start();
Dimension d = getSize();
buffer = createImage(d.width,d.height);
}
public void run() {
try {
while(true)
{
//requesting repaint
repaint();
if(counter==x)
{
Thread.sleep(200);
counter=0;
i=0;
}
else
{
Thread.sleep(400);
}
}
}
catch(Exception e) {
}
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
if(bufferg == null) {
Dimension d = getSize();
bufferg.setColor(Color.green);
g.setFont(new Font("Comic Sans MS",Font.BOLD,36));
bufferg.drawString(str.charAt(i)+"",20,20);
counter++;
i+=1;
//update screen
g.drawImage(buffer,0,0,this);
}
}
}
I am working on command prompt and its giving me bunch of different errors. I want to know why the errors occurring if anyone could explain me by trying it. Thanx in advance.
The problems I found include:
Use JApplet instead of Applet.
In the init method, create the buffer before starting the thread.
Update the buffer with the letters in the run method. The paint method just paints. No calculations.
Here's the working code. I formatted the code in Eclipse, an integrated development environment (IDE) for Java development.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import javax.swing.JApplet;
/*<applet code="MessageWithDelay" width=400 height=200>
</applet>*/
public class MessageWithDelay extends JApplet implements Runnable {
private static final long serialVersionUID = 1722008447683646619L;
Thread t;
String str = "message";
Image buffer;
#Override
public void init() {
Dimension d = getSize();
buffer = createImage(d.width, d.height);
// Initialize the thread
t = new Thread(this);
t.start();
}
#Override
public void run() {
int x = 40;
int y = 40;
for (int i = 0; i < str.length(); i++) {
Graphics g = buffer.getGraphics();
g.setFont(new Font("Comic Sans MS", Font.BOLD, 36));
g.setColor(Color.GREEN);
g.drawString("" + str.charAt(i), x, y);
g.dispose();
x += 40;
repaint();
try {
Thread.sleep(1000L);
} catch (InterruptedException e) {
}
}
}
#Override
public void update(Graphics g) {
paint(g);
}
#Override
public void paint(Graphics g) {
g.drawImage(buffer, 0, 0, this);
}
}
I am trying to implement a busy waiting mechanism, using 2 flags. I get a deadlock, but just can't understand why... it looks to me as if it should work...
sorry for the long code, That's the shortest I succeeded to make it.
package pckg1;
public class MainClass {
public static void main(String[] args) {
Buffer b = new Buffer();
Producer prod = new Producer(b);
Consumer cons = new Consumer(b);
cons.start();
prod.start();
}
}
class Producer extends Thread {
private Buffer buffer;
public Producer(Buffer buffer1) {
buffer = buffer1;
}
public void run() {
for (int i = 0; i < 60; i++) {
while (!buffer.canUpdate)
;
buffer.updateX();
buffer.canUpdate = false;
buffer.canUse = true;
}
}
}
class Consumer extends Thread {
private Buffer buffer;
public Consumer(Buffer buffer1) {
buffer = buffer1;
}
public void run() {
for (int i = 0; i < 60; i++) {
while (!buffer.canUse)
;
buffer.consumeX();
buffer.canUse = false;
buffer.canUpdate = true;
}
}
}
class Buffer {
private int x;
public boolean canUpdate;
public boolean canUse;
public Buffer() {
x = 0;
canUpdate = true;
}
public void updateX() {
x++;
System.out.println("updated to " + x);
}
public void consumeX() {
System.out.println("used " + x);
}
}
I recommend that all the logic concerning Buffer should go into that class.
Also, accessing (and modifying) the flags must be protected, if 2 or more have access to it. That's why I put synchronised to the 2 methods.
class Buffer {
private int x;
private boolean canUpdate;
private boolean canUse;
public Buffer() {
x = 0;
canUpdate = true;
}
public synchronised void updateX() {
x++;
System.out.println("updated to " + x);
canUpdate = false;
canUse = true;
}
public synchronised void consumeX() {
System.out.println("used " + x);
canUpdate = true;
canUse = false;
}
public synchronised boolean canUse() {
return canUse;
}
public synchronised boolean canUpdate() {
return canUpdate;
}
}
Also, remove the canUpdate and canUse writes from the Producer and Consumer classes, and replace the reads (in the conditons) with the methods.
Also, it would be useful to introduce some Thread.sleep(100) in the waiting loops.