我正在尝试编写一些自定义绘画代码。具体来说,我想要一堆扩展的 JPanels 来绘制我的 GUI 的不同方面,但这些扩展面板中的每一个都包含如何绘制的说明。
我已经创建了代码,但由于某种原因,无论我做什么,扩展的 JPanel 都不会在我的 JFrame 中的主 JPanel 上绘制。这是我的主要课程的要点,也是我的扩展JPanels之一。我错过了什么?
突破
//Java imports
import javax.swing.JFrame;
import java.awt.Dimension;
import javax.swing.JPanel;
//Personal imports
import Ball;
public class Breakout {
public static void main (String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable() {//start the GUI in a new thread
public void run(){
showGUI();
}
});
}
private static void showGUI() {
JFrame frame = new JFrame("Breakout");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Dimension d = new Dimension(640,480);
frame.setMinimumSize(d);
frame.setResizable(false);
JPanel p = new JPanel();
p.add(new Ball(200,200,50,255,0,0));
frame.add(p);
frame.setVisible(true);
}
}
球
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
public class Ball extends JPanel {
public int x;
public int y;
public int radius;
public Color colour;
public Ball(int x, int y, int radius, int r, int g, int b) {
super();
this.x = x;
this.y = y;
this.radius = radius;
colour = new Color(r,g,b);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
//define constants
int topLeftX = x+radius;
int topLeftY = y+radius;
int diameter = radius *2;
//draw outline
g.setColor(Color.BLACK);
g.drawOval(topLeftX, topLeftY, diameter, diameter);
//fill it in
g.setColor(colour);
g.fillOval(topLeftX, topLeftY, diameter, diameter);
}
}
以这种方式使用 JPanel
会给你带来无穷无尽的问题。
您遇到的两个主要问题是...
-
JPanel
已经知道了大小和位置,添加另一个 x/y 坐标只会令人困惑,并可能导致您绘制组件的可视空间 JPanel
的默认首选大小为 0x0。 这意味着当您使用FlowLayout
将其添加另一个JPanel
时,面板的大小为0x0,因此不会绘制任何内容。
相反,创建一个interface
,它具有一个名为 paint
的方法并采用Graphics2D
对象。
对于要绘制的每个形状,创建一个实现此interface
的新类,并使用它paint
方法根据需要绘制对象。
创建自定义组件,从JPanel
延伸并维护这些形状的List
。 在它的paintComponent
中,使用for-loop
绘制List
中的每个形状。
然后,此自定义组件应添加到您的框架中...
在主类的showGUI
方法中,您有以下代码:
JPanel p = new JPanel();
p.add(new Ball(200,200,50,255,0,0));
frame.add(p);
此代码创建一个新的 JPanel,然后向其添加另一个 JPanel。这是不正确的,因为将另一个JPanel
添加到您刚刚创建的完全好的JPanel
中根本没有意义。相反,只需这样做:
frame.getContentPane().add(new Ball(200, 200, 50, 255,0,0));
或者,如果您愿意:
Ball ball = new Ball(200, 200, 50, 255,0,0);
frame.getContentPane().add(ball);