2015-12-15 35 views
0

好的,所以我试图制作一个笑脸表情程序,当它第一次启动它应该显示默认的笑脸(这部分工作,这是很好,我猜)如何从Java中的多个方法中绘制?

但是,那么它应该给你两个按钮从微笑中挑选,皱眉按钮应该重新绘制脸部以显示一个微笑或皱眉,但由于某种原因它不起作用。

我一直在阅读有关的图形和我知道你不应该从油漆(外界称他们)方法,因此我适时改变我的代码,我可以告诉这些按钮的工作,因为我让他们打印出来的东西每次但实际重绘都不起作用。我试过使用repaint()和revalidate()。由于某种原因,如果使用repaint(),每次都会重新绘制越来越多的奇怪图片,但也许它应该是这样的?

可有人请看看代码,让我知道你在想什么是问题或者我应该寻找一个解决方案,我用java一段时间,但我从来没有使用图形:/我已经阅读你应该在最后使用setVisible/setSize(或pack()),这实际上帮助我解决了一些问题,但是当你想绘制多个东西时,我不知道该怎么做。大多数示例只显示绘制一个东西。

import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 

public class JSmileFacePanel2 extends JFrame { 

/** 
* 
*/ 
private static final long serialVersionUID = 1L; 

JButton smile = new JButton("SMILE"); 
JButton frown = new JButton("FROWN"); 

public JSmileFacePanel2() { 
    setLayout(new FlowLayout()); 
    setTitle("JSmileFace-V2: Jose M. Tobar"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    add(frown); 
    add(smile); 

    setSize(800, 800); 
    setVisible(true); 
} 

public void paint(Graphics g) { 
    super.paint(g); 
    //by default should show smiling 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 

    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      drawSmile(g); 

     } 
    }); 

    frown.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("FROWN BUTTON CLICKED"); 
      drawFrown(g); 
     } 
    }); 
} 

public void drawSmile(Graphics g) { 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 
    repaint(); 
} 

public void drawFrown(Graphics g) { 
    g.setColor(Color.WHITE); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 
    repaint(); 
} 


public static void main(String[] args) { 
    JSmileFacePanel2 js = new JSmileFacePanel2(); 
} 

} 

回答

1

您仍在调用paint方法之外的绘画方法,因为actionPerformed方法的方法与paint方法不同。它们在文本上并不重要,它仍然是一种不同的方法。

此外,您反复添加每次有一个重绘事件,这将下降到停止减缓你的应用程序,它也不会正确重绘时的动作侦听器。

所以,请检查您是否微笑或皱眉的paint方法内,并添加构造函数中的动作监听器。然后

的代码变为:

import java.awt.Color; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 

import javax.swing.JButton; 
import javax.swing.JFrame; 

public class JSmileFacePanel2 extends JFrame { 

    private static final long serialVersionUID = 1L; 

    // by default should show smiling 
    private boolean doSmile = true; 

    JButton smile = new JButton("SMILE"); 
    JButton frown = new JButton("FROWN"); 

    public JSmileFacePanel2() { 
     setLayout(new FlowLayout()); 
     setTitle("JSmileFace-V2: Jose M. Tobar"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     add(frown); 
     add(smile); 

     smile.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("SMILE BUTTON CLICKED"); 
       doSmile = true; 
       repaint(); 
      } 
     }); 

     frown.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       System.out.println("FROWN BUTTON CLICKED"); 
       doSmile = false; 
       repaint(); 
      } 
     }); 

     setSize(800, 800); 
     setVisible(true); 
    } 

    public void paint(final Graphics g) { 
     super.paint(g); 

     if (doSmile) { 
      drawSmile(g); 
     } else { 
      drawFrown(g); 
     } 
    } 

    public void drawSmile(Graphics g) { 
     g.setColor(Color.YELLOW); 
     g.fillOval(200, 200, 500, 500); 
     g.setColor(Color.BLUE); 
     g.fillOval(300, 360, 50, 50); 
     g.setColor(Color.BLUE); 
     g.fillOval(600, 360, 50, 50); 
     g.drawArc(400, 400, 100, 40, 180, 185); 
    } 

    public void drawFrown(Graphics g) { 
     g.setColor(Color.WHITE); 
     g.fillOval(200, 200, 500, 500); 
     g.setColor(Color.BLUE); 
     g.fillOval(300, 360, 50, 50); 
     g.setColor(Color.BLUE); 
     g.fillOval(600, 360, 50, 50); 
     g.drawArc(400, 400, 100, 40, 180, 185); 
    } 

    public static void main(String[] args) { 
     JSmileFacePanel2 js = new JSmileFacePanel2(); 
    } 

} 
0

主要问题:你加入了很多在你的代码actionlisters的...

