我正在研究java中的动画类程序和可视化。我正在使用swing
和awt
库。我查看了十几个这样的实现,并且当他们想要在JFrame上绘制形状时,所有这些实现都使用paint
Component方法然后使用repaint()
。
是否有一些方法可以从我想要的任何类中调用,例如可以更改单个像素值?
我还想制作一个带有形状的数组列表:
ArrayList<Rectangle> rectangles = new ArrayList<Rectangle>();
我很好奇如何添加东西。 我在想:
Rectangle rect = "something"
rectangles.add(rect);
但我不确定应该是什么。 我对此比较陌生,所以如果我遗漏了一些明显的东西,请随时表达你的观点。
答案 0 :(得分:3)
是否有一些方法可以从我想要的任何类中调用,例如可以更改单个像素值?
您可以创建一个BufferedImage,它具有setRGB(...)
方法,可以通过使用Graphics paintComponent(...)
方法在drawImage(...)
方法中绘制图像来实现您想要的效果。
关于Rectangle rect = "something"
- 只需在Rectangle API中查找可用的Rectangle构造函数,并使用最合适的构造函数。
答案 1 :(得分:1)
有人建议您使用getGraphics
而不是paintComponent
,让我们看一下......
哦,哦,这并不像我们期望的那样完美!我们甚至会忽略为什么你不应该直接绘制到顶级容器(导致在标题栏下绘画)
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JButton draw = new JButton("Draw");
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(draw);
frame.setSize(150, 150);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
draw.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
drawARectangle(frame.getGraphics());
}
});
}
});
}
public void drawARectangle(Graphics g) {
g.setColor(Color.RED);
g.fillRect(20, 20, 100, 100);
}
}
好的,我们来看看paintComponent
和repaint
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private boolean drawBox;
public TestPane() {
setLayout(new GridBagLayout());
JButton draw = new JButton("Draw");
add(draw);
draw.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
drawBox = !drawBox;
repaint();
}
});
}
@Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (drawBox) {
g.setColor(Color.RED);
g.fillRect(20, 20, 100, 100);
}
}
}
}
Swing有完整记录的绘画过程,请查看Painting in AWT and Swing和Performing Custom Painting以获取更多详细信息,其中一个应该在API的设计中工作。
在有人跳下我的喉咙并建议你可以使用WindowListener
或ContainerListener
或其他听众之前,答案是,为什么? paintComponent
工作正常。
Swing使用被动渲染引擎,这意味着绘画可能由于多种原因而发生,大多数时候你没有实例化或了解,所以除非你链接到绘画过程,否则你不会知道它发生了,调整大小只是展示它的一种非常好的方式
因此,我们可以停止建议使用getGraphics
或使用null
布局或KeyListener
或DocumentListener
等错误方法来实时过滤文本组件,也许我们可以保存一群人一堆头痛
答案 2 :(得分:-2)
当我打电话给每个人使用重绘()时,我显然是在咆哮;这是更好的方式。 假设我想在jframe上创建一个矩形或图像或线条或椭圆,
public JFrame frame = new JFrame();
public void paintingHome(){
//设置jframe和东西
System.out.println(“这是一个矩形”);
paintARectangle(frame.getGraphics(),42,256);
}
public void paintARectangle(Graphics g,int xCoord,int yCoord,int width,int height){
g.fillRact(xCoord,yCoord,width,height);
//这很简单 }
//你可以拥有你想要的任意数量 public void paintWhatever(Graphics g,Something whatever){
g.doSomethingWith(无论);
//在oracle发布版本238249.3432.4之前不会真正起作用 }
//关键是使用frame.getGraphics()方法
//重绘是不必要的和限制性的