简体   繁体   English

Java中可以更改像素值的方法

[英]Methods in Java which can change pixel values

I am working on an animation kind of program in java and for visualization. 我正在用Java和可视化来开发一种动画程序。 I am using the swing and awt libraries. 我正在使用swingawt库。 I looked at a dozen implementations of this and all of them use a paint Component method and then repaint() when they want to draw shapes on the JFrame. 我研究了十二种方法的实现,它们都使用paint Component方法,然后在想要在JFrame上绘制形状时使用repaint()

Is there some method that I can call from any class that I want that can for example change a single pixel value? 我可以从任何想要的类中调用某些方法来改变单个像素值吗?

I also want to make an array list with shapes: 我还想用形状制作一个数组列表:

ArrayList<Rectangle> rectangles = new ArrayList<Rectangle>(); 

And I am curious how to add things to it. 我很好奇如何添加一些东西。 I was thinking: 我刚在想:

Rectangle rect = "something"
rectangles.add(rect);

But I'm not sure what something should be. 但是我不确定应该是什么。 I am relatively new to this, so feel free to express your views if I'm missing something obvious. 我对此还比较陌生,因此,如果我缺少明显的内容,请随时发表您的看法。

Is there some method that I can call from any class that I want that can for example change a single pixel value? 我可以从任何想要的类中调用某些方法来改变单个像素值吗?

You could create a BufferedImage, which has a setRGB(...) method that would achieve what you wanted by drawing the image within the paintComponent(...) method with Graphics drawImage(...) method. 您可以创建一个BufferedImage,它具有setRGB(...)方法,该方法可以通过使用Graphics drawImage(...)方法在paintComponent(...)方法中绘制图像来实现所需的功能。

With regard to Rectangle rect = "something" -- just look up the Rectangle constructors available to you in the Rectangle API and use the most appropriate one for you. 关于Rectangle rect = "something" -只需在Rectangle API中查找可用的Rectangle构造函数,然后使用最合适的Rectangle构造函数即可。

It's been suggested the you should use getGraphics over paintComponent , let's take a look at that for a second... 有人建议您应该使用getGraphics不是paintComponent ,让我们再paintComponent ...

馊主意

Opps, oh, that didn't quite work the way we'd expect! 哦,噢,这并没有达到我们期望的效果! Let's even ignore why you shouldn't paint directly to top level containers (cause that's painting under the title bar) 让我们甚至忽略为什么不应该直接在顶层容器上绘画(因为这是在标题栏下绘画)

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JButton draw = new JButton("Draw");

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(draw);
                frame.setSize(150, 150);
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);

                draw.addActionListener(new ActionListener() {
                    @Override
                    public void actionPerformed(ActionEvent e) {
                        drawARectangle(frame.getGraphics());
                    }
                });
            }
        });
    }

    public void drawARectangle(Graphics g) {
        g.setColor(Color.RED);
        g.fillRect(20, 20, 100, 100);
    }

}

Okay, let's have a look at paintComponent and repaint 好吧,让我们看一下paintComponentrepaint

好主意

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;

public class Test {

    public static void main(String[] args) {
        new Test();
    }

    public Test() {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
                } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
                    ex.printStackTrace();
                }

                JFrame frame = new JFrame("Testing");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.setLayout(new GridBagLayout());
                frame.add(new TestPane());
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }

    public class TestPane extends JPanel {

        private boolean drawBox;

        public TestPane() {
            setLayout(new GridBagLayout());
            JButton draw = new JButton("Draw");
            add(draw);
            draw.addActionListener(new ActionListener() {
                @Override
                public void actionPerformed(ActionEvent e) {
                    drawBox = !drawBox;
                    repaint();
                }
            });
        }

        @Override
        public Dimension getPreferredSize() {
            return new Dimension(150, 150);
        }

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            if (drawBox) {
                g.setColor(Color.RED);
                g.fillRect(20, 20, 100, 100);
            }
        }

    }

}

Swing has well documented painting process, have a look at Painting in AWT and Swing and Performing Custom Painting for more details and one should work within the design of the API. Swing记录了完整的绘画过程,请参阅AWT中的绘画和Swing执行自定义绘画以获取更多详细信息,并且应该在API的设计范围内进行工作。

Before anyone jumps down my throat and suggest you could use a WindowListener or ContainerListener or some other listener, the answer is, why? 在有人跳下我的喉咙并建议您可以使用WindowListenerContainerListener或其他某种侦听器之前,答案是,为什么? paintComponent works just fine. paintComponent可以正常工作。

Swing uses a passive rendering engine, meaning that a paint might occur for any number of reasons, most of the time which you don't instantiate or know about, so unless your linked into the painting process, you won't know that it's occurred, resizing is just a really good way to demonstrate it Swing使用被动渲染引擎,这意味着绘画可能会由于多种原因而发生,在大多数情况下您都不是实例化或不知道的,因此,除非您链接到绘画过程,否则您不会知道绘画的发生,调整大小只是演示它的一种非常好的方法

So can we please stop suggesting bad approaches like using getGraphics or using null layouts or KeyListener or DocumentListener for real time filtering of text components and maybe we can save a bunch of people a bunch of head aches 因此,我们能否停止建议使用getGraphics或使用null布局或KeyListenerDocumentListener进行文本组件实时过滤的不良方法,也许我们可以为一堆人节省很多头疼

Apparently I was ranting when I called everyone an idiot for using repaint(); 当我称每个人使用repaint()都是一个白痴时,我显然感到很恼火。 here's the better way. 这是更好的方法。 Say I wanted to create a rectangle or image or line or oval on the jframe, 假设我想在jframe上创建矩形,图像,线条或椭圆形,

public JFrame frame = new JFrame(); 公共JFrame框架=新的JFrame();
public void paintingHome(){ 公共无效paintingHome(){
//set up the jframe and stuff //设置jframe和其他东西
System.out.println("This is a rectangle"); System.out.println(“这是一个矩形”);
paintARectangle(frame.getGraphics(), 42, 256); paintARectangle(frame.getGraphics(),42,256);
} }
public void paintARectangle(Graphics g, int xCoord, int yCoord, int width, int height){ public void paintARectangle(图形g,int xCoord,int yCoord,int宽度,int高度){
g.fillRact(xCoord, yCoord, width, height); g.fillRact(xCoord,yCoord,width,height);
//simple as that //就那么简单
} }
//and you can have as many as you want //您可以随心所欲
public void paintWhatever(Graphics g, Something whatever){ 公共无效的油漆无论如何(图形g,随便什么){
g.doSomethingWith(whatever); g.doSomethingWith(whatever);
//that won't actually work until oracle releases version 238249.3432.4 //在oracle发布238249.3432.4版本之前这实际上不会起作用
} }
//the key is using the frame.getGraphics() method //关键是使用frame.getGraphics()方法
//repaint is unnecessary and restrictive //重新绘制是不必要且有限制性的

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

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