我遇到的问题是,在这段代码中,如果我从中摆脱 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
。