我遇到的问题是,在这段代码中,如果我从中删除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来解决。答案 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
。