从绘图对象中清除窗口

我有4节课:

Draw,Rectangle(extends Draw),FreeHand(extends Draw)和测试类。

我将自由手绘制的矩形和线条添加到arrayList中。

我有一个选择Back和Clear的菜单栏。 返回删除最后绘制的对象。 它是通过删除arraylist中的最后一个对象来完成的。 清除窗户。 这是通过清除所有项目中的arraylist来完成的。

现在我的问题:窗口不清楚。 我不知道如何编写代码使其重新正确重绘,以便从窗口中删除项目。 你能帮我解释一下这个代码的样子,以及我把它放在哪里。 我很感激,谢谢。

我的问题2:在我删除了arraylist中的最后一项后,我需要绘制arrayList中的所有项目。 我试过了

for (Draw d : shapeList) { d.draw(g2); } 

但它不起作用。 有什么建议么? class级抽奖:

 import java.awt.Graphics; import java.awt.Graphics2D; import javax.swing.JPanel; public abstract class Draw extends JPanel { public int startX, startY, endX, endY, width, height, w, h; public String color = "Black"; public Draw(int startX, int startY, int width, int height) { this.startX = startX; this.startY = startY; this.width = width; this.height = height; } public abstract void draw(Graphics2D g); @Override public int getX() { return startX; } public void setX(int startX) { this.startX = startX; } @Override public int getY() { return startY; } public void setY(int startY) { this.startY = startY; } @Override public int getWidth() { return width; } public void setWidth(int width) { this.width = width; } @Override public int getHeight() { return height; } public void setHeight(int height) { this.height = height; } public void setColor(String color) { this.color = color; } } 

类矩形:

 import java.awt.Color; import java.awt.Graphics2D; public class Rectangle extends Draw { public Rectangle(int x, int y, int width, int height) { super(x, y, width, height); } @Override public void draw(Graphics2D g2) { switch (color) { case "Red": g2.setColor(Color.RED); break; case "Green": g2.setColor(Color.GREEN); break; case "Blue": g2.setColor(Color.BLUE); break; case "Yellow": g2.setColor(Color.YELLOW); break; case "Orange": g2.setColor(Color.ORANGE); break; case "Black": g2.setColor(Color.BLACK); break; } g2.drawRect(getX(), getY(), getWidth(), getHeight()); } } 

