【问题标题】:Trouble Drawing In JPanel在 JPanel 中绘制问题
【发布时间】:2016-05-25 23:27:36
【问题描述】:

我首先要说我几乎可以保证这个问题将是一个副本,但我找不到任何其他适合我需要/适用于我的程序的答案。我需要在JPanel 上画画,但我似乎无法画出我需要画出来的线条。

JFrame drawF = new JFrame("Simulator");
        JPanel simPanel = new JPanel();
        drawF.setVisible(true);
        drawF.setSize(1000,650);
        drawF.add(simPanel);
        drawF.pack();
        simPanel.setLayout(null);
        simPanel.setSize(1000,650);
        simPanel.setVisible(true);
        simPanel.setBackground(Color.BLACK);

        //add drawing surface


        //start drawing
            simPanel.add(new JComponent()
            {
            public void paint(Graphics g)
            {
                g.setColor(Color.RED);
                int xLast,yLast;
                for(int i=0;i < 5000000; i++)  // five million
                {

                    double dX = (Math.E*Math.exp(-numd1*i)*Math.sin(i*numf1+nump1))+(Math.E*Math.exp(-numd2*i)*Math.sin(i*numf2*nump2));
                    double dY = (Math.E*Math.exp(-numd3*i)*Math.sin(i*numf3+nump3))+(Math.E*Math.exp(-numd4*i)*Math.sin(i*numf4*nump4));
                    int drawX = (int)dX;
                    int drawY = (int)dY;
                    if (i==0)
                    {
                        xLast = 0;
                        yLast = 0;
                        g.drawLine(xLast,yLast,drawX,drawY);

                        simPanel.revalidate();
                        simPanel.repaint();
                    }
                    else
                    {
                        xLast = drawX;
                        yLast = drawY;
                        g.drawLine(xLast,yLast,drawX,drawY);

                        simPanel.revalidate();
                        simPanel.repaint();
                    }
                }
            }
        });





        repaint();

JComponent 添加到我的JPanel 有什么问题吗?

【问题讨论】:

  • 你想画什么方程?为什么你在计算中使用Math.E 并乘以相同的数字(欧拉常数,e)提高到某个幂?
  • 对不起,我一直很忙。我正在模拟一个和声仪。
  • 哦,顺便说一下,这(显然)只是一个更大的程序的一部分。
  • 如果它是一个更大的 GUI,那么您将不希望在它自己的 JFrame 中显示它。如果需要进入子窗口,则将其显示在对话框窗口中,例如在 JDialog 中。
  • 只是为了好奇拥有多个 JFrame 会发生什么?帧速率降低?

标签: java swing jframe jpanel


【解决方案1】:

您的问题可能是布局管理器之一。 JPanel 默认使用 FlowLayout,因此您的 JComponent 将调整到其自然首选大小,即 [0, 0],因此在这种情况下不会显示任何内容。尝试制作 JPanel 的布局 BorderLayout 并添加 JComponent BorderLayout.CENTER。

其他问题:

  • 重写 JComponent 的paintComponent 方法,而不是paint 方法,否则您会因为不考虑边框和子项的绘制而冒着意想不到的副作用。
  • 如果您按照我的建议覆盖paintComponent,请在覆盖中调用super 的绘画方法super.paintComponent(g);。这将有助于清除所有脏像素。
  • 摆脱所有不必要的重绘、重新验证和 setVisible 调用。
  • 在将所有组件添加到 GUI 之后在 JFrame 上调用 setVisible。
  • 我自己,我更喜欢在 JPanel 的 paintComponent 方法中绘制,而不是在 JComponent 中绘制,因为它不会自动绘制背景。
  • 而且我更喜欢在自己的独立班级中进行绘画,而不是埋在匿名的内部班级中。以这种方式埋葬的功能太重要了。
  • 您在绘画方法中调用的运行时间越长或 CPU 密集型代码越长,您的 GUI 似乎响应越慢。卸载类的构造函数中的 for 循环和数学计算,并从绘画方法中删除。将结果存储在数组或列表中,或者如果您希望绘制到 BufferedImage,然后在 paintComponent 方法中显示该图像。

