2016-02-26 57 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); 
     } 
    } 
} 
相关问题