【问题标题】:Background color of button when using Windows LAF?使用 Windows LAF 时按钮的背景颜色?
【发布时间】:2012-06-10 23:07:23
【问题描述】:

我有一个使用本机 LAF 的 Java 应用程序,如下所示:

    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());

这很好用,但是,我正在尝试使按钮具有红色背景,但结果如下:

如您所见,我在按钮上设置了背景和前景,但结果并不令人赏心悦目。 有没有办法让按钮在不继承 JButton 的情况下绘制红色背景?

【问题讨论】:

    标签: java swing jbutton look-and-feel


    【解决方案1】:

    您必须了解,在 Swing 的 Look & Feel 结构下,是 JButton 的 UI 委托进行绘制,而不是 JButton 本身,因此setBackground(...) 在这种情况下无法正常工作。您最好在按钮上添加一个图标。

    【讨论】:

    • +1 表示Icon;更多建议here.
    【解决方案2】:

    我创建了自己的 CustomColorButton,在 click鼠标悬停 上具有 漂亮的渐变 末端效果,在 /p>

    UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    

    您可以像这样创建一个新按钮:

    CustomColorButton button = new CustomColorButton(Color.RED, Color.WHITE); // Background and font color
    button.setText("Color button!");
    

    CustomColorButton 类:

    public class CustomColorButton extends JButton implements ActionListener, MouseListener
    {
        private boolean hovered = false;
        private boolean clicked = false;
    
        private Color normalColor = null;
        private Color lightColor = null;
        private Color darkColor = null;
    
        public CustomColorButton(Color normalRedColor, Color fontColor)
        {
            setForeground(fontColor);
    
            this.normalColor = normalRedColor;
            this.lightColor = normalRedColor.brighter();
            this.darkColor = normalRedColor.darker();
    
            addActionListener(this);
            addMouseListener(this);
            setContentAreaFilled(false);
        }
    
        /**
         * Overpainting component, so it can have different colors
         */
        @Override
        public void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            Graphics2D g2d = (Graphics2D) g;
    
            GradientPaint gp = null;
    
            if (clicked)
                gp = new GradientPaint(0, 0, darkColor, 0, getHeight(), darkColor.darker());
            else if (hovered)
                gp = new GradientPaint(0, 0, lightColor, 0, getHeight(), lightColor.darker());
            else
                gp = new GradientPaint(0, 0, normalColor, 0, getHeight(), normalColor.darker());
    
            g2d.setPaint(gp);
    
            // Draws the rounded opaque panel with borders
            g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // For High quality
            g2d.fillRoundRect(0, 0, getWidth(), getHeight(), 7, 7);
    
            g2d.setColor(darkColor.darker().darker());
            g2d.drawRoundRect(0, 0, getWidth() - 1, getHeight() - 1, 7, 7);
    
            super.paintComponent(g);
        }
    
        @Override
        public void actionPerformed(ActionEvent arg0)
        {
            System.out.println("Button clicked!");
        }
    
        @Override
        public void mouseClicked(MouseEvent arg0)
        {
    
        }
    
        @Override
        public void mouseEntered(MouseEvent arg0)
        {
            hovered = true;
            clicked = false;
    
            repaint();
        }
    
        @Override
        public void mouseExited(MouseEvent arg0)
        {
            hovered = false;
            clicked = false;
    
            repaint();
        }
    
        @Override
        public void mousePressed(MouseEvent arg0)
        {
            hovered = true;
            clicked = true;
    
            repaint();
        }
    
        @Override
        public void mouseReleased(MouseEvent arg0)
        {
            hovered = true;
            clicked = false;
    
            repaint();
        }
    }
    

    【讨论】:

      【解决方案3】:

      对于遇到我遇到的问题的任何人,这是我采用的解决方案:

      我切换到使用 ImageIcon 添加为按钮子项的图像:

          BufferedImage stopPicture = null;
          try {
              stopPicture = ImageIO.read(new File("stop.png"));
          } catch (IOException ex) { }
          JLabel picLabel = new JLabel(new ImageIcon( stopPicture ));
          JButton btnStop = new JButton("");
          btnStop.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                  SerialTest.getInstance().stopMoving();
              }
          });
          btnStop.add(picLabel);
      

      【讨论】:

        【解决方案4】:

        如果“没有子类化”意味着不必自己扩展它,那么您可以选择使用 SwingX JXButton,它将 JButton 扩展为使用画家(以及更多):

        JButton button = new JButton();
        button.setBackground(bg);
        

        变成

        JXButton button = new JXButton();
        button.setBackgroundPainter(new MattePainter(bg));
        

        如果您必须坚持使用基本 JButton,我认为没有解决方案,因为您的 L&F 工作方式。

        【讨论】:

        • 我很自然地喜欢看到提到的 SwingX :-) 不过,您应该小心不要对几个问题发布完全相同的答案 - 要么可能不适合所有人,要么问题是重复的应该这样标记/关闭
        • 好吧,虽然这两个答案确实使用了相同的示例(因为它简单明了),但每个问题的答案本身都是不同的,即注意这个不需要被子类化(如果您注意到,即使该示例在另一个答案中也多了 1 行;))。问题是我在尝试解决同一主题时发现了这两个问题,找到了这个(你的)解决方案并且只是想分享它。事实上,自提出问题以来,作者可能已经在 1 年多的时间里解决了这个问题,仅针对所有面临相同问题的人。
        猜你喜欢
        • 2013-06-24
        • 2020-08-19
        • 2013-08-06
        • 2021-08-10
        • 1970-01-01
        • 2021-02-23
        • 2020-11-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多