2016-10-01 170 views
0

當我運行此代碼時,顏色按鈕將出現在左上角。當我拖動窗口時,按鈕消失。代碼基本上可以工作,但我不知道會發生這種情況。每次單擊它時,按鈕都會出現。當我點擊一個按鈕時,爲什麼會出現相同的按鈕?

import javax.swing.*; 
import java.awt.*; 
import java.awt.event.*; 

public class TrafficLightPanel extends JPanel implements ActionListener{ 
private JLabel changeColor; 
private Color color; 

public TrafficLightPanel(){ 
    setSize(new Dimension(300,200));  
    setPreferredSize (new Dimension(300, 200)); 
    color = color.RED; 

} 
public void paintComponent(Graphics g){ 
    g.setColor(color); 
    g.fillOval(100,100,100,100); 
} 
public void setColor (Color shade) 
{ 
    color = shade; 
} 
public void createButton(){} 
public void actionPerformed(ActionEvent e) { 
    // TODO Auto-generated method stub 

} 
public static void main(String[] args){ 
    JFrame frame = new JFrame("Color Circle"); 
    JButton[] buttons = new JButton[3]; 
    String[] colors = new String[]{"RED", "GREEN", "BLUE"}; 
    TrafficLightPanel panel = new TrafficLightPanel() 
    { 
     @Override 
     public void createButton(){ 
      for(int i = 0; i < 3; i++) 
      { 
       // make new button name 

       buttons[i] = new JButton("" + colors[i]); 
       if(i == 0) 
        buttons[i].addActionListener(this); 
       else if(i == 1) 
        buttons[i].addActionListener(this); 
       else if(i == 2) 
        buttons[i].addActionListener(this); 

       add(buttons[i]); 
       //System.out.println(buttons[i]); 
      } 
     } 
     @Override 
     public void actionPerformed(ActionEvent e) { 
       if (e.getSource() == buttons[0]) { 
        setColor(Color.RED); 
        repaint(); 
       } else if (e.getSource() == buttons[1]) { 
        setColor(Color.GREEN); 
        repaint(); 
       } 
       else if (e.getSource() == buttons[2]) { 
        setColor(Color.BLUE); 
        repaint(); 
        } 
      } 

      }; 
      panel.createButton(); 
    frame.getContentPane().add(panel); 
    frame.pack(); 
    frame.setVisible(true); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 


} 

}

+0

請參閱編輯回答。 –

回答

3

你的paintComponent方法應該調用超類的方法,第一件事情,這樣的的JPanel將盡自己的看家圖形,其中包括消除所謂的「髒」的像素。所以:

@Override 
protected void paintComponent(Graphics g) { 
    super.paintComponent(g); // *** add this *** 
    g.setColor(color); 
    g.fillOval(100, 100, 100, 100); 
} 

我自己,我會做的事情有點不同,有一些建議你可以考慮與否:

  • 創建一個JPanel,這只是用於繪圖,沒有別的,沒有任何按鍵,沒什麼。
  • 將JButton放置在不同的JPanel中。
  • 使用一個枚舉(可能稱爲LightColor),該枚舉用於將Color與String組合起來,並在創建按鈕時使用。
  • 在paintComponent方法中,將Graphics對象轉換爲Graphics2D對象,以便我們可以使用RenderingHints繪製更平滑的圓。
  • 避免設置任何尺寸。取而代之,在需要時重寫setPreferredSize,並在創建它之前但在顯示它之前,通過在JFrame上調用pack()來讓應用程序的組件和佈局管理器自行調整大小。

例如:

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.RenderingHints; 
import java.awt.event.ActionEvent; 

import javax.swing.*; 

// main GUI JPanel that holds the light drawing JPanel as well as the buttons 
@SuppressWarnings("serial") 
public class TrafficLightPanel2 extends JPanel { 
    private static final int LIGHT_SIZE = 200; // size of the circle 
    private static final int GAP = 10; // border gap around the jpanel 

