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

时间:2015-06-11 14:21:31

标签: java swing user-interface jpanel jlabel

我遇到的问题是,在这段代码中,如果我从中删除JLabel,则该行根本不会绘制。我测试了它,没有JLabel的东西,paintComponent(Graphics g)根本没有运行。我想知道为什么会这样,以及为什么JLabel会像这样影响JPanel。

我在网上看过,如果paintComponent(Graphics g)处于无限循环中,那么它可能无法运行,但我仍然不了解JLabel如何影响这个特性。

我猜它可能需要对布局做些什么,但我真的不明白布局如何影响这样的事情

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类

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类

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来解决。

1 个答案:

答案 0 :(得分:1)

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

其次,paintComponent应该只是制作图纸,所以你必须使用某种(1)双缓冲(创建一个离线BufferedImage及其相关的Graphics,它并在刷新中使用它,(2)Point中收集的mouseDragged并在drawPolyline方法中将它们用于paintComponent

第三个不要在repaint()内拨打paintComponent。这将在一种永无止境的循环中不必要地触发对paintComponent的调用。

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