2013-02-06 19 views
2

我希望能夠即時更新Swing GUI的LookAndFeel屬性。在這種情況下,我有一個簡單的Swing/Awt遊戲,運行的遊戲以Nimbus LookAndFeel開始。在啓動後的各個點上,我想改變(讓我們說)一個細節:我的應用程序的背景顏色。更新LookAndFeel值在飛行中

我可以做這個改變背景顏色:

for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
    if ("Nimbus".equals(info.getName())) { 
     UIManager.setLookAndFeel(info.getClassName()); 
     UIManager.getLookAndFeelDefaults().put("Panel.background", Color.RED); 
     SwingUtilities.updateComponentTreeUI(SomeGame.this); 
     break; 
    } 
} 

中的應用改變背景色正確這個「作品」,程序不會崩潰。但在命令行我得到錯誤:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException 
    at javax.swing.plaf.synth.SynthLookAndFeel.paintRegion(SynthLookAndFeel.java:371) 
    at javax.swing.plaf.synth.SynthLookAndFeel.update(SynthLookAndFeel.java:335) 

顯然,東西是空的,但我不明白它是什麼或如何解決它。肯定有一些我不明白的東西。我查看了有關setting background colors in Nimbusoverriding the LookAndFeel information after startup的其他StackOverflow問題。

  • 當我致電getLookAndFeelDefaults()時是否還需要指定其餘的默認值?
  • Java 1.6和1.7之間的工作方式是否發生了變化?

回答

4
  • 爲的Java6的所有代碼,必須改變雨雲進口Java7

  • Nimbus有幾個suprises,其中之一是這是可能的(不髒黑客,我要走了徵求意見那些黑客)更改爲BackgroundJPanel一次

enter image description here

enter image description here

enter image description here

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.Color; 
import java.awt.AlphaComposite; 
import javax.swing.*; 
import javax.swing.UIManager.LookAndFeelInfo; 
import javax.swing.border.EmptyBorder; 

public class ButtonTest { 

    private JFrame frame; 
    private JPanel panel; 
    private JButton opaqueButton1; 
    private JButton opaqueButton2; 
    private SoftJButton softButton1; 
    private SoftJButton softButton2; 
    private Timer alphaChanger; 

