2013-02-04 19 views
1

我正在使用繪圖組件和圖形2D在JPanel上繪製線條,但JPanel的背景設置爲用戶輸入某些尺寸時繪製的網格。如何在單擊按鈕時清除JPanel上繪製的線條,但是使用繪製的網格線再次重新生成新面板?使用清除按鈕的動作事件方法,我嘗試使用repaint(),removeAll()並創建一個新的JPanel實例,但似乎沒有任何工作。如何清除我的Jpanel,但保持網格線?

這裏與主面板和按鈕功能的類代碼:

package floorplan; 

/** 
* 
* @author xodkx 
*/ 


import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.GridLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.BorderFactory; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JRadioButton; 
import javax.swing.SwingUtilities; 


public class FloorPlan extends JFrame 
{ 

private JPanel backPanel = new JPanel(); 
private JPanel toolsPanel = new JPanel(); 
private JFrame chooseFurniture; 
private JFrame chooseFixture; 
private JFrame chooseFramework; 
private JButton furnitureButton = new JButton(); 
private JButton fixturesButton = new JButton(); 
private JButton frameworkButton = new JButton(); 
private JButton deleteButton = new JButton(); 
private JButton saveButton = new JButton(); 
private JButton clearButton = new JButton(); 
private JButton closeButton = new JButton(); 
private JRadioButton wall = new JRadioButton("Wall"); 
private JRadioButton door = new JRadioButton("Door"); 
private JRadioButton window = new JRadioButton("Window"); 


Floor floor = new Floor(); 

public FloorPlan() 
{ 
    super("Floor Plan Generator"); 
    createWindow(); 
    buttonFunctions(); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    pack(); 
    setVisible(true); 
} 

private void createWindow() 
{ 
    backPanel.setLayout(new BorderLayout()); 
    backPanel.setBorder(BorderFactory.createEmptyBorder(200, 200, 200, 200)); 
    GridLayout panelLayout = new GridLayout(); 
    frameworkButton.setText("Framework"); 
    fixturesButton.setText("Fixtures"); 
    furnitureButton.setText("Furniture"); 
    deleteButton.setText("Delete"); 
    saveButton.setText("Save"); 
    clearButton.setText("Clear"); 

    add(backPanel, BorderLayout.CENTER); 
    backPanel.add(toolsPanel, BorderLayout.NORTH); 
    backPanel.add(floor, BorderLayout.CENTER); 
    backPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20)); 
    toolsPanel.add(frameworkButton); 
    toolsPanel.add(fixturesButton); 
    toolsPanel.add(furnitureButton); 
    toolsPanel.add(deleteButton); 
    toolsPanel.add(saveButton); 
    toolsPanel.add(clearButton); 
    add(backPanel); 
} 


