我有一個程序,我希望能夠在「日」和「夜」模式之間進行切換,其中「夜」模式具有50%灰色背景。我通過調用UIManager.put(關鍵,新的顏色)爲所有從這個頁面中的「背景」鍵這樣做:無法更新外觀和感覺
http://alvinalexander.com/java/java-uimanager-color-keys-list
然後,我結合使用SwingUtilities.updateComponentTreeUI()與Java。 awt.Window.getWindows()獲取現有的窗口來獲取更改。
當我切換模式時,新創建的窗口將具有適當的背景,所以第一部分工作。但是,現有的窗口表現得很奇怪:它們瞬間閃爍新顏色,然後切換回來。例如,如果我在Day模式下啓動程序,那麼主程序窗口會有效地停留在Day模式,反之亦然。
我試圖做一個示例程序。它的行爲與我現有的程序不完全相同,但它的表現仍然很奇怪:外觀只能修改一次。在此之後,新的變化將被忽略:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.Frame;
import javax.swing.JLabel;
import java.awt.GridLayout;
import java.util.Random;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class Demo {
public static void main(String[] args) {
new Demo();
}
public Demo() {
JFrame frame = new JFrame("Look and feel test");
frame.setLayout(new GridLayout(3, 3));
// Fill in non-central locations in the layout.
// Hacky way to keep the button from monopolizing the frame
for (int i = 0; i < 4; ++i) {
frame.add(new JLabel(""));
}
JButton button = new JButton("Set new LAF");
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
setNewLAF();
}
});
frame.add(button);
// Fill in non-central locations in the layout.
for (int i = 0; i < 4; ++i) {
frame.add(new JLabel(""));
}
frame.setMinimumSize(new Dimension(400, 400));
frame.show();
System.out.println("Initial frame background is " + frame.getBackground());
}
public void setNewLAF() {
Random rng = new Random();
Color newBackground = new Color(rng.nextInt(255),
rng.nextInt(255), rng.nextInt(255));
System.out.println("New color is " + newBackground);
UIManager.put("Panel.background", newBackground);
for (Frame f : Frame.getFrames()) {
SwingUtilities.updateComponentTreeUI(f);
System.out.println("Frame now has background " + f.getBackground());
}
}
}
這將產生輸出,如:
Initial frame background is com.apple.laf.AquaImageFactory$SystemColorProxy[r=238,g=238,b=238]
New color is java.awt.Color[r=243,g=209,b=134]
Frame now has background java.awt.Color[r=243,g=209,b=134]
New color is java.awt.Color[r=205,g=141,b=58]
Frame now has background java.awt.Color[r=243,g=209,b=134]
New color is java.awt.Color[r=141,g=22,b=92]
Frame now has background java.awt.Color[r=243,g=209,b=134]
感謝你願意分享的任何建議。
如果不是所有UI元素,您至少需要在頂級/根容器上調用'updateUI'。一般而言,外觀和感覺並非真正爲此設計的 – MadProgrammer
您是否有推薦的方法可以在運行時切換幀中的所有組件的背景顏色?外觀和感覺是我可以看到的最接近的選項,它沒有手動遍歷組件層次結構並在每個元素上調用setBackground()。 – chris