我首先要说的是,我几乎可以保证这个问题将是一个副本,但我找不到任何其他适合我的需求/适用于我的程序的答案。我需要在 JPanel
上绘图,但我似乎无法让我需要绘制的线条显示出来。
JFrame drawF = new JFrame("Simulator");
JPanel simPanel = new JPanel();
drawF.setVisible(true);
drawF.setSize(1000,650);
drawF.add(simPanel);
drawF.pack();
simPanel.setLayout(null);
simPanel.setSize(1000,650);
simPanel.setVisible(true);
simPanel.setBackground(Color.BLACK);
//add drawing surface
//start drawing
simPanel.add(new JComponent()
{
public void paint(Graphics g)
{
g.setColor(Color.RED);
int xLast,yLast;
for(int i=0;i < 5000000; i++) // five million
{
double dX = (Math.E*Math.exp(-numd1*i)*Math.sin(i*numf1+nump1))+(Math.E*Math.exp(-numd2*i)*Math.sin(i*numf2*nump2));
double dY = (Math.E*Math.exp(-numd3*i)*Math.sin(i*numf3+nump3))+(Math.E*Math.exp(-numd4*i)*Math.sin(i*numf4*nump4));
int drawX = (int)dX;
int drawY = (int)dY;
if (i==0)
{
xLast = 0;
yLast = 0;
g.drawLine(xLast,yLast,drawX,drawY);
simPanel.revalidate();
simPanel.repaint();
}
else
{
xLast = drawX;
yLast = drawY;
g.drawLine(xLast,yLast,drawX,drawY);
simPanel.revalidate();
simPanel.repaint();
}
}
}
});
repaint();
向我的 JPanel
添加 JComponent
是否有问题?
最佳答案
您的问题可能是布局管理器之一。 JPanel 默认使用 FlowLayout,因此您的 JComponent 将调整其自然首选大小,即 [0, 0],因此在这种情况下不会显示任何内容。尝试将 JPanel 的布局设为 BorderLayout 并添加 JComponent BorderLayout.CENTER。
其他问题:
- 重写 JComponent 的 PaintComponent 方法,而不是 Paint 方法,否则您将因不考虑边框和子项的绘制而面临意外副作用的风险。
- 如果您按照我的建议重写paintComponent,请在您的重写中调用super的绘制方法,
super.paintComponent(g);
。这将有助于清理所有脏像素。 - 摆脱所有不必要的重绘、重新验证和 setVisible 调用。
- 将所有组件添加到 GUI 后,在 JFrame 上调用 setVisible。
- 就我个人而言,我更喜欢在 JPanel 的 PaintComponent 方法中进行绘制,而不是在 JComponent 中进行绘制,因为它不会自动绘制背景。
- 而且我更喜欢在自己的独立类中进行绘画,而不是埋藏在匿名内部类中。这个功能太重要了,不能以这种方式埋葬。
- 您在绘画方法中调用的运行时间越长或 CPU 密集型代码越多,您的 GUI 的响应速度就越慢。卸载类的构造函数中的 for 循环和数学计算以及绘画方法。将结果存储在数组或列表中,或者如果您希望绘制 BufferedImage,然后在 PaintComponent 方法中显示该图像。
例如:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.*;
@SuppressWarnings("serial")
public class DrawingStuff extends JPanel {
private static final int PREF_W = 1000;
private static final int PREF_H = 650;
private static final Color BG = Color.BLACK;
private static final Color GRAPHICS_COLOR = Color.RED;
private static final int LOOP_COUNT = 5000000; // 5 million
private BufferedImage image = null;
private MathParams[] params;
public DrawingStuff(MathParams[] params) {
this.params = params;
setBackground(BG);
image = drawImage();
}
private BufferedImage drawImage() {
BufferedImage img = new BufferedImage(PREF_W, PREF_H, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
g2.setColor(GRAPHICS_COLOR);
int xLast, yLast;
for (int i = 0; i < LOOP_COUNT; i++) {
double dX = params[0].doCalc0(i) + params[1].doCalc1(i);
double dY = params[2].doCalc0(i) + params[3].doCalc1(i);
int drawX = (int) dX;
int drawY = (int) dY;
if (i == 0) {
xLast = 0;
yLast = 0;
g2.drawLine(xLast, yLast, drawX, drawY);
} else {
xLast = drawX;
yLast = drawY;
g2.drawLine(xLast, yLast, drawX, drawY);
}
}
g2.dispose();
return img;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g.drawImage(image, 0, 0, this);
}
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Drawing Stuff");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// TODO: fix this -- what numbers to use??? These don't work
MathParams[] paramArray = {
new MathParams(1, 2, 3),
new MathParams(1, 2, 3),
new MathParams(3, 4, 5),
new MathParams(3, 4, 5)
};
frame.getContentPane().add(new DrawingStuff(paramArray));
frame.setResizable(false);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
public class MathParams {
private int numd;
private int numf;
private int nump;
public MathParams(int numd, int numf, int nump) {
this.numd = numd;
this.numf = numf;
this.nump = nump;
}
public double doCalc0(int i) {
return (Math.E * Math.exp(-numd * i) * Math.sin(i * numf + nump));
}
public double doCalc1(int i) {
return (Math.E * Math.exp(-numd * i) * Math.sin(i * numf * nump));
}
}
关于java - 在 JPanel 中绘图时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37449227/