摆脱当前形状的JFrame。即清除Microsoft画布中的“画布”

时间:2018-04-16 04:25:59

标签: java graphics jframe actionlistener jmenuitem

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

为了澄清,第一个粘贴的代码段是我认为该问题所在的位置。第二个粘贴的部分是我到目前为止所做的一切。如果问题很清楚,我将不会因为告诉我答案它是否真的是一个非常简单的解决方案而破坏了我的学习经验。我将继续寻找简单的解决方案,希望在我自己的研究中保留更多信息。简单地给我一个研究java的领域。希望这会有所帮助!!!

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

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

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

3。)我尝试从类的开头实例化一个Graphics对象,然后创建一个接受Graphics对象并将其转换为Graphics2D的方法,然后在该方法中绘制一个简单的方形JFrame的中心 Error 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.access$500(EventQueue.java:97)
        at java.awt.EventQueue$3.run(EventQueue.java:709)
        at java.awt.EventQueue$3.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$4.run(EventQueue.java:731)
        at java.awt.EventQueue$4.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();
   }
}

1 个答案:

答案 0 :(得分:0)

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种不同的操作可用 - 自由绘图,矩形,多边形和圆形。您需要重置所有值。

如果你需要一个空的画布(即你想要删除其中的所有组件),请声明一个布尔变量,将boolean reset = false称为类变量,并在paintComponent()方法中有一个检查:

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

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