Un moyen plus facile de créer une application de peinture en java?


Donc, fondamentalement, j'ai un code sur lequel je travaillais il y a quelques jours qui est un peu comme Paint, qui vous permet de dessiner essentiellement sur l'écran en utilisant la souris. J'ai en quelque sorte découvert cette propriété par accident, et j'ai réalisé qu'elle est vraiment inefficace et je me demande s'il existe un moyen plus pratique de le faire. Il n'y a pas vraiment de raison de donner tout mon code, mais voici les parties importantes

private static void createAndShowGui() {
    SimpleDraw mainPanel = new SimpleDraw();
    MenuBar.createMenuBar();
    JLabel label = new JLabel();
    label.setText("Drawing prototype 0.0.1");
     // label.setHorizontalTextPosition(JLabel.NORTH);
    label.setFont(new Font("Serif", Font.BOLD, 20));
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.getContentPane().add(mainPanel);
    frame.pack();
    frame.setLocationByPlatform(true);
    frame.getContentPane().setLayout(new BoxLayout(frame.getContentPane(),BoxLayout.PAGE_AXIS));
    frame.setVisible(true);
    frame.setJMenuBar(MenuBar.getMenuBar());
    frame.setBackground(Color.WHITE);
    frame.add(label);

Le bloc de code ci-dessus configure le jframe (le fenêtre)

 @Override
    public void mouseDragged(MouseEvent e)
    {
    // These console outputs are just so that I know what is happening
        System.out.println("Event: MOUSE_DRAG");
        System.out.println(e.getX());
        System.out.println(e.getY());
        System.out.println(e.getComponent());
        System.out.println(e.getWhen());
        System.out.println(e.getButton());
         MOUSE_X = e.getX() - 5;  //-5 so that the cursor represents the center of the square, not the top left corner.
         MOUSE_Y = e.getY() - 5;  //^
         rect = new Rectangle(MOUSE_X, MOUSE_Y, 10, 10 ); //This doesn't ever come into action.
         repaint();  

     }

Le code ci-dessus définit à peu près simplement les variables MOUSE_X et MOUSE_Y et la méthode repaint ();

@Override
    protected void paintComponent(Graphics g) {

    Graphics2D g2 = (Graphics2D) g;
    if (rect != null) {

        if (!colorChoice.equals("Default"))
        {
            g2.setColor(Color.BLACK);
        }

        switch(colorChoice) {

        case "GRAY":
            g2.setColor(Color.GRAY);
            break;
        case "CYAN":
            g2.setColor(Color.CYAN);
            break;
        case "BLUE":
            g2.setColor(Color.BLUE);
            break;
        case "RED":
            g2.setColor(Color.RED);
            break;
        case "PINK":
            g2.setColor(Color.PINK);
            break;
        case "YELLOW":
            g2.setColor(Color.YELLOW);
            break;
        case "GREEN":
            g2.setColor(Color.GREEN);
            break;
        case "PURPLE":
            g2.setColor(Color.MAGENTA);
            break;
        case "RESET":
            g2.setColor(Color.WHITE);
        case "WHITE":
            g2.setColor(Color.WHITE);

        }





        g2.fillRect(MOUSE_X, MOUSE_Y, 15, 15); 

        if (colorChoice.equals("RESET")) 
        resetColorOnCursor(); 

        }
    }

    public static void clearBoard()
    {
    tempColor = colorChoice;
    setColorChoice("RESET");
    frame.repaint();




    }


    public static void resetColorOnCursor()
    {
    setColorChoice(tempColor);
    }

C'est la chose que je suis tombé accidentellement. Ce que j'essayais de faire quand j'ai découvert cela était essentiellement de faire en sorte qu'un carré suive votre curseur chaque fois que vous déplacez votre souris. Mais j'ai oublié de taper la partie de code paintComponent(g);, ce qui transforme ce programme en la chose que je voulais à l'origine. Les parties inférieures de cela sont essentiellement la façon dont je voudrais effacer le tableau. Je suis 100% sûr que ce n'est pas la bonne façon d'effacer/réinitialiser un cadre comme celui-ci, mais je ne pouvais pas trouver un autre moyen. Si quelqu'un a des conseils ou de meilleures méthodes à utiliser pour ce faire correctement, je serais très reconnaissante. Merci! : D

Author: Peter_Browning, 2015-10-07

1 answers

Votre approche actuelle est fondamentalement de casser les exigences de la chaîne de peinture, en n'appelant pas super.paintComponent. La méthode paintComponent effectue un ensemble d'opérations, que vous ne prenez pas en charge et qui pourraient entraîner des artefacts de peinture très étranges qui sont difficiles à répliquer de manière cohérente.

Graphics est une ressource partagée, donc le contexte Graphics qui a été utilisé pour peindre un autre contrôle sera le même qui est utilisé pour peindre votre composant, sauf si vous "nettoyez" le contexte avant main, ce qui a été précédemment peint dans le contexte restera (c'est pourquoi vous codez actuellement "semble" fonctionner).

Au Lieu de cela, vous devez utiliser un MouseListener pour définir un point d'ancrage, qui représente le point où la souris a été pressé et ensuite utiliser le MouseMotionListener pour définir l'étendue de la zone de sélection, par exemple...

Choix De Peintures

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

    }

}

Juste pour mettre en évidence le problème auquel vous serez confronté si vous continuez à violer les exigences de la méthode paintComponent, voici ce que arrive quand je n'appelle pas super.paintComponent

Bafoués

J'ai simplement ajouté deux JButton au JFrame (donc pas même directement au panneau). paintComponent fait une série de travaux importants, que vous avez négligé d'effectuer, ce qui va causer plus de problèmes et de problèmes.

Exemple de ligne de formulaire libre...

Une ligne de forme libre est en fait une illusion, c'est une série de (petites) lignes tracées entre une série de points, la raison en est que le MouseListener ne rapportera pas tous position de la souris il se déplace à travers, en fonction de la vitesse de la souris est déplacée, vous pourriez obtenir beaucoup de rappels ou quelques-uns.

Donc, au lieu de dessiner pour simplement dessiner les points, nous stockons les points dans un List et dessinons des lignes entre eux, par exemple...

Libre

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

    }

}
 7
Author: MadProgrammer, 2015-10-07 01:06:22