最小化/重新打开窗口后 Java JFrame 重新绘制

标签 java jframe

我有一个程序,可以使用绘制方法将车辆对象(例如汽车形状)绘制到 JFrame 上。然而,每当我单击屏幕来绘制车辆时,我都必须刷新窗 Eloquent 能显示它们即使添加了 repaint() 方法

<小时/>

第一张图片显示了我点击的位置。什么都没发生。

enter image description here

最小化并打开窗口后。

enter image description here

    import java.awt.Graphics;
    import java.awt.Graphics2D;
    import java.awt.event.MouseEvent;
    import java.awt.event.MouseListener;
    import java.util.Iterator;
    import java.util.LinkedList;
    import javax.swing.JFrame;


    /** Program specs: Draws shapes (Vehicles) that are contained within LinkedLists. 
     * When a shape is drawn over another shape it 'joins' its list. (not implemented yet, not my issue)

     */

    /**
      Creates JFrame
    */
    public class FramePanel extends JFrame implements MouseListener
    {
       private static final int FRAME_WIDTH = 600;
       private static final int FRAME_HEIGHT = 600;

       Car car; // Car is a subclass of Vehicle. It only contains a draw method.
       //Vehicle is an abstract class that only contains a draw method

       LinkedList<LinkedList<Vehicle>> list = new LinkedList<LinkedList<Vehicle>>();
       LinkedList<Vehicle> temp = new LinkedList <Vehicle>();

       /**
          Constructs the frame.
       */
       public FramePanel()
       {  
          addMouseListener(this);
          setSize(FRAME_WIDTH, FRAME_HEIGHT);

          repaint();
       }


    @Override
    public void mouseClicked(MouseEvent evt) {

    car = new Car (evt.getX(), evt.getY()); 
    temp.add(car); //Add Vehicle to LinkedList
    list.add(temp); //Add LinkedList to Collection of LinkedLists

    }

    public void mouseEntered(MouseEvent arg0) {}
    public void mouseExited(MouseEvent arg0) {}
    public void mousePressed(MouseEvent arg0) {}
    public void mouseReleased(MouseEvent arg0) {}


    public void paint(Graphics g) {
        super.paintComponents(g) ;
         Graphics2D g2 = (Graphics2D) g;

       for (LinkedList<Vehicle> veh : list){ // list is collection of Linked Lists

        Iterator<Vehicle> it = veh.iterator();
           while (it.hasNext()){
               it.next().draw(g2);
           }  
       }
    }

    public static void main(String[] args)
    {  
       JFrame frame = new FramePanel();
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
       frame.setTitle("Viewer");
       frame.setVisible(true);      
    }

    }
<小时/>

注意:如果我在 Paint(Graphic g) 方法中添加 repaint() 语句,汽车将被绘制,但在构造函数中使用/不使用 repaint() 时会出现不良闪烁。我不想要这个。

最佳答案

mouseClicked 方法的最后一行添加对 repaint() 的调用即可解决此问题。

但是,还有其他几点:

  • 不要扩展 JFrame(尤其是不要重写 JFramepaint 方法)。相反,使用 JPanel 进行绘制,并重写其 paintComponent 方法。
  • 不要让顶级类实现 MouseListener 接口(interface)
  • 请勿将列表声明为 LinkedList,而仅声明为 List ( What does it mean to "program to an interface"? )
  • GUI 应在 Event-Dispatch-Thread 上创建
  • 字段应为私有(private)(如果可能的话,应为最终)

一些清理工作:

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.LinkedList;
import java.util.List;

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

public class FramePanel extends JPanel
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI();
            }
        });
    }

    private static void createAndShowGUI()
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        FramePanel framePanel = new FramePanel();
        f.getContentPane().add(framePanel);

        f.setSize(600,600);
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    private final List<List<Vehicle>> list = new LinkedList<List<Vehicle>>();

    /**
      Constructs the panel.
     */
    public FramePanel()
    {  
        addMouseListener(new MouseAdapter()
        {
            @Override
            public void mouseClicked(MouseEvent e)
            {
                addCarAt(e.getX(), e.getY());
            }
        });
    }

    private void addCarAt(int x, int y)
    {
        Car car = new Car(x, y); 
        List<Vehicle> temp = new LinkedList<Vehicle>();
        temp.add(car); //Add Vehicle to LinkedList
        list.add(temp); //Add LinkedList to Collection of LinkedLists
        repaint();
    }

    @Override
    protected void paintComponent(Graphics gr) 
    {
        super.paintComponent(gr) ;
        Graphics2D g = (Graphics2D)gr;

        for (List<Vehicle> veh : list) // list is collection of Linked Lists
        { 
            for (Vehicle v : veh)
            {
                v.draw(g);
            }  
        }
    }
}

关于最小化/重新打开窗口后 Java JFrame 重新绘制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22736029/

相关文章:

java - 使用 EJB 定时器服务执行外部服务

java - 查找用于选项处理的 WEKA 属性类名称

java - 如何等待 GUI 的输入返回到主程序?

java - ExecutorService 中对 MongoRepository 的调用无法完成

java - MapReduce java.lang.ArrayIndexOutOfBoundsException : 0

java - 在Java中将变量返回到第二帧

java - 从另一个子JFrame发送数据到JFrame而不打开新的JFrame

java - 如何将图像绘制到 JPanel 或 JFrame?

java - 在 JFrame 或打开浏览器中显示 HTML 标记

java - SQLite 查询 - 一旦找到特定项目就停止从数据库返回行