Problem with having Canvas and Panel rendering on Frame for animation
i have problem with canvas Jpanel and need optimized solution i got this design from one of the post on this forum.
i have three classes :
one is for animation which is canvas(BallPanel), one is frame(Main) and one is panel for swing controls(ControlPanel)
Main is rending both Controlpanel and BallPanel, but in the end, i can't see the drawworld() rendering from BallPanel but i can only ControlPanel.
I can't see animation and black background,seems like controlpanel is all on frame and canvas (black background) is behind/underneath that or somewhere but invisible
BallPanel:
public BallPanel()
{
try {
this.aBall = (BallServer) Naming
.lookup("rmi://localhost/BouncingBalls");
} catch (Exception e) {
System.out.println("Exception: " + e);
}
box = new Box(0, 0, BOX_WIDTH, BOX_HEIGHT);
setPreferredSize(new Dimension(800, 600));
setIgnoreRepaint(true);
// Wire up Events
// MouseHandler mouseHandler = new MouseHandler();
// addMouseMotionListener(mouseHandler);
// addMouseListener(mouseHandler);
}
public void drawworld() throws RemoteException {
if (strategy == null || strategy.contentsLost())
{
// Create BufferStrategy for rendering/drawing
this.createBufferStrategy(2);
strategy = getBufferStrategy();
Graphics g = strategy.getDrawGraphics();
this.g2 = (Graphics2D) g;
}
// Turn on anti-aliasing
this.g2.setRenderingHint (RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// box.draw(this.g2); // this can be another but it's also not working
// Render Background
this.g2.setColor(Color.BLACK);
this.g2.fillRect(0, 0, getWidth(), getHeight());
serball = aBall.getState();// other version UNcomment this line
for (int i = 0; i < currentNumBalls; i++) {
this.g2.setColor(serball[i].getBallColor(velocity.getLength()));
this.g2
.fillOval((int) (serball[i].position.getX() - serball[i]
.getRadius()),
(int) (serball[i].position.getY() - serball[i]
.getRadius()), (int) (2 * serball[i]
.getRadius()), (int) (2 * serball[i]
.getRadius()));
}
public void mainLoop() {
long previousTime = System.currentTimeMillis();
long currentTime = previousTime;
long elapsedTime;
long totalElapsedTime = 0;
int frameCount = 0;
while (true) {
currentTime = System.currentTimeMillis();
elapsedTime = (currentTime - previousTime); // elapsed time in
// seconds
totalElapsedTime += elapsedTime;
if (totalElapsedTime > 1000) {
currentFrameRate = frameCount;
frameCount = 0;
totalElapsedTime = 0;
}
try {
drawworld();
开发者_运维知识库 } catch (RemoteException e1) {
e1.printStackTrace();
}
try {
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
previousTime = currentTime;
frameCount++;
}
}
public void start()
{
mainLoop();
}
the Main class above start() is calling from here :
public static void main(String[] args)
{
JFrame frame = new JFrame("BallBounce");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.Y_AXIS));
BallPanel ballCanvas = new BallPanel();
ControlPanel controlPanel = new ControlPanel(ballCanvas);
frame.getContentPane().add(ballCanvas);
frame.getContentPane().add(controlPanel);
frame.pack();
frame.setVisible(true);
ballCanvas.start();
}
this is controlpanel whichis working as controller:
public class ControlPanel extends JPanel {
private BallPanel mainPanel;
private JButton resetButton;
public ControlPanel(BallPanel mainPanel)
{
this.setPreferredSize(new Dimension(200, 60));
this.setMaximumSize(new Dimension(5000, 100));
this.mainPanel = mainPanel;
....
..
..
private class ButtonHandler implements ActionListener
{
public void actionPerformed(ActionEvent e)
{
JButton source = (JButton)e.getSource();
if (source == resetButton)
{
mainPanel.clearBalls();
}
Many thanks for any help and how we could handle such GUI with RMI animation and swing control for interacting/controlling that can somebody tell optimized way. jibby lala
P.S: i thought there is some thread problem while i m calling the remote method and rendering the drawworld, either of thread is going on suspension or blocked
cross post: http://www.coderanch.com/forums/jforum?module=posts&action=edit&post_id=2406332&start=0
i made this with timer but the problems persist please help:
public CopyOfCleanBallPanel2() throws IOException, InterruptedException {
frame = new JFrame("simple gaming loop in java");
frame.setSize(BOX_WIDTH, BOX_WIDTH);
frame.setResizable(false);
displayCanvas = new CustomCanvas();
displayCanvas.setLocation(0, 0);
displayCanvas.setSize(CANVAS_WIDTH, CANVAS_HEIGHT);
displayCanvas.setBackground(Color.BLACK);
displayCanvas.setFont(new Font("Arial", Font.BOLD, 14));
displayCanvas.setPreferredSize(new Dimension(CANVAS_WIDTH,CANVAS_HEIGHT));
frame.add(displayCanvas);
displayCanvas.requestFocus();
frame.setLocationRelativeTo(null);
try {
this.aBall = (BallServer) Naming
.lookup("rmi://localhost/BouncingBalls");
} catch (Exception e) {
System.out.println("Exception: " + e);
}
frame.pack();
frame.setVisible(true);
aBall.start();
startFrameTimer();
}
/*
* Initializes the frame (also game update) timer.
*/
private void startFrameTimer() {
frameTimer.schedule(new FrameTimerTask(), 1, GAME_TIMER_COOLDOWN);
}
public void updateSimulation() throws RemoteException {
repaintCanvas();
}
/*
* This method gets called by the timer. It updates the game simulation and
* redraws it.
*/
private void onFrameTimer() throws RemoteException {
updateSimulation();
}
/*
* Causes the whole canvas to get repainted.
*/
private final void repaintCanvas() throws RemoteException {
Graphics g = displayCanvas.getGraphics();
drawworld(g);
}
private class FrameTimerTask extends TimerTask {
public void run() {
try {
onFrameTimer();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
/*
* This custom canvas overrides the paint method thus allowing for a custom
* painting on the component.
*/
private class CustomCanvas extends Canvas {
@Override
public void paint(Graphics g) {
// Currently the game message gets drawn over the inner border
// of the canvas so we have to repaint the whole thing.
try {
repaintCanvas();
} catch (RemoteException e) {
e.printStackTrace();
}
}
}
public void drawworld(Graphics g) throws RemoteException {
g.setColor(Color.BLACK);
g.fillRect(0, 0, CANVAS_WIDTH, CANVAS_HEIGHT);
System.out.println("i m in drawworld ");
serBall = aBall.getState1();// other version UNcomment this line
System.out.println("i m in drawworld "+serBall.length);
for (int i = 0; i < currentNumBalls; i++) {
g.setColor(serBall[i].getBallColor(velocity.getLength()));
g
.fillOval((int) (serBall[i].position.getX() - serBall[i]
.getRadius()),
(int) (serBall[i].position.getY() - serBall[i]
.getRadius()), (int) (2 * serBall[i]
.getRadius()), (int) (2 * serBall[i]
.getRadius()));
// Draw our framerate and ball count
g.setColor(Color.WHITE);
g.drawString("FPS: " + currentFrameRate + " Balls: "
+ currentNumBalls, 15, 15);
}
}
Please Help.
It looks like a thread issue as it appears to me you're calling while (true) and Thread.sleep(...) on the EDT, the main Swing thread. Have you read up on Concurrency in Swing? If not, check out the article linked to within. Also strongly consider using a Swing Timer to drive your animation instead of while (true) and Thread.sleep(...).
精彩评论