我正在向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; }
}
答案 0 :(得分:2)
我注意到的一件事是您的首选尺寸计算不正确。您将首选大小设置为图像的大小。问题是你在(x,y)处绘制图像。因此,首选大小需要考虑到这一点。
否则我不明白这个问题并且运行代码没有帮助,因为我不知道你的图像大小是否应该是大,小,相同大小等。
答案 1 :(得分:1)
@camickr可能是正确的,为什么你现有的方法没有得到你想要的结果。
作为替代方案,您可以考虑在JInternalFrame
内使用JDesktopPane
。通过这种方式,您的图像将是可以单独移动,调整大小和滚动的文档。文章How to Use Internal Frames概述了这种实现的外观。这个example显示了一种简单的方法来交错框架并从菜单中选择它们。