Java 重新喷漆赢得';在for循环只有两帧的情况下逃逸之前,不会发生这种情况
我正在尝试做一些基本的Java,我的框架中有一个形状。它使用一个JComponent类来绘制形状,通过在顶部单击按钮来触发动画 组件代码就是这样添加到jpanel中的Java 重新喷漆赢得';在for循环只有两帧的情况下逃逸之前,不会发生这种情况,java,animation,jcomponent,Java,Animation,Jcomponent,我正在尝试做一些基本的Java,我的框架中有一个形状。它使用一个JComponent类来绘制形状,通过在顶部单击按钮来触发动画 组件代码就是这样添加到jpanel中的 public void paintComponent(Graphics g){ Dimension dim = getSize(); g.setColor(Color.GREEN); g.fillOval(margin, 150, 100, 100); super.pain
public void paintComponent(Graphics g){
Dimension dim = getSize();
g.setColor(Color.GREEN);
g.fillOval(margin, 150, 100, 100);
super.paintComponent(g);
}
动画是在for循环中完成的,该循环只编辑左边界,使圆向右移动
int getMarg = cc.getMargin();
for(int i = 1;i < 20;i++){
getMarg = cc.getMargin();
cc.setMargin(getMarg + 1);
reValidate();
System.out.println(i);
int-getMarg=cc.getMargin();
对于(inti=1;i<20;i++){
getMarg=cc.getMargin();
抄送setMargin(getMarg+1);
重新验证();
系统输出打印LN(i);
但它似乎直到循环结束才移动,一次移动20个像素。我以前有一个睡眠功能,但当它没有动画时,它似乎毫无意义
有什么见解吗?干杯
所有感兴趣的人都可以使用完整的代码,代码凌乱,主要是为了获得样式:
class Main extends JFrame{
public JPanel panel = new JPanel();
JButton button1 = new JButton("Move Right");
CreateComps cc = new CreateComps();
Main(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initUI();
}
void initUI(){
setSize(800,800);
setBackground(Color.GRAY);
setLayout(new BoxLayout(this.getContentPane(), BoxLayout.Y_AXIS));
JPanel topBar = new JPanel();
topBar.setPreferredSize(new Dimension(800,30));
topBar.setMaximumSize(new Dimension(800,30));
topBar.setLayout(new BorderLayout());
topBar.add(button1, BorderLayout.WEST);
topBar.setBackground(Color.GRAY);
JPanel container = new JPanel();
container.setLayout(new GridBagLayout());
container.setBackground(Color.DARK_GRAY);
panel.setPreferredSize(new Dimension(600,500));
panel.setMinimumSize(new Dimension(600,500));
panel.setBackground(Color.WHITE);
panel.setLayout(new BorderLayout());
panel.add(cc, BorderLayout.CENTER);
add(topBar);
add(container);
container.add(panel);
Listener listen = new Listener();
button1.addActionListener(listen);
setVisible(true);
}
public void reValidate(){
panel.revalidate();
panel.repaint();
}
public static void main (String[] args){
Main main = new Main();
}
class Listener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Listening..");
if(e.getSource().equals(button1)){
int getMarg = cc.getMargin();
for(int i = 1;i < 20;i++){
getMarg = cc.getMargin();
cc.setMargin(getMarg + 1);
reValidate();
System.out.println(i);
}
}
}
}
}
class CreateComps extends JComponent{
int margin = 10;
public void setMargin(int marg){
margin = marg;
}
public int getMargin(){
return margin;
}
@Override
public Dimension getPreferredSize(){
return new Dimension(new Dimension(200,200));
}
@Override
public Dimension getMaximumSize(){
return new Dimension(new Dimension(200,200));
}
@Override
public Dimension getMinimumSize(){
return new Dimension(new Dimension(200,200));
}
public void paintComponent(Graphics g){
Dimension dim = getSize();
g.setColor(Color.GREEN);
g.fillOval(margin, 150, 100, 100);
super.paintComponent(g);
}
class Main扩展JFrame{
公共JPanel面板=新JPanel();
JButton button1=新JButton(“向右移动”);
CreateComps cc=新建CreateComps();
Main(){
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
initUI();
}
void initUI(){
设置大小(800800);
挫折背景(颜色:灰色);
setLayout(新的BoxLayout(this.getContentPane(),BoxLayout.Y_轴));
JPanel topBar=新的JPanel();
topBar.setPreferredSize(新尺寸(800,30));
顶杆设置最大尺寸(新尺寸(800,30));
setLayout(新的BorderLayout());
添加(按钮1,边框布局。西);
顶栏。立根背景(颜色。灰色);
JPanel容器=新的JPanel();
setLayout(新的GridBagLayout());
容器.立根(颜色.深灰色);
面板。设置首选尺寸(新尺寸(600500));
面板设置最小尺寸(新尺寸(600500));
面板.立根背景(颜色.白色);
panel.setLayout(新的BorderLayout());
面板.添加(cc,BorderLayout.CENTER);
添加(顶栏);
添加(容器);
容器。添加(面板);
Listener listen=新的Listener();
按钮1.addActionListener(监听);
setVisible(真);
}
公共无效重新验证日期(){
panel.revalidate();
panel.repaint();
}
公共静态void main(字符串[]args){
Main Main=新Main();
}
类侦听器实现ActionListener{
@凌驾
已执行的公共无效操作(操作事件e){
System.out.println(“侦听…”);
如果(例如getSource()等于(按钮1)){
int getMarg=cc.getMargin();
对于(inti=1;i<20;i++){
getMarg=cc.getMargin();
抄送setMargin(getMarg+1);
重新验证();
系统输出打印LN(i);
}
}
}
}
}
类CreateComps扩展了JComponent{
整数裕度=10;
公共空白设定保证金(整数保证金){
保证金=保证金;
}
公共int getMargin(){
收益率;
}
@凌驾
公共维度getPreferredSize(){
返回新维度(新维度(200200));
}
@凌驾
公共维度getMaximumSize(){
返回新维度(新维度(200200));
}
@凌驾
公共维度getMinimumSize(){
返回新维度(新维度(200200));
}
公共组件(图形g){
维度dim=getSize();
g、 setColor(Color.GREEN);
g、 圆角(边缘,150100100);
超级组件(g);
}
}如果不暂停,您将调用堆叠到
重新验证
,只会看到最后一次调用的结果
您以前拥有的sleep函数可能是在上调用的,这一点都不好,因为您正在阻止整个事件调度和GUI更新
考虑对另一个线程使用sleep
调用:
@Override
public void actionPerformed(final ActionEvent e) {
System.out.println("Listening..");
if (e.getSource().equals(button1)) {
new Thread() {
@Override
public void run() {
int getMarg = cc.getMargin();
for (int i = 1; i < 20; i++) {
getMarg = cc.getMargin();
cc.setMargin(getMarg + 1);
reValidate();
System.out.println(i);
try {
Thread.sleep(50);
} catch (Throwable e) {
}
}
}
}.start();
}
}
@覆盖
已执行的公共无效行动(最终行动事件e){
System.out.println(“侦听…”);
如果(例如getSource()等于(按钮1)){
新线程(){
@凌驾
公开募捐{
int getMarg=cc.getMargin();
对于(int i=1;i<20;i++){
getMarg=cc.getMargin();
抄送setMargin(getMarg+1);
重新验证();
系统输出打印LN(i);
试一试{
睡眠(50);
}捕获(可丢弃的e){
}
}
}
}.start();
}
}
或者您也可以简单地使用a,这对此工作非常有用。不停顿地将调用堆叠到revalidate
,只会看到最后一次调用的结果
您以前拥有的sleep函数可能是在上调用的,这一点都不好,因为您正在阻止整个事件调度和GUI更新
考虑对另一个线程使用sleep
调用:
@Override
public void actionPerformed(final ActionEvent e) {
System.out.println("Listening..");
if (e.getSource().equals(button1)) {
new Thread() {
@Override
public void run() {
int getMarg = cc.getMargin();
for (int i = 1; i < 20; i++) {
getMarg = cc.getMargin();
cc.setMargin(getMarg + 1);
reValidate();
System.out.println(i);
try {
Thread.sleep(50);
} catch (Throwable e) {
}
}
}
}.start();
}
}
@覆盖
已执行的公共无效行动(最终行动事件e){
System.out.println(“侦听…”);
如果(例如getSource()等于(按钮1)){
新线程(){
@凌驾
公开募捐{
int getMarg=cc.getMargin();
对于(int i=1;i<20;i++){
getMarg=cc.getMargin();
抄送setMargin(getMarg+1);
重新验证();
系统输出打印LN(i);
试一试{
睡眠(50);
}捕获(可丢弃的e){
}
}
}
}.start();
}
}
或者你也可以简单地使用a,这对这项工作很好。虽然这确实说明了问题的核心(紧循环/在EDT上睡觉),但我不能否定这样一个答案,即在这么小的一段代码中存在如此大量的错误做法。这一次,Swing中几乎每个类都有Swing不是线程安全的