使用JLabel背景将JLabel添加到JFrame

时间:2017-03-12 20:35:42

标签: java swing jframe jlabel bufferedimage

当我已经添加JLabel作为背景时,我花了两天时间试图找出如何向JFrame添加JLabel。我使用getContentPane()方法创建了一个Container,并添加了背景JLabel(播种时很好),稍后,我想添加另一个JLabel(我是确定存在并且具有32x32图像作为其图标)。但是,第二个JLabel没有显示出来。

这是我的类,其中包含屏幕设置(重要位):

package com.elek.engine.graphics;

import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import java.util.ArrayList;
import java.util.ConcurrentModificationException;

import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;

/**
 * IGNORE THIS LONG JAVADOC COMMENT; IT'S OLD AND NEEDS UPDATED!
 * A shortcut class that makes it easy to create a frame with an image on it. Uses the
 * <code>JFrame</code> class to create the frame and uses the <code>BufferedImage</code>
 * class with a <code>BufferStrategy</code> and the <code>Graphics</code> class to paint
 * the image onto the frame. 
 * <p>
 * An array of integers represents the pixels on the screen. Each element of the pixel 
 * array contains the RGB color value for the corresponding pixel. The pixels are arranged
 * in such a way that in order to access the pixel at coordinate <code><strong>(x, y)</code></strong>,
 * the element at index <code><strong>(x + y * WIDTH)</code></strong> must be referenced, 
 * where <code><strong>x</code></strong> and <code><strong>y</code></strong> are the desired
 * coordinates and <code><strong>WIDTH</code></strong> is the width of the frame.
 * <p>
 * A separate <code>Thread</code> is created to handle the screen's update and render loops.
 * Each iteration clears the screen and then draws the next frame from the pixel array.
 * <p>
 * In order to change the image on the screen, implementing classes must change the pixel
 * array values. To allow for this, the drawPixels method is called every screen loop
 * iteration. This method is to be overridden in the implementation class with information
 * regarding the color of each pixel.
 * 
 * @author my name
 * @version 1.0
 */
public class Screen extends JFrame implements Runnable {
    private static final long serialVersionUID = 1L;

    public static int WIDTH, HEIGHT;

    private Container cp;

    public JLabel label;

    private BufferStrategy strategy;

    private Graphics g;
    private BufferedImage image;

    /**
     * Holds color information of each pixel on the screen. Each element referrs to an
     * individual pixel and holds the RGB value of that pixel in base 10.
     */
    public int[] pixels;

    private Thread graphicsThread;
    private boolean running = false;

    /* -- Constructor -- */

    /**
     * Creates a new Screen object. Sets up the BufferStrategy and the JFrame.
     * 
     * @param   width   Width of the JFrame
     * @param   height  Height of the JFrame
     * @param   name    Name of the JFrame title bar
     */
    public Screen(int width, int height, String name) {
        // Create frame
        super(name);

        // Create a content pane to add multiple JLabels
        cp = this.getContentPane();
        cp.setLayout(new FlowLayout(FlowLayout.CENTER));

        // Define width and height constants
        WIDTH = width;
        HEIGHT = height;

        // Set up frame
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(WIDTH, HEIGHT);
        setLocationRelativeTo(null);
        setResizable(false);
        setVisible(true);

        // Create double buffer strategy
        createBufferStrategy(2);
        strategy = getBufferStrategy();

        // Set up initial image-drawing stuff
        g = strategy.getDrawGraphics(); // Changes every iteration of render method
        image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
        pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();

        // Create component to draw image on
        label = new JLabel(new ImageIcon(image));

        // Create a new thread for this screen and start it
        running = true;
        graphicsThread = new Thread(this);
        graphicsThread.start();

        // Add the label with the images drawn onto it to the frame
        cp.add(label);
    }

    /* -- Methods -- */

    /**
     * Loop of the Screen class. Calls the update and render methods repeatedly.
     */
    @Override
    public void run() {
        while (running) {
            // Focus on this window
            this.setFocusable(true);
            this.requestFocus();
            this.requestFocusInWindow();

            // Update and render the screen
            update();
            render();

            // Sleep a bit to avoid choking up the Thread
            try {
                Thread.sleep(5);
            } catch (InterruptedException e) {
                e.printStackTrace();
                //System.exit(1);
            }
        }
    }

    /**
     * Called by the thread run method repeatedly. First, clears the screen of the previous
     * image in order to prevent ghost-imaging or blurring. Then, updates the pixel array 
     * to whatever it needs to be for the next iteration of the render method.
     */
    private void update() {     
        // Clean up the screen and then update pixel array to make the next frame
        clearScreen();
        drawPixels();
    }

    /**
     * Called by the thread run method repeatedly. Draws the pixel array and TextString 
     * objects onto the JFrame using a Graphics object and the BufferStrategy.
     */
    private void render() {
        // Draw image
        g = strategy.getDrawGraphics();
        g.drawImage(image, 0, 0, WIDTH, HEIGHT, null);

        // Dispose old frames and then show current frame
        g.dispose();
        strategy.show();
    }

    /**
     * Clears the screen by setting every pixel in the pixel array to black. Used to prevent
     * ghost-images or blurring.
     */
    public void clearScreen() {
        for (int i = 0; i < pixels.length; i++)
            pixels[i] = 0;
    }

    /**
     * Adds a component to the screen at a specific X and Y coordinate.
     * 
     * @param   component   Component to draw onto the screen
     * @param   x           X coordinate to place the component
     * @param   y           Y coordinate to place the component
     */
    public void addComponent(JLabel component, int x, int y) {
        component.setLocation(x, y);
        component.setSize(component.getPreferredSize());
        cp.add(component);
        System.out.println(component.getLocation());
    }

    /**
     * Screen objects draw images by directly referencing the {@link #pixels} array. Implementation
     * classes will override this method with pixel color information. If this method is
     * not overridden it will draw the String "Override drawPixles()" onto the screen.
     */
    public void drawPixels() {
        drawText("Override drawPixels()", 50, 100);
    }
}

当我使用JLabel方法添加其他addComponent()时,添加的JLabel不会显示。它会添加JLabel,如显示其位置的println(component.getLocation())命令所示。

我认为问题在于添加的JLabel位于后台JLabel之下,但我不知道如何解决这个问题。我尝试过扩展JPanel类而不是JFrame类,但这导致根本没有窗口出现。

任何帮助都将不胜感激。

0 个答案:

没有答案