...每当repaint()被调用时,它调用内部的paint(Graphics g)方法和您的油漆方法内你”重(一遍又一遍又一遍,只要你重绘)添加的ActionListener

尝试在构造函数中添加的ActionListener:

public JSmileFacePanel2() { 
    setLayout(new FlowLayout()); 
    setTitle("JSmileFace-V2: Jose M. Tobar"); 
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

    add(frown); 
    add(smile); 

    setSize(800, 800); 
    setVisible(true); 


    //here: 
    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      drawSmile(g); 

     } 
    }); 

    frown.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("FROWN BUTTON CLICKED"); 
      drawFrown(g); 
     } 
    }); 

} 
1

总之,没有。但是,你仍然在正确的轨道上。

请记住,您正在事件驱动的环境中运行,这意味着发生了一些事情,然后您对此做出响应。

绘画应该什么都不做更多的则只是油漆的当前状态,在你的榜样,每次paint被调用时,您要添加新的ActionListener的按钮,这样你就可以用连接到每个3+ ActionListener s结尾了只有当屏幕变得可见时,才会产生严重的奇怪行为。

你也不应该直接或间接地从你的paint方法中修改组件的状态,这可能会导致repaint被调度,这将导致你的paint方法被重复调用,最终会消耗你的CPU周期,至少可以说是凌乱。

您还应该避免从顶级容器延伸并覆盖paint(通常),而不是使用JPanel并改为使用paintComponent方法。

这样做的两个主要原因,首先,它会将您锁定为一个用例,这意味着您无法重新使用您的组件,然后直接将其绘制到顶级容器(如JFrame)可能会让您在框架的装饰下绘画/边界,并因为绘画的工作方式,甚至有帧内容画在它上面。

Painting in AWT and SwingPerforming Custom Painting更多细节

一般的解决方法是使用一个标志,以更改您的绘画过程中的作品,当你需要相应地改变该标志的方式(从按钮的ActionListener秒钟内例如)

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.FlowLayout; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
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 JSmileFace { 

    private static final long serialVersionUID = 1L; 

    public static void main(String[] args) { 
     new JSmileFace(); 
    } 

    public JSmileFace() { 
     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.add(new SmilyPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class SmilyPane extends JPanel { 

     JButton smile = new JButton("SMILE"); 
     JButton frown = new JButton("FROWN"); 

     private boolean frowning = false; 

     public SmilyPane() { 
      setLayout(new FlowLayout()); 

      add(frown); 
      add(smile); 

      smile.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        frowning = false; 
        repaint(); 
       } 
      }); 

      frown.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("FROWN BUTTON CLICKED"); 
        frowning = true; 
        repaint(); 
       } 
      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(800, 600); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      super.paintComponent(g); 
      g.setColor(Color.YELLOW); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 

      if (frowning) { 
       drawFrown(g); 
      } else { 
       drawSmile(g); 
      } 
     } 

     public void drawSmile(Graphics g) { 
      g.setColor(Color.YELLOW); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 
     } 

     public void drawFrown(Graphics g) { 
      g.setColor(Color.WHITE); 
      g.fillOval(200, 200, 500, 500); 
      g.setColor(Color.BLUE); 
      g.fillOval(300, 360, 50, 50); 
      g.setColor(Color.BLUE); 
      g.fillOval(600, 360, 50, 50); 
      g.drawArc(400, 400, 100, 40, 180, 185); 
     } 

    } 

} 
0

一个小小的瑕疵: 不叫里面drawFrown(g)drawSmile(g)actionListener(你不能了,你不知道graphics了),而不是调用repaint()

但你repaint()告诉你之前,你的图形什么将(我使用这一个int,更好的使用Enums但它会为现在工作中得出

我只是做smile-一部分,皱眉部分是相同的

private int style = 0; 

public JSmileFacePanel2() { 

    //other code as above 
    ... 

    smile.addActionListener(new ActionListener() { 
     public void actionPerformed(ActionEvent e) { 
      System.out.println("SMILE BUTTON CLICKED"); 
      style = 1; //1=smile, 2=frown 
      repaint(); //this calls internally the paint(g) method 
     } 
    }); 
} 

和调整你的paint方法:

public void paint(Graphics g) { 
    super.paint(g); 
    //by default should show smiling 
    g.setColor(Color.YELLOW); 
    g.fillOval(200, 200, 500, 500); 
    g.setColor(Color.BLUE); 
    g.fillOval(300, 360, 50, 50); 
    g.setColor(Color.BLUE); 
    g.fillOval(600, 360, 50, 50); 
    g.drawArc(400, 400, 100, 40, 180, 185); 

    if(style == 1){ 
     drawSmile(g); 
    } 

    if(style == 2){ 
     drawFrown(g); 
    } 
}