当我尝试添加实例" panel"在我的构造函数中的JFrame中,我得到一个空指针异常。然而真正的问题是没有添加" panel"到JFrame,我对borderlayout的北部布局工作正常,在我添加之后,应用程序全部为白色,除非你滚动北面板中的不同按钮。我想知道如何摆脱空指针异常,以及如何使我的DrawPanel适合我的JFrame边界布局的中心。我有以下全部代码。
package doStuff;
import java.awt.BorderLayout;
import java.awt.*;
import javax.swing.Timer;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.security.SecureRandom;
import javax.swing.JLabel;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.*;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import javax.swing.JPanel;
class DrawPanel extends JPanel
{
private MyShape[] shapes;//stores all shapes the user draws
private int shapeCount;//counts number of shapes in array
private int shapeType;//determines type of shape to draw
private MyShape currentShape;//represents current shape user is drawing
private Color currentColor;//represents current drawing color
private boolean filledShape;//determines whether to draw a filled shape
private JLabel statusLabel;//status bar that displays coordinates of mouse position
public DrawPanel(JLabel statusLabel)
{
this.statusLabel=statusLabel;
shapes=new MyShape[100];
shapeCount=0;
shapeType=1;
currentShape=null;
currentColor=Color.BLACK;
//setBackground(Color.GREEN);
setBackground(Color.WHITE);
addMouseListener(new MouseEventHandler());
}
public void setshapeType(int shape)
{
this.shapeType=shape;
}
public void setcurrentColor(Color color)
{
this.currentColor=color;
}
public void setfilledShape(boolean filledShape)
{
this.filledShape=filledShape;
}
public void clearLastShape()
{
if (shapeCount==0)
shapeCount=0;
else
shapeCount--;
repaint();
}
public void clearDrawing()
{
shapeCount=0;
repaint();
}
private class MouseEventHandler extends MouseAdapter implements MouseMotionListener
{
@Override
public void mousePressed(MouseEvent event)
{
if(shapeType==1)
{
currentShape=new MyLine();
}
if(shapeType==2)
{
currentShape = new MyRect();
}
else
{
currentShape = new MyOval();
}
currentShape.setx1(event.getPoint().x);
currentShape.sety1(event.getPoint().y);
}
@Override
public void mouseReleased(MouseEvent event)
{
currentShape.setx2(event.getPoint().x);
currentShape.sety2(event.getPoint().y);
shapes[shapeCount-1]=currentShape;
currentShape=null;
repaint();
}
@Override
public void mouseMoved(MouseEvent event)
{
statusLabel.setText("("+event.getPoint().x+","+event.getPoint().y+")");
}
@Override
public void mouseDragged(MouseEvent event)
{
currentShape.setx2(event.getPoint().x);
currentShape.sety2(event.getPoint().y);
repaint();
statusLabel.setText("("+event.getPoint().x+","+event.getPoint().y+")");
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(MyShape shape: shapes)
shape.draw(g);
}
}
class DrawFrame extends JFrame
{
private static final String[] colorNames = {"Black", "Blue", "Cyan", "Dark Gray", "Gray", "Green", "Light Gray",
"Magenta", "Orange", "Pink", "Red", "White", "Yellow"};
private static final Color[] colors = {Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY,
Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED,
Color.WHITE, Color.YELLOW};
private static final String[] shapeNames = {"Line", "Rectangle", "Oval"};
private static final int[] shapes = {1,2,3};
private final JButton undoButton;
private final BorderLayout layout;
private final JButton clearButton;
private final JComboBox<String> colorsJComboBox;
private final JComboBox<String> shapesJComboBox;
private final JCheckBox fillCheckBox;
private JLabel statusLabel= new JLabel();
DrawPanel panel = new DrawPanel(statusLabel);
public DrawFrame()
{
super("Java Drawings");
//setLayout(new BorderLayout())
layout= new BorderLayout(5,5);
setLayout(layout);
colorsJComboBox = new JComboBox<String>(colorNames);
colorsJComboBox.setMaximumRowCount(4);
shapesJComboBox = new JComboBox<String>(shapeNames);
shapesJComboBox.setMaximumRowCount(3);
undoButton = new JButton("Undo");
clearButton = new JButton("Clear");
fillCheckBox = new JCheckBox("Filled");
/*JPanel centerPanel = new JPanel();
centerPanel.setLayout(new BorderLayout());
centerPanel.add(panel);
add(centerPanel, BorderLayout.CENTER);*/
JPanel northPanel = new JPanel();
northPanel.setLayout(new FlowLayout());
northPanel.add(undoButton);
northPanel.add(clearButton);
northPanel.add(colorsJComboBox);
northPanel.add(shapesJComboBox);
northPanel.add(fillCheckBox);
add(northPanel, BorderLayout.NORTH);
JPanel bottomPanel= new JPanel();
bottomPanel.setLayout(new FlowLayout());
bottomPanel.add(statusLabel);
add(bottomPanel, BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);//problem here
//Event Handlers
CheckBoxHandler checkBoxHandler = new CheckBoxHandler();
fillCheckBox.addItemListener(checkBoxHandler);
undoButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
panel.clearLastShape();
}
});
clearButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
panel.clearDrawing();
}
});
colorsJComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange() == ItemEvent.SELECTED)
panel.setcurrentColor(colors[colorsJComboBox.getSelectedIndex()]);
}
}
);
shapesJComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange() == ItemEvent.SELECTED)
panel.setshapeType(shapes[shapesJComboBox.getSelectedIndex()]);
}
}
);
}
private class CheckBoxHandler implements ItemListener
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(fillCheckBox.isSelected())
panel.setfilledShape(true);
}
}
}
abstract class MyShape
{
private int x1;
private int y1;
private int x2;
private int y2;
private Color color;
public MyShape()
{
this.x1=this.x2=this.y1=this.y2=0;
this.color=Color.BLACK;
}
public MyShape(int x1, int y1, int x2, int y2, Color color)
{
this.x1=x1;
this.x2=x2;
this.y1=y1;
this.y2=y2;
this.color=color;
}
public void setx1(int x1)
{
this.x1=x1;
}
public void setx2(int x2)
{
this.x2=x2;
}
public void sety1(int y1)
{
this.y1=y1;
}
public void sety2(int y2)
{
this.y2=y2;
}
public void setColor(Color color)
{
this.color=color;
}
public Color getColor()
{
return color;
}
public int getx1()
{
return x1;
}
public int getx2()
{
return x2;
}
public int gety2()
{
return y2;
}
public int gety1()
{
return y1;
}
public int getUpperLeftx()
{
if (x1<=x2)
return x1;
else
return x2;
}
public int getUpperLefty()
{
if (y1<=y2)
return y1;
else
return y2;
}
public int getHeight()
{
return(Math.abs(y1-y2));
}
public int getWidth()
{
return(Math.abs(x1-x2));
}
public void draw(Graphics g)
{
}
}
abstract class MyBoundedShape extends MyShape
{
private boolean fillyn;
MyBoundedShape()
{
super();
fillyn=false;
}
MyBoundedShape(int x1,int y1,int x2,int y2,Color color, boolean fillyn)
{
super(x1,y1,x2,y2,color);
this.fillyn=fillyn;
}
public void setfillyn(boolean fillyn)
{
this.fillyn=fillyn;
}
public boolean getfillyn()
{
return fillyn;
}
@Override
public void draw(Graphics g)
{
}
}
class MyLine extends MyShape
{
MyLine()
{
super();
}
MyLine(int x1, int y1, int x2, int y2, Color color)
{
super(x1,y1,x2,y2,color);
}
@Override
public void draw(Graphics g)
{
g.setColor(super.getColor());
g.drawLine(getx1(), gety1(), getx2(), gety2());
}
}
class MyRect extends MyBoundedShape
{
MyRect()
{
super();
}
MyRect(int x1, int y1, int x2, int y2, Color color, boolean fillyn)
{
super(x1,y1,x2,y2,color,fillyn);
}
@Override
public void draw(Graphics g)
{
g.setColor(getColor());
if(super.getfillyn())
g.fillRect(getx1(), gety1(), getx2(), gety2());
else
g.drawRect(getx1(), gety1(), getx2(), gety2());
}
}
class MyOval extends MyBoundedShape
{
MyOval()
{
super();
}
MyOval(int x1, int y1, int x2, int y2, Color color, boolean fillyn)
{
super(x1,y1,x2,y2,color,fillyn);
}
@Override
public void draw(Graphics g)
{
g.setColor(super.getColor());
if(getfillyn())
g.fillOval(getx1(), gety1(), getx2(), gety2());
else
g.drawOval(getx1(), gety1(), getx2(),gety2());
}
}
public class doStuff {
public static void main(String[] args)
{
/* DrawPanel panel = new DrawPanel();
JFrame app = new JFrame();
JLabel statusLabel = new JLabel(panel.getNumStatus());
app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
app.add(panel);
app.add(statusLabel, BorderLayout.SOUTH);
app.setSize(300,300);
app.setVisible(true);*/
DrawFrame drawFrame = new DrawFrame();
drawFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawFrame.setSize(600,600);
drawFrame.setVisible(true);
}
}
这是我的固定代码:我必须更改clearDrawing和clearLastShape方法以适应从数组到列表的更改以及我在拖动鼠标时正确显示的paintComponent方法。我知道几个冗余的进口。谢谢你的帮助!
package doStuff;
import java.awt.BorderLayout;
import java.awt.*;
import java.util.List;
import java.util.LinkedList;
import java.util.ListIterator;
import javax.swing.Timer;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.security.SecureRandom;
import javax.swing.JLabel;
import javax.swing.JFrame;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.ListSelectionModel;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JScrollPane;
import javax.swing.ListSelectionModel;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.*;
import java.awt.Point;
import java.awt.Graphics;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.JPanel;
class DrawPanel extends JPanel
{
private List<MyShape> shapes;
private int shapeType;//determines type of shape to draw
private MyShape currentShape;//represents current shape user is drawing
private Color currentColor;//represents current drawing color
private boolean filledShape;//determines whether to draw a filled shape
private JLabel statusLabel;//status bar that displays coordinates of mouse position
public DrawPanel(JLabel statusLabel)
{
this.statusLabel=statusLabel;
shapes = new ArrayList<>(100);
shapeType=1;
currentShape=null;
currentColor=Color.BLACK;
setBackground(Color.WHITE);
MouseEventHandler handler = new MouseEventHandler();
addMouseListener(handler);
addMouseMotionListener(handler);
}
public void setshapeType(int shape)
{
this.shapeType=shape;
}
public void setcurrentColor(Color color)
{
this.currentColor=color;
}
public void setfilledShape(boolean filledShape)
{
this.filledShape=filledShape;
}
public void clearLastShape()
{
if (shapes.size()<=1)
shapes.removeAll(shapes);
else
shapes.remove(1);
repaint();
}
public void clearDrawing()
{
shapes.removeAll(shapes);
repaint();
}
private class MouseEventHandler extends MouseAdapter implements MouseMotionListener
{
@Override
public void mousePressed(MouseEvent event)
{
if(shapeType==1)
{
currentShape=new MyLine(event.getX(),event.getY(),0,0,currentColor);
}
else if(shapeType==2)
{
currentShape= new MyRect(event.getX(),event.getY(),0,0,currentColor,filledShape);
}
else
{
currentShape= new MyOval(event.getX(),event.getY(),0,0,currentColor,filledShape);
}
}
@Override
public void mouseReleased(MouseEvent event)
{
currentShape.setx2(event.getX());
currentShape.sety2(event.getY());
shapes.add(currentShape);
currentShape=null;
repaint();
}
@Override
public void mouseMoved(MouseEvent event)
{
statusLabel.setText("("+event.getX()+","+event.getY()+")");
}
@Override
public void mouseDragged(MouseEvent event)
{
currentShape.setx2(event.getX());
currentShape.sety2(event.getY());
repaint();
statusLabel.setText("("+event.getX()+","+event.getY()+")");
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
if(currentShape!=null)
{
currentShape.draw(g);
for(MyShape shape:shapes)
{
shape.draw(g);
}
}
else{
for(MyShape shape:shapes)
{
shape.draw(g);
}
}
}
}
class DrawFrame extends JFrame
{
private static final String[] colorNames = {"Black", "Blue", "Cyan", "Dark Gray", "Gray", "Green", "Light Gray",
"Magenta", "Orange", "Pink", "Red", "White", "Yellow"};
private static final Color[] colors = {Color.BLACK, Color.BLUE, Color.CYAN, Color.DARK_GRAY,
Color.GRAY, Color.GREEN, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE, Color.PINK, Color.RED,
Color.WHITE, Color.YELLOW};
private static final String[] shapeNames = {"Line", "Rectangle", "Oval"};
private static final int[] shapes = {1,2,3};
private final JButton undoButton;
private final BorderLayout layout;
private final JButton clearButton;
private final JComboBox<String> colorsJComboBox;
private final JComboBox<String> shapesJComboBox;
private final JCheckBox fillCheckBox;
private JLabel statusLabel= new JLabel();
DrawPanel panel = new DrawPanel(statusLabel);
public DrawFrame()
{
super("Java Drawings");
//setLayout(new BorderLayout())
layout= new BorderLayout(5,5);
setLayout(layout);
colorsJComboBox = new JComboBox<String>(colorNames);
colorsJComboBox.setMaximumRowCount(4);
shapesJComboBox = new JComboBox<String>(shapeNames);
shapesJComboBox.setMaximumRowCount(3);
undoButton = new JButton("Undo");
clearButton = new JButton("Clear");
fillCheckBox = new JCheckBox("Filled");
JPanel northPanel = new JPanel();
northPanel.setLayout(new FlowLayout());
northPanel.add(undoButton);
northPanel.add(clearButton);
northPanel.add(colorsJComboBox);
northPanel.add(shapesJComboBox);
northPanel.add(fillCheckBox);
add(northPanel, BorderLayout.NORTH);
JPanel bottomPanel= new JPanel();
bottomPanel.setLayout(new FlowLayout());
bottomPanel.add(statusLabel);
add(bottomPanel, BorderLayout.SOUTH);
add(panel, BorderLayout.CENTER);
//Event Handlers
CheckBoxHandler checkBoxHandler = new CheckBoxHandler();
fillCheckBox.addItemListener(checkBoxHandler);
undoButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
panel.clearLastShape();
}
});
clearButton.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent event)
{
panel.clearDrawing();
}
});
colorsJComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange() == ItemEvent.SELECTED)
panel.setcurrentColor(colors[colorsJComboBox.getSelectedIndex()]);
}
}
);
shapesJComboBox.addItemListener(new ItemListener()
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(event.getStateChange() == ItemEvent.SELECTED)
panel.setshapeType(shapes[shapesJComboBox.getSelectedIndex()]);
}
}
);
}
private class CheckBoxHandler implements ItemListener
{
@Override
public void itemStateChanged(ItemEvent event)
{
if(fillCheckBox.isSelected())
panel.setfilledShape(true);
}
}
}
abstract class MyShape
{
private int x1;
private int y1;
private int x2;
private int y2;
private Color color;
public MyShape()
{
this.x1=this.x2=this.y1=this.y2=0;
this.color=Color.BLACK;
}
public MyShape(int x1, int y1, int x2, int y2, Color color)
{
this.x1=x1;
this.x2=x2;
this.y1=y1;
this.y2=y2;
this.color=color;
}
public void setx1(int x1)
{
this.x1=x1;
}
public void setx2(int x2)
{
this.x2=x2;
}
public void sety1(int y1)
{
this.y1=y1;
}
public void sety2(int y2)
{
this.y2=y2;
}
public void setColor(Color color)
{
this.color=color;
}
public Color getColor()
{
return color;
}
public int getx1()
{
return x1;
}
public int getx2()
{
return x2;
}
public int gety2()
{
return y2;
}
public int gety1()
{
return y1;
}
public int getUpperLeftx()
{
if (x1<=x2)
return x1;
else
return x2;
}
public int getUpperLefty()
{
if (y1<=y2)
return y1;
else
return y2;
}
public int getHeight()
{
return(Math.abs(y1-y2));
}
public int getWidth()
{
return(Math.abs(x1-x2));
}
public void draw(Graphics g)
{
}
}
abstract class MyBoundedShape extends MyShape
{
private boolean fillyn;
MyBoundedShape()
{
super();
fillyn=false;
}
MyBoundedShape(int x1,int y1,int x2,int y2,Color color, boolean fillyn)
{
super(x1,y1,x2,y2,color);
this.fillyn=fillyn;
}
public void setfillyn(boolean fillyn)
{
this.fillyn=fillyn;
}
public boolean getfillyn()
{
return fillyn;
}
@Override
public void draw(Graphics g)
{
}
}
class MyLine extends MyShape
{
MyLine()
{
super();
}
MyLine(int x1, int y1, int x2, int y2, Color color)
{
super(x1,y1,x2,y2,color);
}
@Override
public void draw(Graphics g)
{
g.setColor(super.getColor());
g.drawLine(getx1(), gety1(), getx2(), gety2());
}
}
class MyRect extends MyBoundedShape
{
MyRect()
{
super();
}
MyRect(int x1, int y1, int x2, int y2, Color color, boolean fillyn)
{
super(x1,y1,x2,y2,color,fillyn);
}
@Override
public void draw(Graphics g)
{
int x = Math.min(getx1(), getx2());
int y = Math.min(gety1(), gety2());
int w = Math.abs(getx1() - getx2());
int h = Math.abs(gety1() - gety2());
g.setColor(getColor());
if(super.getfillyn())
g.fillRect(x,y,w,h);
else
g.drawRect(x,y,w,h);
}
}
class MyOval extends MyBoundedShape
{
MyOval()
{
super();
}
MyOval(int x1, int y1, int x2, int y2, Color color, boolean fillyn)
{
super(x1,y1,x2,y2,color,fillyn);
}
@Override
public void draw(Graphics g)
{
int x = Math.min(getx1(), getx2());
int y = Math.min(gety1(), gety2());
int w = Math.abs(getx1() - getx2());
int h = Math.abs(gety1() - gety2());
g.setColor(getColor());
if(super.getfillyn())
g.fillOval(x,y,w,h);
else
g.drawOval(x,y,w,h);
}
}
public class doStuff {
public static void main(String[] args)
{
DrawFrame drawFrame = new DrawFrame();
drawFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawFrame.setSize(600,600);
drawFrame.setVisible(true);
}
}
&#13;
答案 0 :(得分:2)
您的NullPointerException
是由
shapes = new MyShape[100];
您创建了一个MyShape
类型的数组,但从不向其中添加任何内容,因此它已满null
个。
考虑将其更改为使用某种<{1}}
List
更正class DrawPanel extends JPanel {
private List<MyShape> shapes;//stores all shapes the user draws
//...
public DrawPanel(JLabel statusLabel) {
//...
shapes = new ArrayList<>(100);
后,NullPointException
应该没问题。