问题描述
我一直在尝试重写并使用paint组件方法而不是paint方法,因为我在这里遇到了多个问题.
I have been trying to override and use the paint component method instead of the paint method because I've seen it been suggested in multiple questions around here.
我已经浏览了许多问题,但似乎还是无法解决这个问题.我正在发布用于渲染屏幕的原始代码.我认为扩展JFrame不是正确的方法,相反,我需要扩展JPanel,并从那里使用paint组件.我有另一个对象,我实际上在其中扩展了JPanel,并添加了JFrame(用于渲染).
I've looked through many questions but I still can't seem to get this to work. I'm posting my original piece of code used to render a screen. I am thinking that extending JFrame is not the right way to go and instead I need to extend JPanel, and use paint component from there. I have another object where I actually extend the JPanel, and add in the JFrame (for rendering).
这是我用来渲染的对象,顺便说一句,它可以完美地覆盖paint方法.
Here is the object I use to render, this, by the way works perfectly overriding the paint method.
package render;
import java.util.Arrays;
import javax.swing.*;
import java.awt.*; //Graphics, Graphics2D, Image
import sprites.Picture;
public class Window extends JFrame{
private static final long serialVersionUID = 1L;
public static Picture[] image_list = new Picture[0]; // All the images I want to render
private static String win_title = "Window"; // The name of the window
private static CustomComponents cc = new CustomComponents();
public Window(){
setTitle(win_title); // set my title
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // close when you hit x button
setUndecorated(true); // window has nothing on it
}
// paints all the images in image list according to their priority
public void display(){
add(cc);
CustomComponents.updateImageList(image_list);
pack();
setMinimumSize(getSize());
setLocationRelativeTo(null); // puts the screen in the middle
setResizable(false); // can't resize the window
setVisible(true); // to see the window
}
public double[] getWinSize(){
double[] size = {this.getSize().getWidth(),this.getSize().getWidth()};
return size;
}
public static void endAll(){
for (Picture i:image_list){
i = null;
}
image_list = new Picture[0];
CustomComponents.updateImageList(image_list);
}
// close the window (seen in the game object)
public static void close(){
System.exit(0);
}
// called when adding a new sprite to the image_list array
public static void addPicture(Picture element){
Picture[] result = Arrays.copyOf(image_list, image_list.length +1); // does the same thing as the addObject method in objects
result[image_list.length] = element;
image_list = result;
Arrays.sort(image_list);
CustomComponents.updateImageList(image_list);
}
// updates the screen... Just repaints everything
public void update() {
cc.repaint();
}
}
class CustomComponents extends JComponent {
private static final long serialVersionUID = 1L;
private static Picture[] image_list;
public static void updateImageList(Picture[] image_list){
CustomComponents.image_list = image_list;
}
@Override
public Dimension getMinimumSize() {
return new Dimension(640,360);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(640,360);
}
@Override
public Dimension getMaximumSize() {
return new Dimension(640,360);
}
@Override
public void paintComponent(Graphics graphics) {
super.paintComponent(graphics);
Graphics2D g2d = (Graphics2D) graphics;
for (Picture i:image_list){
if (i.getVisibility()){
g2d.drawImage(i.getPic(), i.getXY()[0], i.getXY()[1], this);
}
}
Toolkit.getDefaultToolkit().sync(); // this is for linux machines
graphics.dispose(); // just good programming practice to collect the garbage
}
}
我会发布实际上添加到窗口中的对象,但是现在它太复杂了,只发生了几件事.在构造函数中,我在上面添加了JFrame窗口,然后使用计时器调用JFrame对象上的update方法.
I would post the object that actually adds in the window but it's way too convoluted now, and only a few thing happens. In the constructor I add the JFrame window above, and then I use a timer to call the update method on the JFrame object.
如果你们真的需要代码,我可以发布它,但希望这足够了.
If you guys really need to the code I can post it but hopefully this will be enough.
推荐答案
-
不绘画
don't paint
- 直接使用
paintComponent()
到JFrame
- 直接绘画到
JFrame
并不是一个好主意,JFrame
不是完成此任务的合适容器 - 必须使用
paint()
代替paintComponent()
来使用JFrame
- by using
paintComponent()
directly to theJFrame
, - not good idea to paint directly to
JFrame
,JFrame
isn't proper container for this job - have to use
paint()
instead ofpaintComponent()
forJFrame
,
- 直接使用
-
在您认为 应该覆盖父方法的任何方法(此处为
paintComponent(...)
方法)之前添加@Override
.这样,如果您实际上没有超越您原本的想法,编译器就会警告您. Add
@Override
before any methods that you think should override a parent method, here thepaintComponent(...)
method. This way, the compiler will warn you if you are in fact not overriding what you thought you were.将
JComponent / JPanel
放入JFrame
覆盖
JComponent / JPanel
(您的硬编码// window size handle
)的getPreferredSize
,否则,JComponent / JPanel
返回零尺寸,简单的什么都看不到.override
getPreferredSize
forJComponent / JPanel
(your hardcoded// window size handle
) , otherwiseJComponent / JPanel
returns zero dimension, simple nothing will be visible on the creen这篇关于paintComponent不起作用(Java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!