简体   繁体   English

没有JLabel不能调用JPane“ paintComponent”

[英]JPane “paintComponent” can't be called without JLabel

My problem that I am having is that in this code, the line will not draw at all if I get rid of the JLabel from it. 我遇到的问题是,在这段代码中,如果我摆脱了JLabel,这条线根本不会画。 I tested it out and without the JLabel stuff with in it, the paintComponent(Graphics g) won't run at all. 我对其进行了测试,并且其中没有JLabel内容,paintComponent(Graphics g)根本无法运行。 I want to know why this is and why JLabel effects the JPanel like this. 我想知道为什么会这样,为什么JLabel会像这样影响JPanel。

I have read online that sometime the paintComponent(Graphics g) might not run if it is in a infinite loop but i still don't understand how the JLabel would effect this trait. 我已经在线阅读了一些信息,如果paintComponent(Graphics g)处于无限循环中,则有时可能无法运行,但我仍然不了解JLabel将如何影响此特性。

I would guess that it might have to do something with the layout but i don't really understand how layout effects things like this 我猜想它可能必须对布局做些什么,但我不太了解布局如何影响这样的事情

MouseAction Class MouseAction类

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,%d\n",mouse.getX(),mouse.getY());
                statusBar.setText(String.format("%d,%d",mouse.getX(),mouse.getY()));
            }
        }
    }
}

GraphicsPanel class GraphicsPanel类

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();
    }
}

MainProg class MainProg类

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);
    }
}

EDIT: Code now contains double buffering and been revamped so the GraphicsPanel doesn't instantiate multiple of time how ever the issue of not be able to remove JLabel without breaking the program continues. 编辑:代码现在包含双缓冲并已进行了修改,因此GraphicsPanel不会实例化多个时间,但是在不中断程序的情况下无法删除JLabel的问题仍在继续。

EDIT 2: after some messing around with the window after removing the JLabel, It seems to only work when i dragged on the screen,resized the window and then drag on the screen again. 编辑2:删除JLabel后,在与窗口弄乱后,似乎只在我在屏幕上拖动,调整窗口大小然后再次在屏幕上拖动时才起作用。 So it would seem there is some jpanel layout error which some how gets fixed by the jlabel being there. 因此,似乎存在一些jpanel布局错误,并且该错误由jlabel在那里得到解决。

First problem with your code is that you instanciate graphics at each mouseDragged event. 代码的第一个问题是在每个mouseDragged事件中实例化graphics This is weird and bad. 这很奇怪也很糟糕。 You must only handle each mouseDragged , store the coordinates and call repaint on the single graphics instance created and added to the interface at the beginning. 您只必须处理每个mouseDragged ,存储坐标并在创建并在开始时添加到接口的单个graphics实例上调用repaint This will cause a refresh. 这将导致刷新。

Second, the paintComponent should just make the drawings so you must use some kind of (1) double buffering (create a off-line BufferedImage and its associated Graphics , draw into it and use it in the refresh), (2) collection of Point caught in mouseDragged and use them to drawPolyline in the paintComponent method. 其次, paintComponent应该只是绘制图形,所以您必须使用某种(1)双重缓冲(创建离线BufferedImage及其相关的Graphics ,将其绘制并刷新使用),(2) Point集合陷入mouseDragged并用它们来drawPolylinepaintComponent方法。


Third don't call repaint() inside paintComponent . 第三,不要在paintComponent内调用repaint() This will unnecessarily triggers calls to paintComponent in a kind of never ending loop. 这将以一种paintComponent无休止的循环不必要地触发对paintComponent调用。

Fourthly don't create a double buffer each time paint is called. 第四,不要在每次调用paint创建一个双缓冲区。 At each refresh you will create a new Image . 每次刷新时,您都会创建一个新的Image Create it once, draw in it in your mouseDragged method and trigger from it a repaint() , then make a drawImage in paintComponent . 创建一次,在mouseDragged方法中绘制它,并从中触发一个repaint() ,然后在paintComponent创建一个drawImage

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM