2013-03-08 2 views
4

Это мой код. Я хотел бы установить размер окна, в котором мяч отскакивает, до размера окна, даже если окно изменяется пользователем, например, восстановление окна или перетаскивание его в размер. Большое спасибо.Как установить размер панели на размер окна, даже если размер окна изменится?

import java.awt.*; 
import javax.swing.*; 
import java.awt.event.*; 

/** 
* One ball bouncing inside a rectangular box. 
* All codes in one file. Poor design! 
*/ 
// Extends JPanel, so as to override the paintComponent() for custom rendering codes. 
public class BouncingBallSimple extends JPanel { 
// Container box's width and height 
private final int BOX_WIDTH = 700; 
private final int BOX_HEIGHT = 700; 

// Ball's properties 
private float ballRadius = 15; // Ball's radius 
private float ballX = ballRadius + 50; // Ball's center (x, y) 
private float ballY = ballRadius + 20; 
private float ballSpeedX = 60; // Ball's speed for x and y 
private float ballSpeedY = 60; 

private static final int UPDATE_RATE = 30; // Number of refresh per second 

/** Constructor to create the UI components and init game objects. */ 
public BouncingBallSimple() { 
    this.setPreferredSize(new Dimension(BOX_WIDTH, BOX_HEIGHT)); 

    // Start the ball bouncing (in its own thread) 
    Thread gameThread; 
    gameThread = new Thread() { 
@Override 
public void run() { 
    while (true) { // Execute one update step 
    // Calculate the ball's new position 
    ballX += ballSpeedX; 
    ballY += ballSpeedY; 
    // Check if the ball moves over the bounds 
    // If so, adjust the position and speed. 
    if (ballX - ballRadius < 0) { 
     ballSpeedX = -ballSpeedX; // Reflect along normal 
     ballX = ballRadius; // Re-position the ball at the edge 
    } else if (ballX + ballRadius > BOX_WIDTH) { 
     ballSpeedX = -ballSpeedX; 
     ballX = BOX_WIDTH - ballRadius; 
    } 
    // May cross both x and y bounds 
    if (ballY - ballRadius < 0) { 
     ballSpeedY = -ballSpeedY; 
     ballY = ballRadius; 
    } else if (ballY + ballRadius > BOX_HEIGHT) { 
     ballSpeedY = -ballSpeedY; 
     ballY = BOX_HEIGHT - ballRadius; 
    } 
    // Refresh the display 
    repaint(); // Callback paintComponent() 
    // Delay for timing control and give other threads a chance 
    try { 
     Thread.sleep(1000/UPDATE_RATE); // milliseconds 
    } catch (InterruptedException ex) { } 
    } 
} 
}; 
    gameThread.start(); // Callback run() 
} 

/** Custom rendering codes for drawing the JPanel */ 
@Override 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); // Paint background 

    // Draw the box 
    g.setColor(Color.CYAN); 
    g.fillRect(0, 0, getWidth(), getHeight()); 

    // Draw the ball 
    g.setColor(Color.BLUE); 
    g.fillOval((int) (ballX - ballRadius), (int) (ballY - ballRadius), 
     (int)(2 * ballRadius), (int)(2 * ballRadius)); 
        Graphics2D comp2D = (Graphics2D) g;     
        comp2D.drawRect(0, 645, 1365, 100); 
        comp2D.setColor(Color.GREEN); 
        comp2D.fillRect(0, 645, 1365, 100); 
        Graphics2D stand = (Graphics2D) g; 
        stand.setColor(Color.BLACK); 
        stand.fillRect(80, 575, 30, 70); 
        Graphics2D sling = (Graphics2D) g; 
        sling.drawArc(15, 570, 90, 50, 50, 250); 
} 

/** main program (entry point) */ 
public static void main(String[] args) { 
    // Run GUI in the Event Dispatcher Thread (EDT) instead of main thread. 
    javax.swing.SwingUtilities.invokeLater(new Runnable() { 
    @Override 
    public void run() { 
     // Set up main window (using Swing's Jframe) 
     JFrame frame = new JFrame("Angry Birds for Annie May Tion"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setContentPane(new BouncingBallSimple()); 
     frame.pack(); 
     frame.setVisible(true); 
    } 
    }); 
} 
} 
+0

использование 'BorderLayout'. для получения дополнительной информации см. [Как использовать BorderLayout] (http://docs.oracle.com/javase/tutorial/uiswing/layout/border.html). – mre

+0

thankyou, я попробую это – user2149407

+1

Не устанавливайте предпочтительный размер вашего компонента. –

ответ

0

Это должно быть так же просто, как удаление вызова this.setPreferredSize() в конструкторе. Когда окно будет изменено, оно попросит панель изменить размер. В вашей рутине рисования вы получаете текущие границы панели и подпрыгиваете между ними, поэтому она должна просто работать.

На несвязанной ноте: вы должны заменить aameThread на javax.swing.Timer. Как бы то ни было, вы вызываете запросы на краску из-за потока потока событий, что является плохой идеей.

+0

Нет, вызов repaint() является потокобезопасным. Это один из немногих звонков, которые вы можете сделать из любого потока. Ему также необходимо изменить свои условия, чтобы полагаться на 'getWidth()' и 'getHeight' вместо констант' BOX_WIDTH/BOX_HEIGHT' –

0

Здесь нет простого ответа, потому что вы имеете жестко закодированные значения x, y, w, h. Непростым ответом является использование переменных вместо жестко закодированных значений и динамическая корректировка этих значений внутри метода paintComponent().

+0

Они используют жестко закодированные значения x, y, w, h. comp2D.drawRect (0, 645, 1365, 100); comp2D.fillRect (0, 645, 1365, 100); stand.fillRect (80, 575, 30, 70); sling.drawArc (15, 570, 90, 50, 50, 250); – Java42

2
  1. падения этой линии: this.setPreferredSize(new Dimension(BOX_WIDTH, BOX_HEIGHT));
  2. Где бы вы использовали BOX_WIDTH заменить его getWidth()
  3. Где бы вы использовали BOX_HEIGHT заменить его getHeight()

Это должно сделать трюк.

+0

большое спасибо. Я сделал это, и теперь он работает. Спасибо. – user2149407