【问题标题】:Java Canvas Class does not paintJava Canvas 类不绘制
【发布时间】:2014-10-30 23:55:40
【问题描述】:

我想编写一个程序,检查选择了哪个 RadioButton(圆形、实心圆形或矩形)。然后用户单击画布字段上的某处。它应该识别用户单击的坐标,然后在该位置绘制任何被选为单选按钮的内容。

遗憾的是它没有这样做。事实上,我的代码甚至没有到达“ActionListener”。我已经检查了 5 次代码并进行了一些测试,但仍然无法弄清楚。

希望你能帮忙

public class Optionen extends JFrame {
MeinCanvas drawspace = new MeinCanvas();
ButtonGroup btngrp= new ButtonGroup();
int xpos, ypos;

public Optionen(String titel) {
    super(titel);  
    setLayout(new FlowLayout());
    JPanel panel = new JPanel();
    panel.setLayout(new GridLayout(3,1,20,20));
    JRadioButton opt1 = new JRadioButton();
    JRadioButton opt2 = new JRadioButton();
    JRadioButton opt3 = new JRadioButton();
    opt1.setActionCommand("Kreis"); //circle
    opt1.setActionCommand("Scheibe"); // filled circle
    opt1.setActionCommand("Rechteck"); //rectangle
    opt1.setText("Kreis");
    opt2.setText("Scheibe");
    opt3.setText("Rechteck");
    btngrp.add(opt1);
    btngrp.add(opt2);
    btngrp.add(opt3);
    panel.add(opt1);
    panel.add(opt2);
    panel.add(opt3);


    add(drawspace);
    add(panel);
    setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

}

public static void main(String[] args) {
    Optionen fenster = new Optionen("Optionswindow");
    fenster.pack();
    fenster.setSize(450,500);
    fenster.setResizable(true);
    fenster.setVisible(true);
}

class MeinCanvas extends Canvas {
class MeinMausAdapter extends MouseAdapter {
    public void mousPressed(MouseEvent e) {
        xpos = e.getX();
        ypos = e.getY();
        JOptionPane.showInputDialog(this);
        repaint();
    }
}

public MeinCanvas() {
    addMouseListener(new MeinMausAdapter());
    setBackground(Color.black);
    setForeground(Color.orange);
}

public void paint(Graphics g) {
    ButtonModel btnmdl= m_formauswahl.getSelection();
    String label = btnmdl.getActionCommand();
    int w = (int) (Math.random()*300);
    int h = (int) (Math.random()*300);
    if (label.equals("Kreis"))
        g.drawOval(xpos, ypos, w, w);
    if (label.equals("Scheibe"))
        g.fillOval(xpos, ypos, w, h);
    if (label.equals("Rechteck"))
        g.drawRect(xpos, ypos, w, h);
}
public Dimension getMinimumSize() {
    return new Dimension(300,300);
}
public Dimension getPreferredSize() {
    return getMinimumSize();
}
}
}

Eclipse 告诉我代码没问题,但是每当我运行程序时,它都会立即抛出异常。这是转储:

    Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at kapitel10.Optionen$MeinCanvas.paint(Optionen.java:79)
at sun.awt.RepaintArea.paintComponent(Unknown Source)
at sun.awt.RepaintArea.paint(Unknown Source)
at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEventImpl(Unknown Source)
at java.awt.EventQueue.access$400(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.awt.EventQueue$3.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.awt.EventQueue$4.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.security.ProtectionDomain$1.doIntersectionPrivilege(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilters(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)

【问题讨论】:

    标签: java canvas radio-button draw paint


    【解决方案1】:

    问题:

    1. 不要将 AWT (Canvas) 组件与 Swing (JFrame) 组件混合使用。坚持使用所有 Swing 组件。
    2. 而是按照 Swing 绘画教程中所述进行绘制 - 在 JPanel 的 paintComponent 覆盖方法中。
    3. 不要忘记在覆盖中调用 super 方法。
    4. 您的大部分代码甚至不应该在绘画方法中,而应该在 MouseListener 代码中。您可能会收到 NPE,因为当 GUI 首次绘制自身时尚未选择 JRadioButton。
    5. 在你的 MouseListener 中,获取 ButtonModel,检查它是否为 null,然后获取 actionCommand,然后更改 paintComponent 方法使用的类字段的状态,然后调用 @987654322 @。

    编辑

    也不是mousPressed,而是mousePressed!! 您必须在所有被覆盖的方法之前使用@Override 注解以避免此类错误。

      class MeinMausAdapter extends MouseAdapter {
    
         @Override  // this will cause a compiler error
         public void mousPressed(MouseEvent e) { // until you fix this spelling!
            ButtonModel btnmdl = btngrp.getSelection();
            if (btnmdl == null) {
               System.out.println("btn model is null");
               return;
            }
            actionCmd = btnmdl.getActionCommand();
            System.out.println(actionCmd);
            xpos = e.getX();
            ypos = e.getY();
            // JOptionPane.showInputDialog(this);
            repaint();
         }
      }
    

    另外:您必须明确设置 JRadioButton 的 actionCommands。您只为 一个 JRadioButton 执行此操作 - 请仔细查看您的代码。

    【讨论】:

    • 我看到人们在游戏中经常使用CanvasJFrame。您不应该将 AWT 与 Swing 一起使用,因为一个是重量级的,一个是轻量级的,尽管我也听说 JFrames 是重量级的。你能解释一下吗?
    • 你能打我的脸吗?非常感谢充满鳗鱼的气垫船!!!有时我觉得自己很迟钝。我的代码现在运行良好!一开始我很害怕,我需要整个周末才能让它运行起来。我还是个初学者。再次非常感谢!
    猜你喜欢
    • 2014-05-11
    • 2013-01-09
    • 1970-01-01
    • 1970-01-01
    • 2015-09-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-15
    相关资源
    最近更新 更多