我的正弦图在缩小时不会继续,但在使应用程序窗口变长时会继续,不确定其 wro 的位置

My Sine Graph doesn't carry on when zooming out but carrys on when making the app window longer not sure where its wro

提问人:AXX3 提问时间:11/5/2023 最后编辑:camickrAXX3 更新时间:11/7/2023 访问量:68

问:

缩小之前 缩小后 缩小后 当使窗口变长时,它会在左侧继续

这是我项目的JPanel。

package SineWave;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import java.awt.geom.Line2D;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

public class SineWave extends JPanel implements MouseWheelListener {
    private double scale = 1.0;

    public SineWave() {
        addMouseWheelListener(this);
        
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setColor(Color.BLACK);
        double xScale = getWidth() / 2 * scale;
        double yScale = getHeight() / 2 * scale;
        g2.draw(new Line2D.Double(0, getHeight() / 2 * scale, getWidth(), getHeight() / 2 * scale));
        g2.draw(new Line2D.Double(getWidth() / 2 * scale, 0, getWidth() / 2 * scale, getHeight()));
        g2.setColor(Color.BLUE);
        double x, y, oldx = 0, oldy = getHeight() / 2;
        for (x = 0; x <= getWidth(); x += 0.1) {
            y = getHeight() / 2 - Math.sin((x - getWidth() / 2) / 100) * 100;
            g2.draw(new Line2D.Double(oldx * scale, oldy * scale, x * scale, y * scale));
            oldx = x;
            oldy = y;
        }
    }

    public void mouseWheelMoved(MouseWheelEvent e) {
        
        
        
        if (e.getWheelRotation() < 0) {
            
            scale *= 1.1;
        } else {
            scale /= 1.1;
        }
        repaint();
    }
}

这是我项目的JFrame。

package SineWave;

import javax.swing.JFrame;

public class MyFrame extends JFrame{
    MyFrame(){
        this.setSize(500, 500);
        SineWave wave = new SineWave();
        this.add(wave);
        this.setVisible(true);
    }

}

我试过查看油漆组件,但不确定它哪里出了问题以及解决方案是什么,轴也没有居中。我尝试进行编辑,但它只是使比色变得奇怪并停止绘制。

我也尝试让 AI 找到问题所在,但除了在 stackoverflow 上提问外,无法想出有用的答案。

像这样的东西:

i.stack.imgur.com/sPVC9.png

java swing jframe paintcomponent

评论

1赞 Reilas 11/5/2023
getWidthgetHeight 方法返回 int 值,因此这些操作中的任何一个都将返回非小数值。
0赞 VGR 11/5/2023
改变规模应该做什么?坐标原点是否始终位于组件的中心?
0赞 AXX3 11/5/2023
是的,它应该始终位于屏幕中央。

答:

1赞 camickr 11/5/2023 #1

你的缩放值不是你所期望的,因为 MouseWheelListener 没有按照你预期的方式工作。

请尝试以下代码:

public void mouseWheelMoved(MouseWheelEvent e) {

    System.out.println( e.getWheelRotation() );

    if (e.getWheelRotation() == 0) return;

    if (e.getWheelRotation() < 0) {
        scale *= 1.1;
    } else {
        scale /= 1.1;
    }

    repaint();
}

您将看到旋转在 1 或 -1 之前多次为 0,因此您的 else 条件被多次执行,导致比例因子减小。

编辑:

根据您的图像,您似乎希望能够控制显示完整正弦波所需的“宽度”。

您当前的代码实质上是在面板中绘制单个正弦波。您不能只是“缩放”图像以在可用空间中创建更多(或更少)正弦波。相反,你需要实际绘制更多的正弦波。

那么你是怎么做到的呢?

根据反复试验,我意识到是您传递给控制宽度的 sine(...) 方法的参数。

下面的代码使用鼠标滚轮调整此值以控制正弦波的宽度:

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Line2D;
import javax.swing.*;

public class SineWave extends JPanel implements MouseWheelListener
{
    private int scale = 100;

    public SineWave()
    {
        addMouseWheelListener(this);
    }

    public void paintComponent(Graphics g)
    {
        super.paintComponent(g);
        Graphics2D g2 = (Graphics2D) g;
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        double midX = getWidth() / 2;
        double midY = getHeight() / 2;

        g2.setColor(Color.BLACK);
        g2.draw(new Line2D.Double(0, midY, getWidth(), midY));
        g2.draw(new Line2D.Double(midX, 0, midX, getHeight()));

        g2.setColor(Color.BLUE);
        double x, y, oldx = 0, oldy = midY;

        for (x = 0; x <= getWidth(); x += 1)
        {
            y = midY - Math.sin(x / scale) * 100;
            System.out.println(x + " : " + y);
            g2.draw(new Line2D.Double(oldx, oldy, x, y));
            oldx = x;
            oldy = y;
        }
    }

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

    public void mouseWheelMoved(MouseWheelEvent e)
    {
        if (e.getWheelRotation() == 0) return;

        if (e.getWheelRotation() < 0) {
            scale += 5;
        } else {
            scale -= 5;
        }

        if (scale < 5)
            scale = 5;

        repaint();
    }

    public static void main(String[] args) throws Exception
    {
        JFrame frame = new JFrame();
//      frame.setSize(d500, 500);
        SineWave wave = new SineWave();
        frame.add(wave);
        frame.pack();
        frame.setVisible(true);
    }
}

注意:我选择了面板 628 的首选宽度,因为这是使用比例因子 100 时完成正弦波所需的迭代次数,正如您在绘制正弦波时生成的输出所见。

评论

0赞 AXX3 11/5/2023
感谢您的帮助,但它仍然没有修复我的正弦曲线,它只是没有在新的缩小面板中重新绘制。正弦曲线在缩小时变得越来越小,但在新的缩小屏幕中不会继续。像这样的东西:i.stack.imgur.com/sPVC9.png
0赞 camickr 11/6/2023
您不了解缩放和自定义绘画的上下文。请参阅编辑。
0赞 AXX3 11/7/2023
非常感谢你,这绝对是神奇的。你有什么资源可以让我更深入地了解这一点吗?我有一个问题,我不明白的一件事是,你如何得出选择比例因子的结论?
0赞 AXX3 11/7/2023
你如何得出以下数学公式: y = getHeight() / 2 - Math.sin(x / scale ) * 100;
0赞 camickr 11/7/2023
这实际上是一个关于三角学和理解正弦(...)方法如何工作的问题。我不记得我的任何 trig 类,所以我只是使用了您原始帖子中的代码并玩了不同的值并注意到了该模式。这只是通过反复试验。