java - 在单个 JFrame 上显示多个 JPanel 图像

标签 java swing jframe

首先,我是 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); 的注释并注意其中的差异。

  1. 框架很小,我们必须手动调整它的大小才能看到我们的场景。
  2. 只有一个圆圈。
  3. 如果您点击圆圈,它就会移动。

那是因为我们已经告诉 swing 不要对 JPanel 场景使用布局管理器。这意味着它不会为我们重新定位场景中的组件,也不会为我们调整大小。

注释的另一行setPreferredSize使场景告诉父组件它想要的大小。如果您取消注释该行,那么 JFrame 一开始就不会非常小。您应该仅将其与自定义组件一起使用,否则最终可能会与布局管理器发生冲突。

我发现有用的另一个工具是 JLayeredPane因为它给你一些深度。我也觉得这个例子很好。

最后,另一种任意放置自定义图形的技术是@Override PaintComponent。这样您就可以在组件上的任何位置绘制任何内容。

关于java - 在单个 JFrame 上显示多个 JPanel 图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60924004/

相关文章:

java - 使用 SwingEventMonitor 监控其他应用程序?

java - 数组到字符串以附加到 JFrame GUI 中的文本区域?

java - 如何捕获 throws 子句中列出的异常

java - 用于为 Java 定义关系数据库结构的图形实用程序

java - @Autowired BeanCreationException 与 JUnit

java - 如何更改滚动面板中按钮的大小

java - JPanels、JFrames 和 Windows,天哪!

java - KeyListener 不响应按键输入

当我将它放入它自己的方法中时,Java gui 没有显示

java - jaxws复杂类型包