2017-07-29 43 views
0

你好我是新來的,也是Java編程的新手。最近我試圖在JPanel中編寫一個繪圖函數。問題是,當我添加新的drawRect(只需在JRadiobutton中選擇繪製矩形,然後拖動空白區域),它可以正常工作,但是當我按下撤消按鈕時,原點處會出現一個圓點。繪製橢圓形並繪製折線效果很好。誰能幫我嗎? (對不起,我可憐的英語,如果你沒有得到我的問題,我很抱歉,你可以嘗試運行代碼 - >繪製矩形 - >點擊撤消 - >在原點得到了一個點(這就是問題我「M試圖解釋))(drawRect)爲什麼點擊撤消按鈕後始終有一個點在原點?

package com.jetbrains; 

import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 
import java.awt.image.BufferedImage; 

public class Main 
{ 
private BufferedImage buffPNG = new BufferedImage(900,550,BufferedImage.TYPE_INT_ARGB); 

private Main() 
{ 
    draw_Image img = new draw_Image(); 

    JFrame frame = new JFrame("Ken's Paint"); 
    JButton undo_Button = new JButton("Undo"); 
    JRadioButton rb1 = new JRadioButton("Free Hand"); 
    JRadioButton rb2 = new JRadioButton("Draw Rect"); 
    JRadioButton rb3 = new JRadioButton("Draw Oval"); 
    JMenuBar menu_Bar = new JMenuBar(); 

    undo_Button.setContentAreaFilled(false); 
    undo_Button.setFocusPainted(false); 
    ButtonGroup mode_Group = new ButtonGroup(); 
    mode_Group.add(rb1); 
    mode_Group.add(rb2); 
    mode_Group.add(rb3); 
    img.setDraw_Mode(1); 
    rb1.setSelected(true); 

    menu_Bar.add(rb1); 
    menu_Bar.add(rb2); 
    menu_Bar.add(rb3); 
    menu_Bar.add(undo_Button); 
    frameCreate(frame); 
    frame.setJMenuBar(menu_Bar); 
    frame.add(img); 

    rb1.addActionListener(e -> img.setDraw_Mode(1)); 
    rb2.addActionListener(e -> img.setDraw_Mode(2)); 
    rb3.addActionListener(e -> img.setDraw_Mode(3)); 
    undo_Button.addActionListener(e -> img.undo_Pressed()); 
} 

class draw_Image extends JPanel 
{ 
    int layerX = 0; 
    int layerY = 0; 
    int[] polyX = new int[3000]; 
    int[] polyY = new int[3000]; 
    int[] thick = new int[10000]; 
    int[] nPoint = new int[10000]; 
    int[] draw_Mode = new int[10000]; 
    int[][] x = new int[10000][3000]; 
    int[][] y = new int[10000][3000]; 
    Color[] color = new Color[10000]; 
    boolean dragged = false; 

    draw_Image() 
    { 
     setLayout(null); 
     setBounds(0,0,900,550); 
     setBackground(Color.lightGray); 
     for(int p = 0; p < 10000; p++) 
     { 
      draw_Mode[p] = 1; 
      thick[p] = 3; 
      color[p] = Color.black; 
     } 

     addMouseListener(new MouseAdapter() 
     { 
      @Override 
      public void mouseClicked(MouseEvent e) {super.mouseReleased(e);} 

      @Override 
      public void mouseReleased(MouseEvent e) 
      { 
       super.mouseReleased(e); 
       if(dragged) 
       { 
        layerX++; 
        dragged = false; 
       } 
       layerY = 0; 
      } 
     }); 

     addMouseMotionListener(new MouseMotionListener() 
     { 
      @Override 
      public void mouseDragged(MouseEvent e) 
      { 
       dragged = true; 
       for(int k = layerY; k < 3000; k++) 
       { 
        x[layerX][k] = e.getX(); 
        y[layerX][k] = e.getY(); 
       } 
       nPoint[layerX]++; 
       layerY++; 
       repaint(); 
      } 

      @Override 
      public void mouseMoved(MouseEvent e){} 
     }); 
    } 

    @Override 
    public void paint(Graphics g) 
    { 
     super.paint(g); 
     Graphics2D g2 = (Graphics2D)g; 
     Graphics2D g3 = buffPNG.createGraphics(); 
     g2.setColor(Color.white); 
     g2.fillRect(0,0,900,550); 
     g3.setColor(Color.white); 
     g3.fillRect(0,0,900,550); 

     /* Draw the image in polyline form (implemented multidimensional array (2D is used)) */ 
     for(int i = 0; i <= layerX; i++) 
     { 
      for(int j = 0; j < 3000; j++) 
      { 
       polyX[j] = x[i][j]; 
       polyY[j] = y[i][j]; 
      } 

      g2.setColor(color[i]);   /* Set the line color (g2 is for display) */ 
      g3.setColor(color[i]);   /* Set the line color (g3 is for buffered image) */ 
      g2.setStroke(new BasicStroke(thick[i])); /* Set line thickness (g2 is for display) */ 
      g3.setStroke(new BasicStroke(thick[i])); /* Set line thickness (g3 is for buffered image) */ 

      if(draw_Mode[i] == 1) /* free hand */ 
      { 
       g2.drawPolyline(polyX,polyY,nPoint[i]); 
       g3.drawPolyline(polyX,polyY,nPoint[i]); 
      } 

      else if(draw_Mode[i] == 2) /* draw rect */ 
      { 
       g2.drawRect(polyX[0],polyY[0],(polyX[2999] - polyX[0]),(polyY[2999] - polyY[0])); 
       g3.drawRect(polyX[0],polyY[0],(polyX[2999] - polyX[0]),(polyY[2999] - polyY[0])); 
      } 

      else if(draw_Mode[i] == 3) /* draw oval */ 
      { 
       g2.drawOval(polyX[0],polyY[0],(polyX[2999] - polyX[0]),(polyY[2999] - polyY[0])); 
       g3.drawOval(polyX[0],polyY[0],(polyX[2999] - polyX[0]),(polyY[2999] - polyY[0])); 
      } 
     } 
    } 

