我需要在表单上显示大量(500+)个小圆圈来模拟LED。但是,这些圆圈需要非常小,直径大约为8或9像素。
到目前为止,在我的测试中,我已经整理了一些代码,这些代码创建了一个使用Shape(Ellipse2D.Double)的Led类,并直接在JFrame的paint方法中显示它。
这让我有两个观察/问题:
1)首先,除非有替代方法,否则Java在绘制小圆圈时似乎有问题。它们似乎在右下角“打破”,笔宽为默认值(或1像素),这会使这部分切掉,留下变形的圆圈。如果有任何方法我可以绘制(很多)小圆圈并让它们看起来正确吗?
2)我的子类JFrame重写了paint方法来绘制这些'leds',尽管也调用super.paint来确保绘制JFrame。然而,我看到它很少在第一次出现时绘制LED,或者当窗体移出屏幕并返回时,或者当它放在前面并再次移开的应用程序时,以及绘制方法的唯一时间当我最小化/最大化表格时调用。每次表格需要绘画时都不应该调画吗?
答案 0 :(得分:3)
你不应该覆盖paint()。请改用paintComponent()。此外,JFrames有些奇怪,我会使用JPanel作为我的BaseClass。
关于你的观察:这可能是由抗锯齿引起的吗?您是否尝试通过setRenderingHints()来关闭抗锯齿?
编辑:在下面的评论之后,我写了一个小测试程序。圈子看起来很不错:import javax.swing.*;
import java.awt.Graphics2D;
import java.awt.Graphics;
import java.awt.Dimension;
import java.awt.RenderingHints;
class Test extends JFrame {
public Test() {
setContentPane(new JPanel() {
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (int i = 0; i < 500; i++){
int x = (int) (Math.random() * getWidth());
int y = (int) (Math.random() * getHeight());
g.fillOval(x,y,8,8);
}
}
});
}
public static void main(String[] args){
Test t = new Test();
t.setSize(new Dimension(640, 480));
t.setVisible(true);
}
}
答案 1 :(得分:2)
我一直在讨论这个问题一段时间,结果与这里描述的结果类似,当我最终得知fillOval()比drawOval()做得更好的事实。或Ellipse2D。以下略显苛刻的方法让我得到了我所需要的东西:
g2d.setColor(Color.black);
g2d.fillOval((int)x, (int)(y - w / 2), (int)w, (int)w);
g2d.setColor(Color.white);
g2d.fillOval((int)x+1, (int)(y - w / 2)+1, (int)w-2, (int)w-2);
答案 2 :(得分:1)
这些LED应该是与表单上其他所有内容相同的组件。我认为您应该使用图标,可能ImageIcon
来表示您的LED。这样,您基本上可以将它们渲染一次,然后在需要时显示相同的图像。您可以使用图像,因为这样您就可以使用具有您想要看到的形状的图像。
答案 3 :(得分:1)
就'break'而言,我会看一下你的图形对象的斜角设置。
但是,我建议在程序启动时读取.png,然后显示它而不是自己绘制。
RE:paint()没有一直被调用。
是的,这就是它的工作原理。如果您需要在特定时间重新绘制组件,则需要强制它。调用repaint()强制重绘。如果你打算从另一个线程(即一个计时器线程)调用repaint(),请确保将调用包装在SwingUtilities.invokeLater()中:
SwingUtilities.invokeLater( new Runnable()
{
@Override
public void run()
{
myForm.repaint();
}
} );
更新:也许你应该发布一些代码......我把一个小测试应用程序放在一起,并没有看到小圆圈的任何问题。
public class MyPanel extends JPanel
{
public void paint(Graphics _g)
{
Graphics2D g = (Graphics2D) _g;
g.setStroke( new BasicStroke(1f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND) );
for(int x = 10, w = 1; w < 20; x += w*2, w++)
{
Ellipse2D.Double ed = new Ellipse2D.Double(x, 10, w, w);
g.fill( ed );
}
for(int x = 10, w = 1; w < 20; x += w*2, w++)
{
Ellipse2D.Double ed = new Ellipse2D.Double(x, 80, w, w);
g.draw( ed );
}
}
public static void main(String[] args)
{
JFrame frame = new JFrame();
frame.add( new MyPanel() );
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.setSize( 400, 400 );
frame.setVisible( true );
}
}
我尝试改变中风参数,看看我是否可以造成视力中断但是不成功。你看到了什么?
不要击败死马,但当我放大该程序的输出时,我的圆圈几乎是对称的,减去左边的一个小像素:
这与你得到的相似吗?