Easier way to make a paint application in java?

前端 未结 3 1440
无人及你
无人及你 2020-12-16 09:02

So basically I have some code I was working on a couple of days ago that is kind of like Paint, which allows you to essentially draw on the screen using the mouse. I kind of

相关标签:
3条回答
  • 2020-12-16 09:23

    Or we can try drawing for only java code , I think it's so easy and powerful.

    package drawingbymouse;
    
    import java.awt.*;
    import java.awt.event.*;
    
    public class DrawingByMouse extends Frame 
                              implements MouseMotionListener{
    
        DrawingByMouse(){
            addMouseMotionListener(this);
            setSize(400, 400);
            setLayout(null);
            setVisible(true);
        }
        @Override
        public void mouseDragged(MouseEvent e){
            Graphics g = getGraphics();
            g.setColor(Color.BLACK);
            g.fillOval(e.getX(), e.getY(), 10, 10);
        }
        public void mouseMoved(MouseEvent e){
        }
        public static void main (String[]args){
            new DrawingByMouse();
        }
    }
    
    0 讨论(0)
  • 2020-12-16 09:28

    You're current approach is basically breaking the requirements of the paint chain, by not calling super.paintComponent. The paintComponent method does a set of operations, which you are not taking over and which could result in some very weird paint artifacts which are difficult to replicate consistently.

    Graphics is a shared resource, so the Graphics context which was used to paint some other control will be the same which is used to paint your component, unless you are "cleaning" the context before hand, what was previously painted to the context will remain (which is why you code currently "seems" to work).

    Instead, you should use a MouseListener to define a anchor point, which represents the point at which the mouse was pressed and then use the MouseMotionListener to define the extent of the selection area, for example...

    import java.awt.AlphaComposite;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class SelectExample {
    
        public static void main(String[] args) {
            new SelectExample();
        }
    
        public SelectExample() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private Rectangle selection;
    
            public TestPane() {
                MouseAdapter ma = new MouseAdapter() {
    
                    private Point clickPoint;
    
                    @Override
                    public void mousePressed(MouseEvent e) {
                        clickPoint = e.getPoint();
                        selection = null;
                    }
    
                    @Override
                    public void mouseDragged(MouseEvent e) {
                        Point dragPoint = e.getPoint();
                        int x = Math.min(clickPoint.x, dragPoint.x);
                        int y = Math.min(clickPoint.y, dragPoint.y);
    
                        int width = Math.max(clickPoint.x, dragPoint.x) - x;
                        int height = Math.max(clickPoint.y, dragPoint.y) - y;
    
                        if (selection == null) {
                            selection = new Rectangle(x, y, width, height);
                        } else {
                            selection.setBounds(x, y, width, height);
                        }
                        repaint();
                    }
    
                    @Override
                    public void mouseReleased(MouseEvent e) {
                        selection = null;
                        repaint();
                    }
    
                };
    
                addMouseListener(ma);
                addMouseMotionListener(ma);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                if (selection != null) {
                    g.setColor(UIManager.getColor("List.selectionBackground"));
                    Graphics2D g2d = (Graphics2D) g.create();
                    g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
                    g2d.fill(selection);
                    g2d.dispose();
                    g2d = (Graphics2D) g.create();
                    g2d.draw(selection);
                    g2d.dispose();
                }
            }
    
        }
    
    }
    

    Just to highlight the issue you will face if you continue to violate the requirements of the paintComponent method, this is what happens when I don't call super.paintComponent

    I simply added two JButton's to the JFrame (so not even directly to the panel). paintComponent does a series of important jobs, which you neglected to perform, which is going to cause more problems and issues.

    Free form line example...

    A free form line is actually a illusion, it's a series of (small) lines drawn between a series of points, the reason for this is because the MouseListener won't report every mouse position it moves across, depending on the speed the mouse is moved, you might get lots of call backs or a few.

    So, instead of drawing to just draw the points, we store the points in a List and draw lines between them, for example...

    import java.awt.AlphaComposite;
    import java.awt.Dimension;
    import java.awt.EventQueue;
    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.Point;
    import java.awt.Rectangle;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.util.ArrayList;
    import java.util.List;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.UIManager;
    import javax.swing.UnsupportedLookAndFeelException;
    
    public class FreeFormLines {
    
        public static void main(String[] args) {
            new FreeFormLines();
        }
    
        public FreeFormLines() {
            EventQueue.invokeLater(new Runnable() {
                @Override
                public void run() {
                    try {
                        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                        ex.printStackTrace();
                    }
    
                    JFrame frame = new JFrame("Testing");
                    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                    frame.add(new TestPane());
                    frame.pack();
                    frame.setLocationRelativeTo(null);
                    frame.setVisible(true);
                }
            });
        }
    
        public class TestPane extends JPanel {
    
            private List<List<Point>> points;
    
            public TestPane() {
                points = new ArrayList<>(25);
                MouseAdapter ma = new MouseAdapter() {
    
                    private List<Point> currentPath;
    
                    @Override
                    public void mousePressed(MouseEvent e) {
                        currentPath = new ArrayList<>(25);
                        currentPath.add(e.getPoint());
    
                        points.add(currentPath);
                    }
    
                    @Override
                    public void mouseDragged(MouseEvent e) {
                        Point dragPoint = e.getPoint();
                        currentPath.add(dragPoint);
                        repaint();
                    }
    
                    @Override
                    public void mouseReleased(MouseEvent e) {
                        currentPath = null;
                    }
    
                };
    
                addMouseListener(ma);
                addMouseMotionListener(ma);
            }
    
            @Override
            public Dimension getPreferredSize() {
                return new Dimension(200, 200);
            }
    
            protected void paintComponent(Graphics g) {
                super.paintComponent(g);
                Graphics2D g2d = (Graphics2D) g.create();
                for (List<Point> path : points) {
                    Point from = null;
                    for (Point p : path) {
                        if (from != null) {
                            g2d.drawLine(from.x, from.y, p.x, p.y);
                        }
                        from = p;
                    }
                }
                g2d.dispose();
            }
    
        }
    
    }
    
    0 讨论(0)
  • 2020-12-16 09:30

    This is a simple example for a practical paint Application, where you can control and change the size and the Color of your drawing.

    public class Main extends Application{
        @Override
        public void start(Stage stage){
            try{
                g = can.getGraphicsContext2D();
                g.setStroke(Color.BLACK);
                g.setLineWidth(1);
                c.setValue(Color.BLACK);
                c.setOnAction(e->{
                    g.setStroke(c.getValue());
                });
                sli.setMin(1);
                sli.setMax(100);
                sli.setShowTickLabels(true);
                sli.setShowTickMarks(true);
                sli.valueProperty().addListener(e->{
                    double val = sli.getValue();
                    String str = String.format("%.1f",  val);
                    lab.setText(str);
                    g.setLineWidth(val);
                });
                gri.addRow(0,  c, sli, lab);
                gri.setHgap(20);
                gri.setAlignement(Pos.TOP_CENTER);
                gri.setPadding( new Insets( 20, 0, 0, 0));
    
                scene.setOnMousePressed(e->{.
                   g.beginPath();
                   g.lineTo(e.getSceneX(), e.getSceneY());
                   g.stroke();
                });
                scene.setOnMoudrDragged(e->{. 
                    g.lineTo(e.getSceneX(),  e.getSceneY());
                    g.stroke();
                });
                pan.getChildren().addAll(can, gri);
                stage.setScene(scene);
                stage.show();
            }catch(Exception e){
    
                e.printStrackTrace();
            }
    
           Canvas can = new Canvas(760, 490);
           GraphicsContext  g ;
           ColorPicker  c =  new ColorPicker();
           Slider sli = new Slider();
           Label lab = new Label("1.0");
           GridPane gri = new GridPane();
           StackPane pan =  new StackPane();
           Scene  scene = new Scene(pan, 760, 490);
       public static void main (String [] args){
           launch(args);
       }
    }
    
    0 讨论(0)
提交回复
热议问题