从绘图对象中清除窗口(Clear window from drawing objects)

我有4节课:

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

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

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

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

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

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

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

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<Draw> 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"); } }

I have 4 classes:

Draw, Rectangle (extends Draw), FreeHand (extends Draw) and a test class.

I add rectangles and lines drawn by free hand to an arrayList.

I have a menubar with choices Back and Clear. Back removes the last drawn object. It is done by removing the last object in the arraylist. Clear clears the windows. It is done by clear the arraylist from all items.

Now to my problem: The window does not clear. I don't know how to write the code to make it repaint properly so that the items removes from the window. Can you please help me with how the code for this would look like, and where I put it. I appreciate it, thank you.

My problem no 2: After I have removed the last item in the arraylist I need to draw all the items in the arrayList. I have tried

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

But it does not work. Any suggestions? Class Draw:

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; } }

Class Rectangle:

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()); } }

Class 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<Draw> 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颜色绘制线 重绘中的图形绘制随机线条

Your problem looks to be that your paint method is not calling the super's paint method since this will have the component clean itself of all "dirty" image bits. But having said that, you shouldn't draw directly in the JFrame. Instead draw in the paintComponent method of a JComponent or JPanel, and in that method be sure to call the super's paintComponent method:

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

Also, why does your Draw class, and thus all classes that derive from it, extend JPanel when it is not being used as a JPanel? You are giving a lot of unnecessary overhead to these classes this way.


Edit You ask:

So you mean I should move Everything in the paint-method to the paintComponent-method in Draw? Why protected?

No. I mean that Draw should not extend JPanel, but instead should be a logical class, not a Swing component-derived class. I think that you should create a new class, say called MyDrawingPanel where you do all of your drawing. Please see my code snippet above. Also paintComponent is declared in JComponent to be protected, not public, and I see no advantage to making it public when overriding it, so I recommend leaving it protected.

Please read the Swing Info Links to see the Swing graphics tutorials and give them a read.


Edit 2 You're also using a getGraphics() call on a component to get your Graphics object, not good as this will return an unstable Graphics object. Instead do all drawing in the paintComponent method or on a BufferedImage (that again is drawn in paintComponent).


Edit 3

Some of my code examples:

Minimal way to make a cleanable drawing area Changing JPanel Graphics g color drawing line Graphics in repaint draws random lines

更多推荐