private void buttonFunctions() 
{ 
    frameworkButton.addActionListener(new ActionListener() 
    { 
     @Override 
     public void actionPerformed(final ActionEvent e) 
     { 
      chooseFramework = new JFrame("Pick A Framework"); 
      chooseFramework.setSize(250,250); 
      chooseFramework.setLayout(new GridLayout(4,1)); 
      chooseFramework.add(wall); 
      chooseFramework.add(door); 
      chooseFramework.add(window); 
      chooseFramework.add(closeButton); 
      closeButton.setText("Close"); 


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

       floor.setFramework(Framework.WALL); 



     }}); 

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

       floor.setColor(Color.RED); 
       floor.setFramework(Framework.DOOR); 


     }}); 

      window.addActionListener(new ActionListener() 
      { 
       @Override 
       public void actionPerformed(ActionEvent e) 
      { 
       floor.setColor(Color.BLUE); 
       floor.setFramework(Framework.WALL); 


     }}); 

      closeButton.addActionListener(new ActionListener() 
      { 
       @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       chooseFramework.setVisible(false); 

      } 
      }); 

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      pack(); 
      chooseFramework.setVisible(true); 
     } 
    }); 

    furnitureButton.addActionListener(new ActionListener() 
    { 
     @Override 
     public void actionPerformed(final ActionEvent e) 
     { 
      chooseFurniture = new JFrame("Pick Furniture to add"); 
      chooseFurniture.setSize(250,250); 
      chooseFurniture.setLayout(new GridLayout(4,1)); 
      chooseFurniture.add(closeButton); 
      closeButton.setText("Close"); 

      closeButton.addActionListener(new ActionListener() 
      { 
       @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       chooseFurniture.setVisible(false); 
      } 
      }); 

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      pack(); 
      chooseFurniture.setVisible(true); 
     } 
    }); 

    fixturesButton.addActionListener(new ActionListener() 
    { 
     @Override 
     public void actionPerformed(final ActionEvent e) 
     { 
      chooseFixture = new JFrame("Pick Furniture to add"); 
      chooseFixture.setSize(250,250); 
      chooseFixture.setLayout(new GridLayout(4,1)); 
      chooseFixture.add(closeButton); 
      closeButton.setText("Close"); 

      closeButton.addActionListener(new ActionListener() 
      { 
       @Override 
      public void actionPerformed(ActionEvent e) 
      { 
       chooseFixture.setVisible(false); 
      } 
      }); 

      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      pack(); 
      chooseFixture.setVisible(true); 
     } 
    }); 

     **clearButton.addActionListener(new ActionListener() 
    { 
     @Override 
     public void actionPerformed(final ActionEvent e) 
     { 
      **//THIS IS WHERE I WANT TO CLEAR THE JPANEL WHEN THIS BUTTON IS CLICKED** 
     } 
    });** 
}  
public static void main(String[] args) 
{ 
    SwingUtilities.invokeLater(new Runnable() 
    { 

     @Override 
      public void run() 
      { 
      FloorPlan floorPlan = new FloorPlan(); 
      } 

    }); 
} 
} 

這裏是做所有的圖形的東西,吸引到的JPanel

package floorplan; 

/** 
* 
* @author xodkx 
*/ 

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

