Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/371.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 自定义渐变按钮-can';我看不见文字_Java_Swing_Gradient_Jbutton - Fatal编程技术网

Java 自定义渐变按钮-can';我看不见文字

Java 自定义渐变按钮-can';我看不见文字,java,swing,gradient,jbutton,Java,Swing,Gradient,Jbutton,我正在制作一个带有渐变效果的自定义按钮。我可以设置渐变效果,但看不到文字。我哪里做错了 class CustomButton extends JButton { Color color1, color2; public CustomButton(String text, Color color1, Color color2) { super(text); this.color1 = color1; t

我正在制作一个带有渐变效果的自定义按钮。我可以设置渐变效果,但看不到文字。我哪里做错了

class CustomButton extends JButton {   
    Color color1, color2;   

    public CustomButton(String text, Color color1, Color color2) {   
        super(text);   
        this.color1 = color1;   
        this.color2 = color2;   
        setOpaque(false);   
        setSize(new Dimension(450, 350));
        setForeground(Color.white);
        setText(text);
        setContentAreaFilled(false);
    }   

    protected void paintComponent(Graphics g) {    
        super.paintComponent(g);
        int width = getWidth();   
        int height = getHeight();   

        GradientPaint paint = new GradientPaint(0, 0, color1, width, height,
                color2, true);
        Graphics2D g2d = (Graphics2D)g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);   
        Paint oldPaint = g2d.getPaint();
        g2d.setPaint(paint);
        g2d.fillRect(0, 0, width, height);
        g2d.drawString("Button 1", getWidth()/2, 10);
        g2d.setPaint(oldPaint);
    }   
}  

注意:我允许用户在运行时更改颜色。根据更改为的颜色,我相应地设置了背景。

您覆盖了paintComponent方法,而不调用它的超级版本

paintComponent负责编写实际的文本——因此,如果它没有被调用,则不为您编写文本

因此,在这一点上:

自己编写代码来绘制标签,这可能复杂,也可能不复杂,这取决于您将如何处理大小调整等


调用super.paintComponent——如果它重新绘制背景,则可能不起作用。

将component不透明设置为false以避免绘制背景

Paint oldPaint = g2d.getPaint();  
g2d.setPaint(paint);  
g2d.fillRect(0, 0, width, height);  
g2d.setPaint( oldPaint ); // try adding this
g2d.drawString("Button 1", getWidth()/2, 10);
//g2d.setPaint( oldPaint );

调用所有渐变绘制代码,并在方法末尾调用
super.paintComponent()

我认为使用
paintComponent()
为自定义JButton创建背景不是正确的方法,此背景可能会双向更改

1) 替换默认值

2) 覆盖,注意
MetalButtonUI
仅在
CrossPlatformLookAndFeel
=
MetalLookAndFeel

编辑(最好从ButtonModel中删除/禁用balast)


正如斯坦已经回答的那样,解决方案的一部分是

button.setOpaque(false)
按钮有点疯狂,它们想要缩成一团,而不是画背景

button.setContentAreaFilled(false)
注意:确切的结果可能仍然高度依赖LAF——f.i.看起来非常糟糕。对于基于合成器的(如F.I.NimBUS),您可能会考虑安装一个定制的画家,配置渐变/颜色作为用户

的选择。 编辑

只是仔细检查一下:

// tell ui to not paint the background
button.setOpaque(false);
button.setContentAreaFilled(false);

// override paintComponent
protected void paintComponent(...) {
     // do custom backgroudn painting
     ...
     // let ui handle the foreground (it wont touch the background due to the false settings above)
     super.paintComponent()
}

适用于所有core Laf(on win)

看起来您使用相同的绘制对象绘制背景和前景,所以我猜文本只是与背景合并

Paint oldPaint = g2d.getPaint();  
g2d.setPaint(paint);  
g2d.fillRect(0, 0, width, height);  
g2d.setPaint( oldPaint ); // try adding this
g2d.drawString("Button 1", getWidth()/2, 10);
//g2d.setPaint( oldPaint );

super.paintComponent不起作用,我尝试了使用和不使用,但它无法帮助显示文本。你能给我一些提示代码或例子或指导来开始写这篇文章吗在最后调用super.paintComponents时,显示正常按钮I mena,颜色丢失。我想保留颜色,同时显示文本。你所说的“调用所有渐变绘制代码”是什么意思?显然,背景是以某种方式绘制的。尝试检查调用getBackground()的位置。尝试在super之前将background()设置为透明颜色,并在.mKorbel之后重置。如果用户更改颜色,我可以更改背景颜色(请参见Q中的注释)。在这种情况下,我将能够经常替换默认背景,并对其进行更新。mKorbel创建了BasicButtonUI的子类,但这并不仅仅显示按钮。以下是我实现的类:我在该类中哪里出错了。@Tvd查看我的编辑,我从代码中提取paintText,将MetalXxxXx更改为BasicXxxXx,并更改颜色(仅用于测试目的),我看不出有什么错误,请检查并还原否,否,否。。。a) 不要做自定义字符串绘图b)不要动态扩展UISomething(很难做到正确,而且必须对所有受支持的LAF进行扩展)c)即使是最简单的LAF(如f.i.Metal),也不要覆盖基本的UISomething(如果有MetalSomething)d)确保解决方案代码比问题代码更干净,毕竟,在回答问题时,你扮演的是专家的角色;-)@mKorbel,是的,你的代码起作用了。但这会在水平方向上产生梯度&我想要垂直方向。我用我的paintComponent()代码替换了paint的内容,它确实起了作用。对于文本,我调用了paintText,虽然在您的版本中,您不需要调用,但我必须调用其他,因为没有可见的文本。在paint()中,我将JComponent强制转换为AbstractButton,并像调用paintText()时在其他paint方法中一样传递其边界和文本。但是文本在左上角可见,而不是在绘制代码中显示的中心。为什么会有这种差异?正如您在更新的cade中所看到的,我实现了set不透明和setContentAreaFilled。还增加了拉绳。但是字符串在任何情况下都是不可见的。@Tvd您仍然没有将超级调用移到方法的末尾,我试过了。如果我这样做,那么所有的颜色变化都消失了,默认颜色出现了。所以我又换到了顶部,我试着把L&F换成Motif,然后换成它的工作方式。现在我不使用任何抽绳。非常感谢。+1接得好!甚至没看到他/她在拉绳子。这是错误的,正如我们所知:-)让ui尽可能多地处理kleopatra建议的,drawString()方法甚至不应该被使用。当drawString()方法被删除,并且在Paint对象恢复为原始Paint之后添加了
super.paintComponent(g)
时,海报代码对我来说效果很好。。您真的需要恢复图形的状态吗?没有(我天生懒惰:-)你的权利!我也很懒。我懒得在测试之前删除代码行:)仍然没有将super.paintComponent移到末尾。。。为什么不呢?不要走任何阴暗的小路(如手动绘制文本,f.i.)。。手头的任务是找出为什么我发布的解决方案(并由Rob检查)不适用于您的环境(就像在我们的环境中一样),并在您遇到问题时展示SSCCE。我的直觉告诉我还有什么不对劲。。。