删除当前形状的 JFrame。即清除 "canvas",例如在 Microsoft Paint 中

Ridding a JFrame of the current shape. i.e Clearing the "canvas" such as in Microsoft Paint

要解决此特定问题,就必须能够摆脱 JFrame 中的当前形状。我刚刚在 Java 上读完了 Joyce Farrel 的书,所以我决定挑战自己来创建这个迷你应用程序,但我一直坚持让这个形状消失。我撕掉了与问题无关的其余代码,以使问题更容易回答。我仍然将整个项目添加到最后,以供那些可能想要更深入地了解一下,或者可能有助于找到解决方案的人使用。

澄清一下,我认为第一个粘贴的代码段是问题所在。第二个粘贴片段是到目前为止我已经放在一起的所有内容。如果问题很清楚,如果它确实是一个非常简单的解决方案,我希望不要通过告诉我答案来破坏我的学习经验。我将继续寻找简单的解决方案,希望在我自己的研究中保留更多信息。只需给我一个研究领域 java。希望这对您有所帮助!!!

当应用程序处于 运行 时,用户选择 JMenuItem "New Canvas" 并且应用程序突然冻结?它不会崩溃,但会冻结整个 JFrame,迫使用户关闭 JFrame 并重新开始应用程序。理想情况下,当用户选择 "New Canvas" 选项时,JFrame 中心的形状会消失,但不幸的是,所有形状都会在应用程序冻结时一直存在。我假设的是,一旦我摆脱了形状,它就会立即恢复,因为 paintComponent() 方法并导致应用程序冻结。

尝试过---- 1.) 我调用了 repaint() 方法和 validate() 方法作为按下 JMenuItem 时要执行的操作

2.) 我尝试在 paintComponent() 方法中注释掉对 super 的调用并确实收到了相当整洁的结果,但是它没有解决问题

3.) 我尝试从 class 开始实例化一个 Graphics 对象,然后创建一个接受 Graphics 对象并将其转换为 Graphics2D 的方法,这然后将在 JFrameError from this attempt

的中心绘制一个简单的正方形
 Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
        at JHouse.draw(JHouse.java:73)
        at JHouse.actionPerformed(JHouse.java:123)
        at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)
        at javax.swing.AbstractButton$Handler.actionPerformed(AbstractButton.java:2348)
        at javax.swing.DefaultButtonModel.fireActionPerformed(DefaultButtonModel.java:402)
        at javax.swing.DefaultButtonModel.setPressed(DefaultButtonModel.java:259)
        at javax.swing.AbstractButton.doClick(AbstractButton.java:376)
        at javax.swing.plaf.basic.BasicMenuItemUI.doClick(BasicMenuItemUI.java:833)
        at javax.swing.plaf.basic.BasicMenuItemUI$Handler.mouseReleased(BasicMenuItemUI.java:877)
        at java.awt.Component.processMouseEvent(Component.java:6533)
        at javax.swing.JComponent.processMouseEvent(JComponent.java:3324)
        at java.awt.Component.processEvent(Component.java:6298)
        at java.awt.Container.processEvent(Container.java:2236)
        at java.awt.Component.dispatchEventImpl(Component.java:4889)
        at java.awt.Container.dispatchEventImpl(Container.java:2294)
        at java.awt.Component.dispatchEvent(Component.java:4711)
        at java.awt.LightweightDispatcher.retargetMouseEvent(Container.java:4888)
        at java.awt.LightweightDispatcher.processMouseEvent(Container.java:4525)
        at java.awt.LightweightDispatcher.dispatchEvent(Container.java:4466)
        at java.awt.Container.dispatchEventImpl(Container.java:2280)
        at java.awt.Window.dispatchEventImpl(Window.java:2746)
        at java.awt.Component.dispatchEvent(Component.java:4711)
        at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:758)
        at java.awt.EventQueue.access0(EventQueue.java:97)
        at java.awt.EventQueue.run(EventQueue.java:709)
        at java.awt.EventQueue.run(EventQueue.java:703)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:90)
        at java.awt.EventQueue.run(EventQueue.java:731)
        at java.awt.EventQueue.run(EventQueue.java:729)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:80)
        at java.awt.EventQueue.dispatchEvent(EventQueue.java:728)
        at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:201)
        at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:116)
        at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:105)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
        at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93)
        at java.awt.EventDispatchThread.run(EventDispatchThread.java:82)

这是包含形状未正确消失的主要问题的缩短代码:

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

public class JHouse extends JPanel implements MouseListener, MouseMotionListener, ActionListener {

   private boolean isPressed;
   // Menus/Panel

   private static JFrame frame;
   private static JMenuBar mainBar = new JMenuBar();
   private static JMenu create = new JMenu("Create");
   private static JMenuItem canvas = new JMenuItem("New Canvas");

   // Locations/Sizes (Tools)
   private static int JSize = 700;
   private int rectXLoc = 200;
   private int rectYLoc = 200;
   private int rectXSize = 300;
   private int rectYSize = 300;

   public static void createJFrame() {

      frame = new JFrame();
      frame.add(new JHouse());
      frame.setLocation(650, 225);
      frame.setSize(JSize, JSize);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setJMenuBar(mainBar);
      mainBar.add(create);
      create.add(canvas);
      frame.add(new JHouse(), "Center");
   }

   public JHouse() {

     canvas.addActionListener(this);
     addMouseListener(this);
     addMouseMotionListener(this);
   }

