1

JPanel に画像を追加していますが、画像が途切れています。私はもともと BorderLayout を試していましたが、それは 1 つの画像に対してのみ機能し、他の画像を追加すると画像のカットオフが追加されました。だから私は他のレイアウトに切り替えました.私が得ることができる最良かつ最も近いものはBoxLayoutでしたが、それは受け入れられない非常に大きなカットオフを追加します.

だから基本的に; コードに存在するような悪影響を与えることなく、(カスタム JComponent から) 画像をカスタム JPanel に追加するにはどうすればよいですか。

カスタム JPanel:

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.BoxLayout;
import javax.swing.JPanel;
import javax.swing.Timer;

public class GraphicsPanel extends JPanel implements MouseListener {
    private Entity test;
    private Timer timer;
    private long startTime = 0;
    private int numFrames = 0;
    private float fps = 0.0f;

    GraphicsPanel() {      
        test = new Entity("test.png");
        Thread t1 =  new Thread(test);
        t1.start();

        Entity ent2 = new Entity("images.jpg");
        ent2.setX(150);
        ent2.setY(150);
        Thread t2 = new Thread(ent2);
        t2.start();

        Entity ent3 = new Entity("test.png");
        ent3.setX(0);
        ent3.setY(150);
        Thread t3 = new Thread(ent3);
        t3.start();

        //ESSENTIAL COMMENT ANY OF THESE and you will see the problem immediately
        //You can use ANY image to reproduce the problem
        setLayout(new BoxLayout(this, BoxLayout.X_AXIS));
        add(test);
        add(ent2);
        add(ent3);

        //GAMELOOP
        timer = new Timer(30, new Gameloop(this));
        timer.start();
        addMouseListener(this);
    }

    @Override
    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g.create();
        g2.setClip(0, 0, getWidth(), getHeight());

        g2.setColor(Color.BLACK);
        g2.drawString("FPS: " + fps, 1, 15);
    }

    public void getFPS()
    {
        ++numFrames;
        if (startTime == 0) {
            startTime = System.currentTimeMillis();
        } else {
            long currentTime = System.currentTimeMillis();
            long delta = (currentTime - startTime);
            if (delta > 1000) {
                fps = (numFrames * 1000) / delta;
                numFrames = 0;
                startTime = currentTime;              
            }
        }
    }

    public void mouseClicked(MouseEvent e) {}
    public void mousePressed(MouseEvent e) {}
    public void mouseReleased(MouseEvent e) {}
    public void mouseEntered(MouseEvent e) { }
    public void mouseExited(MouseEvent e) { }

    class Gameloop implements ActionListener
    {
        private GraphicsPanel gp;

        Gameloop(GraphicsPanel gp) {
            this.gp = gp;
        }

        public void actionPerformed(ActionEvent e) {
            try {
                gp.getFPS();
                gp.repaint();
            } catch (Exception ez) { }
        }
    }
}

メインクラス:

import java.awt.EventQueue;
import javax.swing.JFrame;

public class MainWindow
{
    public static void main(String[] args)
    {
        new MainWindow();
    }

    private JFrame frame;
    private GraphicsPanel gp = new GraphicsPanel();

    MainWindow()
    {
        EventQueue.invokeLater(new Runnable() {
            public void run() {

                frame = new JFrame("Graphics Practice");
                frame.setSize(680, 420);
                frame.setVisible(true);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                frame.add(gp);
            }
        });
    }
}

カスタム JComponent

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import javax.swing.JComponent;

public class Entity extends JComponent implements Runnable {
    private BufferedImage bImg;
    private int x = 0;
    private int y = 0;
    private int entityWidth, entityHeight;
    private String filename;

    Entity(String filename) {
        this.filename = filename;       
    }

    public void run() {
        bImg = loadBImage(filename);
        entityWidth = bImg.getWidth();
        entityHeight = bImg.getHeight();
        setPreferredSize(new Dimension(entityWidth, entityHeight));
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g.create();

        g2d.drawImage(bImg, x, y, null);

        g2d.dispose();
    }

    public BufferedImage loadBImage(String filename) {
        try {
            bImg = ImageIO.read(getClass().getResource(filename));
        } catch (Exception e) { }
        return bImg;
    }

    public int getEntityWidth() { return entityWidth; }
    public int getEntityHeight() { return entityHeight; }

    public int getX() { return x; }
    public int getY() { return y; }
    public void setX(int x) { this.x = x; }
    public void setY(int y) { this.y = y; }
}
4

2 に答える 2

2

私が気づいたことの1つは、希望するサイズが正しく計算されていないことです。希望するサイズを画像のサイズに設定します。問題は、(x、y)で画像をペイントすることです。したがって、推奨サイズはそれを考慮に入れる必要があります。

そうでなければ、私は質問を理解できず、画像のサイズが大きいか、小さいか、同じサイズかなどがわからないため、コードを実行しても役に立ちません。

于 2010-03-17T15:25:21.327 に答える
1

@camickrは、既存のアプローチで期待する結果が得られない理由について正しいと思われます。

JInternalFrame別の方法として、内での使用を検討することもできますJDesktopPane。このように、画像は個別に移動、サイズ変更、スクロールできるドキュメントになります。記事「内部フレームの使用方法」では、そのような実装がどのように見えるかについて説明しています。このは、フレームをずらしてメニューから選択する簡単な方法を示しています。

于 2010-03-17T16:19:13.090 に答える