【问题标题】:How do I call a function with a graphics object from another class?如何使用另一个类的图形对象调用函数?
【发布时间】:2019-11-29 03:46:50
【问题描述】:

我想从main() 调用paint(),但我需要一个参数。我不知道要传递哪个参数,而且当我在外部定义g 时似乎无法使用Graphics 对象参数,因为它不能被初始化。

我尝试在 main() 中创建 Graphics 类的对象,然后将其作为参数传递,但每当我尝试使用 g 时,它都会给我一个 nullException

import java.util.*;
import java.awt.*;
import javax.swing.JFrame;
 class Boards extends Canvas
{
    JFrame frame;    
     void frame()
    {
        JFrame frame = new JFrame("SNAKES AND LADDERS");
        Canvas canvas= new Boards();
        canvas.setSize(1000,1000);
        frame.add(canvas);
        frame.pack();
        frame.setVisible(true); 
        frame.getGraphics();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);  
        Graphics g;

    }
    public void paint(Graphics g)
    {
      g.fillRect(0,0,100,1000);
    }
}

 class snakes_and_ladders
{
    Scanner s= new Scanner (System.in);
    Boards board= new Boards();
     void main()    
    {
        board.frame();
        board.paint();
    }
}

【问题讨论】:

    标签: java graphics awt


    【解决方案1】:

    您需要致电repaint。来自文档:

    public void repaint(long tm, int x, int y, int width, int height)

    如果组件是,则将指定区域添加到脏区域列表中 显示。组件将在当前所有 挂起的事件已被调度。

    编辑

    间接参数化的一个例子:

    protected String test = "foo";
    
    public void myRepaint(long tm, int x, int y, int width, int height, test) {
        this.test = test;
        repaint(tm, x, y, width, height);
    }
    
    public void paint(Graphics g) {
        //do something with this.test
    }
    

    【讨论】:

    • 我将 paint() 重命名为 repaint()。现在我没有收到语法错误,但它没有在画布上绘制矩形。这是一个 sn-p-public void repaint(Graphics g) { g.setColor(Color.black); g.fillRect(0,0,100,1000); } } public class snakes_and_ladders { Scanner s= new Scanner (System.in);板板=新板();无效 main() { board.frame(); board.repaint();
    • @Mendax 不会重命名您的绘制方法,而是在您的 snakes_and_ladders 类中调用 repaint。
    • 它现在可以工作了。非常感谢。但是你能告诉我它为什么工作吗?为什么当我调用 repaint() 时会调用paint()?
    • @Mendax 很简单。您的 Boards 类扩展了 Canvas,而 Canvas 又扩展了 Component 类。 Component 类有一些方法,比如paint 和repaint。 repaint 使一个区域无效,生成一个 Graphics 对象,然后调用 paint(),传递该 Graphics 对象。由于您已经覆盖了绘画,因此在您的类中,这意味着您的绘画方法将被重绘调用。因此,调用paint 或多或少是一件私人事务,即使它被标记为public,并且最好将此调用委托给repaint。
    • @Lajos_Arpad 再次感谢您。是否可以将值传递给paint(),就像我可以向paint() 添加参数一样?
    【解决方案2】:

    要重绘图形区域,不要直接调用paint 方法,而是使用invalidate 方法。

    【讨论】:

    • 你是怎么做到的?
    【解决方案3】:

    我建议您使用 Swing 扩展 JPanel 并覆盖 paintComponentCanvasAWT 类,您不应混合使用 SwingAWT 功能。

    并确保调用 super.paintComponent() 作为第一条语句。要重新绘制面板,您只需致电repaint()

    你不应该直接调用paint方法,因为它应该在事件调度线程(EDT)中完成。您也不需要保护图形上下文。

    这是一个演示运动的非常简单的示例。

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class MovementDemo extends JPanel implements ActionListener {
    
       JFrame frame      = new JFrame("Movement Demo");
       int    size       = 500;
       int    x          = 50;
       int    y          = 200;
       int    diameter   = 50;
       int    yinc       = 2;
       int    xinc       = 2;
       int    xdirection = 1;
       int    ydirection = 1;
    
       public MovementDemo() {
          setPreferredSize(new Dimension(size, size));
          frame.add(this);
          frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
          frame.pack();
          frame.setLocationRelativeTo(null);
          frame.setVisible(true);
    
       }
    
       public static void main(String[] args) {
          SwingUtilities.invokeLater(() -> new MovementDemo().start());
       }
    
       public void start() {
    
          Timer timer = new Timer(100, this);
          timer.setDelay(5);
          timer.start();
       }
    
       public void actionPerformed(ActionEvent ae) {
    
          if (x < 0) {
             xdirection = 1;
          }
          else if (x > size - diameter) {
             xdirection = -1;
          }
          if (y < 0) {
             ydirection = 1;
          }
          else if (y > size - diameter) {
             ydirection = -1;
          }
          x = x + xdirection * xinc;
          y = y + ydirection * yinc;
          repaint();
       }
    
       public void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2d = (Graphics2D) g.create();
          g2d.setColor(Color.BLUE);
          g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
          g2d.fillOval(x, y, diameter, diameter);
    
       }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多