    public void createAndShowGUI() { 
     opaqueButton1 = new JButton("Opaque Button"); 
     opaqueButton2 = new JButton("Opaque Button"); 
     softButton1 = new SoftJButton("Transparent Button"); 
     softButton2 = new SoftJButton("Transparent Button"); 
     opaqueButton1.setBackground(Color.GREEN); 
     softButton1.setBackground(Color.GREEN); 
     panel = new JPanel(); 
     panel.setLayout(new java.awt.GridLayout(2, 2, 10, 10)); 
     panel.add(opaqueButton1); 
     panel.add(softButton1); 
     panel.add(opaqueButton2); 
     panel.add(softButton2); 
     panel.setBorder(new EmptyBorder(10, 10, 10, 10)); 
     frame = new JFrame(); 
     frame.add(panel); 
     frame.setLocation(150, 100); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setVisible(true); 
     alphaChanger = new Timer(50, new ActionListener() { 

      private float incrementer = -.03f; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       float newAlpha = softButton1.getAlpha() + incrementer; 
       if (newAlpha < 0) { 
        newAlpha = 0; 
        incrementer = -incrementer; 
       } else if (newAlpha > 1f) { 
        newAlpha = 1f; 
        incrementer = -incrementer; 
       } 
       softButton1.setAlpha(newAlpha); 
       softButton2.setAlpha(newAlpha); 
      } 
     }); 
     alphaChanger.start(); 
     Timer uiChanger = new Timer(3500, new ActionListener() { 

      private final LookAndFeelInfo[] laf = UIManager.getInstalledLookAndFeels(); 
      private int index = 1; 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       try { 
        UIManager.setLookAndFeel(laf[index].getClassName()); 
        if (laf[index].getClassName().equals("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel")) { 
         UIManager.getLookAndFeelDefaults().put("Panel.background", Color.orange); 
         SwingUtilities.updateComponentTreeUI(frame); 
        } else { 
         panel.setBackground(Color.yellow); 
         SwingUtilities.updateComponentTreeUI(frame); 
        } 
        opaqueButton1.setText(laf[index].getClassName()); 
        softButton1.setText(laf[index].getClassName()); 
        frame.pack(); 
       } catch (Exception exc) { 
        exc.printStackTrace(); 
       } 
       index = (index + 1) % laf.length; 
      } 
     }); 
     uiChanger.start(); 
    } 

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

      @Override 
      public void run() { 
       new ButtonTest().createAndShowGUI(); 
      } 
     }); 
    } 

    private static class SoftJButton extends JButton { 

     private static final JButton lafDeterminer = new JButton(); 
     private static final long serialVersionUID = 1L; 
     private boolean rectangularLAF; 
     private float alpha = 1f; 

     SoftJButton() { 
      this(null, null); 
     } 

     SoftJButton(String text) { 
      this(text, null); 
     } 

     SoftJButton(String text, Icon icon) { 
      super(text, icon); 
      setOpaque(false); 
      setFocusPainted(false); 
     } 

     public float getAlpha() { 
      return alpha; 
     } 

     public void setAlpha(float alpha) { 
      this.alpha = alpha; 
      repaint(); 
     } 

     @Override 
     public void paintComponent(java.awt.Graphics g) { 
      java.awt.Graphics2D g2 = (java.awt.Graphics2D) g; 
      g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha)); 
      if (rectangularLAF && isBackgroundSet()) { 
       Color c = getBackground(); 
       g2.setColor(c); 
       g.fillRect(0, 0, getWidth(), getHeight()); 
      } 
      super.paintComponent(g2); 
     } 

     @Override 
     public void updateUI() { 
      super.updateUI(); 
      lafDeterminer.updateUI(); 
      rectangularLAF = lafDeterminer.isOpaque(); 
     } 
    } 
} 

enter image description here

工作10

enter image description here

import java.awt.Color; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.Random; 
import javax.swing.JFrame; 
import javax.swing.LookAndFeel; 
import javax.swing.SwingUtilities; 
import javax.swing.Timer; 
import javax.swing.UIDefaults; 
import javax.swing.UIManager; 
import javax.swing.UIManager.LookAndFeelInfo; 
import javax.swing.UnsupportedLookAndFeelException; 

public class NimbusTestButtonsBackground extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private javax.swing.JButton button; 

    public NimbusTestButtonsBackground() { 
     button = new javax.swing.JButton(); 
     button.setText("Text"); 
     add(button); 
     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 
     this.pack(); 
     Timer t = new Timer(1000, new ActionListener() { 

      private Random r = new Random(); 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       Color c = new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256)); 
       try { 
        LookAndFeel lnf = UIManager.getLookAndFeel().getClass().newInstance(); 
        UIDefaults uiDefaults = lnf.getDefaults(); 
        uiDefaults.put("nimbusBase", c); 
        UIManager.getLookAndFeel().uninitialize(); 
        UIManager.setLookAndFeel(lnf); 
       } catch (InstantiationException ex) { 
       } catch (IllegalAccessException ex) { 
       } catch (UnsupportedLookAndFeelException ex) { 
       } 
       UIDefaults defaults = UIManager.getDefaults(); 
       defaults.put("Button.background", c); 
       SwingUtilities.updateComponentTreeUI(button); 
      } 
     }); 
     t.start(); 
    } 

    public static void main(String args[]) { 
     try { 
      for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (Exception e) { 
      return; 
     } 

     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new NimbusTestButtonsBackground().setVisible(true); 
      } 
     }); 
    } 
} 
  • 然後我看到(這種方式是最舒適的,最簡單的,等..)爲JPanel覆蓋paintComponent最佳的最好辦法

