我有一个JPanel
我在其中绘制线条来创造铅笔的错觉。此面板位于ScrollPane
。
当我调整面板大小时,会自动调用revalidate()
方法,此面板中所有绘制的线条都将消失。有没有办法让我的画线在新面板的面板中保留?
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.AdjustmentEvent;
import java.awt.event.AdjustmentListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
*
* @author Sanjeev
*/
public class WorkArea extends JFrame implements ActionListener, MouseListener, MouseMotionListener
{
private final int PEN_OP = 1;
private final int ERASER_OP = 2;
private final int SCROLL_OP = 3;
private int mousex = 0;
private int mousey = 0;
private int prevx = 0;
private int prevy = 0;
private boolean initialPen = true;
private boolean initialEraser = true;
private int eraserLength = 5;
private int opStatus = PEN_OP;
private Color mainColor = new Color(0,0,0);
private int drawPanelHeight =1000;
public WorkArea()
{
initComponents();
setLocationRelativeTo(null);
pencilButton.addActionListener(this);
eraserButton.addActionListener(this);
drawPanel.addMouseMotionListener(this);
drawPanel.addMouseListener(this);
drawPanel.add(new TestPane());
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
private void initComponents() {
headerPanel = new javax.swing.JPanel();
backButton = new javax.swing.JLabel();
headerImage = new javax.swing.JLabel();
controlPanel = new javax.swing.JPanel();
scrollButton = new javax.swing.JButton();
pencilButton = new javax.swing.JButton();
eraserButton = new javax.swing.JButton();
drawingPanel = new javax.swing.JPanel();
drawingScrollPane = new javax.swing.JScrollPane();
drawPanel = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
setTitle("v0.1");
setBackground(new java.awt.Color(237, 254, 255));
setBounds(new java.awt.Rectangle(0, 0, 513, 693));
setResizable(false);
headerPanel.setBackground(new java.awt.Color(237, 254, 255));
headerPanel.setPreferredSize(new java.awt.Dimension(513, 25));
headerPanel.setLayout(null);
backButton.setBackground(new java.awt.Color(237, 254, 255));
backButton.setFont(new java.awt.Font("Tahoma", 0, 10)); // NOI18N
backButton.setForeground(new java.awt.Color(255, 255, 255));
backButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/back-arrow.png"))); // NOI18N
backButton.setText("Back");
backButton.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
backButton.setPreferredSize(new java.awt.Dimension(40, 20));
headerPanel.add(backButton);
backButton.setBounds(0, 3, 40, 20);
headerImage.setBackground(new java.awt.Color(237, 254, 255));
headerImage.setFont(new java.awt.Font("Tahoma", 1, 14)); // NOI18N
headerImage.setForeground(new java.awt.Color(255, 255, 255));
headerImage.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/topbar_ipad_wide.png"))); // NOI18N
headerImage.setText("Work Area");
headerImage.setHorizontalTextPosition(javax.swing.SwingConstants.CENTER);
headerImage.setPreferredSize(new java.awt.Dimension(513, 25));
headerPanel.add(headerImage);
headerImage.setBounds(0, 0, 513, 25);
controlPanel.setBackground(new java.awt.Color(237, 254, 255));
controlPanel.setPreferredSize(new java.awt.Dimension(90, 670));
controlPanel.setLayout(null);
scrollButton.setBackground(new java.awt.Color(237, 254, 255));
scrollButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/up_down_ipad.png"))); // NOI18N
scrollButton.setPreferredSize(new java.awt.Dimension(60, 60));
scrollButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
scrollButtonMouseClicked(evt);
}
});
controlPanel.add(scrollButton);
scrollButton.setBounds(20, 570, 60, 60);
pencilButton.setBackground(new java.awt.Color(237, 254, 255));
pencilButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/pencil_ipad.png"))); // NOI18N
pencilButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
pencilButtonMouseClicked(evt);
}
});
controlPanel.add(pencilButton);
pencilButton.setBounds(20, 450, 60, 60);
eraserButton.setBackground(new java.awt.Color(237, 254, 255));
eraserButton.setIcon(new javax.swing.ImageIcon(getClass().getResource("/images/eraser_ipad.png"))); // NOI18N
eraserButton.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent evt) {
eraserButtonMouseClicked(evt);
}
});
controlPanel.add(eraserButton);
eraserButton.setBounds(20, 510, 60, 60);
drawingPanel.setBackground(new java.awt.Color(237, 254, 255));
drawingPanel.setPreferredSize(new java.awt.Dimension(420, 670));
drawingPanel.setLayout(null);
drawingScrollPane.setBorder(null);
drawingScrollPane.setPreferredSize(new java.awt.Dimension(423, 1000));
drawPanel.setBackground(new java.awt.Color(237, 254, 255));
drawPanel.setPreferredSize(new java.awt.Dimension(400, 1000));
drawPanel.setLayout(null);
drawingScrollPane.setViewportView(drawPanel);
drawingPanel.add(drawingScrollPane);
drawingScrollPane.setBounds(0, 0, 424, 670);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 513, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addComponent(headerPanel, javax.swing.GroupLayout.Alignment.TRAILING, javax.swing.GroupLayout.PREFERRED_SIZE, 513, javax.swing.GroupLayout.PREFERRED_SIZE))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 90, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 423, Short.MAX_VALUE)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 93, Short.MAX_VALUE)
.addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 420, javax.swing.GroupLayout.PREFERRED_SIZE)))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 693, Short.MAX_VALUE)
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addComponent(headerPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 25, javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(0, 668, Short.MAX_VALUE)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 23, Short.MAX_VALUE)
.addComponent(controlPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 670, javax.swing.GroupLayout.PREFERRED_SIZE)))
.addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
.addGap(0, 23, Short.MAX_VALUE)
.addComponent(drawingPanel, javax.swing.GroupLayout.PREFERRED_SIZE, 670, javax.swing.GroupLayout.PREFERRED_SIZE)))
);
pack();
}
@Override
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand() == "Pen")
opStatus = PEN_OP;
if (e.getActionCommand() == "Eraser")
opStatus = ERASER_OP;
if(e.getActionCommand() == "Scroll")
opStatus = SCROLL_OP;
}
private void pencilButtonMouseClickedTest(java.awt.event.MouseEvent evt)
{
opStatus = PEN_OP;
Graphics g = drawPanel.getGraphics();
if (initialPen)
{
setGraphicalDefaults(evt);
initialPen = false;
g.drawLine(prevx,prevy,mousex,mousey);
}
if (mouseHasMoved(evt))
{
mousex = evt.getX();
mousey = evt.getY();
g.drawLine(prevx,prevy,mousex,mousey);
prevx = mousex;
prevy = mousey;
}
}
private void eraserButtonMouseClickedTest(java.awt.event.MouseEvent evt)
{
opStatus = ERASER_OP;
Graphics g = drawPanel.getGraphics();
if (initialEraser)
{
setGraphicalDefaults(evt);
initialEraser = false;
mousex = evt.getX();
mousey = evt.getY();
System.out.println("Initial Eraser ::::::::x's value is : "+prevx+" , "+mousey+" and y's value is : "+mousex+" , "+mousey);
g.setColor(new java.awt.Color(237,254,255));
g.fillRect(mousex-eraserLength, mousey-eraserLength,eraserLength*2,eraserLength*2);
//g.setColor(Color.black); //Eraser Border
g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2);
prevx = mousex;
prevy = mousey;
}
if (mouseHasMoved(evt))
{
System.out.println("Eraser ::::::::x's value is : "+prevx+" , "+mousey+" and y's value is : "+mousex+" , "+mousey);
g.setColor(new java.awt.Color(237,254,255));
g.drawRect(prevx-eraserLength, prevy-eraserLength,eraserLength*2,eraserLength*2);
mousex = evt.getX();
mousey = evt.getY();
/* Draw eraser block to panel */
g.setColor(new java.awt.Color(237,254,255));
g.fillRect(mousex-eraserLength, mousey-eraserLength,eraserLength*2,eraserLength*2);
g.setColor(Color.black);//Eraser Border
g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2);
prevx = mousex;
prevy = mousey;
}
}
private void scrollButtonMouseClicked(java.awt.event.MouseEvent evt) {
opStatus = SCROLL_OP;
drawingScrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() {
@Override
public void adjustmentValueChanged(AdjustmentEvent e)
{
int extent,curValue;
extent = drawingScrollPane.getVerticalScrollBar().getModel().getExtent();
curValue = drawingScrollPane.getVerticalScrollBar().getValue()+extent;
if(curValue==drawPanel.getHeight())
{
System.out.println("value of scroll equals to Max value....");
drawPanel.setPreferredSize(new Dimension(423,drawPanelHeight*4));
}
System.out.println("Value: " + curValue + " Max: " + drawingScrollPane.getVerticalScrollBar().getMaximum());
}
});
}
private void eraserButtonMouseClicked(java.awt.event.MouseEvent evt) {
eraserButtonMouseClickedTest(evt);
updateMouseCoordinates(evt);
}
private void pencilButtonMouseClicked(java.awt.event.MouseEvent evt) {
opStatus = PEN_OP;
}
public boolean mouseHasMoved(MouseEvent e)
{
return (mousex != e.getX() || mousey != e.getY());
}
public void setGraphicalDefaults(MouseEvent e)
{
mousex = e.getX();
mousey = e.getY();
prevx = e.getX();
prevy = e.getY();
}
@Override
public void mouseDragged(MouseEvent e)
{
updateMouseCoordinates(e);
switch (opStatus)
{
case PEN_OP : pencilButtonMouseClickedTest(e);
break;
case ERASER_OP: eraserButtonMouseClicked(e);
break;
case SCROLL_OP: scrollButtonMouseClicked(e);
break;
}
}
public void mouseReleased(MouseEvent e)
{
updateMouseCoordinates(e);
switch (opStatus)
{
case PEN_OP : releasedPen();
break;
case ERASER_OP : releasedEraser();
break;
}
}
public void mouseEntered(MouseEvent e)
{
updateMouseCoordinates(e);
}
public void releasedPen()
{
initialPen = true;
}
public void releasedEraser()
{
initialEraser = true;
Graphics g = drawPanel.getGraphics();
g.setColor(mainColor.white);
g.drawRect(mousex-eraserLength,mousey-eraserLength,eraserLength*2,eraserLength*2);
}
public void updateMouseCoordinates(MouseEvent e)
{
String xCoor ="";
String yCoor ="";
if (e.getX() < 0) xCoor = "0";
else
{
xCoor = String.valueOf(e.getX());
}
if (e.getY() < 0) xCoor = "0";
else
{
yCoor = String.valueOf(e.getY());
}
}
public static void main(String args[]) {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException ex) {
java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (InstantiationException ex) {
java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (IllegalAccessException ex) {
java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
} catch (javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(WorkArea.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new WorkArea().setVisible(true);
}
});
}
private javax.swing.JLabel backButton;
private javax.swing.JPanel controlPanel;
private javax.swing.JPanel drawPanel;
private javax.swing.JPanel drawingPanel;
private javax.swing.JScrollPane drawingScrollPane;
private javax.swing.JButton eraserButton;
private javax.swing.JLabel headerImage;
private javax.swing.JPanel headerPanel;
private javax.swing.JButton pencilButton;
private javax.swing.JButton scrollButton;
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
updateMouseCoordinates(e);
}
@Override
public void mouseMoved(MouseEvent e) {
updateMouseCoordinates(e);
}
@Override
public void mousePressed(MouseEvent e) {
updateMouseCoordinates(e);
}
}
答案 0 :(得分:4)
我假设您正在使用JPanel
并使用getGraphics()
渲染出paintComponent
。
您现在已经看到了为什么不应该这样做。重新绘制组件后,擦除之前绘制的任何内容都会被清除,并且您需要重新绘制内容。
首先覆盖super.paintComponent
并更新此方法中的所有行(不要忘记致电import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
public class MouseDraggedTest {
public static void main(String[] args) {
new MouseDraggedTest();
}
public MouseDraggedTest() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new TestPane()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Map<Point, List<Point>> mapPoints;
private Point currentPoint;
public TestPane() {
mapPoints = new HashMap<>(25);
MouseAdapter mouseListener = new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
currentPoint = e.getPoint();
mapPoints.put(currentPoint, new ArrayList<Point>(25));
}
@Override
public void mouseReleased(MouseEvent e) {
List<Point> points = mapPoints.get(currentPoint);
if (points.isEmpty()) {
mapPoints.remove(currentPoint);
}
currentPoint = null;
}
@Override
public void mouseDragged(MouseEvent me) {
List<Point> points = mapPoints.get(currentPoint);
points.add(me.getPoint());
repaint();
}
};
addMouseListener(mouseListener);
addMouseMotionListener(mouseListener);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 800);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Point startPoint : mapPoints.keySet()) {
List<Point> points = mapPoints.get(startPoint);
for (Point p : points) {
if (startPoint != null) {
g.drawLine(startPoint.x, startPoint.y, p.x, p.y);
}
startPoint = p;
}
}
}
}
}
有关详细信息,请参阅Performing Custom Painting和Painting in AWT and Swing
例如......
更新了示例
这是MouseEvent is not registering a release when I release the mouse button答案的修改版本,其中包含滚动窗格......
BufferedImage
更新了BufferedImage示例
由于您需要提供的操作不仅仅是绘图,因此您可能会发现使用DrawingPanel
作为主绘图表面并将其呈现给import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Line2D;
import java.awt.image.BufferedImage;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MyPicture {
public static void main(String[] args) {
new MyPicture();
}
public MyPicture() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public enum DrawOperation {
Draw,
Erase
}
public class TestPane extends JPanel {
private DrawOperation op;
private JToggleButton pencil;
private JToggleButton eraser;
private DrawPane drawPane;
public TestPane() {
setLayout(new BorderLayout());
drawPane = new DrawPane();
MouseAdapter adapter = new MouseAdapter() {
private Point startPoint;
@Override
public void mouseEntered(MouseEvent e) {
drawPane.updateDrawCursor(e.getPoint(), op);
}
@Override
public void mouseExited(MouseEvent e) {
drawPane.removeDrawCursor();
}
@Override
public void mousePressed(MouseEvent e) {
startPoint = e.getPoint();
}
@Override
public void mouseReleased(MouseEvent e) {
startPoint = null;
}
@Override
public void mouseDragged(MouseEvent e) {
drawPane.applyOperation(startPoint, e.getPoint(), op);
drawPane.updateDrawCursor(e.getPoint(), op);
startPoint = e.getPoint();
}
@Override
public void mouseMoved(MouseEvent e) {
drawPane.updateDrawCursor(e.getPoint(), op);
}
};
drawPane.addMouseListener(adapter);
drawPane.addMouseMotionListener(adapter);
JPanel operations = new JPanel(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
pencil = new JToggleButton("Draw");
eraser = new JToggleButton("Erase");
ButtonGroup bgOps = new ButtonGroup();
bgOps.add(pencil);
bgOps.add(eraser);
operations.add(pencil, gbc);
operations.add(eraser, gbc);
pencil.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
op = DrawOperation.Draw;
}
});
eraser.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
op = DrawOperation.Erase;
}
});
add(operations, BorderLayout.WEST);
add(new JScrollPane(drawPane));
}
}
public class DrawPane extends JPanel {
private BufferedImage image;
private Shape drawCursor;
private Point cursorPoint;
private int eraseSize = 20;
public DrawPane() {
image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = image.createGraphics();
g2d.setBackground(Color.WHITE);
g2d.fillRect(0, 0, 400, 400);
g2d.dispose();
}
@Override
public Dimension getPreferredSize() {
return new Dimension(400, 400);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
if (image != null) {
g2d.drawImage(image, 0, 0, this);
}
if (drawCursor != null && cursorPoint != null) {
int x = (cursorPoint.x - (drawCursor.getBounds().width) / 2);
int y = (cursorPoint.y - (drawCursor.getBounds().height) / 2);
g2d.translate(x, y);
g2d.draw(drawCursor);
g2d.translate(-x, -y);
}
g2d.dispose();
}
public void updateDrawCursor(Point point, DrawOperation op) {
cursorPoint = point;
if (op != null) {
switch (op) {
case Draw:
drawCursor = new Ellipse2D.Float(0, 0, 4, 4);
break;
case Erase:
drawCursor = new Ellipse2D.Float(0, 0, eraseSize, eraseSize);
break;
}
} else {
drawCursor = null;
}
repaint();
}
protected void removeDrawCursor() {
drawCursor = null;
repaint();
}
protected void applyOperation(Point fromPoint, Point toPoint, DrawOperation op) {
if (image != null) {
if (op != null) {
Graphics2D g2d = image.createGraphics();
switch (op) {
case Draw:
g2d.setColor(Color.BLACK);
g2d.draw(new Line2D.Float(fromPoint, toPoint));
break;
case Erase:
g2d.setColor(Color.WHITE);
g2d.setStroke(new BasicStroke(eraseSize));
g2d.draw(new Line2D.Float(fromPoint, toPoint));
break;
}
g2d.dispose();
}
}
repaint();
}
}
}
{{1}}