2016-02-26 56 views
0

我有一個非常簡單的程序,要求用戶點擊與其背景顏色匹配的四個面板中的一個,以便隨機設置較大的面板(又稱displaypanel)它的背景色作爲四個之一。如果錯誤的面板被點擊,Joptionpane會出現; displaypanels背景被臨時設置爲黑色。如果點擊是,則displaypanel應該重新設置其背景顏色。問題是我不總是看到更新的背景。反而有時背景保持黑色。 ...更令人困惑的是,如果您在該程序的窗口上拖動另一個窗口,如果看到部分顏色被更新爲在顯示面板上移動或只是切換到另一個窗口並重新搜索,然後您看到完成更新的背景顏色。爲什麼在這個簡單的程序中,爲什麼不立即一致地更新背景顏色

那麼setMethod爲什麼會被調用,但只是偶爾由幕後的任何paint方法執行?以及爲什麼要鑄造其他窗口或框架使其可見?它是否與正在處理的鼠標單擊事件有關?

我感謝所有的做任何解釋,謝謝你們

public class MainPanel extends JPanel{ 


    Subpanel panel1; 
    Subpanel panel2; 
    Subpanel panel3; 
    Subpanel panel4; 
    Subpanel displaypanel; 

    Color[] color; //stores all the colors that display on the subpanels 


    public static void main(String[] args) { 
     JFrame window=new JFrame("This is a test"); 
     window.setContentPane(new MainPanel()); 
     window.setLocation(100,30); 
     window.setSize(600,500); 
     window.setVisible(true); 

    } 


    public MainPanel(){ 


     setLayout(new FlowLayout(FlowLayout.CENTER,80,30)); 


     panel1= new Subpanel(); 
     panel2= new Subpanel(); 
     panel3= new Subpanel(); 
     panel4= new Subpanel(); 

     //the big sub panel 
     displaypanel= new Subpanel(); 

     color=new Color[4]; 
     color[0]=Color.BLUE; 
     color[1]=Color.RED; 
     color[2]=Color.YELLOW; 
     color[3]=Color.GREEN; 



     setBackground(Color.GRAY); 
     displaypanel.setBackground(displayRandomColor()); 
     panel1.setBackground(color[0]); 
     panel2.setBackground(color[1]); 
     panel3.setBackground(color[2]); 
     panel4.setBackground(color[3]); 

     displaypanel.setPreferredSize(new Dimension(400,250)); 
     panel1.setPreferredSize(new Dimension(70,70)); 
     panel2.setPreferredSize(new Dimension(70,70)); 
     panel3.setPreferredSize(new Dimension(70,70)); 
     panel4.setPreferredSize(new Dimension(70,70)); 

     add(displaypanel); 
     add(panel1); 
     add(panel2); 
     add(panel3); 
     add(panel4); 





    } 


    public void paintComponent(Graphics g){ 
     super.paintComponent(g); 



    } 

    public Color displayRandomColor(){ 
      Color i=Color.WHITE; 
     switch ((int)(Math.random()*4)+1){ 
      case 1: 
      i= Color.YELLOW; 
      break; 

      case 2: 
      i= Color.BLUE; 
      break; 

      case 3: 
      i= Color.GREEN; 
      break; 

      case 4: 
      i= Color.RED; 
     } 
     return i; 
    } 


    public class Subpanel extends JPanel{ 

     public Subpanel(){ 
       this.addMouseListener(new MouseAdapter(){ 
       public void mouseClicked(MouseEvent evt){ 
        Component source=(Component)evt.getSource(); 

         if((source.getBackground()).equals(displaypanel.getBackground())){ 
          //do nothing for this test.. 
        } 
         else{ 
           displaypanel.setBackground(Color.BLACK); 

           //ask user to reset the background color 
           //**the following 2 lines introduces the problem 
          if(JOptionPane.showOptionDialog(null,"click Yes to see a new Color","Incorrect",JOptionPane.YES_NO_OPTION,JOptionPane.PLAIN_MESSAGE,null,null,null)==JOptionPane.YES_OPTION){ 
           displaypanel.setBackground(displayRandomColor()); 

          } 
         } 

         } 





     }); 
     } //end of constructor 
     public void paintComponent(Graphics g){ 
      super.paintComponent(g); 

     } 

    } 

} 
+1

