2014-02-23 61 views
0

我被賦予了一個簡單的使用GUI的繪圖程序,它具有基本的I/O功能。那是我的教授被告知要做的。不過,我以前只做過一個GUI程序,所以直接跳到這個繪圖程序中一直很頭疼。現在我差不多完成了,但程序並沒有像我預期的那樣行事。在面板上繪製新對象時,它們會在其下方的對象上繪製不可見的白色矩形,從而擦除這些對象。我認爲這是repaint(xMin,yMin,xMax - xMin + 1,yMax - yMin + 1)的結果;方法在DrawShapes中,但不能想出一種方法來解決它。我如何獲得這個Paintcomponent按照我的意圖行事?

另一方面,對象也沒有正確保存。我可以按照我的意圖將它導出爲jpg,但是,它只會導出最後一個繪製的圖像,而不是導出到paintComponent畫布上的所有圖像。

最後,DrawShapes中的清除方法的工作方式非常類似。當清除方法被激活時,它將清除除最後繪製的圖像之外的所有內容。

有沒有人比我更熟悉這些工具,可以看到一種方法來解決這些問題?這只是我用過的第一個程序,和I/O。

這裏是形狀都應該上繪製的面板類:

/** 
* @author me 
*/ 
import java.util.*; 
import java.awt.*; 
import java.awt.event.*; 
import java.awt.image.*; 
import java.io.File; 
import javax.imageio.ImageIO; 
import javax.swing.*; 
import javax.swing.event.*; 

public class DrawShapes extends JPanel{ 
    Point startPoint = null; 
    Point endPoint = null; 
    public int drawType = 1; 
    BufferedImage image; 
    Graphics2D g2d; 

public DrawShapes(){ 
    setBackground(Color.WHITE); 

    MyMouseListener m1 = new MyMouseListener(); 
    addMouseListener(m1); 
    addMouseMotionListener(m1); 
}//end constructor 

//sets draw type, which is the decider of what is being drawn. 
public void setType(int type){ 
    if(type == 1) 
    { 
     drawType = 1; 
    } 
    else if(type == 2) 
    { 
     drawType = 2; 
    } 
    else if(type == 3) 
    { 
     drawType = 3; 
    } 
}//end setType 


    public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    if (image == null) 
    { 
     createEmptyImage(); 
    } 

    g.drawImage(image, 0, 0, null); 

    if (startPoint != null && endPoint != null) 
    { 
      int x = Math.min(startPoint.x, endPoint.x); 
      int y = Math.min(startPoint.y, endPoint.y); 
      int width = Math.abs(startPoint.x - endPoint.x); 
      int height = Math.abs(startPoint.y - endPoint.y); 
      switch (drawType) 
       { 
        case 1: 
         g.drawRect(x, y, width, height); 
         break; 
        case 2: 
         g.drawOval(x, y, width, height); 
         break; 
        case 3: 
         g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y); 
         break; 
       } 
    } 
}//end paintComponent 

public void save() 
{ 
    BufferedImage bi = new BufferedImage(this.getSize().width, this.getSize().height, BufferedImage.TYPE_INT_RGB); 
    Graphics g = bi.createGraphics(); 
    this.paint(g); 
    g.dispose(); 
    try{ImageIO.write(bi, "png",new File("test.png")); 
    }catch (Exception e){} 
    } 

private void createEmptyImage() 
{ 
    image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); 
    g2d = (Graphics2D)image.getGraphics(); 
    g2d.setColor(Color.BLACK); 
    g2d.drawString("Add a shape by clicking and dragging.", 40, 15); 
} 

public void addRect(int x, int y, int width, int height, Color color) 
{ 
     g2d.setColor(color); 
     g2d.drawRect(x, y, width, height); 
     repaint(); 
} 

public void addOval(int x, int y, int width, int height, Color color) 
{ 
     g2d.setColor(color); 
     g2d.drawOval(x, y, width, height); 
     repaint(); 
} 

public void addLine(int x1, int y1, int x2, int y2, Color color) 
{ 
     g2d.setColor(color); 
     g2d.drawLine(x1, y1, x2, y2); 
     repaint(); 
} 

public void clear() 
{ 
     createEmptyImage(); 
     repaint(); 
} 

class MyMouseListener extends MouseInputAdapter 
{ 
    private int xMin; 
    private int xMax; 
    private int yMin; 
    private int yMax; 

    public void mousePressed(MouseEvent e) 
    { 
      startPoint = e.getPoint(); 
      endPoint = startPoint; 
      xMin = startPoint.x; 
      xMax = startPoint.x; 
      yMin = startPoint.y; 
      yMax = startPoint.y; 
    } 

    public void mouseDragged(MouseEvent e) 
    { 
     //This is code I found that should make it so the only area affected by the dragging is repainted. 
     endPoint = e.getPoint(); 
     xMin = Math.min(xMin, endPoint.x); 
     xMax = Math.max(xMax, endPoint.x); 
     yMin = Math.min(yMin, endPoint.y); 
     yMax = Math.max(yMax, endPoint.y); 
     repaint(xMin, yMin, xMax - xMin + 1, yMax - yMin + 1); 

    } 