   public void paintComponent(Graphics g) {

      super.paintComponent(g);
      BasicStroke aStroke = new BasicStroke(1.0f,
         BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
      Graphics2D gr2D = (Graphics2D)g;
      gr2D.setStroke(aStroke);
      gr2D.drawRect(rectXLoc, rectYLoc, rectXSize, rectYSize);
   }

   public void mouseClicked(MouseEvent e) {

   }

   public void mousePressed(MouseEvent e) {

      isPressed = true;
   }

   public void mouseDragged(MouseEvent e) {

      int x = e.getX();
      int y = e.getY();

      if(isPressed){
         rectXLoc = x;
         rectYLoc = y;
         repaint();
         validate();     
      }
   }

   public void mouseReleased(MouseEvent e) {

      isPressed = false;
   }

   public void mouseEntered(MouseEvent e) {
   }

   public void mouseExited(MouseEvent e) {
   }

   public void mouseMoved(MouseEvent e) {
   }

   public void actionPerformed(ActionEvent e) {

      Object source = e.getSource();

      if(source == canvas) {
         frame.removeAll();
         frame.repaint();
         frame.validate();
      }
   }

   public static void main(String [] args) {

      createJFrame();
   }
}

下面是我目前正在做的项目的完整代码:

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

public class JHouse extends JPanel implements MouseListener, MouseMotionListener, ActionListener {

   //Graphics g;  This was part of attempt # 3 (Failed attempt)

   private boolean isPressed;

   // Menus/Panel
   private static JFrame frame;
   private static JMenuBar mainBar = new JMenuBar();
   private static JMenu create = new JMenu("Create");
   private static JMenu presets = new JMenu("Presets");
   private static JMenu transform = new JMenu("Transform");
   private static JMenu tools = new JMenu("Tools");
   private static JMenuItem canvas = new JMenuItem("New Canvas");
   private static JMenuItem freeDraw = new JMenuItem("Free Draw");
   private static JMenuItem rectangle = new JMenuItem("Rect Tool");
   private static JMenuItem polygon = new JMenuItem("Polygon Tool");
   private static JMenuItem circle = new JMenuItem("Circular Tool");

   // Locations/Sizes (Tools)
   private static int JSize = 700;
   private int rectXLoc = 200;
   private int rectYLoc = 200;
   private int rectXSize = 300;
   private int rectYSize = 300;

   public static void createJFrame() {

      frame = new JFrame();
      frame.add(new JHouse());
      frame.setLocation(650, 225);
      frame.setSize(JSize, JSize);
      frame.setVisible(true);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.setJMenuBar(mainBar);
      mainBar.add(create);
      mainBar.add(tools);
      mainBar.add(presets);
      create.add(canvas);
      tools.add(freeDraw);
      tools.add(rectangle);
      tools.add(polygon);
      tools.add(circle);
   }

   public JHouse() {

     canvas.addActionListener(this);
     freeDraw.addActionListener(this);
     rectangle.addActionListener(this);
     polygon.addActionListener(this);
     circle.addActionListener(this);
     addMouseListener(this);
     addMouseMotionListener(this);
   }

   public void paintComponent(Graphics g) {

      super.paintComponent(g);
      BasicStroke aStroke = new BasicStroke(1.0f,
         BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);
      Graphics2D gr2D = (Graphics2D)g;
      gr2D.setStroke(aStroke);
      gr2D.drawRect(rectXLoc, rectYLoc, rectXSize, rectYSize);
   }

  /* public void draw(Graphics g) {
      BasicStroke aStroke = new BasicStroke(1.0f,
         BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND);        This was a part of attempt # 3 (Failed attempt)
      Graphics2D gr2D = (Graphics2D)g;
      gr2D.setStroke(aStroke);
      gr2D.drawRect(rectXLoc, rectYLoc, rectXSize, rectYSize);
   }*/

   public void mouseClicked(MouseEvent e) {

      /* rectXSize += 6;
      repaint();
      validate();*/
   }
   public void mousePressed(MouseEvent e) {

      isPressed = true;
   }

   public void mouseDragged(MouseEvent e) {

      int x = e.getX();
      int y = e.getY();

      if(isPressed){
         rectXLoc = x;
         rectYLoc = y;
         repaint();
         validate();     
      }
   }

   public void mouseEntered(MouseEvent e) {
   }

   public void mouseExited(MouseEvent e) {
   }

   public void mouseMoved(MouseEvent e) {
   }

   public void mouseReleased(MouseEvent e) {

      isPressed = false;
   }

   public void actionPerformed(ActionEvent e) {

      Object source = e.getSource();

      if(source == canvas) {
         frame.removeAll();
         frame.repaint();  
         frame.validate();
         //draw(g);    This was part of attempt #3 (Failed attempt)

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

      createJFrame();
   }
}

frame.removeAll() 方法删除框架中的所有组件。包括您的菜单,这就是您收到空指针异常的原因。这里的解决方案是使用私有方法重置此处设置的初始值。 例如:

private void resetValues() {
    JSize = 700;   
    rectXLoc = 200;
    rectYLoc = 200;
    rectXSize = 300;
    rectYSize = 300;
}

使用此方法将值重置为初始值,然后调用此方法而不是 frame.removeAll()。所以你的条件是:

if(source == canvas) {
     resetValues();
     frame.repaint();  
     frame.validate();
}

在这里您可以使用此方法重置所有操作的值。我看到您有 4 种不同的操作可用 - 自由绘制、矩形、多边形和圆形。您需要重置所有值。

如果您需要一个空的 canvas(即您希望删除其中的所有组件),请声明一个布尔变量,例如 boolean reset = false 作为 class 变量,并且在 paintComponent() 方法中进行检查:

if(reset) {
   reset = false; // you dont want reset to be set true permanantly
   return;
}
// rest of your code

并且在 actionPerformed() 方法中,在调用 frame.repaint() 之前设置 reset = true。这将重新绘制组件。但是什么都不会画,所以你会得到一个空的 canvas.