【问题标题】:JFrame repaint() issues - JavaJFrame repaint() 问题 - Java
【发布时间】:2011-09-18 21:26:54
【问题描述】:

我希望能够在 JFrame 上使用 Java 的 paint() 进行绘制。当我单击 JFrame(现在任何地方)时,我希望使用单击的坐标重新绘制 JFrame - 类似于这个 Java 小程序 http://www.realapplets.com/tutorial/MouseClickExample.html

目前工作:

  • 最初绘制所有内容并正确显示 JFrame

不工作:

  • 即使声明了 repaint(),JFrame 也不会重新绘制和更新

这是我的代码 - 请尽可能严格 - 我想改进我的 Java 编程技术,所以(如果你有时间的话)指出我可以改进的每一个方面。

非常感谢任何帮助。

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

class AreaForText extends JPanel implements MouseListener {

int xpos; 
int ypos;

JFrame myJFrame = new JFrame();

public void setJFrame() {

    myJFrame.setSize(300, 150);
    myJFrame.setTitle("Bigger Text!");
    myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    myJFrame.setVisible(true);
    myJFrame.getContentPane().add(new AreaForText());
    myJFrame.addMouseListener(new AreaForText());

}

public void mouseClicked(MouseEvent me) {
    //Save the coordinates of the click lke this. 
    xpos = MouseInfo.getPointerInfo().getLocation().x; 
    ypos = MouseInfo.getPointerInfo().getLocation().y;
    System.out.print("Click" + "  x: " + xpos + "  y: " + ypos);
    myJFrame.invalidate();
    repaint();
    revalidate();
}


public void mouseEntered(MouseEvent e){
}

public void mouseReleased(MouseEvent e) { 
}

public void mousePressed(MouseEvent e) {
}

public void mouseExited(MouseEvent e) { 
}

public void paint(Graphics g) {

    System.out.print("hello");
    g.drawString("Hello World", 30, 80);
    g.fillRect(20,20,20,20);        
    g.drawString("("+xpos+","+ypos+")",xpos,ypos);

    }
}

class EnlargeText {

    public static void main(String args[]) {

       AreaForText test = new AreaForText();

       test.setJFrame();

    }

 } 

【问题讨论】:

  • 干得好,包括一个工作代码示例,在您的第一个问题上格式正确!
  • 代码中不需要使用invalidate()和revalidate()。

标签: java awt jframe validation repaint


【解决方案1】:

您没有调用 JFrames repaint() 您正在调用 JPanel 重绘方法(您所在的类)

试试:

myJFrame.repaint();

【讨论】:

  • 不幸的是,这似乎仍然没有重新绘制我的 JFrame。我是否正确地认为如果它被重新绘制然后在我的绘制方法中它会输出“你好”(在控制台中)我已经监控控制台寻找你好不幸的是无济于事。
【解决方案2】:

您正在创建 2 个 AreaForText 实例,这不是您想要做的。一个添加到 JFrame,一个添加到侦听器。因此,实际获取鼠标事件并调用 repaint 的对象与正在显示的对象不同。

您的某些代码组织不是最好的。您有一个 JPanel 子类,它构建自己的 JFrame 并将自己放入面板中。如果你真的需要它,你应该只传递 JFrame。我在下面做了一些更改。

编辑。我修复了一些鼠标监听器的东西,你得到了错误的 X/Y 坐标,而且,你应该直接将监听器添加到面板,而不是 JFrame,这样你就不必翻译坐标。

EDIT 我将paint 方法更改为paintComponent,这是此处要覆盖的首选方法。请查看Swing Paint Tutorial 了解更多信息。

import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.MouseInfo;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;

import javax.swing.JFrame;
import javax.swing.JPanel;

class AreaForText extends JPanel implements MouseListener {

    private int xpos;
    private int ypos;


    public AreaForText() {
        super();
        this.addMouseListener(this);
    }

    public void mouseClicked(MouseEvent me) {
        // Save the coordinates of the click lke this.
        xpos = me.getX();
        ypos = me.getY();
        System.out.print("Click" + "  x: " + xpos + "  y: " + ypos);
        repaint();
    }

    public void mouseEntered(MouseEvent e) {
    }

    public void mouseReleased(MouseEvent e) {
    }

    public void mousePressed(MouseEvent e) {
    }

    public void mouseExited(MouseEvent e) {
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        System.out.print("hello");
        g.drawString("Hello World", 30, 80);
        g.fillRect(20, 20, 20, 20);
        g.drawString("(" + xpos + "," + ypos + ")", xpos, ypos);

    }
}

class EnlargeText {

    public static void main(String args[]) {

        EventQueue.invokeLater(new Runnable() {
            public void run() {
                JFrame myJFrame = new JFrame("Bigger Text!");
                myJFrame.setSize(300, 150);
                myJFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                myJFrame.getContentPane().add(new AreaForText());
                myJFrame.setVisible(true);
            }
        });
    }

}

【讨论】:

  • 另外,如果你想要这两个类(EnlargeText 和 AreaForText),你应该把它们分成单独的文件,或者有一个作为嵌套的静态类。
  • @Mr Tickle 如果你想知道EventQueue.invokeLater,看看here
  • 太棒了!感谢您帮助我 a) 解决我的问题 b) 提高​​我的整体技术 - 我必须确保我阅读了 EventQueue.invokeLater。这个 Stack 溢出是一个多么出色的网站,用于寻求帮助:D
  • @Mr Tickle 另外不要忘记将帮助您的答案标记为正确的解决方案:)
猜你喜欢
  • 2014-11-07
  • 2017-01-18
  • 2010-09-27
  • 2014-08-14
  • 1970-01-01
  • 2011-10-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多