2017-01-16 3 views
-1

Je veux essentiellement faire une application à fenêtre unique où l'utilisateur sera capable de dessiner des lignes de segments. Le débit d'application doit être:Chaîne d'événements sur Java Swing

  1. l'utilisateur clique sur le bouton unique de l'application afin de démarrer le processus
  2. L'utilisateur sélectionne en cliquant sur le premier point du segment
  3. L'utilisateur sélectionne en cliquant sur le deuxième point du segment

I ont déjà le morceau de code suivant:

public class LineEditor extends JComponent{ 

     private class Point{ 
      int x, y; 

      public Point(int x, int y){ 
       this.x = x; 
       this.y = y; 
      } 
     } 
     private class Line{ 
      Point a, b; 

      public Line(Point a, Point b){ 
       this.a = a; 
       this.b = b; 
      } 
     } 

     private ArrayList<Line> lines = new ArrayList<Line>(); 

     public void setLine(Point a, Point b){ 
      lines.add(new Line(a, b)); 
      repaint(); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      for (Line line : lines) { 
       g.setColor(line.color); 
       g.drawLine(line.a.x, line.a.y, line.b.x, line.b.y); 
      } 
     } 

     public static void main(String[] args){ 
      int height = 500, width = 500; 

      JFrame frame = new JFrame(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      // Properties of the main window 
      frame.setAlwaysOnTop(true); 
      final LineEditor lineEditor = new LineEditor(); 
      lineEditor.setPreferredSize(new Dimension(width, height)); 

      JPanel panelCanvas = new JPanel(); 
      panelCanvas.setPreferredSize(new Dimension(width, height)); 


      JPanel secondaryPanel = new JPanel(); 
      JButton addLineButton = new JButton("Add new line"); 
      secondaryPanel.add(addLineButton); 


      frame.getContentPane().add(lineEditor, BorderLayout.CENTER); 
      frame.getContentPane().add(panelCanvas, BorderLayout.CENTER); 
      frame.getContentPane().add(secondaryPanel, BorderLayout.NORTH); 

      panelCanvas.addMouseListener(new MouseAdapter() { 
       @Override 
       public void mousePressed(MouseEvent e) { 
        int x = e.getX(); 
        int y = e.getY(); 
       } 
      }); 

      addLineButton.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        // x 
       } 
      }); 

      frame.pack(); 
      frame.setVisible(true); 

     } 
    } 

Je ne comprends pas comment:

  1. Activez le panneauCanvas.addMouseListener uniquement après que l'utilisateur a appuyé sur le bouton.
  2. obtenir les coordonnées de la souris (après le clic a été) de la addLineButton.addActionListener pour que je puisse créer deux objets Point et après qui font un appel à lineEditor.setLine (Pointa, pointB)

Je veux réaliser quelque chose comme:

addLineButton.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(ActionEvent e) { 

     // Wait for the first user click 
     int x1 = mouseListener.getX(); 
     int y1 = mouseListener.getY(); 
     Point a = new Point(x1, y1); 

     // Wait for the second user click 
     int x2 = mouseListener.getX(); 
     int y2 = mouseListener.getY(); 
     Point b = new Point(x2, y2); 

     lineEditor.setLine(a, b); 
    } 
}); 
+0

Ce que vous pourriez avoir besoin est une sorte de modèle que le '' MouseListener' de panelCanvas' peut mettre à jour et à partir de laquelle '' ActionListener' de la addLineButton' peut lire. Personnellement, je pense que vous pourriez l'avoir en arrière, ce qui devrait arriver est l'utilisation devrait sélectionner "ligne de dessin", puis cliquez sur la toile les points qu'ils veulent dessiner entre. Encore une fois, une grande partie de ce serait contrôlé par une sorte de modèle – MadProgrammer

+0

Un exemple est cité [ici] (http://stackoverflow.com/a/11944233/230513). – trashgod

+0

@trashgod cet exemple n'était pas lié à ce que je cherchais mais reste un échantillon intéressant à avoir en tête. – Erwol

Répondre

0

J'ai finalement résolu le problème en forçant l'utilisateur à suivre le flux suivant lors de l'élaboration d'une nouvelle ligne:

  1. lorsque la Les premiers utilisateurs essayent de cliquer sur le premier point de la ligne, une boîte JColor est ouverte pour que la couleur de la ligne puisse être facilement sélectionnée.
  2. Ensuite, l'utilisateur doit cliquer sur le premier point où il veut définir le premier point de la ligne.
  3. Le deuxième point de la ligne sera situé dans les coordonnées où l'utilisateur relâche le bouton de clic.

Notez que c'est juste une approche de ce que je cherchais (d'abord cliquer sur & release = premier point, deuxième clic & release = second point), mais je pense que ce pourrait être un bon exemple pour les débutants swing.

public class LineEditor extends JComponent{ 

    private static class Point{ 
     final int x, y; 

     public Point(int x, int y){ 
      this.x = x; 
      this.y = y; 
     } 
    } 
    private static class Line{ 
     final Point a, b; 
     final Color color; 

     public Line(Point a, Point b, Color color) { 
      this.a = a; 
      this.b = b; 
      this.color = color; 
     }    
    } 

    private final LinkedList<Line> lines = new LinkedList<Line>(); 

    public void addLine(int xa, int ya, int xb, int yb, Color color) { 
     lines.add(new Line(new Point(xa, ya), new Point(xb, yb), color));   
     repaint(); 
    } 

    public void clearScreen() { 
     if(lines.size() > 0){ 
      lines.remove(lines.getLast()); 
      repaint(); 
     } 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); 
     for (Line line : lines) { 
      g.setColor(line.color); 
      g.drawLine(line.a.x, line.a.y, line.b.x, line.b.y); 
     } 
    } 

    public static void main(String[] args) { 
     int width, height; 
     width = 500; 
     height = 500; 

     JFrame backgroundFrame = new JFrame(); 
     backgroundFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     final LineEditor lineEditor = new LineEditor(); 
     lineEditor.setPreferredSize(new Dimension(width, height)); 
     backgroundFrame.getContentPane().add(lineEditor, BorderLayout.CENTER); 

     JPanel buttonsPanel = new JPanel(); 
      JButton clearScreen = new JButton("Remove last line"); 
      buttonsPanel.add(clearScreen); 
      backgroundFrame.getContentPane().add(buttonsPanel, BorderLayout.SOUTH); 

     backgroundFrame.addMouseListener(new MouseAdapter() { 
      int ax, ay, bx, by; 
      Color color; 
      Boolean colorSetted = false; 
      @Override 
      public void mouseEntered(MouseEvent e) { 
       if(!colorSetted){ 
        JColorChooser colorChooser =new JColorChooser(); 
        this.color = colorChooser.showDialog(null, "Select a color", Color.BLACK); 
        colorSetted = true; 
       } 
      } 
      @Override 
      public void mousePressed(MouseEvent e) { 
       ax = e.getX(); 
       ay = e.getY(); 
       System.out.println("Mouse pressed: " + ax + ", " + ay); 


      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
       bx = e.getX(); 
       by = e.getY(); 
       System.out.println("Mouse released: " + bx + ", " + by); 
       lineEditor.addLine(ax, ay, bx, by, color); 
       colorSetted = false; 
      } 
     }); 

     clearScreen.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       lineEditor.clearScreen(); 
      } 
     }); 

     backgroundFrame.pack(); 
     backgroundFrame.setVisible(true); 
    } 
}