[英]I'm trying to make chart with a string of number but if I try to repaint my paintComponent(Graphics g) method won't be called
I'm trying to make chart with a string of number but if I try to repaint my paintComponent(Graphics g) method won't be called. 我正在尝试使用数字字符串制作图表,但是如果我尝试重绘我的paintComponent(Graphics g)方法,将不会调用该方法。 I debugged the file and i really don't understand why this happens.
我调试了文件,但我真的不明白为什么会这样。 This class extends JPanel and the method: "verwerkData(String s)" is called when I press a button on my JFrame.
此类扩展了JPanel,当我按下JFrame上的按钮时,将调用方法“ verwerkData(String s)”。
Try-catch is used because when I start the program paintComponent(Graphics g) is called and "punt" and "punti" aren't initialized yet that's why i throw a NullPointerException. 使用try-catch是因为启动程序时调用了paintComponent(Graphics g),并且尚未初始化“ punt”和“ punti”,这就是为什么我抛出NullPointerException的原因。
package grafiek;
import java.awt.Graphics;
public class Grafiek extends javax.swing.JPanel {
private String[] punt;
private int[] punti;
private int afstandX, afstandY, puntX1=0, puntY1=0, puntX2=0, puntY2=0;
private int max=0;
/**
* Creates new form Grafiek
*/
public Grafiek() {
initComponents();
}
@Override
public void paintComponent(Graphics g) {
try{
for(int i=0; i<punti.length; i++) {
if(max >= punti[i]) {
max = punti[i];
}
}
afstandX = getWidth()/punt.length;
afstandY = getHeight()/max;
for(int i=0; i<punti.length; i++) {
puntX1 = puntX2;
puntY1 = puntY2;
puntX2 += afstandX;
puntY2 = punti[i]*afstandY;
System.out.println(puntX1+" "+puntY1+" "+puntX2+" "+puntY2);
g.drawLine(puntX1, puntY1, puntX2, puntY2);
}
}catch(java.lang.NullPointerException npe) {
super.paintComponent(g);
}
}
public void verwerkData(String s) {
punt = s.split(" ");
punti = new int[punt.length];
for(int i=0; i<punt.length; i++) {
punti[i] = Integer.parseInt(punt[i]);
}
repaint();
}
/**
* This method is called from within the constructor to initialize the form.
* WARNING: Do NOT modify this code. The content of this method is always
* regenerated by the Form Editor.
*/
@SuppressWarnings("unchecked")
// <editor-fold defaultstate="collapsed" desc="Generated Code">
private void initComponents() {
setBackground(new java.awt.Color(204, 204, 204));
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
this.setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 300, Short.MAX_VALUE)
);
}// </editor-fold>
}
EDIT : When you call
repaint()
, you only tell the system to callpaintComponent()
as soon as possible.编辑:当您调用
repaint()
,您只告诉系统尽快调用paintComponent()
。 But the actual call topaintComponent()
is done by another thread (the Event dispatch thread).但是对
paintComponent()
的实际调用是由另一个线程(事件分发线程)完成的。 This is explained well in the Swing Custom Painting Tutorial在Swing自定义绘画教程中对此进行了很好的解释
The computation of max
was wrong: max
remained zero, which caused an ArithmeticException
due to division by zero. max
的计算是错误的: max
保持为零,这由于除以零而导致ArithmeticException
。 This may already have messed up some things. 这可能已经弄乱了一些东西。 Fixing this and inserting a
main
method caused the program to run properly for me, and to display the data... somehow. 解决此问题并插入
main
方法导致该程序对我来说正常运行,并以某种方式显示数据。
Apart from that: NEVER catch a NullPointerException
. 除此之外: 永远不要捕获
NullPointerException
。 Instead, check whether the respective variables are null
, and skip further computations if necessary. 相反,请检查各个变量是否为
null
,并在必要时跳过进一步的计算。
The initComponents
method is useless here (I don't really like these "Visual GUI Builders", but some may find them convenient). 这里的
initComponents
方法是没有用的(我不太喜欢这些“ Visual GUI Builders”,但有些人会发现它们很方便)。
Another very general hint: You should try to keep the scope of variables as small as possible !. 另一个非常笼统的提示:您应尝试将变量的范围保持尽可能小 ! Particularly, the variables
afstandX .... puntY2
are only needed in paintComponent
. 特别是, 仅在
paintComponent
需要变量afstandX .... puntY2
。 So you should also declare them in paintComponent
. 因此,您还应该在
paintComponent
声明它们。
Your way of drawing the lines was not perfect. 您画线的方式并不完美。 It worked partially, but some variables have not been reset to zero (which is related to the previous point that I mentioned), and the fact that all computations are made with
int
values may have undesirable effects. 它部分起作用,但是一些变量尚未重置为零(这与我提到的上一点有关),并且所有计算都是使用
int
值进行的事实可能会产生不良影响。
A slightly cleaned up MCVE . 稍微清理一下MCVE 。 One could go very far with further improvements, but then, this answer would become "A tutorial for writing a line-chart plotter", which is beyond the scope that such an answer should have.
可以进行进一步的改进,这可能会走得很远,但随后,该答案将变成“编写线图绘图仪的教程”,这超出了该答案应有的范围。 If you want to draw sophisticated line charts, you should consider using an appropriate library, as it was already suggested in the comments.
如果要绘制复杂的折线图,则应考虑使用适当的库,如注释中已建议的那样。
package stackoverflow;
import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Grafiek extends javax.swing.JPanel {
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Grafiek g = new Grafiek();
g.verwerkData("50 100 60 90 70 80");
f.getContentPane().add(g);
f.setSize(300,300);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
private String[] punt;
private int[] punti;
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
System.out.println("paintComponent is being called!");
if (punt == null || punti == null)
{
return;
}
int max = Integer.MIN_VALUE;
for(int i=0; i<punti.length; i++) {
if(max < punti[i]) {
max = punti[i];
}
}
int afstandX = getWidth()/(punt.length-1);
int afstandY = getHeight()/max;
int puntX1 = 0;
int puntY1 = punti[0] * afstandY;
for(int i=1; i<punti.length; i++) {
int puntX2 = puntX1 + afstandX;
int puntY2 = punti[i]*afstandY;
System.out.println(puntX1+" "+puntY1+" "+puntX2+" "+puntY2);
g.drawLine(puntX1, puntY1, puntX2, puntY2);
puntX1 = puntX2;
puntY1 = puntY2;
}
}
public void verwerkData(String s) {
punt = s.split(" ");
punti = new int[punt.length];
for(int i=0; i<punt.length; i++) {
punti[i] = Integer.parseInt(punt[i]);
}
repaint();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.