2012-12-10 31 views
1

我用Java編寫了一個簡單的繪圖程序,允許用戶在不同的形狀,大小和顏色之間進行選擇(在JMenuBar中)並用鼠標繪製它們。在克服了許多與該程序有關的問題後(​​我最初編寫的代碼是AWT,但確信要切換到Swing,所以請原諒任何可憐的Swing編碼,因爲這是我第一次使用它),我還有一個問題需要解決。只要用戶在屏幕上繪製某些東西(默認情況下是帶有黑色邊框的紅色矩形),JMenuBar就會在原來的JMenuBar下重複。我認爲paintComponent緩衝屏幕的方式有些奇怪,但由於我以前從未使用過,所以我不知道它是如何工作的。繪圖程序重複JMenuBar

任何想法,我可以使它停止重複JMenuBar

import java.awt.*; 
import java.awt.event.*; 
import java.lang.*; 
import javax.swing.*; 

public class E3G04 extends JFrame implements WindowListener, ActionListener, MouseListener, MouseMotionListener 
{ 
    //Variables are declared as volatile to ensure that they're always called from system RAM 
    static volatile String type = "rectangle"; 
    static volatile Boolean fill = true; 
    static Color lineColor = Color.BLACK; 
    static Color fillColor = Color.RED; 
    static int size = 1; 

    CanvasEX cx = new CanvasEX(); 

    static boolean running = true; 

    JMenuBar mb = new JMenuBar(); 
     JMenu fileMenu = new JMenu("File"); 
      JMenuItem newItem = new JMenuItem("New"); 
      JMenuItem quitItem = new JMenuItem ("Quit"); 


    protected E3G04() 
    { 

     mb.add(fileMenu); 
     fileMenu.add(newItem); 
     fileMenu.add(quitItem);    
     newItem.setMnemonic('N'); 
     quitItem.setMnemonic('Q'); 
     newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK)); 
     quitItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.CTRL_MASK));   
     newItem.addActionListener(this); 
     quitItem.addActionListener(this); 
     cx.setSize(800,600); 
     cx.addMouseListener(this); 
     cx.addMouseMotionListener(this); 
     setJMenuBar(mb); 
     setBounds(100,100,800,600); 
     setLayout(new BorderLayout()); 
     add("Center",cx); 
     addWindowListener(this); 
     setResizable(true); 
     setVisible(true); 
    } 

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


    public void stop() 
    { 
     newItem.removeActionListener(this); 
     quitItem.removeActionListener(this);  
     dispose(); 
     System.exit(0); 
    } 

    public void actionPerformed(ActionEvent e) 
    { 
     Object o = e.getSource(); 

     if (o == newItem) 
     { 
      cx.erase = true; 
      cx.repaint(); 
     } 

     if (o == quitItem) 
     { 
      running = false; 
      stop(); 
     } 

    }  

    public void mousePressed(MouseEvent m) 
    { 
     cx.start = m.getPoint(); 
     cx.end = cx.start; 
     cx.cur = cx.start; 
    } 

    public void mouseDragged(MouseEvent m) 
    { 
     cx.cur = m.getPoint(); 
    } 

    public void mouseReleased(MouseEvent m) 
    { 
     cx.end = cx.cur; 
     cx.repaint(); 
    } 
    public void itemStateChanged(ItemEvent e) 
    { 
     Object o = e.getSource(); 

    } 
    public void windowClosing(WindowEvent e) 
    { 
     running = false; 
     stop(); 
    } 
    public void mouseClicked(MouseEvent m){}  
    public void mouseExited(MouseEvent m){} 
    public void mouseEntered(MouseEvent m){}  
    public void mouseMoved(MouseEvent m){} 
    public void windowClosed(WindowEvent e){} 
    public void windowOpened(WindowEvent e){} 
    public void windowActivated(WindowEvent e){} 
    public void windowDeactivated(WindowEvent e){} 
    public void windowIconified(WindowEvent e){} 
    public void windowDeiconified(WindowEvent e){} 
} 


class CanvasEX extends JPanel 
{ 
    Point start = new Point(100,100); 
    Point cur = new Point(100,100); 
    Point end = new Point(100,100); 
    boolean erase = false; 



    public void paintComponent(Graphics g) 
    { 

     Graphics buffer = g; 
     if (erase) 
     { 
      g.dispose(); 
      erase = false; 
     } 
     g.setColor(E3G04.lineColor); 
     if (end.x > start.x && end.y > start.y) 
      g.fillRect(start.x,start.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y)); 
     if (end.x > start.x && end.y < start.y) 
      g.fillRect(start.x,end.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y)); 
     if (end.x < start.x && end.y > start.y) 
      g.fillRect(end.x, start.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y)); 
     if (end.x < start.x && end.y < start.y) 
      g.fillRect(end.x, end.y, Math.abs(end.x-start.x),Math.abs(end.y-start.y)); 
     g.setColor(E3G04.fillColor); 
     if (end.x > start.x && end.y > start.y) 
      g.fillRect(start.x + E3G04.size,start.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size); 
     if (end.x > start.x && end.y < start.y) 
      g.fillRect(start.x + E3G04.size,end.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size); 
     if (end.x < start.x && end.y > start.y) 
      g.fillRect(end.x + E3G04.size, start.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size); 
     if (end.x < start.x && end.y < start.y) 
      g.fillRect(end.x + E3G04.size, end.y + E3G04.size, Math.abs(end.x-start.x) - 2 * E3G04.size,Math.abs(end.y-start.y) - 2 * E3G04.size);   
    } 
} 

回答

4

你不兌現油漆鏈(你應該),在被覆蓋的paintComponent(..)方法調用super.paintComponent(Graphics g)

@Override 
public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 

    //do rest of painting etc 
} 
+0

好吧,那固定的菜單欄在那裏的問題,但現在我的繪畫不是持久的。我如何解決這個問題? –

+0

你需要像'ArrayList'這樣的東西來保存所有的'Rectanlges'來繪製,而在'paintComponent'中,你將遍歷數組列表並重繪每個'Rectangle',因此繪圖將會持久 –

+0

儘管不是所有的矩形, 。沒有一種方法可以創建屏幕圖像(減去JMenubar),然後將該圖像繪製回屏幕上? –