当前位置: 首页 > 知识库问答 >
问题:

动态更新LookAndFeel值

晏树
2023-03-14

我希望能够动态更新我的Swing GUI的LookAnd感到属性。在这种情况下,我有一个简单的Swing/Awt游戏,运行的最初是NimbusLookAnd感到。在启动后的不同时间点,我想更改(让我们说)一个细节:我的应用程序的背景颜色。

我可以通过这样做来改变背景颜色:

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)

显然,有些东西是空的,但我不知道它是什么,也不知道如何修复它。一定有什么我不明白的。我已经研究了关于在Nimbus中设置背景色以及在启动后覆盖LookAndFeel信息的其他StackOverflow问题。

  • 当我调用getLookAndFeelDefaault()时,我是否也需要指定其余的默认值?
  • 在Java1.6和1.7之间,它的工作方式是否发生了变化?

共有1个答案

焦阎宝
2023-03-14

>

  • Java6的所有代码,必须更改Java7的Nimbus导入

    Nimbus有一些惊喜,其中之一是可以(没有肮脏的黑客,我为这些黑客留下评论)更改背景JBoard只有一次

    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();
            }
        }
    }
    
    • 但是对于JComponent,可以通过调用UIManager来更改其颜色字体,等等。getLookAndFeel()。取消初始化(),但这不适用于容器

    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);
                }
            });
        }
    }
    
    • 然后我看到(这种方式是最舒适、最简单的等)覆盖JGroup油漆组件是最好的方法

    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();
                }
            });
        }
    }
    

  •  类似资料:
    • 问题内容: 我基本上有一个具有多个选项卡的MainActivity。每个选项卡都是一个ShowListFragment,它扩展了Fragment。现在,每个选项卡都包含我从数据库中获取的数据。我有一个MOVE按钮,可将数据从每个片段的一个选项卡移动到另一个选项卡: 片段不会直接更新,而是在选项卡之间滑动了几下(恰好3次)。单击按钮后如何强制片段立即更新?我不想通过ViewPager中的onPage

    • V1.1.1新增 <?php $data=array("URL_HTML_SUFFIX"=>".html"); $result=sp_set_dynamic_config($data); ?>

    • 计算属性检测对属性所做的更改,并在使用set()方法调用它们时动态更新计算属性。 语法 (Syntax) ClassName.set('VariableName', 'UpdatedValue'); 例子 (Example) 以下示例显示了对属性进行更改时动态更新的值 - import Ember from 'ember'; export default function() { var

    • 我试图建立在一个问题的答案关于SwingProperty tyChangeSupport 我试图修改这里给出的代码,这是一个非常有用的、满是鳗鱼的气垫船的回答:WindowListener无法按预期工作,以便在通过输入对话框输入更改时更新显示的数组。 阵列已正常更新,但未在GUI中刷新。我希望有人能告诉我哪里出了问题。 以下是代码: -编辑-希望删除编译错误。

    • 我用chartjs创建了一个基本的条形图,效果很好。现在,我想以基于时间的间隔更新这些值。我的问题是,在我创建图表之后,我不知道如何正确地更新它的值。。。 我的代码: 在测试代码中,我正在使用-这是正确的方法吗?问题是每次调用,值都会重置为0,然后设置为随机值(就像我正在重新创建图表一样)。这样,所有动画总是从0到值,这看起来很奇怪。我希望如果我将一个值从50更新到10,该条将从50下降到10,而

    • 问题内容: 我希望从我的观点动态更新ModelForm的内联Meta类。尽管此代码似乎更新从元类的排除列表,输出,等不反映更新的Meta排除。 然后,我假定在创建ModelForm时而不是在调用时生成html 。有没有办法强制更新HTML? 这甚至是最好的方法吗?我只是认为这 应该 工作。 有什么想法吗? 问题答案: Meta类用于动态构造表单定义-因此,在创建ModelForm实例时,不包含在不