Метод paintComponent (Graphics) не работает - PullRequest
0 голосов
/ 31 октября 2019

Я новичок в Java и пытаюсь создать простую программу рисования, в которой пользователь нажимает кнопку для рисования линий путем перетаскивания мышью

Моя проблема в том, что линии не отображаются на холсте, хотя свойствакаждой строки сохраняются. Когда я пытаюсь нарисовать линию в методе «мышь отпущена», это работает, поэтому я предполагаю, что проблема связана с «PaintComponent», но я не могу ее найти.

import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;

public class GUI extends JPanel{
    public JFrame frame = new JFrame();
    public Canvas canvas = new Canvas();
    private Point p1,p2;
    private List<pro> lineList = new ArrayList<>();
    private pro currentLine = null;

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GUI window = new GUI();
                    window.frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public GUI() {
        initialize();
    }

    public void paintComponent(Graphics page) {
        super.paintComponent(page);
        for (pro line : lineList) {
            line.draw(page);
            System.out.println(line);
        }

        if (currentLine != null) {
           currentLine.draw(page);
        }
    }

    private void initialize(){

        frame.getContentPane().setBackground(Color.BLACK);
        frame.setBounds(0, 0, 346, 300);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.getContentPane().setLayout(null);
        frame.getContentPane().add(canvas); 
        Canvas canvas = new Canvas();
        canvas.setLocation(10, 10);
        canvas.setSize(200, 241);
        canvas.setBackground(Color.DARK_GRAY);
        frame.getContentPane().add(canvas); 

        JButton btnLine = new JButton("Line");
        frame.getContentPane().add(btnLine);
        btnLine.setBackground(Color.DARK_GRAY);
        btnLine.setForeground(Color.RED);
        btnLine.setFont(new Font("Stencil", Font.BOLD, 16));


        btnLine.addActionListener(new ActionListener() {
            int x1;
            int y1;
            public void actionPerformed(ActionEvent e) {
                canvas.addMouseListener(new MouseAdapter(){
                    public void mousePressed(MouseEvent e) {
                        x1 = e.getX();
                        y1 = e.getY();
                        currentLine = null;
                    }
                    public void mouseReleased(MouseEvent e) {
                        pro line = createLine(e,Color.red);
                        lineList.add(line);
                        currentLine = null;
                        canvas.repaint();
                    }
                });
                canvas.addMouseMotionListener(new MouseAdapter() {
                    public void mouseDragged(MouseEvent e) {
                        currentLine = createLine(e, Color.white);
                        repaint();
                    }
                });           
            }
            private pro createLine(MouseEvent e, Color currentColor) {
                int x2 = e.getX();
                int y2 = e.getY();
                return new pro(x1, x2, y1, y2, currentColor);
            }

        });
        btnLine.setBounds(229, 95, 91, 31);
        frame.getContentPane().add(btnLine);

        }   

    class pro {

        private int x1, x2, y1, y2;
        private Color color;

        public pro(int x1, int x2, int y1, int y2, Color color) {
            this.x1 = x1;
            this.x2 = x2;
            this.y1 = y1;
            this.y2 = y2;
            this.color = color;
        }

        public void draw(Graphics page) {
            page.setColor(color);
            page.drawLine(x1, y1, x2, y2); 
        }
    }

}

1 Ответ

1 голос
/ 31 октября 2019

JFrame s не предназначены для переопределения paintComponent: это многослойные контейнеры. Если вы хотите нарисовать пользовательский компонент, создайте подкласс JComponent (или JPanel), а затем вставьте его (панель содержимого) в ваш JFrame.

. Это работает для меня:

public class SketchPad extends JComponent {
    private final List<Line> lineList = new ArrayList<>();
    private Line currentLine = null;
    private Color drawingColor = Color.RED;

    public SketchPad() {
        initialize();
    }

    public Color getDrawingColor() {
        return drawingColor;
    }

