2015-10-06 59 views
0

我正在嘗試創建一個界面,用戶可以更改線條的顏色以標記背景或圖像的前景。到目前爲止,我已經編寫了這一點:如何在JAVA中設置運行時的筆觸顏色?

private class ImageLine extends JComponent 
{ 

    java.awt.Point p1,p2; 
    BufferedImage show; 
    ArrayList <Shape> shapes = new ArrayList<Shape>(); 
    int flag = 0; 
    Color color = Color.ORANGE; 


    public ImageLine(BufferedImage img) 
    { 
     show = img; 
     setPreferredSize(new Dimension(img.getWidth(), img.getHeight())); 
     this.addMouseListener 
     (
       new MouseAdapter() 
       { 
        @Override 
        public void mousePressed(MouseEvent e) 
        { 
         p1 = e.getPoint(); 

        } 

        @Override 
        public void mouseReleased(MouseEvent e) 
        { 
         p2 = e.getPoint(); 
         Shape r = createLine(p1.x,p1.y,e.getX(),e.getY()); 

         shapes.add(r); 
         repaint(); 


        } 

        @Override 
        public void mouseDragged(MouseEvent e) 
        { 

         mouseReleased(e); 
         repaint(); 

        } 


       } 


     ); 

     this.addKeyListener(

       new KeyAdapter() 
         { 


          @Override 
          public void keyPressed(KeyEvent e) 
          { 

           if(e.getKeyChar() == 'b') 
           { 

            color = Color.GREEN; 
            System.out.println("bck"); 

           } 
           if(e.getKeyChar() == 'f') 
           { 

            color = Color.RED; 
            System.out.println("fgr"); 


           } 


          } 





         } 







     ); 

     this.setFocusable(true); 


    } 


    private Line2D.Float createLine(int x1, int y1, int x2, int y2) 
    { 
      return new Line2D.Float(x1,y1 ,x2, y2); 
    }  

直到這部分一切正常,我的真正的問題是,當我嘗試覆蓋paintComponent()方法,在這裏其實我不知道如何設置顏色爲KeyListener的表示在這種情況下,如果用戶按下「b」鍵,線的顏色必須改變爲綠色,另一方面,如果用戶按下「f」鍵,線的顏色必須改變爲紅色,如果用戶繪製不同的線,則這些線必須保持顯示。我已經使用此代碼嘗試沒有sucess:

public void paintComponent(Graphics g) { 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 
     g2.setStroke(new BasicStroke(10)); 
     g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.50f)); 

     for (Shape s : shapes) { 
     //g2.setPaint(Color.BLACK); 
     g2.draw(s); 
     g2.setPaint(color); 
     //g2.fill(s); 
     } 

     if (p1 != null && p2 != null) { 
     g2.setPaint(Color.CYAN); 
     Shape r = createLine(p1.x, p1.y, p2.x, p2.y); 
     g2.draw(r); 
     } 
    } 

但結果不是我想要的,我畫的線條和改變顏色,但是當這種情況發生,我改變之前提請線自動it's顏色到所選的顏色,他們不保留它的「原始顏色」。任何消化?提前致謝。

+0

