Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby-on-rails-4/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JPanel:在创建时自动绘制?_Java_Swing_Jframe_Jpanel_Paint - Fatal编程技术网

Java JPanel:在创建时自动绘制?

Java JPanel:在创建时自动绘制?,java,swing,jframe,jpanel,paint,Java,Swing,Jframe,Jpanel,Paint,这肯定是相当琐碎和直截了当的,但我无法理解 这就是我的JPanel的样子,它被添加到JFrame中: private class RadarPanel extends JPanel { public RadarPanel() { super(); this.repaint(); } @Override public void paintComponent(Graphic

这肯定是相当琐碎和直截了当的,但我无法理解

这就是我的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的大小时,JPanel的paintComponent方法似乎不会被调用,即使我在构造函数中调用了repaint

有什么建议吗?谢谢

更新:

更完整的代码(除图形逻辑外的所有内容):

导入java.awt.Color;
导入java.awt.Dimension;
导入java.awt.Graphics;
导入java.awt.event.WindowAdapter;
导入java.awt.event.WindowEvent;
导入java.util.ArrayList;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
公共类PlayerRadar扩展了JFrame{
私有静态最终长serialVersionUID=230324190;
//背景
专用静态最终int windowWidth=300;
专用静态最终内窗高度=300;
专用静态最终整数最大距离=250;
//组成部分
私人游乐场雷达窗口;
私人JPanel雷达板;
公共PlayerRadar(字符串标题){
超级(标题);
//设定参考
radarWindow=此;
//创建雷达窗口
维度screenSize=java.awt.Toolkit.getDefaultToolkit().getScreenSize();
此.setAlwaysOnTop(true);
此.setBackground(新颜色(0xFFFFFF));
这个.setBounds(screenSize.width-windowWidth,0,windowWidth,windowHeight);
this.addWindowListener(新的WindowAdapter(){
公共无效窗口关闭(WindowEvent e){
radarWindow.setVisible(假);
}
});
此.setVisible(true);
//为绘图创建JPanel
雷达面板=新雷达面板();
radarPanel.setBounds(0,0,窗宽,窗高);
雷达板背景(新颜色(0xFFFFFF));
//添加到框架
this.getContentPane().add(radarPanel);
}
私有类RadarPanel扩展了JPanel{
私有静态最终长serialVersionUID=230324191;
专用静态最终喷漆重新喷漆间隔=500;
公共雷达板(){
超级();
}
@凌驾
公共空间涂料(图g){
超级油漆(g);
//绘制播放器椭圆形(框架的中心)
g、 setColor(Color.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=播放器本地区-ovalWidth/2;
int ovalY=玩家本地-卵形高度/2;
g、 卵圆形(卵形、卵形、卵形宽、卵形高);
g、 setColor(Color.BLACK);//黑色
g、 drawOval(卵形、卵形、卵形宽、卵形高);
//获取玩家自身的信息
PlayerInfo thisPlayer=GameUtil.getPlayerInfo();
float playerPosZ=thisPlayer.position[0];
float playerPosX=thisPlayer.position[2];
//float playerRotRad=thisPlayer.rotation;
//设置矩形规格
int rectWidth=this.getWidth()/40;
int rectHeight=this.getWidth()/40;
//只有在我们有玩家信息的情况下才能继续
if(thisPlayer!=null){
//找到附近的玩家
ArrayList PlayerInfo=GameUtil.getNearByPlayer();
//为其他玩家绘制一个矩形
for(PlayerInfo PlayerInfo:PlayerInfo){
//获取数据
float posZ=播放器信息位置[0];
float posX=播放器信息位置[2];
//float rotRad=playerInfo.rotation;
//计算相对x和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;
//画矩形
g、 setColor(Color.RED);
g、 fillRect(rectX、rectY、rectWidth、rectHeight);
g、 设置颜色(颜色为黑色);
g、 drawRect(rectX、rectY、rectWidth、rectHeight);
}
}
//尽快重新油漆
这个。重绘(重绘区间);
}
}
}

在显示表单并初始化图形之前,它不会重新绘制。我认为在构造函数中调用重绘不是一个好主意。一旦组件可见,它将重新喷漆。

您将在第一次更正的位置重新喷漆。自定义绘制是在paintComponent()方法中完成的,而不是在paint()方法中完成的

永远不要从paintComponent()方法中调用repaint(),因为这将导致无限循环

如果要设置绘画动画,则应使用摆动计时器来安排动画

您不应该使用use setSize()。这是布局管理器的工作。相反,您可以覆盖面板的getPreferredSize()方法(或使用setPreferredSize()),然后可以打包()框架,而不是设置其大小


在框架可见之前,应该将面板添加到框架中,否则它的大小为(0,0),这意味着没有任何可绘制的内容。

@m0s,这也是我的想法。但当我不在构造函数中添加重绘时,我相信它也不会执行paintComponent。它只在我调整窗口大小一次后才开始更新。刚刚测试过。如果我不调整JFrame的大小,JPanel就永远不会被绘制。当我调整JFrame的大小时,JPanel会每隔500毫秒被绘制和更新一次。你的JFrame够大吗?如果您的JPanel的高度或宽度为0,则不会进行绘制。@lins314159,这是我为JFrame设置的:this.setBounds(screenSize.width-windowWidth,0,windowWidth,windowHeight);这就是我为JPane设定的
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);
    }
    }
}