首先,我是 JFrame 和所有相关类的新手,所以我仍在学习如何执行此操作。 我当前的目标是在单个 JFrame 上绘制多个图像。到目前为止,我可以绘制 test2.png,但不能绘制 test1.png。如有任何建议或帮助理解 JFrame,我们将不胜感激。这是我的主要类(class):
package com.osj.oneshotjava;
import java.awt.Dimension;
import javax.swing.JFrame;
/**
*
* @author BCG04
*/
public class actorTest {
public static void main(String []args){
JFrame jFrame = new JFrame("OSJ actor test");
jFrame.setPreferredSize(new Dimension(640, 480)); // sets window size
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Actor2 Background = new Actor2(jFrame, "test1.png");
Actor2 testActor = new Actor2(jFrame, "test2.png");
jFrame.pack(); // automatically adjusts window size (also sets window size based on the maximum and minimum sizes)
jFrame.setVisible(true);
}
}
这是 Actor 2:
package com.osj.oneshotjava;
import java.awt.BorderLayout;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
/**
*
* @author BCG04
*/
public class Actor2 { //Purpose: make it easer to add multiple images to a single JFrame using only a single call to Actor2's constuctor rather than repeating the same section of code for each image.
private BufferedImage image = null;
private JLabel jLabel = null;
public Actor2(JFrame jFrame, String filename){
try
{ // try to load a image 'filename' into 'image'
image = ImageIO.read(new File(filename));
}
catch (Exception e)
{
e.printStackTrace(); // if loading fails, print the error
System.exit(1); // then exit with an error code 1 'unsuccessful exit'
}
ImageIcon imageIcon = new ImageIcon(image); // create a new ImageIcon that contains 'image'
JPanel jPanel = new JPanel();
jLabel = new JLabel();
jLabel.setIcon(imageIcon); // set JLabel 'jLabel' to contain 'imageIcon'
jPanel.add(jLabel);
jFrame.getContentPane().add(jPanel, BorderLayout.CENTER); // makes window visible?
}
public JLabel getJLabel(){
return jLabel;
}
}
编辑: - 删除了 Thread.sleep(1000); 和 setLocation(90, 90); ,因为它们与问题或问题无关,我最初让它们进行测试我是否可以移动图像。
-删除了jLabel.setBounds
,因为它似乎没有做任何事情。
+添加了一条评论,阐明了 Actor2 的目标。
我想澄清我的最终目标,我想创建一个使用 Java 的简单 2d 游戏。
最佳答案
这是一个完整的、独立的示例,接近您所追求的。它是为了演示布局管理器的使用。
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
public class DuelingJLabels{
public static void startGui(){
JFrame frame = new JFrame();
JPanel scene = new JPanel();
Actor red = new Actor(Color.RED);
Actor blue = new Actor(Color.BLUE);
//scene.setLayout( null );
scene.add(red.image);
scene.add(blue.image);
//scene.setPreferredSize( new Dimension(512, 512) );
frame.add(scene, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
static class Actor{
int x, y;
JLabel image;
public Actor(Color c){
BufferedImage a = new BufferedImage(64, 64, BufferedImage.TYPE_INT_ARGB);
Graphics g = a.getGraphics();
g.setColor(c);
g.fillOval(0, 0, 64, 64);
image = new JLabel();
image.setIcon(new ImageIcon(a));
image.setLocation( x, y );
image.setSize( 64, 64);
image.addMouseListener( new MouseAdapter(){
@Override
public void mouseClicked(MouseEvent evt){
x = x+64;
if(x>=448){
x = 0;
y += 64;
}
image.setLocation(x, y);
}
});
}
}
public static void main(String[] args){
EventQueue.invokeLater( DuelingJLabels::startGui );
}
}
记下 scene.setLayout(null);
行,如果您运行注释掉该行的示例,那么您将看到两个并排的圆圈。这是因为我们让 swing 处理布局。 scene
是一个默认带有 FlowLayout
的 JPanel。
现在,当您单击圆圈时,什么也不会发生*,因为我们告诉了新位置,但布局管理器重置了位置。 *实际上它们有时会移动,但如果您触发重新验证,它们就会被布局管理器移动。
现在删除对 scene.setLayout(null);
的注释并注意其中的差异。
- 框架很小,我们必须手动调整它的大小才能看到我们的场景。
- 只有一个圆圈。
- 如果您点击圆圈,它就会移动。
那是因为我们已经告诉 swing 不要对 JPanel 场景使用布局管理器。这意味着它不会为我们重新定位场景中的组件,也不会为我们调整大小。
注释的另一行setPreferredSize
使场景告诉父组件它想要的大小。如果您取消注释该行,那么 JFrame 一开始就不会非常小。您应该仅将其与自定义组件一起使用,否则最终可能会与布局管理器发生冲突。
我发现有用的另一个工具是 JLayeredPane因为它给你一些深度。我也觉得这个例子很好。
最后,另一种任意放置自定义图形的技术是@Override PaintComponent。这样您就可以在组件上的任何位置绘制任何内容。
关于java - 在单个 JFrame 上显示多个 JPanel 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60924004/