enter image description hereenter image description hereenter image description here

import java.awt.AlphaComposite; 
import java.awt.Color; 
import java.awt.Container; 
import java.awt.EventQueue; 
import java.awt.GradientPaint; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.GridLayout; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.awt.image.BufferedImage; 
import java.util.Random; 
import javax.swing.JButton; 
import javax.swing.JComponent; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.RepaintManager; 
import javax.swing.Timer; 
import javax.swing.UIManager; 
import javax.swing.UIManager.LookAndFeelInfo; 

public class ChangePanelBackgroundNimbus { 

    private JFrame frame = new JFrame(); 

    public ChangePanelBackgroundNimbus() { 
     GradientPane pane = new GradientPane(); 
     pane.setLayout(new GridLayout(6, 4, 10, 10)); 
     for (int i = 1; i <= 24; i++) { 
      pane.add(createButton(i)); 
     } 
     pane.setOpaque(false); 
     frame.add(pane); 
     RepaintManager.setCurrentManager(new RepaintManager() { 

      @Override 
      public void addDirtyRegion(JComponent c, int x, int y, int w, int h) { 
       Container con = c.getParent(); 
       while (con instanceof JComponent) { 
        if (!con.isVisible()) { 
         return; 
        } 
        if (con instanceof GradientPane) { 
         c = (JComponent) con; 
         x = 0; 
         y = 0; 
         w = con.getWidth(); 
         h = con.getHeight(); 
        } 
        con = con.getParent(); 
       } 
       super.addDirtyRegion(c, x, y, w, h); 
      } 
     }); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setLocationByPlatform(true); 
     //frame.setSize(400, 300); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

    private JButton createButton(final int text) { 
     JButton button = new JButton(Integer.toString(text)); 
     return button; 
    } 

    class GradientPane extends JPanel { 

     private static final long serialVersionUID = 1L; 
     private final int h = 150; 
     private BufferedImage img = null; 
     private BufferedImage shadow = new BufferedImage(1, h, BufferedImage.TYPE_INT_ARGB); 

     public GradientPane() { 
      paintBackGround(new Color(150, 250, 150)); 
      Timer t = new Timer(500, new ActionListener() { 

       private Random r = new Random(); 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        paintBackGround(new Color(r.nextInt(256), r.nextInt(256), r.nextInt(256))); 
       } 
      }); 
      t.start(); 
     } 

     public void paintBackGround(Color g) { 
      Graphics2D g2 = shadow.createGraphics(); 
      g2.setPaint(g); 
      g2.fillRect(0, 0, 1, h); 
      g2.setComposite(AlphaComposite.DstIn); 
      g2.setPaint(new GradientPaint(0, 0, new Color(0, 0, 0, 0f), 0, h, new Color(0.4f, 0.8f, 0.8f, 0.5f))); 
      g2.fillRect(0, 0, 1, h); 
      g2.dispose(); 
     } 

     @Override 
     public void paintComponent(Graphics g) { 
      if (img == null || img.getWidth() != getWidth() || img.getHeight() != getHeight()) { 
       img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB); 
      } 
      Graphics2D g2 = img.createGraphics(); 
      super.paintComponent(g2); 
      Rectangle bounds = this.getVisibleRect(); 
      g2.scale(bounds.getWidth(), -1); 
      g2.drawImage(shadow, bounds.x, -bounds.y - h, null); 
      g2.scale(1, -1); 
      g2.drawImage(shadow, bounds.x, bounds.y + bounds.height - h, null); 
      g2.dispose(); 
      g.drawImage(img, 0, 0, null); 
      repaint(); 
     } 
    } 

    public static void main(String[] args) { 
     try { 
      for (LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) { 
       if ("Nimbus".equals(info.getName())) { 
        UIManager.setLookAndFeel(info.getClassName()); 
        break; 
       } 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       ChangePanelBackgroundNimbus ml = new ChangePanelBackgroundNimbus(); 
      } 
     }); 
    } 
}