java - 从绘图对象中清除窗口

标签 java swing jframe jpanel

我有 4 个类:

Draw、Rectangle(扩展 Draw)、FreeHand(扩展 Draw)和一个测试类。

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

我有一个带有“返回”和“清除”选项的菜单栏。返回删除最后绘制的对象。这是通过删除数组列表中的最后一个对象来完成的。 Clear 清除窗口。这是通过从所有项目中清除数组列表来完成的。

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

我的问题 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());
    }
}

测试类:

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 时扩展它?您以这种方式给这些类带来了很多不必要的开销。


编辑
你问:

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

没有。我的意思是 Draw 不应该扩展 JPanel,而应该是一个逻辑类,而不是 Swing 组件的派生类。我认为您应该创建一个名为 MyDrawingPanel 的新类,您可以在其中进行所有绘图。请看我上面的代码片段。此外,paintComponent 在 JComponent 中被声明为 protected ,而不是公开的,我认为在覆盖它时将其公开没有任何好处,因此我建议将其保留为 protected 。

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


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


编辑3

我的一些代码示例:

关于java - 从绘图对象中清除窗口,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26723764/

相关文章:

java - HashMap<DateTime, ArrayList<Email>>

java - 使用逗号分隔坐标的扫描仪 NextInt()

java - Swing:连接第二个框架的可视化界面

java - 更改 JTable 的单元格颜色时的不同更改

java - 作为调用父框架的对话框启动应用程序

java - 是否有 "superclass of"方法来定义泛型类型或仅 "extends"?

java - 在 GWT Web 应用程序中调用外部应用程序(即 Windows 计算器)

java - 如何模拟 JButton 数组中特定 JButton 的移动

java - 调用另一个类中的函数

java - 退出jframe时 Swing 停止定时器