要解决这个特定问题,就要能够摆脱JFrame中的当前形状。我刚刚完成了Joyce Farrel关于Java的书,所以我决定挑战自己来创建这个迷你应用程序,但我坚持让这种形状消失。我撕掉了与问题无关的其余代码,以使问题更容易回答。我仍然将整个项目添加到最后,供那些可能想要更深入地了解的人使用,或者它可能有助于确保解决方案。
澄清一下,我认为第一个粘贴的代码段是问题所在。第二个粘贴的部分是我到目前为止整理的所有内容。如果问题很清楚,如果它确实是一个非常简单的解决方案,我会很高兴不要通过告诉我答案来破坏我的学习经历。我将继续寻找简单的解决方案,希望在我自己的研究中保留更多信息。只要给我一个研究Java的领域。希望这有帮助!!
当应用程序运行时,用户选择 JMenuItem "新画布",应用程序突然冻结?它不会崩溃,但会冻结整个 JFrame,迫使用户关闭 JFrame 并重新开始应用程序。理想情况下,当用户选择"新建画布"选项时,JFrame中心的形状将消失,但不幸的是,所有形状在应用程序冻结时一直徘徊。我假设的是,一旦我摆脱了形状,它就会立即回来,因为 paintComponent() 方法并导致应用程序冻结。
试---- 1.)我已经调用了 repaint() 方法以及 validate() 方法作为按下 JMenuItem 时要执行的操作
2.)我尝试在 paintComponent() 方法中注释掉对 super 的调用,并且确实收到了相当整洁的结果,但它没有解决问题
3.)我尝试从类的开头实例化一个 Graphics 对象,然后创建一个接受 Graphics 对象并将其转换为 Graphics2D 的方法,然后在 JFrame 的中心绘制一个简单的正方形此尝试出错
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();
}
}
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
.这将重新绘制组件。但是什么都不会画,所以你会得到一张空的画布。