没有 JLabel 就无法调用 JPane "paintComponent"
JPane "paintComponent" can't be called without JLabel
我遇到的问题是,在此代码中,如果我从中删除 JLabel,则根本不会绘制线条。我对其进行了测试,如果其中没有 JLabel 的东西, paintComponent(Graphics g) 根本不会 运行 。我想知道这是为什么以及为什么 JLabel 会这样影响 JPanel。
我在网上看到,有时 paintComponent(Graphics g) 可能不会 运行 如果它处于无限循环中,但我仍然不明白 JLabel 将如何影响此特性。
我猜想这可能与布局有关,但我真的不明白布局如何影响这样的事情
鼠标动作Class
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()));
}
}
}
}
图形面板class
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
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 后对 window 进行了一些修改之后,似乎只有当我在屏幕上拖动时才有效,调整 window 的大小然后再次在屏幕上拖动.所以看起来有一些 jpanel 布局错误,其中一些是如何被那里的 jlabel 修复的。
您的代码的第一个问题是您在每个 mouseDragged
事件中实例化了 graphics
。这很奇怪也很糟糕。您必须只处理每个 mouseDragged
,存储坐标并在开始时创建并添加到界面的单个 graphics
实例上调用 repaint
。这将导致刷新。
其次,paintComponent
应该只是制作图纸,因此您必须使用某种 (1) 双缓冲(创建离线 BufferedImage
及其关联的 Graphics
, draw into it and use it in the refresh), (2) 在 mouseDragged
中捕获的 Point
的集合,并将它们用于 paintComponent
方法中的 drawPolyline
。
第三,不要在paintComponent
里面调用repaint()
。这将在一种永无止境的循环中不必要地触发对 paintComponent
的调用。
第四,不要在每次调用 paint
时都创建双缓冲区。在每次刷新时,您将创建一个新的 Image
。创建一次,在您的 mouseDragged
方法中绘制它并从中触发一个 repaint()
,然后在 paintComponent
.
中创建一个 drawImage
我遇到的问题是,在此代码中,如果我从中删除 JLabel,则根本不会绘制线条。我对其进行了测试,如果其中没有 JLabel 的东西, paintComponent(Graphics g) 根本不会 运行 。我想知道这是为什么以及为什么 JLabel 会这样影响 JPanel。
我在网上看到,有时 paintComponent(Graphics g) 可能不会 运行 如果它处于无限循环中,但我仍然不明白 JLabel 将如何影响此特性。
我猜想这可能与布局有关,但我真的不明白布局如何影响这样的事情
鼠标动作Class
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()));
}
}
}
}
图形面板class
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
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 后对 window 进行了一些修改之后,似乎只有当我在屏幕上拖动时才有效,调整 window 的大小然后再次在屏幕上拖动.所以看起来有一些 jpanel 布局错误,其中一些是如何被那里的 jlabel 修复的。
您的代码的第一个问题是您在每个 mouseDragged
事件中实例化了 graphics
。这很奇怪也很糟糕。您必须只处理每个 mouseDragged
,存储坐标并在开始时创建并添加到界面的单个 graphics
实例上调用 repaint
。这将导致刷新。
其次,paintComponent
应该只是制作图纸,因此您必须使用某种 (1) 双缓冲(创建离线 BufferedImage
及其关联的 Graphics
, draw into it and use it in the refresh), (2) 在 mouseDragged
中捕获的 Point
的集合,并将它们用于 paintComponent
方法中的 drawPolyline
。
第三,不要在paintComponent
里面调用repaint()
。这将在一种永无止境的循环中不必要地触发对 paintComponent
的调用。
第四,不要在每次调用 paint
时都创建双缓冲区。在每次刷新时,您将创建一个新的 Image
。创建一次,在您的 mouseDragged
方法中绘制它并从中触发一个 repaint()
,然后在 paintComponent
.
drawImage