繁体   English   中英

什么是Java中的“ Paint”事件处理程序?

[英]What is “Paint” event handler in Java?

Java中的事件处理程序(使用Net Bean,Swing)是什么类似于C#中的Paint? 恢复表单,调整大小等时应触发的事件

public void paint(Graphics g2){
    g2 = pnlDrawing.getGraphics();
    g2.clearRect(0, 0, size, size);
    g2.setColor(Color.BLACK);
    g2.fillRect(size/2-1, 0, 2, size); // draw y axis
    g2.fillRect(0, size/2-1, size, 2); // draw x axis

    //set the font
    g2.setFont(new Font("Arial", 2, 12));

    // write the values on the X axis
    for(int i=0; i<=10; i++){
        if(i == 0)
            continue;
        int pos1 = (size/2-1)-i*30;
        int pos2 = (size/2-1)+i*30;
        g2.draw3DRect(pos1, size/2-3, 1, 5, true);
        g2.drawString(String.valueOf(-i),pos1-10,size/2-3+20);
        g2.draw3DRect(pos2, size/2-3, 1, 5, true);
        g2.drawString(String.valueOf(i),pos2-5,size/2-3+20);
    }

    for(int i=0; i<=10; i++){
        if(i == 0)
            continue;
        int pos1 = (size/2-1)-i*30;
        int pos2 = (size/2-1)+i*30;
        g2.draw3DRect(size/2-3, pos1, 5, 1, true);
        g2.drawString(String.valueOf(i),size/2-3+10,pos1+5);
        g2.draw3DRect(size/2-3, pos2, 5, 1, true);
        g2.drawString(String.valueOf(-i),size/2-3+10,pos2+5);
    }

       pnlDrawing.invalidate();
}

方法:

public void paint(Graphics g)

java.awt.Component类(这是所有Swing组件的超类)中的是绘画的回调方法。 因此,需要完成的所有组件重涂最终都会调用此方法,因此,如果您要执行自己的绘制,则可以覆盖它。

==更新==

您需要对组件进行子类化以获取绘制回调,例如

public class MyPanel extends JPanel {
    public void paint(Graphics g) {
        // do your painting here
    }
}

或者,如果您不想创建一个全新的类,则可以使用一个匿名内部类。

pnlDrawing = new JPanel() {
    public void paint(Graphics g) {
        // Your painting code
    }
}

您应该重写paintComponent方法,因为paint也负责绘制子组件,边框和其他一些工作。

恢复表单,调整大小等时应触发的事件

我不确定我是否理解您的问题。 Swing将自动确保为您完成绘画,并且没有可以听的“绘画事件”。 如果您想了解有关绘画的更多信息,则可以阅读AWT和Swing中的绘画

如果您想知道表单是什么时候触发什么事件:

a)调整大小-使用ComponentListener
b)恢复-使用WindowListener

在上述情况下,请阅读Swing Tuturial中的相应章节。 您还将在“自定义绘画”中找到一个部分,其中解释了为什么应在paintComponent()方法中进行绘画。

repaint() 如果我没记错的话,它最终会发出一个调用paint()的请求。 paint()是真正的painter方法,但是在还原,调整大小等情况下会触发repaint()

在一个更好的世界中,您不必重新发明轮子,但是在当前世界中,您确实需要。

因此,这里有一个BetterJPanel,它使您可以添加和删除绘画事件,而不必每次都将JPanel子类化。

更好的日本

import java.util.function.*;
import java.util.*;
import javax.swing.*;
import java.awt.*;

public class BetterJPanel extends JPanel
{
    protected Map<String, ArrayList<Function<Map<String, Object>,Void>>> events;
    public final static long serialVersionUID = -4405124172582504448L;

    public BetterJPanel()
    {
        super();
        this.events = new HashMap<String, ArrayList<Function<Map<String, Object>, Void>>>();         
    }

    public void paint(Graphics g)
    {   
        ArrayList<Function<Map<String, Object>,Void>> paintEvents = null;

        if (this.events.containsKey("paint")) {
            paintEvents = this.events.get("paint");

            for (Function<Map<String, Object>,Void> evt : paintEvents) {
                Map<String, Object> eventArguments = new HashMap<String, Object>();
                eventArguments.put("graphics", g);

                evt.apply(eventArguments);
            }    
        }            
    }

    public void on(String eventName, Function<Map<String, Object>, Void> cb)
    {
        if (!events.containsKey(eventName)) {
            ArrayList<Function<Map<String, Object>,Void>> tmp = new ArrayList<Function<Map<String, Object>,Void>>();

            events.put(eventName, tmp);
        }

        events.get(eventName).add(cb);
    }

    public void off(String eventName, Function<Map<String, Object>, Void> cb)
    {
        ArrayList<Function<Map<String, Object>,Void>> events = null;

        if (this.events.containsKey(eventName)) {
             events = this.events.get(eventName);

             events.remove(cb);
        }
    }    
}

这是使用它的演示(请注意,不再包含JPanel的子类):

import java.util.function.*;
import java.awt.*;
import javax.swing.*;
import java.util.*;

public final class TestBetterJPanel
{
    public static void main(String[] args)
    {
        JFrame f = new JFrame("Better JPanel Testing");
        BetterJPanel p = new BetterJPanel();

        p.on("paint", evt -> {
            Graphics g = (Graphics)evt.get("graphics");
            g.setColor(Color.BLACK);
            g.fillRect(0, 0, 800, 500);

            return null;
        });
        p.on("paint", evt -> {
            Graphics g = (Graphics)evt.get("graphics");
            g.setColor(new Color(0x33, 0x66, 0xff));
            g.fillRect(0, 0, 400, 500);

            return null;
        });

        p.setPreferredSize(new Dimension(800, 500));
        f.add(p);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }
}

在此处输入图片说明

黑色矩形由第一个事件绘制,蓝色矩形由第二个事件绘制。

为什么要经历所有这些麻烦? 可重用性:jjs(运行jjs -cp . test.js ,所有新的Java版本随附):

var Thread = java.lang.Thread;
var BetterJPanel = Java.type("BetterJPanel");
var JPanel = javax.swing.JPanel;
var Dimension = java.awt.Dimension;
var Color = java.awt.Color;
var JFrame = javax.swing.JFrame;

var frame = new JFrame("Hello, World!");
var panel = new BetterJPanel();

panel.setPreferredSize(new Dimension(800, 500));
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

var x = 20;
var y = 20;

panel.on("paint", function(e) {
    var g = e.graphics;

    g.setColor(Color.BLACK);
    g.fillRect(0, 0, 800, 500);

    g.setColor(new Color(0x33, 0x66, 0x99));
    g.fillOval(x, y, 30, 30);
});

new Thread(function() {
    for (;;) {
        x += 1;
        y += 1;

        if (x > 800) {
            x = 0;
        } 
        if (y > 500) {
            y = 0;
        }

        panel.repaint();
        Thread.sleep(1000 / 60);
    }
}).start();


frame.setVisible(true);

该球以每1/60秒约1像素的速度向东南移动,当它离开画布时从另一侧开始。

希望当Java9出现时,此类内容会在核心Java中开始出现。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM