2016-10-01 8 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

JPanelのは、いわゆる「汚い」ピクセルを除去することを含むそのハウスキーピンググラフィックスを、行いますようにスーパーのメソッド最初のものを呼び出す必要がありますあなたのpaintComponentメソッド。だから、:

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

私自身、私はあなたが考えるかすることはできませんいくつかの提案で、少し違ったものにしてください:

  • を単に描画し、他には何のためにあるのJPanel、ノーボタンを作成し、いいえ、別に。
  • JButtonを別のJPanelに配置します。
  • ColorをStringと組み合わせ、ボタンを作成するときに使用するための、おそらくLightColorと呼ばれる列挙型を使用します。
  • 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)してください。これは、後に他の人に役立ちます。「答えられた」質問は、問題を研究している人々が調べる可能性が高いからです。 –

関連する問題