    void setDraw_Mode(int mode) /* Method to set draw mode */ 
    { 
     for(int q = layerX; q < 10000; q++) 
     { 
      draw_Mode[q] = mode; 
     } 
    } 


    void undo_Pressed() /* Undo an action/Return to previous line drawing */ 
    { 
     if(layerX > 0)layerX--; 
     for(int j = 0; j < 3000; j++) 
     { 
      x[layerX][j] = 0; 
      y[layerX][j] = 0; 
     } 
     nPoint[layerX] = 0; 
     setDraw_Mode(draw_Mode[layerX+1]); 
     repaint(); 
    } 
} 

private void frameCreate(JFrame frame) 
{ 
    frame.pack(); 
    Insets insetValue = frame.getInsets(); 
    int height = insetValue.top + insetValue.bottom + 600 - 10; 
    int width = insetValue.left + insetValue.right + 900 - 10; 
    frame.setSize(width,height);         /* Set the frame size */ 
    frame.setLocation(195,50);          /* Set the frame start up location */ 
    frame.setResizable(false);          /* Disable frame resize & full window option */ 
    frame.setLayout(null);           /* Set the layout to null */ 
    frame.setVisible(true);           /* Set the frame visible */ 
    frame.getContentPane().setBackground(Color.white);    /* Set the frame background color */ 
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); /* Specify the default behavior upon closing */ 
} 

public static void main(String[] args) 
{ 
    new Main(); 
} 
} 
+0

1)爲了更好地提供幫助,請發佈[MCVE]或[簡短,獨立,正確的示例](http://www.sscce.org/)。 2)請參閱[檢測/修復代碼塊的懸掛緊密支架](http://meta.stackexchange.com/q/251795/155831),以解決問題,我不再擔心修復問題。 3)'frame.setLayout(null); 'Java GUI必須在不同的操作系統上工作,屏幕大小,屏幕分辨率等等,在不同的地區使用不同的PLAF。因此,它們不利於像素的完美佈局。而是使用佈局管理器或[它們的組合](http://stackoverflow.com/a/5630271/418556).. –

+0

..以及佈局填充和邊框爲[空格](http://stackoverflow.com /一個/418556分之17874718)。 –

+0

不便之處,敬請原諒。我會嘗試編輯它並感謝您的建議。 –

回答

1

不會解決你的問題,但有些一般提示:

class draw_Image extends JPanel 
  1. 類名應以大寫字母開頭
  2. 請勿在課程名稱中使用「_」。

使用API​​作爲類命名約定的指南。

int[] polyX = new int[3000]; 
int[] polyY = new int[3000]; 
int[] thick = new int[10000]; 
int[] nPoint = new int[10000]; 

不要在整個程序中使用硬編碼數字。至少使用一個變量:

private static int SMALLER_SIZE = 3000; 
private static int LARGER_SIZE = 10000; 
... 
int[] polyX = new int[SMALLER_SIZE]; 
int[] polyY = new int[SMALLER_SIZE]; 
int[] thick = new int[LARGER_SIZE]; 
int[] nPoint = new int[LARGER_SIZE]; 

更好的是,不要使用數組。請使用ArrayList。那麼你不需要爲數組的大小選擇一些隨機大數。

int[] polyX = new int[SMALLER_SIZE]; 
int[] polyY = new int[SMALLER_SIZE]; 

不要保留兩個數組。如果數據是相關的,那麼數據應該存儲在一個對象中。在上述情況下,您可以使用屬於JDK的Point對象。因此,對於使用ArrayList的(而不是陣列)的代碼會是這樣的:

points.add(new Point(...)); 

現在你的循環代碼有沒有硬:

private ArrayList<Point> points = new ArrayList<Point>(); 

然後你使用類似的代碼添加Point對象到ArrayList編碼值:

for (int i = 0; i < points.getSize(); I++ 
{ 
    Point p = points.get(i); 
    // do something with the Point 
} 

一些繪畫技巧:

public void paint(Graphics g) 

請勿重寫paint(...)。風俗畫是通過覆蓋paintComponent(...)

g2.setColor(Color.white); 
    g2.fillRect(0,0,900,550); 
    g3.setColor(Color.white); 
    g3.fillRect(0,0,900,550); 

不要硬編碼的大小來完成。你不知道屏幕尺寸可能是什麼。相反,當您創建的組件,你只是做:

DrawImage panel= new DrawImage(); 
panel.setBackground(Color.WHITE); 

現在,當super.paintComponent方法(...)被調用面板的背景將被塗成白色。

我也不知道爲什麼你使用透明的BufferedImage。只需直接塗在面板上即可。

如果您確實想知道如何在面板上的隨機位置繪製矩形,那麼您可以檢出Custom Painting Approaches。它演示了兩種常用方法。您可能會使用Draw On Component示例,因爲它允許您「撤消」繪製矩形。當然你需要實現這個邏輯,但是通過保留所有的信息,如果ArrayList這很簡單,就是刪除列表中的最後一項。

+0

謝謝我會修改它。感謝您的寶貴意見! –