PDA

Просмотр полной версии : Простой апплет на Java


Kvarx
18.12.2007, 02:28
По сути в объекте должно быть несколько объектов-кругов, которые будут двигаться до стенки и отскакивать, каждый в своем потоке.

Проблема в том, что не знают как перерисовавыть их в апплете, как сделано - они перирисовыются только при изменинии размеров апплетов.

И еще хотел отлавлитвать событие о изменении размеров окна и обновлять предполагамые размеры для кругов, но тоже не пашет.

Можно сказать, что первая прога на яве, так что код далек от совершенства.

import java.awt.*;
import java.applet.*;

public class Circle extends Component implements Runnable{
Color color;
int radius, posX, posY, velocity;
Dimension dim;
Graphics gr;

public Circle(int red, int green, int blue, int radius, int posX, int posY, int velocity, Dimension dim, Graphics gr) {
this.color = new Color(red, green, blue);
this.radius = radius;
this.posX = posX;
this.posY = posY;
this.velocity = velocity;
this.dim = dim;
this.gr = gr;
}

public void move() {
posX = posX + velocity;
if ((velocity > 0 && posX + radius >= dim.getWidth()) ||
(velocity < 0 && posX - radius <= 0))
{
velocity = -velocity;
}
}

public void paint(Graphics g)
{
g.setColor(color);
g.fillOval(posX, posY, radius*2, radius*2);
}

public void run()
{
Thread thisThread = Thread.currentThread();
Graphics g = getGraphics();
while (true) {
move();
repaint();

try {
Thread.currentThread().sleep(100);
} catch (InterruptedException e) {}
}
}

public void updateDim(Dimension dim)
{
this.dim = dim;
}
}


import java.applet.*;
import java.awt.*;
import java.awt.event.*;

public class Race extends Applet implements KeyListener{
Circle []c;
Thread []t;
Dimension dim;
int size, width, height, radius;

public void destroy() {
super.destroy();
}

public void init() {
size = 10;
width = 800;
height = 600;
radius = 10;

setSize(width, height);
dim = new Dimension(width, height);

c = new Circle[size];
t = new Thread[size];

for(int i = 0; i < size; i++ ){
c[i] = new Circle((int)(Math.random()*255), (int)(Math.random()*255),
(int)(Math.random()*255), radius, 0, (height/size-radius)*(i+1), 20, dim, getGraphics());
t[i] = new Thread(c[i]);
}

addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent m_e)
{
for(int i = 0; i < size; i++ ){
c[i].updateDim(getSize());
}
}
});

}

public void paint(Graphics g) {
super.paint(g);
g.drawString("kvarx", width - 150, height - 5);

for (int i = 0; i < size; i++)
{
c[i].paint(g);
}
}

public void start() {
for (int i = 0; i < size; i++)
{
t[i].start();
}
}

public void stop() {
super.stop();
}

public void keyPressed(KeyEvent k_e)
{

}

public void keyTyped(KeyEvent k_e)
{

}

public void keyReleased(KeyEvent k_e)
{

}
}

EjikVTumane
18.12.2007, 11:30
Ты не прав в следующем: отрисовка идет в методе paint этот метод вызывается только и только тогда когда было известно, что состояние компонента обновилось и его надо перерисовать.
Соответственно у тебя и получается, что он перерисовывается только когда ты изменяешь размер.
Самое простое изменение, которое можно сюда внести - это с определенной переодичностью дергать метод repaint() который будет оповещать о том, что окно апплета надо перерисовать.

Вообще есть немного более красивый вариант - у тебя объекты Circle в любом случае наследуются от Component, поэтому не риуй руками их каждый раз и просто добавляй их внутрь окна апплета (правдо желательно все же использовать lightweight компоненты в качестве базового класса - JComponent)
предварительно у апплета убери лэйаут setLayout(null) и просто меняй координаты объектов Circle, помещенных в окно апплета. Таким образом никакого кода дополнительно отвечающего за перерисовку не потребуется.

Также поток на каждый объект - это расточительство используй один поток для обработки всех объектов.
Вообще в пятой яве появились новые средства для работы с потоками - можешь ознакомиться с пакетом java.util.concurrent.*.

Где-то так... :)