添加 DrawPanel 实例和空指针异常时覆盖整个 GUI
Entire GUI covered when adding instance of DrawPanel and null pointer exception
当我尝试在其构造函数中将实例 "panel" 添加到我的 JFrame 时,出现空指针异常。然而,真正的问题是,如果不向 JFrame 添加 "panel",我的 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);
}
}
您的 NullPointerException
是由
引起的
shapes = new MyShape[100];
您创建了一个 MyShape
类型的数组,但从未向其中添加任何内容,因此它充满了 null
。
考虑将其更改为使用某种 List
class DrawPanel extends JPanel {
private List<MyShape> shapes;//stores all shapes the user draws
//...
public DrawPanel(JLabel statusLabel) {
//...
shapes = new ArrayList<>(100);
一旦您更正了 NullPointException
,DrawPanel
应该就没问题了。
当我尝试在其构造函数中将实例 "panel" 添加到我的 JFrame 时,出现空指针异常。然而,真正的问题是,如果不向 JFrame 添加 "panel",我的 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);
}
}
您的 NullPointerException
是由
shapes = new MyShape[100];
您创建了一个 MyShape
类型的数组,但从未向其中添加任何内容,因此它充满了 null
。
考虑将其更改为使用某种 List
class DrawPanel extends JPanel {
private List<MyShape> shapes;//stores all shapes the user draws
//...
public DrawPanel(JLabel statusLabel) {
//...
shapes = new ArrayList<>(100);
一旦您更正了 NullPointException
,DrawPanel
应该就没问题了。