    // the Jlight drawing JPanel that draws the circles 
    private LightDrawingPanel lightDrawingPanel = new LightDrawingPanel(null, LIGHT_SIZE); 

    public TrafficLightPanel2() { 
     // JPanel to hold the buttons, 1 row, variable number of columns, gap between buttons 
     JPanel buttonPanel = new JPanel(new GridLayout(1, 0, GAP, 0)); 
     for (LightColor lightColor : LightColor.values()) { 
      // create each button within the loop, giving it an Action -- an ActionListener "on steroids" 
      buttonPanel.add(new JButton(new LightColorAction(lightColor, lightDrawingPanel))); 
     } 

     setBorder(BorderFactory.createEmptyBorder(GAP, GAP, GAP, GAP)); 
     setLayout(new BorderLayout(GAP, GAP)); 
     add(lightDrawingPanel, BorderLayout.CENTER); // add the light drawer to the center 
     add(buttonPanel, BorderLayout.PAGE_END); // and the buttons to the bottom 
    } 

    private static void createAndShowGui() { 
     TrafficLightPanel2 mainPanel = new TrafficLightPanel2(); 

     JFrame frame = new JFrame("Traffic Light"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
     frame.getContentPane().add(mainPanel); 
     frame.pack(); // have layout managers do their thing 
     frame.setLocationRelativeTo(null); // center 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(() -> createAndShowGui()); 
    } 
} 

// just acts as a class that connects a Color with a String 
enum LightColor { 
    RED(Color.RED, "Red"), YELLOW(Color.YELLOW, "Yellow"), GREEN(Color.GREEN, "Green"); 

    private LightColor(Color color, String text) { 
     this.color = color; 
     this.text = text; 
    } 
    private Color color; 
    private String text; 

    public Color getColor() { 
     return color; 
    } 

    public String getText() { 
     return text; 
    } 

    @Override 
    public String toString() { 
     return text; 
    } 
} 

// create a class that only draws the circle, and that's it 
@SuppressWarnings("serial") 
class LightDrawingPanel extends JPanel { 
    private Color color; 
    private int size; 

    public LightDrawingPanel(Color color, int size) { 
     this.color = color; 
     this.size = size; 
    } 

    public void setColor(Color color) { 
     this.color = color; 
     repaint(); 
    } 

    @Override 
    protected void paintComponent(Graphics g) { 
     super.paintComponent(g); // again, the super must be called 

     // if no color defined, get out of here 
     if (color == null) { 
      return; 
     } 

     g.setColor(color); 

     // make for smooth rendering 
     Graphics2D g2 = (Graphics2D) g; 
     g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 

     // center the circle 
     int x = (getWidth() - size)/2; 
     int y = (getHeight() - size)/2; 
     g2.fillOval(x, y, size, size); 
    } 

    // make our JPanel at least as large as the circle 
    @Override 
    public Dimension getPreferredSize() { 
     if (isPreferredSizeSet()) { 
      return super.getPreferredSize(); 
     } 
     return new Dimension(size, size); 
    } 
} 

// AbstractAction for our buttons 
// like an ActionListener "on steroids" 
@SuppressWarnings("serial") 
class LightColorAction extends AbstractAction { 
    private LightColor lightColor; 
    private LightDrawingPanel lightDrawingPanel; 

    public LightColorAction(LightColor lightColor, LightDrawingPanel lightDrawingPanel) { 
     super(lightColor.getText()); // text for the button to show 

     // initialize our fields 
     this.lightColor = lightColor; 
     this.lightDrawingPanel = lightDrawingPanel; 

     // alt-key mnemonic derived from the text String 
     int mnemonic = (int) lightColor.getText().charAt(0); 
     putValue(MNEMONIC_KEY, mnemonic); 
    } 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     // set the color of the drawing panel 
     lightDrawingPanel.setColor(lightColor.getColor()); 
    } 
} 
+0

如果幫助解決問題,請[接受答案](http://meta.stackexchange.com/a/5235/155831)。這有助於其他人,因爲「回答」的問題更有可能由研究問題的人進行檢查。 –

相關問題