当我已经添加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
类,但这导致根本没有窗口出现。
任何帮助都将不胜感激。