所以我正在创建一个免费的手绘JPanel,它会对鼠标移动作出反应并绘制线条。我得到它主要工作除了一个错误,它会随机在线之间画一条直线。该随机直线不是故意的,在缓冲图像上绘制的内容应该严格地是用户绘制的内容。这些随机绘制的行不是由用户完成的,而且令人困惑。以下是我的代码,有谁可以看看?包含的图像可以直观地显示它正在做什么。
public class NoteDocument extends JPanel implements MouseListener, MouseMotionListener {
private Frame commands;
private JDesktopPane desktop;
private JInternalFrame colorFrame;
private JPanel colorPanel;
private JColorChooser colorChooser;
private enum State { IDLING, DRAGGING };
private enum ButtonPosition { PRESSED, RELEASED };
private enum Shape { SQUARE, RECTANGLE, CIRCLE, OVAL, LINE };
private State state = State.IDLING;
private ButtonPosition position = ButtonPosition.RELEASED;
private Shape shape = null;
//private ArrayList<Point> points = new ArrayList<Point>();
private ArrayList<Point> pressedPoints = new ArrayList<Point>();
private ArrayList<Point> draggedPoints = new ArrayList<Point>();
private ArrayList<Point> releasedPoints = new ArrayList<Point>();
private BufferedImage bufferedImage = null;
public NoteDocument(Frame commands) {
this.commands = commands;
setBackground(Color.WHITE);
addMouseListener(this);
addMouseMotionListener(this);
createColorChooser();
}
private void createColorChooser() {
for (int i = 0; i < commands.getLayeredPane().getComponentCount(); i++) {
if (commands.getLayeredPane().getComponent(i) instanceof JDesktopPane) {
desktop = (JDesktopPane) commands.getLayeredPane().getComponent(i);
}
}
colorChooser = new JColorChooser();
colorPanel = new JPanel();
colorFrame = new JInternalFrame();
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(colorPanel);
colorPanel.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(colorChooser, javax.swing.GroupLayout.PREFERRED_SIZE, 434, javax.swing.GroupLayout.PREFERRED_SIZE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(colorChooser, javax.swing.GroupLayout.PREFERRED_SIZE, 328, javax.swing.GroupLayout.PREFERRED_SIZE)
);
colorFrame.add(colorPanel);
desktop.add(colorFrame);
colorFrame.pack();
colorFrame.setVisible(true);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if(bufferedImage == null)
{
int panelHeight = this.getHeight();
int panelWidth = this.getWidth();
bufferedImage = (BufferedImage) this.createImage(panelHeight, panelWidth);
Graphics2D gc = bufferedImage.createGraphics();
gc.setColor(Color.WHITE);
gc.fillRect(0, 0, panelWidth, panelHeight);
g2.drawImage(bufferedImage, null, 0, 0);
}
//draw pressed points
for (int a = 0; a < pressedPoints.size(); a++) {
Point p1 = pressedPoints.get(a);
g.drawLine(p1.x, p1.y, p1.x, p1.y);
}
//draw draggedPoints
for (int b = 0; b < draggedPoints.size() - 2; b++) {
Point p1 = draggedPoints.get(b);
Point p2 = draggedPoints.get(b + 1);
g.drawLine(p1.x, p1.y, p2.x, p2.y);
}
//draw released points
for (int c = 0; c < releasedPoints.size(); c++) {
Point p1 = releasedPoints.get(c);
g.drawLine(p1.x, p1.y, p1.x, p1.y);
}
}
@Override
public void mouseClicked(MouseEvent e) {}
@Override
public void mouseEntered(MouseEvent e) {}
@Override
public void mouseExited(MouseEvent e) {}
@Override
public void mousePressed(MouseEvent e) {
if (e.getButton() == MouseEvent.BUTTON1) {
position = ButtonPosition.PRESSED;
state = State.DRAGGING;
pressedPoints.add(e.getPoint());
this.repaint();
} else if (e.getButton() == MouseEvent.BUTTON2) {
//TODO right click popup
}
}
@Override
public void mouseReleased(MouseEvent e) {
if (state == State.DRAGGING) {
releasedPoints.add(e.getPoint());
position = ButtonPosition.RELEASED;
state = State.IDLING;
this.repaint();
}
}
@Override
public void mouseDragged(MouseEvent e) {
if ((state == State.DRAGGING) && (position == ButtonPosition.PRESSED)) {
draggedPoints.add(e.getPoint());
this.repaint();
} else if ((state == State.IDLING) && (position == ButtonPosition.RELEASED)) {
return;
}
}
@Override
public void mouseMoved(MouseEvent e) {
if ((state == State.DRAGGING) && (position == ButtonPosition.PRESSED)) {
draggedPoints.add(e.getPoint());
this.repaint();
} else if ((state == State.IDLING) && (position == ButtonPosition.RELEASED)) {
return;
}
}
}
答案 0 :(得分:4)
您可能希望嵌套列表以实现目标:
List<List<Point>>
这样,当按下鼠标时,启动一个ArrayList,当释放时,完成它。然后,您可以使用嵌套的for循环绘制所有曲线。
例如(来自我以前的答案):
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;
public class LineDrawEg {
private static void createAndShowGui() {
JPanel mainPanel = new JPanel(new GridLayout(1, 0));
mainPanel.setPreferredSize(new Dimension(800, 400));
MyMouseAdapter mouseAdapter = new MyMouseAdapter();
JPanel[] panels = {new Panel1(), new Panel2()};
for (int i = 0; i < panels.length; i++) {
String title = "Panel " + (i + 1);
Border border = new TitledBorder(title);
panels[i].setBorder(border);
panels[i].addMouseListener(mouseAdapter);
panels[i].addMouseMotionListener(mouseAdapter);
mainPanel.add(panels[i]);
}
JFrame frame = new JFrame("Line Draw Eg");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Panel1 extends JPanel implements Positionable {
private int xPos = 0;
private int yPos = 0;
@Override
protected void paintComponent(Graphics g) {
// super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(xPos, yPos, 5, 5);
}
@Override
public void mouseDragged(Point p) {
xPos = p.x;
yPos = p.y;
repaint();
}
@Override
public void mousePressed(Point p) {
xPos = p.x;
yPos = p.y;
repaint();
}
@Override
public void mouseReleased(Point p) {
xPos = p.x;
yPos = p.y;
repaint();
}
}
class Panel2 extends JPanel implements Positionable {
private List<List<Point>> listOfLists = new ArrayList<List<Point>>();
private List<Point> currentPoints;
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(new BasicStroke(5f));
if (currentPoints != null && currentPoints.size() > 1) {
g2.setColor(Color.blue);
for (int i = 1; i < currentPoints.size(); i++) {
int x1 = currentPoints.get(i - 1).x;
int y1 = currentPoints.get(i - 1).y;
int x2 = currentPoints.get(i).x;
int y2 = currentPoints.get(i).y;
g2.drawLine(x1, y1, x2, y2);
}
}
g2.setColor(Color.red);
for (List<Point> pointList : listOfLists) {
if (pointList.size() > 1) {
for (int i = 1; i < pointList.size(); i++) {
int x1 = pointList.get(i - 1).x;
int y1 = pointList.get(i - 1).y;
int x2 = pointList.get(i).x;
int y2 = pointList.get(i).y;
g2.drawLine(x1, y1, x2, y2);
}
}
}
}
@Override
public void mousePressed(Point p) {
currentPoints = new ArrayList<Point>();
currentPoints.add(p);
repaint();
}
@Override
public void mouseDragged(Point p) {
currentPoints.add(p);
repaint();
}
@Override
public void mouseReleased(Point p) {
if (currentPoints != null) {
currentPoints.add(p);
listOfLists.add(currentPoints);
}
currentPoints = null;
repaint();
}
}
class MyMouseAdapter extends MouseAdapter {
@Override
public void mouseDragged(MouseEvent mEvt) {
Positionable positionable = (Positionable) mEvt.getSource();
positionable.mouseDragged(mEvt.getPoint());
}
@Override
public void mousePressed(MouseEvent mEvt) {
Positionable positionable = (Positionable) mEvt.getSource();
positionable.mousePressed(mEvt.getPoint());
}
@Override
public void mouseReleased(MouseEvent mEvt) {
Positionable positionable = (Positionable) mEvt.getSource();
positionable.mouseReleased(mEvt.getPoint());
}
}
interface Positionable {
void mouseDragged(Point p);
void mousePressed(Point p);
void mouseReleased(Point p);
}