2016-03-28 56 views
0

我正在使用Java中的簡單繪畫應用程序,當我選擇顏色時,按鈕背景完美變化,但返回的顏色始終是前一個顏色。例如,如果我選擇黑色,然後是藍色,它會以黑色塗色。如果我在藍色之後選擇另一種顏色,它將以藍色繪製。JColorChooser返回以前選擇的顏色

public class ColorChooserBtn extends JButton { 

    private Color color; 

    public ColorChooserBtn() { 
     super(); 
     this.setBackground(Color.BLACK); 
     this.setPreferredSize(new Dimension(16, 16)); 
     this.addActionListener(new ActionListener(){ 
      public void actionPerformed(ActionEvent e) { 
       Color c = JColorChooser.showDialog(null, "Choose a Color", color); 
       if (c != null){ 
        setSelectedColor(c); 
        setBackground(color); 
       } 

      } 
     }); 
    } 
    public Color getSelectedColor() { 
     return color; 
    } 

    public void setSelectedColor(Color newColor) { 
     color = newColor; 
    } 

} 

public class Paint { 
DrawArea drawArea; 
JButton clearBtn; 
ColorChooserBtn colorBtn; 
ActionListener actionListener = new ActionListener() { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     if(e.getSource() == clearBtn){ 
      drawArea.clear(); 
     } else if(e.getSource() == colorBtn){ 
      drawArea.coloring(colorBtn.getSelectedColor()); 
     } 

    } 
}; 

public Paint() { 
    JFrame frame = new JFrame("Paint"); 
    frame.getContentPane().setLayout(new BorderLayout()); 
    drawArea = new DrawArea(); 
    frame.getContentPane().add(drawArea, BorderLayout.CENTER); 
    JPanel controls = new JPanel(); 
    clearBtn = new JButton("Clear"); 
    clearBtn.addActionListener(actionListener); 
    colorBtn = new ColorChooserBtn(); 
    colorBtn.addActionListener(actionListener); 

    controls.add(clearBtn); 
    controls.add(colorBtn); 

    frame.getContentPane().add(controls,BorderLayout.NORTH); 
    frame.setSize(600, 600); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 
} 
public static void main(String[] args) { 

    new Paint(); 

} 

}

+0

也許一個線程問題?讓你的顏色變量爲volatile,然後重試。不知道,它的工作原理... – Seelenvirtuose

+0

我試過了,仍然是同樣的問題。 – edaddou

+0

然後,您還必須顯示您正在使用顏色變量進行繪畫的代碼。顯示的代碼似乎沒問題。 – Seelenvirtuose

回答

1

的問題是其中ActionListener的通知順序。一般情況下,搖擺電話LIFO順序聽

因此,使用下面的代碼,有一些額外的System.out小號...

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JColorChooser; 
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.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      ColorChooserBtn btn = new ColorChooserBtn(); 
      add(btn); 
      btn.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("Get color"); 
        System.out.println(btn.getSelectedColor()); 
       } 
      }); 
     } 

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

    } 

    public class ColorChooserBtn extends JButton { 

     private Color color; 

     public ColorChooserBtn() { 
      super(); 
      this.setBackground(Color.BLACK); 
      this.setPreferredSize(new Dimension(16, 16)); 
      this.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("Choose color"); 
        Color c = JColorChooser.showDialog(null, "Choose a Color", color); 
        if (c != null) { 
         setSelectedColor(c); 
         setBackground(color); 
        } 
       } 
      }); 
     } 

     public Color getSelectedColor() { 
      return color; 
     } 

     public void setSelectedColor(Color newColor) { 
      color = newColor; 
     } 

    } 
} 

打印...

Get color 
null 
Choose color 

這意味着ActionListener用於從按鈕「獲取」所選顏色的操作先被調用,然後用ActionListener實際選擇顏色

一,可能的解決辦法可能是使用PropertyChangeListener並引發propertyChanged事件時selectedColor改變,例如...

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.beans.PropertyChangeEvent; 
import java.beans.PropertyChangeListener; 
import javax.swing.AbstractAction; 
import javax.swing.JButton; 
import javax.swing.JColorChooser; 
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.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     public TestPane() { 
      ColorChooserBtn btn = new ColorChooserBtn(); 
      add(btn); 
      btn.addPropertyChangeListener("selectedColor", new PropertyChangeListener() { 
       @Override 
       public void propertyChange(PropertyChangeEvent evt) { 
        System.out.println("Changed"); 
        System.out.println(evt.getNewValue()); 
       } 
      }); 
     } 

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

    } 

    public class ColorChooserBtn extends JButton { 

     private Color color; 

     public ColorChooserBtn() { 
      super(); 
      this.setBackground(Color.BLACK); 
      this.setPreferredSize(new Dimension(16, 16)); 
      this.addActionListener(new ActionListener() { 
       public void actionPerformed(ActionEvent e) { 
        System.out.println("Choose color"); 
        Color c = JColorChooser.showDialog(null, "Choose a Color", color); 
        if (c != null) { 
         setSelectedColor(c); 
         setBackground(color); 
        } 
       } 
      }); 
     } 

     public Color getSelectedColor() { 
      return color; 
     } 

     public void setSelectedColor(Color newColor) { 
      if (newColor != color) { 
       Color oldColor = color; 
       color = newColor; 
       firePropertyChange("selectedColor", oldColor, newColor); 
      } 
     } 

    } 
} 
+0

感謝它幫助了很多 – edaddou