[英]JPanel: automatically paint at creation?
這一定是微不足道的和直接的,但我無法弄清楚。
這是我的JPanel外觀,它被添加到JFrame中:
private class RadarPanel extends JPanel {
public RadarPanel() {
super();
this.repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
//painting logic here
//repaint in 500 ms
this.repaint(500);
}
}
現在,當我調整JFrame的大小時,這個JPanel一直都在重新繪制。 但是,當我不調整JFrame的大小時,即使我在構造函數中調用了repaint,似乎也未調用JPanel的paintComponent方法。
有什么建議嗎? 謝謝。
更新:
更完整的代碼(除繪圖邏輯外的所有內容):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class PlayerRadar extends JFrame {
private static final long serialVersionUID = 230324190;
//settings
private static final int windowWidth = 300;
private static final int windowHeight = 300;
private static final int maxDistance = 250;
//components
private PlayerRadar radarWindow;
private JPanel radarPanel;
public PlayerRadar(String title) {
super(title);
//set reference
radarWindow = this;
//create radar window
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
this.setAlwaysOnTop(true);
this.setBackground(new Color(0xFFFFFF));
this.setBounds(screenSize.width - windowWidth, 0, windowWidth, windowHeight);
this.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
radarWindow.setVisible(false);
}
});
this.setVisible(true);
//create a JPanel for drawing
radarPanel = new RadarPanel();
radarPanel.setBounds(0, 0, windowWidth, windowHeight);
radarPanel.setBackground(new Color(0xFFFFFF));
//add to frame
this.getContentPane().add(radarPanel);
}
private class RadarPanel extends JPanel {
private static final long serialVersionUID = 230324191;
private static final int repaintInterval = 500;
public RadarPanel() {
super();
}
@Override
public void paint(Graphics g) {
super.paint(g);
//draw player oval (center of the frame)
g.setColor(Color.BLUE); //blue
int ovalWidth = (int) Math.round(this.getWidth() / 30);
int ovalHeight = (int) Math.round(this.getHeight() / 30);
int playerLocalX = (int) Math.round(this.getWidth() / 2);
int playerLocalY = (int) Math.round(this.getHeight() / 2);
int ovalX = playerLocalX - ovalWidth / 2;
int ovalY = playerLocalY - ovalHeight / 2;
g.fillOval(ovalX, ovalY, ovalWidth, ovalHeight);
g.setColor(Color.BLACK); //black
g.drawOval(ovalX, ovalY, ovalWidth, ovalHeight);
//get info of the player itself
PlayerInfo thisPlayer = GameUtil.getPlayerInfo();
float playerPosZ = thisPlayer.position[0];
float playerPosX = thisPlayer.position[2];
//float playerRotRad = thisPlayer.rotation;
//set rectangle specs
int rectWidth = this.getWidth() / 40;
int rectHeight = this.getWidth() / 40;
//only continue if we have information about our player
if (thisPlayer != null) {
//get nearby players
ArrayList<PlayerInfo> playersInfo = GameUtil.getNearbyPlayers();
//for each other player, draw a rectangle
for (PlayerInfo playerInfo : playersInfo) {
//get data
float posZ = playerInfo.position[0];
float posX = playerInfo.position[2];
//float rotRad = playerInfo.rotation;
//calculate relative x and y
int rectX = playerLocalX + Math.round((posX - playerPosX) / maxDistance * this.getWidth() / 2) - rectWidth / 2;
int rectY = playerLocalY + ovalHeight / 2 + Math.round((playerPosZ - posZ) / maxDistance * this.getHeight() / 2) - rectHeight / 2;
//draw rectangle
g.setColor(Color.RED);
g.fillRect(rectX, rectY, rectWidth, rectHeight);
g.setColor(Color.BLACK);
g.drawRect(rectX, rectY, rectWidth, rectHeight);
}
}
//repaint soon
this.repaint(repaintInterval);
}
}
}
您第一次正確的地方。 自定義繪畫是通過paintComponent()方法而不是paint()方法完成的。
永遠不要從paintComponent()方法中調用repaint(),因為那樣會導致無限循環。
如果要對繪畫進行動畫處理,則應使用Swing計時器來安排動畫。
您不應該使用use setSize()。 那是布局管理器的工作。 相反,您可以覆蓋面板的getPreferredSize()方法(或使用setPreferredSize()),然后可以對框架進行包裝(而不是設置其大小)。
在使框架可見之前,應將面板添加到框架,否則面板的大小為(0,0),這意味着沒有要繪畫的東西。
在顯示表單並初始化圖形之前,它不會重新繪制。 我不認為在構造函數中調用repaint是個好主意。 組件可見后,它將重新繪制。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.