從一個廁所開始k [在AWT和Swing中繪畫](http://www.oracle.com/technetwork/java/painting-140037.html)瞭解繪畫在Swing中的工作原理。繪畫具有破壞性,預計每次調用paintComponent時,都將從頭開始徹底重新繪製組件狀態。您將需要根據您的需要維護每條線的顏色信息。例如,您可以維護對當前選定線的引用並對其進行不同的繪製,或者使用某種「Map」將某條線映射到顏色 – MadProgrammer

+0

Tnanks @MadProgrammer我將閱讀關於繪畫的內容,我嘗試過「保存」線條顏色的信息到一個數組,但實際上它不能正常工作.. –

回答

1

有幾種方法可以實現這一點,我有點像將ShapeColor拼接在一起成爲一個對象的想法,但是這可能會在添加更多形狀時呈現更多工作。

另一種解決方案可能是使用一個Map簡單地映射線的顏色,例如

Lines

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.Point; 
import java.awt.Shape; 
import java.awt.event.ActionEvent; 
import java.awt.event.KeyEvent; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.awt.geom.Line2D; 
import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.Map; 
import javax.swing.AbstractAction; 
import javax.swing.ActionMap; 
import javax.swing.InputMap; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.KeyStroke; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class DrawLines { 

    public static void main(String[] args) { 
     new DrawLines(); 
    } 

    public DrawLines() { 
     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 Line2D currentLine; 
     private Map<Shape, Color> mapColors; 

     private Color currentColor; 

     private List<Shape> shapes; 

     public TestPane() { 

      mapColors = new HashMap<>(25); 
      shapes = new ArrayList<>(25); 

      InputMap inputMap = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW); 
      ActionMap actionMap = getActionMap(); 

      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_F, 0), "foreground"); 
      inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_B, 0), "background"); 

      actionMap.put("foreground", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        currentColor = Color.GREEN; 
        if (currentLine != null) { 
         mapColors.put(currentLine, currentColor); 
         repaint(); 
        } 
       } 
      }); 
      actionMap.put("background", new AbstractAction() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        currentColor = Color.RED; 
        if (currentLine != null) { 
         mapColors.put(currentLine, currentColor); 
         repaint(); 
        } 
       } 
      }); 

      MouseAdapter ma = new MouseAdapter() { 

       private Point p1, p2; 

       @Override 
       public void mousePressed(MouseEvent e) { 
        p1 = e.getPoint(); 
        currentLine = null; 
       } 

       @Override 
       public void mouseReleased(MouseEvent e) { 
        p2 = e.getPoint(); 
        if (currentLine == null) { 
         currentLine = createLine(p1.x, p1.y, e.getX(), e.getY()); 
        } else { 
         currentLine.setLine(p1, p2); 
        } 

        mapColors.put(currentLine, currentColor); 
        shapes.add(currentLine); 
        repaint();     
       } 

       @Override 
       public void mouseDragged(MouseEvent e) { 
        p2 = e.getPoint(); 
        if (currentLine == null) { 
         currentLine = createLine(p1.x, p1.y, e.getX(), e.getY()); 
        } else { 
         currentLine.setLine(p1, p2); 
        } 

        repaint(); 
       } 

       private Line2D.Float createLine(int x1, int y1, int x2, int y2) { 
        return new Line2D.Float(x1, y1, x2, y2); 
       } 
      }; 

      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 (Shape shape : shapes) { 
       Color color = mapColors.get(shape); 
       if (color == null) { 
        color = Color.BLACK; 
       } 
       g2d.setColor(color); 
       g2d.draw(shape); 
      } 

      if (currentLine != null) { 
       Color color = mapColors.get(currentLine); 
       if (color == null) { 
        color = currentColor; 
       } 
       g2d.setColor(color); 
       g2d.draw(currentLine); 
      } 
      g2d.dispose(); 
     } 

    } 

} 

而且,我避免使用KeyListener,並使用鍵綁定API相反,它是較少麻煩

請參閱How to Use Key Bindings瞭解更多詳情

+0

謝謝你真的幫助,我在一個類似的解決方案瘦身,但使用地圖我使用數組,但現在我可以看到地圖的應用程序,每天你都可以學習新事物,我感謝你的幫助。感謝您的回答¡¡ –

+0

很高興它可以幫助;) – MadProgrammer

+0

我會在這裏留下一個視頻,試圖瞭解hashmpas如何工作的任何人:https://www.youtube.com/watch?v = c3RVW3KGIIE –

0

結帳Custom Painting Approaches

你會想要使用DrawOnImage方法。它使用ColoredRectangle類來存儲顏色和矩形的信息。然後在paintComponent()方法中遍歷所有ColoredRectangle類並繪製矩形。

您需要添加邏輯來更改選定矩形的顏色。