2013-08-19 30 views
0

这个应用程序有两个按钮。一个用于点击时随机更改颜色,另一个用于更改应用中的标签。使用内部类的多个Jbutton和ActionListener

问题是虽然我写了sepreate ActionListener类,并分别注册与他们的通信方法。

每次我点击“更改标签”按钮,颜色也会改变。这里发生了什么?

package my; 
    import java.awt.*; 
    import java.awt.event.*; 
    import java.util.ArrayList; 

    import javax.swing.*; 

    public class SimpleGui3C { 

     JFrame frame; 
     JLabel label; 

     public static void main(String[] args){ 
      SimpleGui3C gui = new SimpleGui3C(); 
      gui.go(); 
     } 

     public void go(){ 
      frame = new JFrame(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

      JButton labelButton = new JButton("Change Label"); 
      labelButton.addActionListener(new LabelListener()); 

      JButton colorButton = new JButton("Change Circle"); 
      colorButton.addActionListener(new ColorListener()); 

      label = new JLabel("I'm a label"); 

      MyDrawPanel drawPanel = new MyDrawPanel(); 

      frame.getContentPane().add(BorderLayout.SOUTH,colorButton); 
      frame.getContentPane().add(BorderLayout.CENTER,drawPanel); 
      frame.getContentPane().add(BorderLayout.EAST, labelButton); 
      frame.getContentPane().add(BorderLayout.WEST, label); 

      frame.setSize(300,300); 
      frame.setVisible(true); 


     } 

     class LabelListener implements ActionListener{ 
      public void actionPerformed(ActionEvent event1) { 
       ArrayList<String> labelContent = new ArrayList<String>(); 
       labelContent.add("Ouch!"); 
       labelContent.add("Damn!"); 
       labelContent.add("Holy shit!"); 
       labelContent.add("WTF?!"); 
       labelContent.add("Stop it!"); 
       labelContent.trimToSize(); 

       int i = (int)(Math.random()*5); 
       String a = (String)labelContent.get(i); 
       label.setText(a); 
      } 
     } 

     class ColorListener implements ActionListener{ 
      public void actionPerformed(ActionEvent event2) { 
       frame.repaint(); 
      } 
     } 
    } 

      package my; 
      import java.awt.*; 
      import javax.swing.*; 

      public class MyDrawPanel extends JPanel{ 
       /** 
       * 
       */ 
       private static final long serialVersionUID = 1L; 

       public void paintComponent(Graphics g){ 
        Graphics2D g2d = (Graphics2D) g; 

        int red = (int)(Math.random()*255); 
        int blue = (int)(Math.random()*255); 
        int green = (int)(Math.random()*255); 
        Color startColor = new Color(red,blue,green); 

        red = (int)(Math.random()*255); 
        blue = (int)(Math.random()*255); 
        green = (int)(Math.random()*255); 
        Color endColor = new Color(red,blue,green); 

        int startPositionX = (int)(Math.random()*70); 
        int startPositionY = (int)(Math.random()*70); 

        int endPositionX = (int)(Math.random()*150); 
        int endPositionY = (int)(Math.random()*150); 

        GradientPaint gradient = new GradientPaint(startPositionX,startPositionY,startColor,endPositionX,endPositionY,endColor); 
        g2d.setPaint(gradient); 
        g2d.fillOval(20,60,100,100); 

       } 
      } 
+1

欢迎来到StackOverflow。如果您可以缩小代码示例的大小,这将会很有帮助。例如,大部分标签内容都是无关紧要的(对某些人而言)。 – pamphlet

+1

仅供将来参考,在你的LabelListener中,我不认为你的意思是'int i =(int)(Math.random()* 5);'如果你使用模数('%')函数,它只会返回0- [number modding by]。另外,在你的情况下,最好使用'labelContent.size()'而不是'5',这样你可以在不破坏代码的情况下添加/减少选项。所以我建议所有的是:'int i =(int)(Math.random()%labelContent.size());' – sparks

回答

0

每次单击labelButton它烧成重绘事件MyDrawPanel

这会导致颜色再次随机生成,从而改变颜色MyDrawPanel

我建议通过调用MyDrawPanel上ColorListener的方法来修改它的颜色。这将防止面板在每次重绘时都改变颜色。

而这里恰恰是如何做到这一点:

class ColorListener implements ActionListener{ 
    MyDrawPanel colorPanel; 
    public ColorListener(MyDrawPanel panel){ 
     this.colorPanel = panel; 
    } 

    public void actionPerformed(ActionEvent event2) { 
     colorPanel.generateRandomColor(); 
     frame.repaint(); 
    } 
} 

public class MyDrawPanel extends JPanel{ 
    GradientPaint gradient; 
    public MyDrawPanel(){ 
     generateRandomColor(); 
    } 
    public void generateRandomColor(){ 
     int red = (int)(Math.random()*255); 
     int blue = (int)(Math.random()*255); 
     int green = (int)(Math.random()*255); 
     Color startColor = new Color(red,blue,green); 

     red = (int)(Math.random()*255); 
     blue = (int)(Math.random()*255); 
     green = (int)(Math.random()*255); 
     Color endColor = new Color(red,blue,green); 

     int startPositionX = (int)(Math.random()*70); 
     int startPositionY = (int)(Math.random()*70); 

     int endPositionX = (int)(Math.random()*150); 
     int endPositionY = (int)(Math.random()*150); 

     gradient = new GradientPaint(startPositionX,startPositionY, 
      startColor, endPositionX,endPositionY,endColor); 
    } 
} 
+0

非常感谢!但有没有解决方案使用内部类来分离动作? –

2

最可能的是,当您更改标签重绘()被调用,MyDrawPanel.paintComponent()被调用,并用随机颜色框粉刷一新。
更好地执行可以是:

class SimpleGui3C { 
    Color startColor; 
    Color endColor; 

    ColorListener() { 
    startColor = <code to generate a random color>; 
    endColor = <code to generate a random color>; 
    repaint(); 
    } 
} 

MyDrawPanel.paintComponent()使用startColorendColor由听者产生;记得要初始化颜色变量以避免NPE!

相关问题