public class Floor extends JPanel implements MouseListener, MouseMotionListener 
{ 


private static final int WIDTH = Integer.parseInt(JOptionPane.showInputDialog("Please  
                enter the width of your room")); 
private static final int LENGTH = Integer.parseInt(JOptionPane.showInputDialog("Please 
               enter the width of your room")); 
private static final Color BACKGROUND = Color.WHITE; 
private static final Color INITIAL_COLOUR = Color.BLACK; 
private static final Framework INITIAL_FRAMEWORK = Framework.WALL; 

private MouseState state = MouseState.IDLE; 
private Framework frameworkType = INITIAL_FRAMEWORK; 
private Color colour = INITIAL_COLOUR; 


private Point start = null; 
private Point end = null; 
private Point startpt = null; 
private Point endpt = null; 

private BufferedImage bufImage = null; 


public Floor() 
{ 
    setPreferredSize(new Dimension(LENGTH,WIDTH)); 
    setBackground(Color.white); 
    setBorder(BorderFactory.createLineBorder (Color.black, 5)); 

    this.addMouseListener(this); 
    this.addMouseMotionListener(this); 

} 

public void setColor(Color color) 
{ 
    colour = color; 

} 

public void setFramework(Framework framework) 
{ 
    frameworkType = framework; 
} 

@Override 
public void paintComponent(Graphics g) 
{ 
    super.paintComponent(g); 
    Graphics2D g2 = (Graphics2D)g; 
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, 
     RenderingHints.VALUE_ANTIALIAS_ON); 

    if(bufImage == null) 
    { 
     int h = this.getHeight(); 
     int w = this.getWidth(); 
     bufImage = (BufferedImage)this.createImage(h,w); 
     Graphics2D gc = bufImage.createGraphics(); 
     gc.setColor(BACKGROUND); 
     gc.fillRect(0, 0, w, h); 
    } 


    g2.drawImage(bufImage,null,0,0); 

    drawGrid(g2); 

    if(state == MouseState.DRAGGING) 
    { 
     createComponent(g2); 
    } 
} 

public void drawGrid(Graphics g2) 
{ 
    int gridDivisions = 20; 
    int divisionSize = WIDTH/gridDivisions; 
    int grid = WIDTH*LENGTH; 

    g2.setColor(Color.lightGray); 

    for(int i=1; i<grid; i++) 
    { 
     int x = i * divisionSize; 
     g2.drawLine(x,0,x,getSize().height); 
    } 

    for(int i=1; i<grid; i++) 
    { 
     int y = i*divisionSize; 
     g2.drawLine(0,y,getSize().width,y); 
    } 
} 


public void createComponent(Graphics2D g2) 
{ 
    g2.setColor(colour); 

    switch (frameworkType) 
    { 
     case WALL: 
      g2.setStroke(new BasicStroke(5)); 
      g2.drawLine(start.x, start.y, end.x,end.y); 
      break; 

     case DOOR: 
      g2.setStroke(new BasicStroke(5)); 
      g2.drawLine(start.x, start.y, end.x,end.y); 
      break; 

     case WINDOW: 
      g2.setStroke(new BasicStroke(5)); 
      g2.drawLine(start.x, start.y, end.x,end.y); 
      break; 


     default: 
      g2.drawString("test", 10, 20); 
      break; 
    } 
} 


@Override 
public void mousePressed(MouseEvent e) 
{ 
    state = MouseState.DRAGGING; 
    start = e.getPoint(); 
    end = start; 
} 

@Override 

public void mouseDragged(MouseEvent e) 
{ 

    state = MouseState.DRAGGING; 
    end = e.getPoint(); 
    this.repaint(); 

} 

@Override 
public void mouseReleased(MouseEvent e) 
{ 
    end = e.getPoint(); 
    if(state == MouseState.DRAGGING) 
    { 
     state = MouseState.IDLE; 
     createComponent(bufImage.createGraphics()); 
     this.repaint(); 
    } 
} 



@Override 
public void mouseClicked(MouseEvent e) 
{ 

} 

@Override 
public void mouseEntered(MouseEvent e) 
{ 

} 

@Override 
public void mouseExited(MouseEvent e) 
{ 

} 



@Override 
public void mouseMoved(MouseEvent e) 
{ 

} 

} 

回答

1

它是類不清楚你想如何納入顯示網格的邏輯。這裏是一個例子,如何切換它只是爲了給你的想法。在Floor類中添加控制網格是否顯示的boolean標誌。然後在Floor.paintComponent()根據這個boolean標誌的值繪製網格。更改標誌的值應該會觸發重繪。然後,改變這個標誌的值從FloorPlan類,以響應一個動作或其他程序邏輯。下面是一個簡單的實現,切換網格時clear按鈕被點擊:

地板類:

private boolean displayGrid = true; 

public boolean isDisplayGrid() { 
    return displayGrid; 
} 
public void setDisplayGrid(boolean displayGrid) { 
    this.displayGrid = displayGrid; 
    repaint(); 
} 

@Override 
public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    ... 
    if (displayGrid) 
     drawGrid(g2); 
} 

平面圖類:

clearButton.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(final ActionEvent e) { 
     floor.setDisplayGrid(!floor.isDisplayGrid()); 
    } 
}); 

編輯:

似乎我完全誤解了你的問題。如果我理解正確,只需點擊一下按鈕即可清除圖形。看起來所有的圖紙都是在Floor類的bufImage上完成的。只需重置這個圖像,即:

地板類:

public void clear() { 
    bufImage.flush(); 
    bufImage = null; 
    repaint(); 
} 

平面圖類:

clearButton.addActionListener(new ActionListener() { 
    @Override 
    public void actionPerformed(final ActionEvent e) { 
     floor.clear(); 
    } 
}); 
+0

太謝謝你了! – odk

+0

@odk不客氣! :) – tenorsax