    public void setDrawingColor(Color newColor) {
        if (newColor == null) {
            throw new IllegalArgumentException("Drawing color cannot be null");
        }
        this.drawingColor = newColor;
    }

    private void initialize() {
        addMouseListener(new MouseAdapter() {
            int x1;
            int y1;

            @Override
            public void mousePressed(MouseEvent e) {
                x1 = e.getX();
                y1 = e.getY();
                currentLine = null;
            }

            @Override
            public void mouseReleased(MouseEvent e) {
                Line line = createLine(e, drawingColor);
                lineList.add(line);
                currentLine = null;
                repaint();
            }

            @Override
            public void mouseMoved(MouseEvent e) {
                currentLine = createLine(e, Color.BLACK);
                repaint();
            }

            private Line createLine(MouseEvent e, Color currentColor) {
                int x2 = e.getX();
                int y2 = e.getY();
                return new Line(x1, x2, y1, y2, currentColor);
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        for (Line line : lineList) {
            line.draw(g);
            System.out.println(line);
        }

        if (currentLine != null) {
           currentLine.draw(g);
        }
    }

    private static class Line {
        private final int x1;
        private final int x2;
        private final int y1;
        private final int y2;
        private final Color color;

        public Line(int x1, int x2, int y1, int y2, Color color) {
            this.x1 = x1;
            this.x2 = x2;
            this.y1 = y1;
            this.y2 = y2;
            this.color = color;
        }

        public void draw(Graphics page) {
            page.setColor(color); //!! This first!
            page.drawLine(x1, y1, x2, y2);  // **Then** this
        }
    }
}

Основной кадр:

public class MainFrame extends javax.swing.JFrame {
    private SketchPad pad;

    public MainFrame() {
        initComponents();
    }

    @SuppressWarnings("unchecked")
    private void initComponents() {
        pad = new SketchPad();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        getContentPane().add(pad, java.awt.BorderLayout.CENTER);

        pack();
    }
}

ОБНОВЛЕНИЕ: необходим mouseMotionListener:

private void initialize() {
    MouseAdapter adapter = new MouseAdapter() {
        int x1;
        int y1;

        @Override
        public void mousePressed(MouseEvent e) {
            x1 = e.getX();
            y1 = e.getY();
            currentLine = null;
            addMouseMotionListener(this);
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            Line line = createLine(e, drawingColor);
            lineList.add(line);
            currentLine = null;
            repaint();
            removeMouseMotionListener(this);
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            currentLine = createLine(e, Color.BLACK);
            repaint();
        }

        private Line createLine(MouseEvent e, Color currentColor) {
            int x2 = e.getX();
            int y2 = e.getY();
            return new Line(x1, x2, y1, y2, currentColor);
        }
    };
    addMouseListener(adapter);
    addMouseMotionListener(adapter);
}

ОБНОВЛЕНИЕ 2: обрабатывать включение / отключение

private final MouseAdapter adapter = new MouseAdapter() {
        int x1;
        int y1;

        @Override
        public void mousePressed(MouseEvent e) {
            x1 = e.getX();
            y1 = e.getY();
            currentLine = null;
        }

        @Override
        public void mouseReleased(MouseEvent e) {
            Line line = createLine(e, drawingColor);
            lineList.add(line);
            currentLine = null;
            repaint();
        }

        @Override
        public void mouseDragged(MouseEvent e) {
            currentLine = createLine(e, Color.BLACK);
            repaint();
        }

        private Line createLine(MouseEvent e, Color currentColor) {
            int x2 = e.getX();
            int y2 = e.getY();
            return new Line(x1, x2, y1, y2, currentColor);
        }
    };

...

private void initialize() {
    setEnabled(isEnabled());
}

...

@Override
public void setEnabled(boolean enabled) {
    super.setEnabled(enabled);
    if (enabled) {
        addMouseListener(adapter);
        addMouseMotionListener(adapter);
    } else {
        removeMouseListener(adapter);
        removeMouseMotionListener(adapter);
    }
}
...