使用空格謹慎。 [當你確實想要重載'getPreferredSize()'](http://stackoverflow.com/q/7229226/230513)時,不要使用'setPreferredSize()'。另見[*初始線程*](http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html)。 – trashgod

+0

我無法重現您的問題。你使用的是什麼版本的Java?你在運行什麼操作系統? – VGR

+0

在Max OS X 10.7.5上運行java 8。有時需要4或5次錯誤的點擊才能看到該問題。你有沒有做過這麼多的嘗試,你沒有看到背景卡在黑色? – Scottie

回答

1

你的程序的性能非常好,當synchronized correctly。一些注意事項:

  • 儘早在程序執行中儘可能初始化對象。

  • 使用Random的實例來獲得隨機整數;注意displayRandomColor()的簡單實現。

    private Color displayRandomColor() { 
        return color[r.nextInt(color.length)]; 
    } 
    
  • 搖擺GUI對象應當被構造並在event dispatch thread操縱

  • 當您確實想要覆蓋getPreferredSize()]時,請勿使用setPreferredSize(),建議here

  • 使用layoutspack()封閉窗口。

image

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.Component; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 
import java.util.Random; 
import javax.swing.JFrame; 
import javax.swing.JOptionPane; 
import javax.swing.JPanel; 

public class MainPanel extends JPanel { 

    private static final Random r = new Random(); 
    private final JPanel displayPanel; 
    private Color[] color = {Color.RED, Color.GREEN, Color.BLUE, Color.YELLOW}; 
    private Subpanel panel1 = new Subpanel(color[0]); 
    private Subpanel panel2 = new Subpanel(color[1]); 
    private Subpanel panel3 = new Subpanel(color[2]); 
    private Subpanel panel4 = new Subpanel(color[3]); 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       JFrame window = new JFrame("This is a test"); 
       window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       window.add(new MainPanel()); 
       window.pack(); 
       window.setLocationRelativeTo(null); 
       window.setVisible(true); 
      } 
     }); 
    } 

    public MainPanel() { 
     setLayout(new BorderLayout()); 
     setBackground(Color.GRAY); 

     //the big sub panel 
     displayPanel = new JPanel() { 

      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(320, 240); 
      } 
     }; 
     displayPanel.setBackground(displayRandomColor()); 

     //the control panel 
     JPanel p = new JPanel(); 
     p.add(panel1); 
     p.add(panel2); 
     p.add(panel3); 
     p.add(panel4); 

     add(displayPanel, BorderLayout.CENTER); 
     add(p, BorderLayout.SOUTH); 
    } 

    private Color displayRandomColor() { 
     return color[r.nextInt(color.length)]; 
    } 

    public class Subpanel extends JPanel { 

     public Subpanel(Color color) { 
      this.setBackground(color); 
      this.addMouseListener(new MouseAdapter() { 
       @Override 
       public void mousePressed(MouseEvent evt) { 
        Component source = (Component) evt.getSource(); 
        if ((source.getBackground()).equals(displayPanel.getBackground())) { 
         System.out.println(source.getBackground()); 
        } else { 
         displayPanel.setBackground(Color.BLACK); 
         if (JOptionPane.showOptionDialog(null, 
          "Click Yes to see a new Color", "Incorrect", 
          JOptionPane.YES_NO_OPTION, JOptionPane.PLAIN_MESSAGE, 
          null, null, null) == JOptionPane.YES_OPTION) { 
          displayPanel.setBackground(displayRandomColor()); 
         } 
        } 
       } 
      }); 
     } 

     @Override 
     public Dimension getPreferredSize() { 
      return new Dimension(70, 70); 
     } 
    } 
} 
相關問題