JPanel Layout Image Cutoff - PullRequest
       29

JPanel Layout Image Cutoff

1 голос
/ 17 марта 2010

Я добавляю изображения в JPanel, но изображения обрезаются. Первоначально я пробовал BorderLayout, но это работало только для одного изображения, а добавление других добавляло обрезание изображения. Поэтому я переключился на другие макеты, и лучшим и самым близким, что я мог получить, был 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; }
}

Ответы [ 2 ]

2 голосов
/ 17 марта 2010

Одна вещь, которую я заметил, это то, что ваш предпочтительный размер рассчитан неправильно. Вы устанавливаете предпочтительный размер, равный размеру изображения. Проблема в том, что вы рисуете изображение в точке (x, y). Поэтому предпочтительный размер должен принимать это во внимание.

В противном случае я не понимаю вопроса, и выполнение кода не помогает, поскольку я не знаю размера ваших изображений, должны ли они быть большими, маленькими, того же размера и т. Д.

1 голос
/ 17 марта 2010

@ camickr, вероятно, прав насчет того, почему ваш существующий подход не дает желаемых результатов.

В качестве альтернативы вы можете рассмотреть возможность использования JInternalFrame в пределах JDesktopPane. Таким образом, ваши изображения будут документами, которые можно перемещать, изменять размер и прокручивать по отдельности. Статья Как использовать внутренние кадры дает представление о том, как может выглядеть такая реализация. Этот пример показывает простой подход к разбивке кадров и выбору их из меню.

...