[英]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
并用它们来drawPolyline
中paintComponent
方法。
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.