2015-10-07 1 views
0

Donc, fondamentalement, j'ai du 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 hasard, et je me suis rendu compte que c'était vraiment inefficace et je me demande s'il y a un moyen plus pratique de le faire. Il n'y a pas vraiment de raison de donner tout mon code, mais voici les parties importantesUne façon plus facile de faire une application de peinture en Java?

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 définit la JFrame (la 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 assez il suffit de définir les variables MOUSE_X et MOUSE_Y et repaint(); méthode

@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 j'ai rencontrée accidentellement. Ce que j'essayais de faire quand je l'ai trouvé était de faire un carré suivre votre curseur chaque fois que vous avez déplacé votre souris. Mais j'ai oublié de taper la partie code paintComponent(g);, ce qui fait de ce programme la chose que j'avais initialement prévue. Les parties inférieures de ce sont essentiellement comment je voudrais effacer le tableau. Je suis sûr à 100% 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 le faire correctement, je serais très reconnaissant. Merci! : D

+0

Nope, vous devriez appeler 'super.paintComponent' avant de peindre l'état actuel du composant. Sinon, vous pourriez vous retrouver avec toutes sortes de dégâts apparaissant sur votre composant, comme les autres images fantômes de votre composant, par exemple – MadProgrammer

+0

Pour "mettre" la vue en pause, laissez les valeurs qui déterminent comment ou quoi est peint avant d'appeler 'repeindre ' – MadProgrammer

+0

super.paintComponent(); fait un carré mobile. C'est ce que je ne veux pas. Je ne voulais pas rendre l'aspect dessin plus efficace. Appel de super.paintComponent(); Va retourner ce programme dans l'application ennuyeuse "carré mobile" –

Répondre

6

Votre approche actuelle est fondamentalement briser les exigences de la chaîne de peinture, en n'appelant pas super.paintComponent. La méthode paintComponent exécute un ensemble d'opérations que vous ne prenez pas en charge et qui peut générer des artefacts de peinture très étranges, difficiles à répliquer de manière cohérente. Est une ressource partagée, donc le contexte Graphics qui a été utilisé pour peindre un autre contrôle sera le même que celui utilisé pour peindre votre composant, sauf si vous "nettoyez" le contexte avant la main, ce qui a été peint précédemment pour 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, ce qui représente le point où la souris a été pressé puis utilisez la MouseMotionListener pour définir l'étendue de la zone de sélection, par exemple ...

Paint Selection

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 la question que vous ferez face si vous continuez à violer les exigences de la méthode paintComponent, c'est ce qui se passe quand je ne l'appelle pas super.paintComponent

Violated

J'ai simplement ajouté deux JButton « s au JFrame (donc même pas 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 forme libre ...

Une ligne de forme libre est en fait une illusion, il y a une série de (petites) lignes tracées entre une série de points, la raison est parce que le MouseListener ne sera pas signaler chaque position de la souris qu'il déplace, en fonction de la vitesse de déplacement de la souris, vous pourriez avoir beaucoup de rappels ou quelques-uns.

Ainsi, au lieu de tirer juste dessiner des points, nous stockons les points dans un List et tracer des lignes entre elles, par exemple ...

FreeForm

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

Donc évidemment vous êtes plus expérimenté que moi, mais il y a évidemment aussi une erreur de communication ici. Le programme que j'essaye de créer est fondamentalement un logiciel de dessin. EX: Faites glisser la souris et créez une ligne, pas une boîte. –

+0

Ok, donc au lieu de créer un 'Rectangle', créez' Line2D' comme démontré [ici] (http://stackoverflow.com/questions/32979814/how-can-i-set-the-stroke-color-at- runtime-in-java/32981345 # 32981345) (et les ajouter à une sorte de 'Liste' afin que vous puissiez les dessiner quand vous en avez besoin) – MadProgrammer

+0

Ok, je comprends ce que vous dites, mais en utilisant votre méthode, comment serait vous créez des lignes de forme libre? (courbes) –