    public void mouseRelease(MouseEvent e) 
    { 
     //This code paints the shapes on the Buffered Image created as a canvas 
     int x = Math.min(startPoint.x, endPoint.x); 
     int y = Math.min(startPoint.y, endPoint.y); 
     int width = Math.abs(startPoint.x - endPoint.x); 
     int height = Math.abs(startPoint.y - endPoint.y); 

     if (width != 0 || height != 0) 
    { 
     g2d.setColor(e.getComponent().getForeground()); 
//  g2d.drawRect(x, y, width, height); 
       switch (drawType) 
       { 
        case 1: 
         addRect(x, y, width, height, e.getComponent().getForeground()); 
         break; 
        case 2: 
         addOval(x, y, width, height, e.getComponent().getForeground()); 
         break; 
        case 3: 
         addLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y, e.getComponent().getForeground()); 
         break; 
       }//end switch statement. 
    } 

    startPoint = null; 
// repaint(); 
    } 
} 

}//end class 

這裏是對UI代碼:

/*@author Me*/ 
import java.awt.*; 
import java.awt.event.*; 
import javax.swing.*; 

public class MyDrawUI extends JFrame 
{ 
    private DrawShapes draw = new DrawShapes(); 
    private JPanel ButtonPanel = new JPanel(); 
    private JFrame window = new JFrame("Draw!"); 
    //constructor 
    MyDrawUI(){ 
     buildUI(); 
    } 

void buildUI() 
{ 
    window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    window.setLayout(new GridLayout(2,2)); 
    window.add(draw); 
    window.add(ButtonPanel, BorderLayout.SOUTH); 
    ButtonPanel.setBackground(Color.LIGHT_GRAY); 
    draw.setBackground(Color.WHITE); 

    //define buttons 
    JButton rectangle = new JButton("Rectangle"); 
    JButton oval = new JButton("Oval"); 
    JButton line = new JButton("Line"); 
    JButton exit = new JButton("Exit"); 
    JButton save = new JButton("Save"); 
    JButton clear = new JButton("Clear"); 

    //add buttons 
    ButtonPanel.add(rectangle, BorderLayout.SOUTH); 
    ButtonPanel.add(oval, BorderLayout.SOUTH); 
    ButtonPanel.add(line, BorderLayout.SOUTH); 
    ButtonPanel.add(clear, BorderLayout.SOUTH); 
    ButtonPanel.add(save, BorderLayout.SOUTH); 
    ButtonPanel.add(exit, BorderLayout.SOUTH); 
    ButtonPanel.setSize(100, 100); 

    save.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 
     draw.save(); 
     } 
    }); 

    clear.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 
     draw.clear(); 
     } 
    }); 

    rectangle.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 
      draw.setType(1); 
     } 
    }); 

    oval.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 
      draw.setType(2); 
     } 
    }); 

    line.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 
      draw.setType(3); 
     } 
    }); 

    exit.addActionListener(new ActionListener(){ 
     public void actionPerformed(ActionEvent e) 
     { 
      System.exit(0); 
     } 
    }); 

    window.setVisible(true); 
    window.setSize(1024, 800); 
} 
} 
+0

*「最後,..」* SO不是一站式'修理我的代碼商店'。這是一個問答網站,理想情況下,每個線程有一個接受答案的問題。那麼..你對此線程的問題是什麼? –

+0

你最好將形狀放入'List'並重新繪製列表... – MadProgrammer

+0

我想問的是,當你試圖繪製多個物體時,paintcomponent如何工作。原來我看着錯誤的地方。儘管如此,感謝MadProgrammer,它現在按預期工作。有時多個問題可以通過一個答案來解決,並糾正錯字。 – user3344561

回答

3

有幾個問題,我可以看,主要的一個事實是,你「認爲」你已經重寫了MouseAdaptor類中的方法,但沒有

mouseRelease不是會導致任何事件觸發它。你之後的方法是mouseReleased

當覆蓋方法時,請使用@Override註釋,如果您認爲重寫的方法不存在於任何父類中,則會導致編譯器錯誤。

@Override 
public void mouseReleased(MouseEvent e) { 

其他一些東西彈出。

  1. MyDrawUI類從JFrame延伸,但你創造的另一個JFrame稱爲window,在你創建你的UI一個實例。在這種情況下,從MyDrawUI類中刪除extends JFrame,因爲它只是增加了混淆...
  2. 保持對Graphics上下文的引用,即使創建了上下文,也不建議在此上下文中使用。在某些系統上,除非您致電dispose,否則可能沒有任何內容會落實到底層實現中。相反,只需在需要時使用image.getGraphics,並在完成之後致電g2d.dispose
相關問題