FreeHand类:

 import java.awt.BasicStroke; import java.awt.Color; import java.awt.Graphics2D; public class FreeHand extends Draw { public FreeHand(int x, int y, int width, int height) { super(x, y, width, height); } /* public FreeHand() { super(); }*/ @Override public void draw(Graphics2D g2) { //Graphics2D g2 = (Graphics2D) g; g2.setStroke(new BasicStroke(3)); switch (color) { case "Red": g2.setColor(Color.RED); break; case "Green": g2.setColor(Color.GREEN); break; case "Blue": g2.setColor(Color.BLUE); break; case "Yellow": g2.setColor(Color.YELLOW); break; case "Orange": g2.setColor(Color.ORANGE); break; case "Black": g2.setColor(Color.BLACK); break; } g2.drawLine(getX(), getY(), getWidth(), getHeight()); } } 

识别TestClass:

 import java.awt.*; import java.awt.event.*; import java.util.ArrayList; import javax.swing.*; public class JavaApplication30 extends JFrame implements ActionListener { public ArrayList shapeList = new ArrayList(); int startX, startY, endX, endY, w, h; private JPanel topPanel; private JPanel bottomPanel; private JPanel orangePanel; private JPanel greenPanel; private JPanel bluePanel; private JPanel blackPanel; private JPanel redPanel; private JPanel yellowPanel; private JPanel leftPanel; private JPanel rightPanel; private JPanel colorPanel; private JMenuBar menuBar; private JMenu menu; private JMenuItem menuItem1; private JMenuItem menuItem2; private JMenuItem menuItem3; private JComboBox comboBox; private JLabel leftLabel; private JLabel commaLabel; private JLabel colorLabel; private static JLabel xLabel; private static JLabel yLabel; private final String labelText = "Coordinates: "; private final String comma = ","; private final String color = "Color: "; private final String[] boxOptions = new String[] {"Rectangle", "Freehand"}; private String pickedColor = "Black"; private String x = ""; private String y = ""; Container cp = getContentPane(); private int count = 0; public JavaApplication30(String title) { super(title); this.setLayout(new BorderLayout()); this.setLocationRelativeTo(null); this.setSize(840, 500); this.initComponents(); this.initMenu(); this.setVisible(true); } private void initComponents() { cp.setBackground(Color.WHITE); comboBox = new JComboBox(boxOptions); topPanel = new JPanel(new GridLayout(1,7)); bottomPanel = new JPanel(new GridLayout(1,2)); orangePanel = new JPanel(); greenPanel = new JPanel(); bluePanel= new JPanel(); blackPanel = new JPanel(); redPanel = new JPanel(); yellowPanel = new JPanel(); colorPanel = new JPanel(); rightPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); leftPanel = new JPanel(new FlowLayout(FlowLayout.LEFT)); comboBox.setSelectedIndex(0); comboBox.addActionListener(this); topPanel.setPreferredSize(new Dimension(0,40)); bottomPanel.setPreferredSize(new Dimension(0,30)); colorPanel.setPreferredSize(new Dimension(60,20)); leftLabel = new JLabel(labelText); commaLabel = new JLabel(comma); colorLabel = new JLabel(color); bottomPanel.setBackground(Color.LIGHT_GRAY); orangePanel.setBackground(Color.ORANGE); greenPanel.setBackground(Color.GREEN); bluePanel.setBackground(Color.BLUE); blackPanel.setBackground(Color.BLACK); redPanel.setBackground(Color.RED); yellowPanel.setBackground(Color.YELLOW); colorPanel.setBackground(Color.BLACK); topPanel.add(orangePanel); topPanel.add(greenPanel); topPanel.add(bluePanel); topPanel.add(blackPanel); topPanel.add(redPanel); topPanel.add(yellowPanel); topPanel.add(comboBox); rightPanel.add(colorLabel); rightPanel.add(colorPanel); bottomPanel.add(leftPanel); bottomPanel.add(rightPanel); this.add(topPanel, BorderLayout.PAGE_START); this.add(bottomPanel, BorderLayout.PAGE_END); } @Override public void paint(Graphics g) { if(count == 0) { cp.repaint(); } Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); g2.setStroke(new BasicStroke(1)); for (Draw d : shapeList) { d.draw(g2); } if (startX != 0 && startY != 0 && endX != 0 && endY != 0) { int width = Math.abs(startX - endX); int height = Math.abs(startY - endY); int minX = Math.min(startX, endX); int minY = Math.min(startY, endY); Rectangle r = new Rectangle(minX, minY, width, height); g2.setPaint(Color.WHITE); g2.fillRect(r.getX(), r.getY(), r.getWidth(), r.getHeight()); r.setColor(pickedColor); r.draw(g2); } } @Override public void actionPerformed(ActionEvent e) { count++; if (e.getSource().equals(menuItem1)) { shapeList.clear(); //Code to clear window } if (e.getSource().equals(menuItem2)) { shapeList.remove(shapeList.size() - 1); //Code to clear window Graphics g = getGraphics(); Graphics2D g2 = (Graphics2D) g; for (Draw d : shapeList) { d.draw(g2); } } if (e.getSource().equals(menuItem3)) { //Exit } if (e.getSource().equals(comboBox)) { JComboBox cb = (JComboBox)e.getSource(); if (cb.getSelectedItem().equals("Rectangle")) { this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { startX = e.getX(); startY = e.getY(); endX = startX; endY = startY; repaint(); } @Override public void mouseReleased(MouseEvent e) { endX = e.getX(); endY = e.getY(); int width = Math.abs(startX - endX); int height = Math.abs(startY - endY); int minX = Math.min(startX, endX); int minY = Math.min(startY, endY); Rectangle r = new Rectangle(minX, minY, width, height); shapeList.add(r); r.setColor(pickedColor); startX = 0; startY = 0; endX = 0; endY = 0; repaint(); } }); this.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { endX = e.getX(); endY = e.getY(); repaint(); } }); } else if (cb.getSelectedItem().equals("Freehand")) { this.addMouseListener(new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { startX = e.getX(); startY = e.getY(); } }); this.addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent e) { Graphics g = getGraphics(); Graphics2D g2 = (Graphics2D) g; FreeHand fh = new FreeHand(startX, startY, e.getX(), e.getY()); shapeList.add(fh); fh.setColor(pickedColor); fh.draw(g2); startX = e.getX(); startY = e.getY(); } }); } } } private void initMenu() { menuBar = new JMenuBar(); menu = new JMenu("File"); menuBar.add(menu); menuItem1 = new JMenuItem("Clear"); menuItem2 = new JMenuItem("Back"); menuItem3 = new JMenuItem("Exit"); menu.add(menuItem1); menu.add(menuItem2); menu.addSeparator(); menu.add(menuItem3); menu.setMnemonic(KeyEvent.VK_A); KeyStroke ks1 = KeyStroke.getKeyStroke(KeyEvent.VK_N, InputEvent.CTRL_MASK); //Crtl+n KeyStroke ks2 = KeyStroke.getKeyStroke(KeyEvent.VK_I, InputEvent.CTRL_MASK); //Ctrl+i KeyStroke ks3 = KeyStroke.getKeyStroke(KeyEvent.VK_A, InputEvent.CTRL_MASK); //Ctrl+e menuItem1.setAccelerator(ks1); menuItem2.setAccelerator(ks2); menuItem3.setAccelerator(ks3); menuItem1.addActionListener(this); menuItem2.addActionListener(this); menuItem3.addActionListener(this); setJMenuBar(menuBar); } public static void main(String args[]) { new JavaApplication30("Draw"); } } 

您的问题似乎是您的paint方法没有调用super的paint方法,因为这将使组件清除所有“脏”图像位。 但话说回来,你不应该直接在JFrame中绘制。 而是在JComponent或JPanel的paintComponent方法中绘制,并在该方法中确保调用super的paintComponent方法:

 public class MyDrawingPanel extends JPanel { @Override proteced void paintComponent(Graphics g) { super.paintComponent(g); // don't forget this! // do your drawing here } } 

另外,为什么你的Draw类,以及从它派生的所有类,在没有被用作JPanel时扩展JPanel? 这种方式给这些类带来了很多不必要的开销。


编辑
你问:

所以你的意思是我应该将paint-method中的Everything移动到Draw中的paintComponent方法? 为何受到保护

不,我的意思是Draw不应该扩展JPanel,而应该是一个逻辑类,而不是一个Swing组件派生类。 我认为你应该创建一个新类,比如名为MyDrawingPanel,你可以在其中完成所有绘图。 请参阅上面的代码段。 另外paintComponent在JComponent中声明是受保护的,而不是公共的,我认为在覆盖它时将它公开是没有优势的,所以我建议保护它。

请阅读Swing Info Links以查看Swing图形教程并阅读它们。


编辑2
您还在组件上使用getGraphics()调用来获取Graphics对象,这不好,因为这将返回一个不稳定的Graphics对象。 而是在paintComponent方法中或在BufferedImage上绘制所有绘图(再次在paintComponent中绘制)。


编辑3

我的一些代码示例:

  • 制作可清洁绘图区域的最小方法
  • 更改JPanel Graphics g颜色绘制线
  • 重绘中的图形绘制随机线条