亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

JPanel 位置被 BufferStrategy 重擊

JPanel 位置被 BufferStrategy 重擊

RISEBY 2021-12-22 15:59:44
我有一個 JFrame,我向其中添加了一個 JPanel。我正在做一些動畫,所以我實現了一個 BufferStrategy 來渲染。我還有一個渲染循環,以在運行時保持渲染。如果我像往常一樣運行程序,JPanel 就會正確呈現。當然,然后沒有動畫。如果我使用循環和 hte BufferedStrategy 運行它,則 JPanel 將擴展到應用程序的完整大小,并位于 JFrame 的標題欄下方。我找不到發生這種情況的充分理由,但這令人沮喪,因為我需要做一些精確的繪圖,并且不能將其中的一些隱藏在標題欄下方。我認為這是因為我沒有調用super.paintComponent(),但無論如何我真的不應該調用它,因為我是自己渲染的,而不是在正常的 Swing 管道中。是否需要進行一些 API 調用才能使 JPanel 在渲染調用中正確定位?import java.awt.Graphics;import java.awt.image.BufferStrategy;import javax.swing.JFrame;public class MainFrame extends JFrame implements Runnable {    private static final long serialVersionUID = 2190062312369662956L;    protected ViewPanel _viewPanel = null;    public MainFrame() {        setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );        createGui();    }    protected void createGui() {        setSize( 600, 400 );        setTitle( "Exact Positioning" );        setVisible( true );        setResizable( false );        _viewPanel = new ViewPanel();        _viewPanel.init();        // the layout type shouldn't matter since this is the only component in the frame        add( _viewPanel );    }    @Override    public void run() {        // setup        this.createBufferStrategy( 2 );        BufferStrategy buffStrategy = this.getBufferStrategy();        // render loop        while( true ) {            Graphics g = null;            try {                g = buffStrategy.getDrawGraphics();                _viewPanel.render( g );            } finally {                g.dispose();            }            buffStrategy.show();            // pause a tad            try {                Thread.sleep( 500 );            } catch (InterruptedException e) {                // Required catch block                e.printStackTrace();            } catch (Exception e) {                System.out.println( "Sorry, don't know what happened: " + e.toString() );                e.printStackTrace();            }        }    }
查看完整描述

1 回答

?
PIPIONE

TA貢獻1829條經驗 獲得超9個贊

Swing 使用它自己的渲染引擎,這是一種被動實現。你試圖用你自己的、主動的、渲染引擎來規避這個問題,這兩者會發生沖突。

因為BufferStrategy屬于JFrame,它是在它的范圍內創建的,所以0x0將是 的左上角位置,而JFrame不是JPanel。

Swing 的渲染引擎會自動為您進行這種翻譯。

您有兩個基本選擇。

  1. 不要以 a 為基礎進行渲染,JPanel而只是有一個獨立執行此操作的“渲染”類(并使用 aCanvas而不是 theJFrame作為 的基礎BufferStrategy

  2. 使用 SwingTimer作為主要渲染引擎

Timer基于Swing的示例...

import java.awt.Color;

import java.awt.Dimension;

import java.awt.EventQueue;

import java.awt.Graphics;

import java.awt.event.ActionEvent;

import java.awt.event.ActionListener;

import java.util.Random;

import javax.swing.JFrame;

import javax.swing.JPanel;

import javax.swing.Timer;


public class Test {


    public static void main(String[] args) {

        new Test();

    }


    public Test() {

        EventQueue.invokeLater(new Runnable() {

            @Override

            public void run() {

                JFrame frame = new JFrame();

                frame.add(new ViewPanel());

                frame.pack();

                frame.setLocationRelativeTo(null);

                frame.setVisible(true);

            }

        });

    }


    public static class ViewPanel extends JPanel {


        private static int APP_WIDTH = 600;

        private static int APP_HEIGHT = 400;


        private static final long serialVersionUID = -8019663913250286271L;


        public ViewPanel() {

            setBackground(Color.GRAY);

            Timer timer = new Timer(5, new ActionListener() {

                @Override

                public void actionPerformed(ActionEvent e) {

                    repaint();

                }

            });

            timer.start();

        }


        public void init() {

        }


        @Override

        public Dimension getPreferredSize() {

            return new Dimension(APP_HEIGHT, APP_HEIGHT);

        }


        @Override

        protected void paintComponent(Graphics g) {

            super.paintComponent(g);

            render(g);

        }


        // Where I do the drawing. It's called from the rendering loop in the JFrame

        public void render(Graphics g) {


            // refresh the background since we're not relying on paintComponent all the time

            Color bgc = getBackground();

            g.setColor(bgc);

            g.fillRect(0, 0, APP_WIDTH, APP_HEIGHT);


            // just paint a moving box

            drawBox(g);


            // draw a line to prove correctness. In the loop, you can see part of this line is hidden

            // underneath the title bar

            g.setColor(Color.red);

            g.drawLine(0, 0, APP_WIDTH, APP_HEIGHT);

        }


        protected void drawBox(Graphics g) {


            // get a random color

            Random ran = new Random();

            int red = ran.nextInt(255);

            int grn = ran.nextInt(255);

            int ble = ran.nextInt(255);

            Color colour = new Color(red, grn, ble);

            g.setColor(colour);


            // get a random position        

            int x = ran.nextInt(APP_WIDTH - 50);

            int y = ran.nextInt(APP_HEIGHT - 50);


            // draw it

            g.fillRect(x, y, 50, 50);

        }

    }

}


查看完整回答
反對 回復 2021-12-22
  • 1 回答
  • 0 關注
  • 154 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號