java - 如何清除 Jpanel 但保留网格线?

标签 java swing drawing jpanel graphics2d

我使用绘画组件和 2D 图形在 JPanel 上绘制线条,但 JPanel 的背景设置为网格,当用户输入某些尺寸时绘制该网格。单击按钮时如何清除 JPanel 上绘制的线条,但使用绘制的网格线再次重新生成新面板?对于清除按钮的操作事件方法,我尝试使用 repaint()、removeAll() 并创建 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)
{

}

}

最佳答案

目前尚不清楚您想要如何合并显示网格的逻辑。这是一个如何切换它的示例,仅供您引用。在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();
    }
});

关于java - 如何清除 Jpanel 但保留网格线?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14691733/

相关文章:

java - 最终数据成员给出不同的值(非静态数据成员)

java - 在其父 Pane 内设置可拖动 Pane 的边界限制

Java:随着 Swing 的变化控制嵌入式面板的宽度

android 二维位图绘制

ios - 启用抗锯齿后,使用不同颜色在 drawRect 中绘制重叠形状会导致边缘出血

java - spark java api 有像 hadoop MultipleOutputs/FSDataOutputStream 这样的类吗?

java - 可以使用 HashMap 来保存列表元素的索引吗?

java - 显示 CardLayout 的上一个选项卡

swing - 如何从 nasa worldwind 中删除世界地图

javascript - 有什么方法可以为Google Map API3绘图库执行overlayBegin事件吗?