没有 JLabel 就无法调用 JPane "paintComponent"



我遇到的问题是,在这段代码中,如果我从中摆脱 JLabel,这条线根本不会画出来。我测试了它,如果没有JLabel的东西,paintComponent(Graphics g)根本无法运行。我想知道为什么会这样,为什么JLabel会这样影响JPanel。

我在网上读到,有时 paintComponent(Graphics g) 如果处于无限循环中,它可能无法运行,但我仍然不明白 JLabel 如何影响这个特征。

我猜它可能必须对布局做一些事情,但我真的不明白布局如何影响这样的事情

鼠标操作类

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

public class MouseAction extends JFrame{
    private JPanel mousePanel;
    private JLabel statusBar;
    private GraphicsPanel g;
    private int xS;
    private int yS;
    public MouseAction (){
        super("Mouse example");
        mousePanel = new JPanel();
        statusBar = new JLabel("Deafault");
        g = new GraphicsPanel(0,0,0,0);

        add(mousePanel, BorderLayout.CENTER);
        add(statusBar, BorderLayout.SOUTH);
        MouseExploits handler = new MouseExploits();
        mousePanel.addMouseListener(handler);
        mousePanel.addMouseMotionListener(handler);

    }
    private class MouseExploits extends MouseAdapter{
        public void mousePressed(MouseEvent mouse){
            if(mouse.isMetaDown()){
                xS= mouse.getX();
                yS= mouse.getY();
            }
        }
        public void mouseDragged(MouseEvent mouse){
            if(!(mouse.isMetaDown() || mouse.isAltDown())){
                g.updateCoordinates(mouse.getX(),mouse.getY(), xS,yS);
                add(g);
                System.out.printf("%d,%dn",mouse.getX(),mouse.getY());
                statusBar.setText(String.format("%d,%d",mouse.getX(),mouse.getY()));
            }
        }
    }
}

图形面板类

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

public class GraphicsPanel extends JPanel{
    private int x;
    private int y;
    private int xS;
    private int yS;
    private Graphics dB;
    private Image dBImage;
    public graphics(int mouseX, int mouseY, int xSm, int ySm){
        x = mouseX;
        y = mouseY;
        xS=xSm;
        yS=ySm;
        //System.out.println("Breaks2");
    }
    public void updateCoordinates(int mouseX, int mouseY, int xSm, int ySm){
        x = mouseX;
        y = mouseY;
        xS=xSm;
        yS=ySm;
        //repaint();
    }
    public void paint(Graphics g){
        dBImage = createImage(getWidth(),getHeight());
        dB = dBImage.getGraphics();
        paintComponent(dB);
        g.drawImage(dBImage,0,0,this);
    }
    public void paintComponent(Graphics g){
        //super.paintComponent(g);
        System.out.println("Breaks3");
        g.drawLine(xS,yS,x,y);
        repaint();
    }
}

主进度类

import javax.swing.JFrame;
public class MainProg {
    public static void main(String args[]){
        MouseAction frameObj= new MouseAction ();
        frameObj.setSize(300,230);
        frameObj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frameObj.setVisible(true);
    }
}

编辑:代码现在包含双缓冲并进行了改进,因此GraphicsPanel不会实例化多个时间,如何在不破坏程序的情况下无法删除JLabel的问题继续存在。

编辑2:删除JLabel后对窗口进行了一些弄乱之后,它似乎仅在我拖动屏幕上,调整窗口大小然后再次在屏幕上拖动时才有效。因此,似乎存在一些jpanel布局错误,这些错误可以通过jlabel在那里修复

代码的第一个问题是在每个mouseDragged事件中实例化graphics。这很奇怪,也很糟糕。您只能处理每个mouseDragged,将坐标和调用repaint存储在开头创建并添加到接口的单个graphics实例上。这将导致刷新。

其次,paintComponent应该只制作绘图,因此您必须使用某种 (1) 双缓冲(创建离线BufferedImage及其关联的Graphics,绘制并用于刷新),(2) 收集mouseDragged中捕获的Point并使用它们在paintComponent方法中drawPolyline


第三不要在paintComponent里面打电话给repaint()。这将不必要地触发对paintComponent的调用,以一种永无止境的循环。

第四,不要在每次调用paint时都创建双缓冲区。每次刷新时,您将创建一个新Image。创建一次,在mouseDragged方法中绘制它并从中触发一个repaint(),然后在paintComponent中创建一个drawImage

相关内容

  • 没有找到相关文章

最新更新