例如:

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.*;

@SuppressWarnings("serial")
public class DrawingStuff extends JPanel {
    private static final int PREF_W = 1000;
    private static final int PREF_H = 650;
    private static final Color BG = Color.BLACK;
    private static final Color GRAPHICS_COLOR = Color.RED;
    private static final int LOOP_COUNT = 5000000; // 5 million

    private BufferedImage image = null;
    private MathParams[] params;

    public DrawingStuff(MathParams[] params) {
        this.params = params;
        setBackground(BG);
        image = drawImage();
    }

    private BufferedImage drawImage() {
        BufferedImage img = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
        Graphics2D g2 = img.createGraphics();

        g2.setColor(GRAPHICS_COLOR);
        int xLast, yLast;
        for (int i = 0; i < LOOP_COUNT; i++) {
            double dX = params[0].doCalc0(i) + params[1].doCalc1(i);
            double dY = params[2].doCalc0(i) + params[3].doCalc1(i);
            int drawX = (int) dX;
            int drawY = (int) dY;
            if (i == 0) {
                xLast = 0;
                yLast = 0;
                g2.drawLine(xLast, yLast, drawX, drawY);
            } else {
                xLast = drawX;
                yLast = drawY;
                g2.drawLine(xLast, yLast, drawX, drawY);
            }
        }

        g2.dispose();
        return img;
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image != null) {
            g.drawImage(image, 0, 0, this);
        }
    }

    @Override
    public Dimension getPreferredSize() {
        if (isPreferredSizeSet()) {
            return super.getPreferredSize();
        }
        return new Dimension(PREF_W, PREF_H);
    }

    private static void createAndShowGui() {
        JFrame frame = new JFrame("Drawing Stuff");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // TODO: fix this -- what numbers to use??? These don't work
        MathParams[] paramArray = { 
                new MathParams(1, 2, 3), 
                new MathParams(1, 2, 3), 
                new MathParams(3, 4, 5),
                new MathParams(3, 4, 5)
                };

        frame.getContentPane().add(new DrawingStuff(paramArray));
        frame.setResizable(false);
        frame.pack();
        frame.setLocationRelativeTo(null);
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(() -> createAndShowGui());
    }
}

public class MathParams {
    private int numd;
    private int numf;
    private int nump;

    public MathParams(int numd, int numf, int nump) {
        this.numd = numd;
        this.numf = numf;
        this.nump = nump;
    }

    public double doCalc0(int i) {
        return (Math.E * Math.exp(-numd * i) * Math.sin(i * numf + nump));
    }

    public double doCalc1(int i) {
        return (Math.E * Math.exp(-numd * i) * Math.sin(i * numf * nump));
    }
}

【讨论】:

  • 谢谢,我会试试这个,如果它有效,我会通知你
  • @MarkCoats:代码仅供参考,并不意味着“工作”,因为我不知道您要绘制什么图形或哪些参数是正确的。列举的概念正确的,起作用,并且是您问题的实际答案。
  • 在 num 变量中使用数字 (1,2,3,4) 确实区分了摆 1 x 和 y 值和摆 2 x 和 y 值的值(如果那是什么你问过你 paramArray 中的数字)
  • 我已经在这个特定的程序中度过了一个睡眠时间。我已经尝试使用 paintComponent 方法和其他一些方法,但我遇到了一些错误...我会尝试修改我的代码,我会尽快回复您。
  • @MarkCoats:那么看起来是时候让你做一些调试了。
猜你喜欢
  • 1970-01-01
  • 2011-11-05
  • 2015-07-08
  • 2021-09-11
  • 2010-09-06
  • 2013-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多