我有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());
}
}
FreeHandHand:
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");
}
}
答案 0 :(得分:4)
你的问题似乎是你的绘画方法没有调用超级的绘画方法,因为这将使组件清洁所有&#34;脏&#34;图像位。但话说回来,你不应该直接在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
我的一些代码示例: