我正在做一些练习来理解Java和Swing API。为什么在Disegno构造函数中有nullPointerException?我想打印两个矩形的坐标,但它们似乎没有初始化。
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Disegno extends JFrame{
Disegno(){
this.setSize(500, 500);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
MyPanel aba = new MyPanel();
this.setContentPane(aba);
this.setVisible(true);
System.out.println(aba.rect.blue.x + "-" + aba.rect.blue.y);
System.out.println(aba.rect.yellow.x + "-" + aba.rect.yellow.y);
}
public static void main(String[] args){
new Disegno();
}
}
class MyPanel extends JPanel{
JPanel up, down;
RectArea rect;
MyPanel(){
this.setLayout(new BorderLayout());
up = new JPanel();
this.add(up, BorderLayout.NORTH);
up.setBackground(Color.red);
up.setVisible(true);
down = new JPanel();
down.setBackground(Color.green);
this.add(down, BorderLayout.SOUTH);
down.setVisible(true);
rect = new RectArea();
this.add(rect, BorderLayout.CENTER);
this.setVisible(true);
}
}
class RectArea extends JPanel{
Rectangle blue, yellow;
boolean check = false;
RectArea(){
super();
this.setVisible(true);
}
public void initRect(){
blue = new Rectangle(0, 0, 100, 100);
yellow = new Rectangle(this.getWidth(), this.getHeight(), 100, 100);
System.out.println("ok");
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
if(check == false){
this.initRect();
check = true;
}
System.out.println(this.getWidth() + "-" + this.getHeight());
g.setColor(Color.blue);
g.fillRect(blue.x, blue.y, blue.width, blue.height);
g.setColor(Color.yellow);
g.fillRect(yellow.x - yellow.width, yellow.y - yellow.height, yellow.width, yellow.height);
}
}
答案 0 :(得分:5)
其他人帮助建议了检测和避免NullPointerException
的方法。不幸的是,当调用paintComponent()
的实现时,你不能依赖。相反,
根据当前寡妇的大小确定所需的几何图形;在下面的示例中调整窗口大小,以查看yellow
似乎粘贴到右下角。
由于MyPanel
不包含自己的组件,因此您应该覆盖getPreferredSize()
,因为@nIcE cOw显示here。
使用pack()
调整封闭式Window
的大小。
附录:我无法理解为什么要覆盖方法 getPreferredSize()
。
JComponent
的子类覆盖getPreferredSize()
,以便pack()
可以调整Window
的大小以适合其子组件的首选大小和布局。“这样,您就不必担心用户是否有不同的字体,例如。 MyPanel
只是绘制几何形状,所以你是首选大小的老板。正如here所述,演示可能会使用setPreferredSize()
以方便使用,但您应该了解这样做的局限性。
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* @see https://stackoverflow.com/q/11376272/230513
*/
public class Disegno extends JFrame {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Disegno();
}
});
}
Disegno() {
this.setSize(500, 500);
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
MyPanel aba = new MyPanel();
this.add(aba);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
class MyPanel extends JPanel {
private JPanel up, down;
private RectArea rect;
MyPanel() {
super(new BorderLayout());
up = new JPanel();
up.setBackground(Color.red);
this.add(up, BorderLayout.NORTH);
rect = new RectArea();
this.add(rect, BorderLayout.CENTER);
down = new JPanel();
down.setBackground(Color.green);
this.add(down, BorderLayout.SOUTH);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(320, 240);
}
}
class RectArea extends JPanel {
private Rectangle blue = new Rectangle(0, 0, 100, 100);
private Rectangle yellow = new Rectangle(0, 0, 100, 100);
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(this.getWidth() + " x " + this.getHeight());
g.setColor(Color.blue);
g.fillRect(blue.x, blue.y, blue.width, blue.height);
g.setColor(Color.yellow);
int dx = getWidth() - yellow.width;
int dy = getHeight() - yellow.height;
g.fillRect(dx, dy, yellow.width, yellow.height);
}
}
}
答案 1 :(得分:2)
您从未在任何地方致电rect.initRect();
,这就是您在NullPointerException
处收到与System.out.println() lines
相关的错误的原因。为什么在每个班级中使用panelObject.setVisible(true)
,首先将其添加到JPanel
,然后只需拨打setVisible(...)
上的JFrame
即可。在这里观看修改后的代码与所述的东西,按预期工作:
import java.awt.*;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Disegno extends JFrame{
Disegno(){
this.setSize(500, 500);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
MyPanel aba = new MyPanel();
this.setContentPane(aba);
this.setVisible(true);
System.out.println(aba.rect.blue.x + "-" + aba.rect.blue.y);
System.out.println(aba.rect.yellow.x + "-" + aba.rect.yellow.y);
}
public static void main(String[] args){
new Disegno();
}
}
class MyPanel extends JPanel{
JPanel up, down;
RectArea rect;
MyPanel(){
this.setLayout(new BorderLayout());
up = new JPanel();
this.add(up, BorderLayout.NORTH);
up.setOpaque(true);
up.setBackground(Color.red);
down = new JPanel();
down.setOpaque(true);
down.setBackground(Color.green);
this.add(down, BorderLayout.SOUTH);
rect = new RectArea();
rect.initRect();
this.add(rect, BorderLayout.CENTER);
}
}
class RectArea extends JPanel{
Rectangle blue, yellow;
boolean check = false;
RectArea(){
super();
setOpaque(true);
}
public void initRect(){
blue = new Rectangle(0, 0, 100, 100);
yellow = new Rectangle(this.getWidth(), this.getHeight(), 100, 100);
System.out.println("ok");
}
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
if(check == false){
this.initRect();
check = true;
}
System.out.println(this.getWidth() + "-" + this.getHeight());
g.setColor(Color.blue);
g.fillRect(blue.x, blue.y, blue.width, blue.height);
g.setColor(Color.yellow);
g.fillRect(yellow.x - yellow.width, yellow.y - yellow.height, yellow.width, yellow.height);
}
}
如果您要在System.out.println()
内写一个intiRect()
,那么在paintComponent(...)
方法本身之前会调用给出错误的行。因此,在我看来,您必须从paintComponent(...)
方法中取出该逻辑并将其保留在其他位置,否则如果您不需要它们,则删除这些线。
答案 2 :(得分:1)
您正在尝试访问aba.rect.blue
构造函数中的aba.rect.yellow
和Disegno
,但是在调用RectArea.paintComponent
之前不会对其进行初始化,因此会抛出NPE。
答案 3 :(得分:1)
你确定你的代码给出了NullPointerException ....... ??
因为当我运行你的代码时,它工作得很好......
<强>输出:强>
ok
484-442