在秋千上圆滑的圆角 [英] smooth rounded corners in swing

查看:143
本文介绍了在秋千上圆滑的圆角的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想为我的挥杆应用做出光滑的圆角,但我无法得到我想要的结果...



这里是截图:



1. setShape() for JFrame:





2.覆盖 paintComponent() JPanel的方法,而不是使用 setShape()



< img src =https://i.stack.imgur.com/xVnKl.pngalt =在此处输入图像说明>



3。 jFrame的setBackground(new Color(0,0,0,0))





好吧,但文字质量有问题:

$ 3
$ b

在第3步之前:





在第3步之后:





伙计们我很困惑,我搜索过很多次但没有帮助我...... b $ b我该怎么办?请帮助我



这里是完整代码:

  public class WelcomePage扩展JFrame {

private Point initialClick;
private boolean end = false;
private JLabel jLabelAppTitle;
private JPanel jPanelExit;
private JLabel jLabelHint;
private int r = 220,g = 0,b = 0;
private int r2 = 10,g2 = 10,b2 = 10;
private boolean flag = false;

public WelcomePage(){
initComponents();
// setShape(new RoundRectangle2D.Double(0,0,getWidth(),getHeight(),15,15));
centerLocation();
refreshPage();
}

public static void main(String args []){
try {
for(UIManager.LookAndFeelInfo info:UIManager.getInstalledLookAndFeels()){
if(Nimbus.equals(info.getName())){
UIManager.setLookAndFeel(info.getClassName());
休息;
}
}
} catch(ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e){
e.printStackTrace();
}
EventQueue.invokeLater(() - > FadeTransitions.fadeIn(new WelcomePage(),FadeTransitions.NORMAL_FADE,true));
}

private void refreshPage(){
定时器计时器=新计时器(20,e - > {
if(!end){
if(r == 220&& b == 0&& g< 220){
g ++;
}否则if(g == 220&& b == 0 && r> 0){
r--;
}否则if(g == 220&& r == 0&& b< 220){
b ++;
}否则if(b == 220&& r == 0&& g> 0){
g--;
}否则if(例如,如果(r == 220&& g == 0& & b> 0){
b--;
}
if(!flag){
r2 + = 5;
g2 + = 5;
b2 + = 5;
if(r2 == 250){
flag = true;
}
} e lse {
r2 - = 5;
g2 - = 5;
b2 - = 5;
if(r2 == 10){
flag = false;
}
}
jLabelAppTitle.setForeground(new Color(r,g,b));
jLabelHint.setForeground(new Color(r2,g2,b2));
} else {
((Timer)e.getSource())。stop();
}
});
timer.setCoalesce(true);
timer.setRepeats(true);
timer.start();
}

private void centerLocation()抛出HeadlessException {
final Toolkit toolkit = Toolkit.getDefaultToolkit();
final Dimension screenSize = toolkit.getScreenSize();
final int x =(screenSize.width - this.getWidth())/ 2;
final int y =(screenSize.height - this.getHeight())/ 2;
this.setLocation(x,y);
}

@SuppressWarnings(unchecked)
private void initComponents(){

JPanel jPanelMain = new JPanel(){
@Override
protected void paintComponent(Graphics g){
Graphics2D g2 =(Graphics2D)g.create();
RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
qualityHints.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHints(qualityHints);
g2.setPaint(Color.WHITE);
g2.fillRoundRect(0,0,getWidth(),getHeight(),25,25);
g2.dispose();
}
};
jPanelExit = new JPanel();
JLabel jLabelExit = new JLabel();
JLabel jLabelWelcome = new JLabel();
jLabelAppTitle = new JLabel();
jLabelHint = new JLabel();
JButton jButtonGo = new JButton();
setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
setTitle(欢迎来到我的应用程序!);
setUndecorated(true);
setBackground(new Color(0,0,0,0));

addWindowListener(new WindowAdapter(){
@Override
public void windowClosing(WindowEvent e){
close();
}
});
addMouseMotionListener(new java.awt.event.MouseMotionAdapter(){
public void mouseDragged(MouseEvent evt){
thisMouseDragged(evt);
}
});
addMouseListener(new java.awt.event.MouseAdapter(){
public void mousePressed(MouseEvent evt){
thisMousePressed(evt);
}
});

jPanelMain.setBackground(Color.WHITE);
jPanelExit.setBackground(new Color(160,0,20));

jLabelExit.setFont(new Font(Tahoma,Font.BOLD,13));
jLabelExit.setForeground(new Color(255,255,255));
jLabelExit.setHorizo​​ntalAlignment(SwingConstants.CENTER);
jLabelExit.setText(X);
jLabelExit.setCursor(new Cursor(Cursor.HAND_CURSOR));
jLabelExit.addMouseListener(new java.awt.event.MouseAdapter(){
public void mouseClicked(MouseEvent evt){
jLabelExitMouseClicked();
}

public void mouseEntered(MouseEvent evt){
jLabelExitMouseEntered();
}

public void mouseExited(MouseEvent evt){
jLabelExitMouseExited();
}
});

GroupLayout jPanelExitLayout = new GroupLayout(jPanelExit);
jPanelExit.setLayout(jPanelExitLayout);
jPanelExitLayout.setHorizo​​ntalGroup(
jPanelExitLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(GroupLayout.Alignment.TRAILING,jPanelExitLayout.createSequentialGroup()
.addGap(0,0) ,Short.MAX_VALUE)
.addComponent(jLabelExit,GroupLayout.PREFERRED_SIZE,45,GroupLayout.PREFERRED_SIZE))
);
jPanelExitLayout.setVerticalGroup(
jPanelExitLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
.addGroup(GroupLayout.Alignment.TRAILING,jPanelExitLayout.createSequentialGroup()
.addGap(0,0) ,Short.MAX_VALUE)
.addComponent(jLabelExit,GroupLayout.PREFERRED_SIZE,22,GroupLayout.PREFERRED_SIZE))
);

jLabelWelcome.setFont(new Font(Tahoma,0,25));
jLabelWelcome.setForeground(new Color(0,0,100));
jLabelWelcome.setHorizo​​ntalAlignment(SwingConstants.CENTER);
jLabelWelcome.setText(欢迎);

jLabelAppTitle.setFont(new Font(MV Boli,0,29));
jLabelAppTitle.setHorizo​​ntalAlignment(SwingConstants.CENTER);
jLabelAppTitle.setText(我的秋千应用程序);

jButtonGo.setBackground(new Color(100,20,80));
jButtonGo.setFont(new Font(Tahoma,0,15));
jButtonGo.setForeground(new Color(255,255,255));
jButtonGo.setText(GO);
jButtonGo.addActionListener(evt - > jButtonGoActionPerformed());

jLabelHint.setFont(new Font(Tahoma,0,11));
jLabelHint.setHorizo​​ntalAlignment(SwingConstants.CENTER);
jLabelHint.setText(按下GO按钮);

javax.swing.GroupLayout jPanelMainLayout = new javax.swing.GroupLayout(jPanelMain);
jPanelMain.setLayout(jPanelMainLayout);
jPanelMainLayout.setHorizo​​ntalGroup(
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanelMainLayout.createSequentialGroup()
.addContainerGap(48,Short.MAX_VALUE) )
.addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(javax.swing.GroupLayout.Alignment.TRAILING,jPanelMainLayout.createSequentialGroup()
.addGap (0,0,Short.MAX_VALUE)
.addComponent(jPanelExit,javax.swing.GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(15 ,15,15))
.addGroup(jPanelMainLayout.createSequentialGroup()
.addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING,false)
.addComponent(jLabelWelcome,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE)
.addComponent(jLabelAppTitle,javax.swing.GroupLayout.DEFAULT_SIZE,220,Short.MAX_VALUE)
.addComponent(jLabelHint,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE)
.addComponent(jButtonGo,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,Short.MAX_VALUE))
.addContainerGap(48,Short.MAX_VALUE))))
);
jPanelMainLayout.setVerticalGroup(
jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(jPanelMainLayout.createSequentialGroup()
.addComponent(jPanelExit,javax.swing) .GroupLayout.PREFERRED_SIZE,javax.swing.GroupLayout.DEFAULT_SIZE,javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(64,64,64)
.addComponent(jLabelWelcome,javax.swing.GroupLayout.PREFERRED_SIZE ,28,javax.swing.GroupLayout.PREFERRED_SIZE)
.addGap(98,98,98)
.addComponent(jLabelAppTitle)
.addGap(86,86,86)
.addComponent(jLabelHint)
.addGap(24,24,24)
.addComponent(jButtonGo,javax.swing.GroupLayout.PREFERRED_SIZE,40,javax.swing.GroupLayout。 PREFERRED_SIZE)
.addGap(86,86,86))
);

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane()。setLayout(layout);
layout.setHorizo​​ntalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0,0,0) )
.addComponent(jPanelMain,javax.swing.GroupLayout.DEFAULT_SIZE,316,Short.MAX_VALUE)
.addGap(0,0,0))
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGroup(layout.createSequentialGroup()
.addGap(0,0,0) )
.addComponent(jPanelMain,javax.swing.GroupLayout.DEFAULT_SIZE,473,Short.MAX_VALUE)
.addGap(0,0,0))
);

pack();
}

private void thisMousePressed(MouseEvent evt){
initialClick = evt.getPoint();
}

private void thisMouseDragged(MouseEvent evt){
int thisX = this.getLocation()。x;
int thisY = this.getLocation()。y;
int xMoved =(thisX + evt.getX()) - (thisX + initialClick.x);
int yMoved =(thisY + evt.getY()) - (thisY + initialClick.y);
int x = thisX + xMoved;
int y = thisY + yMoved;
this.setLocation(x,y);
}

private void jLabelExitMouseClicked(){
close();
}

private void close(){
end = true;
FadeTransitions.fadeOut(this,FadeTransitions.FAST_FADE,FadeTransitions.EXIT_ON_CLOSE);
}

private void jLabelExitMouseEntered(){
jPanelExit.setBackground(new Color(200,0,20));
}

private void jLabelExitMouseExited(){
jPanelExit.setBackground(new Color(160,0,20));
}

private void jButtonGoActionPerformed(){
end = true;
FadeTransitions.run(这个,新的ServerManager(this),FadeTransitions.NORMAL_FADE,FadeTransitions.DISPOSE_ON_CLOSE);
}

}

谢谢。

解决方案

对不起,不是答案,但希望至少朝着可接受的答案迈出一步:从我迄今为止的分析来看,可能

以下 MVCE 显示两个(未修饰的)帧,每个帧包含一个按钮。它们是相同的,除了用于帧的背景。对于一帧,颜色是透明的,而对于另一帧,它是不透明的。

  import java.awt.Color; 
import java.awt.Font;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

公共类TextRenderBug扩展JFrame {

public static void main(String [] args)
{
setLookAndFeel();
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI(new Color(0,0, 0),400);
createAndShowGUI(new Color(0,0,0,0),600);
}
});
}

private static void setLookAndFeel()
{
try
{
for(UIManager.LookAndFeelInfo info:
UIManager .getInstalledLookAndFeels())
{
if(Nimbus.equals(info.getName()))
{
UIManager.setLookAndFeel(info.getClassName());
休息;
}
}
}
catch(例外e)
{
e.printStackTrace();
}
}

private static void createAndShowGUI(Color background,int x)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(背景);
JButton b = new JButton(Text);
b.setFont(new Font(Tahoma,0,15));
f.getContentPane()。add(b);
f.setBounds(x,400,200,50);
f.setVisible(true);
}
}

它清楚地显示文本已呈现不同的,完全取决于背景是否透明 - 当然,情况并非如此。





(顺便说一下,这不是Nimbus特有的:它也适用于其他LookAndFeel。只需删除设置LaF的行。)



<到目前为止我发现了什么:




  • 行为是由 drawString sun.swing.SwingUtilities2的方法

  • 它不会出现在所有组件中。它可以在 JButton JLabel 上观察到,但不能在正常的 JComponent

  • 更新:它也不依赖于字体(尽管使用其他字体,效果并不那么明显)。正确渲染时,字体看起来更粗体,但当然,它不是与 Font.BOLD 相同的字体。

  • 绘画过程相当复杂。



(好吧,有些人可能已经有了已知后者)。



这是一个显示最后观察结果的例子,也许它可以作为进一步研究其他人的起点:

  import java.awt.Color; 
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.lang.reflect.Method;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

公共类TextRenderBugTest
{
public static void main(String [] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI(new Color(0,0,0),400);
createAndShowGUI(new Color( 0,0,0,0),600);
}
});
}

private static void createAndShowGUI(Color background,int x)
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setUndecorated(true);
f.setBackground(背景);

JButton b = new JButton(Text);
b.setFont(new Font(Tahoma,0,15));

JComponent c = new ExampleComponent();
c.setFont(new Font(Tahoma,0,15));

f.getContentPane()。setLayout(new GridLayout(0,1));
f.getContentPane()。add(b);
f.getContentPane()。add(c);

f.setBounds(x,400,200,100);
f.setVisible(true);
}

静态类ExampleComponent
//扩展JComponent
扩展JButton
{
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(getBackground());
g.fillRect(0,0,getWidth(),getHeight());
g.setColor(getForeground());
g.drawString(Text,10,20);
drawStringWithSwingUtilities(g,60,20);
}

private void drawStringWithSwingUtilities(Graphics g,int x,int y)
{
try
{
Class<?> c = Class.forName(sun.swing.SwingUtilities2);
方法m = c.getMethod(drawString,JComponent.class,
Graphics.class,String.class,int.class,int.class);
m.invoke(null,this,g,Text,x,y);
}
catch(例外e)
{
e.printStackTrace();
}

}

}

}

我已经尝试进一步分析了这个,并且玩 RenderingHints ,如 KEY_TEXT_ANTIALIASING KEY_TEXT_LCD_CONTRAST 以及在绘制管道中朝向最终放置在屏幕上的像素时更改的其他设置,但直到现在还没有进一步的见解。 / p>

(如果您愿意,可以将此信息添加到原始问题中,然后我将删除此(不是)答案)


I want to make smooth rounded corners for my swing application, but I can't get my desired result...

here's the screenshots:

1.setShape() for JFrame :

2.overriding paintComponent() method for JPanel instead of using setShape() :

3.setBackground(new Color(0, 0, 0, 0)) for JFrame :

well, but there's a problem with text quality:

before step 3 :

after step 3 :

guys I'm confused, I've searched many times but nothing helped me... what should I do? please help me

here's the full code :

public class WelcomePage extends JFrame {

private Point initialClick;
private boolean end = false;
private JLabel jLabelAppTitle;
private JPanel jPanelExit;
private JLabel jLabelHint;
private int r = 220, g = 0, b = 0;
private int r2 = 10, g2 = 10, b2 = 10;
private boolean flag = false;

public WelcomePage() {
    initComponents();
//    setShape(new RoundRectangle2D.Double(0, 0, getWidth(), getHeight(), 15, 15));
    centerLocation();
    refreshPage();
}

public static void main(String args[]) {
    try {
        for (UIManager.LookAndFeelInfo info : UIManager.getInstalledLookAndFeels()) {
            if ("Nimbus".equals(info.getName())) {
                UIManager.setLookAndFeel(info.getClassName());
                break;
            }
        }
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }
    EventQueue.invokeLater(() -> FadeTransitions.fadeIn(new WelcomePage(), FadeTransitions.NORMAL_FADE, true));
}

private void refreshPage() {
    Timer timer = new Timer(20, e -> {
        if (!end) {
            if (r == 220 && b == 0 && g < 220) {
                g++;
            } else if (g == 220 && b == 0 && r > 0) {
                r--;
            } else if (g == 220 && r == 0 && b < 220) {
                b++;
            } else if (b == 220 && r == 0 && g > 0) {
                g--;
            } else if (b == 220 && g == 0 && r < 220) {
                r++;
            } else if (r == 220 && g == 0 && b > 0) {
                b--;
            }
            if (!flag) {
                r2 += 5;
                g2 += 5;
                b2 += 5;
                if (r2 == 250) {
                    flag = true;
                }
            } else {
                r2 -= 5;
                g2 -= 5;
                b2 -= 5;
                if (r2 == 10) {
                    flag = false;
                }
            }
            jLabelAppTitle.setForeground(new Color(r, g, b));
            jLabelHint.setForeground(new Color(r2, g2, b2));
        } else {
            ((Timer) e.getSource()).stop();
        }
    });
    timer.setCoalesce(true);
    timer.setRepeats(true);
    timer.start();
}

private void centerLocation() throws HeadlessException {
    final Toolkit toolkit = Toolkit.getDefaultToolkit();
    final Dimension screenSize = toolkit.getScreenSize();
    final int x = (screenSize.width - this.getWidth()) / 2;
    final int y = (screenSize.height - this.getHeight()) / 2;
    this.setLocation(x, y);
}

@SuppressWarnings("unchecked")
private void initComponents() {

    JPanel jPanelMain = new JPanel() {
        @Override
        protected void paintComponent(Graphics g) {
            Graphics2D g2 = (Graphics2D) g.create();
            RenderingHints qualityHints = new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
            qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
            g2.setRenderingHints(qualityHints);
            g2.setPaint(Color.WHITE);
            g2.fillRoundRect(0, 0, getWidth(), getHeight(), 25, 25);
            g2.dispose();
        }
    };
    jPanelExit = new JPanel();
    JLabel jLabelExit = new JLabel();
    JLabel jLabelWelcome = new JLabel();
    jLabelAppTitle = new JLabel();
    jLabelHint = new JLabel();
    JButton jButtonGo = new JButton();
    setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
    setTitle("welcome to My App!");
    setUndecorated(true);
    setBackground(new Color(0, 0, 0, 0));

    addWindowListener(new WindowAdapter() {
        @Override
        public void windowClosing(WindowEvent e) {
            close();
        }
    });
    addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
        public void mouseDragged(MouseEvent evt) {
            thisMouseDragged(evt);
        }
    });
    addMouseListener(new java.awt.event.MouseAdapter() {
        public void mousePressed(MouseEvent evt) {
            thisMousePressed(evt);
        }
    });

    jPanelMain.setBackground(Color.WHITE);
    jPanelExit.setBackground(new Color(160, 0, 20));

    jLabelExit.setFont(new Font("Tahoma", Font.BOLD, 13));
    jLabelExit.setForeground(new Color(255, 255, 255));
    jLabelExit.setHorizontalAlignment(SwingConstants.CENTER);
    jLabelExit.setText("X");
    jLabelExit.setCursor(new Cursor(Cursor.HAND_CURSOR));
    jLabelExit.addMouseListener(new java.awt.event.MouseAdapter() {
        public void mouseClicked(MouseEvent evt) {
            jLabelExitMouseClicked();
        }

        public void mouseEntered(MouseEvent evt) {
            jLabelExitMouseEntered();
        }

        public void mouseExited(MouseEvent evt) {
            jLabelExitMouseExited();
        }
    });

    GroupLayout jPanelExitLayout = new GroupLayout(jPanelExit);
    jPanelExit.setLayout(jPanelExitLayout);
    jPanelExitLayout.setHorizontalGroup(
            jPanelExitLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(GroupLayout.Alignment.TRAILING, jPanelExitLayout.createSequentialGroup()
                            .addGap(0, 0, Short.MAX_VALUE)
                            .addComponent(jLabelExit, GroupLayout.PREFERRED_SIZE, 45, GroupLayout.PREFERRED_SIZE))
    );
    jPanelExitLayout.setVerticalGroup(
            jPanelExitLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                    .addGroup(GroupLayout.Alignment.TRAILING, jPanelExitLayout.createSequentialGroup()
                            .addGap(0, 0, Short.MAX_VALUE)
                            .addComponent(jLabelExit, GroupLayout.PREFERRED_SIZE, 22, GroupLayout.PREFERRED_SIZE))
    );

    jLabelWelcome.setFont(new Font("Tahoma", 0, 25));
    jLabelWelcome.setForeground(new Color(0, 0, 100));
    jLabelWelcome.setHorizontalAlignment(SwingConstants.CENTER);
    jLabelWelcome.setText("Welcome");

    jLabelAppTitle.setFont(new Font("MV Boli", 0, 29));
    jLabelAppTitle.setHorizontalAlignment(SwingConstants.CENTER);
    jLabelAppTitle.setText("My Swing App");

    jButtonGo.setBackground(new Color(100, 20, 80));
    jButtonGo.setFont(new Font("Tahoma", 0, 15));
    jButtonGo.setForeground(new Color(255, 255, 255));
    jButtonGo.setText("GO");
    jButtonGo.addActionListener(evt -> jButtonGoActionPerformed());

    jLabelHint.setFont(new Font("Tahoma", 0, 11));
    jLabelHint.setHorizontalAlignment(SwingConstants.CENTER);
    jLabelHint.setText("press GO button");

    javax.swing.GroupLayout jPanelMainLayout = new javax.swing.GroupLayout(jPanelMain);
    jPanelMain.setLayout(jPanelMainLayout);
    jPanelMainLayout.setHorizontalGroup(
            jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelMainLayout.createSequentialGroup()
                            .addContainerGap(48, Short.MAX_VALUE)
                            .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanelMainLayout.createSequentialGroup()
                                            .addGap(0, 0, Short.MAX_VALUE)
                                            .addComponent(jPanelExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                                            .addGap(15, 15, 15))
                                    .addGroup(jPanelMainLayout.createSequentialGroup()
                                            .addGroup(jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING, false)
                                                    .addComponent(jLabelWelcome, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                    .addComponent(jLabelAppTitle, javax.swing.GroupLayout.DEFAULT_SIZE, 220, Short.MAX_VALUE)
                                                    .addComponent(jLabelHint, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                                                    .addComponent(jButtonGo, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                                            .addContainerGap(48, Short.MAX_VALUE))))
    );
    jPanelMainLayout.setVerticalGroup(
            jPanelMainLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(jPanelMainLayout.createSequentialGroup()
                            .addComponent(jPanelExit, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGap(64, 64, 64)
                            .addComponent(jLabelWelcome, javax.swing.GroupLayout.PREFERRED_SIZE, 28, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGap(98, 98, 98)
                            .addComponent(jLabelAppTitle)
                            .addGap(86, 86, 86)
                            .addComponent(jLabelHint)
                            .addGap(24, 24, 24)
                            .addComponent(jButtonGo, javax.swing.GroupLayout.PREFERRED_SIZE, 40, javax.swing.GroupLayout.PREFERRED_SIZE)
                            .addGap(86, 86, 86))
    );

    javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
    getContentPane().setLayout(layout);
    layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                            .addGap(0, 0, 0)
                            .addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE)
                            .addGap(0, 0, 0))
    );
    layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(layout.createSequentialGroup()
                            .addGap(0, 0, 0)
                            .addComponent(jPanelMain, javax.swing.GroupLayout.DEFAULT_SIZE, 473, Short.MAX_VALUE)
                            .addGap(0, 0, 0))
    );

    pack();
}

private void thisMousePressed(MouseEvent evt) {
    initialClick = evt.getPoint();
}

private void thisMouseDragged(MouseEvent evt) {
    int thisX = this.getLocation().x;
    int thisY = this.getLocation().y;
    int xMoved = (thisX + evt.getX()) - (thisX + initialClick.x);
    int yMoved = (thisY + evt.getY()) - (thisY + initialClick.y);
    int x = thisX + xMoved;
    int y = thisY + yMoved;
    this.setLocation(x, y);
}

private void jLabelExitMouseClicked() {
    close();
}

private void close() {
    end = true;
    FadeTransitions.fadeOut(this, FadeTransitions.FAST_FADE, FadeTransitions.EXIT_ON_CLOSE);
}

private void jLabelExitMouseEntered() {
    jPanelExit.setBackground(new Color(200, 0, 20));
}

private void jLabelExitMouseExited() {
    jPanelExit.setBackground(new Color(160, 0, 20));
}

private void jButtonGoActionPerformed() {
    end = true;
    FadeTransitions.run(this, new ServerManager(this), FadeTransitions.NORMAL_FADE, FadeTransitions.DISPOSE_ON_CLOSE);
}

}

thanks.

解决方案

Sorry, not an answer, but hopefully at least one step towards an acceptable answer: From my analysis so far, it might be that this is simply a bug somewhere deep (deeeep!) inside the rendering pipeline.

The following MVCE shows two (undecorated) frames, each containing a button. They are equal, except for the background of the frames. For one frame, the color is transparent, and for the other one, it is opaque.

import java.awt.Color;
import java.awt.Font;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class TextRenderBug extends JFrame {

    public static void main(String[] args)
    {
        setLookAndFeel();
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI(new Color(0,0,0  ), 400);
                createAndShowGUI(new Color(0,0,0,0), 600);
            }
        });
    }

    private static void setLookAndFeel()
    {
        try
        {
            for (UIManager.LookAndFeelInfo info : 
                    UIManager.getInstalledLookAndFeels())
            {
                if ("Nimbus".equals(info.getName()))
                {
                    UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        }
        catch (Exception e)
        {
            e.printStackTrace();
        }
    }

    private static void createAndShowGUI(Color background, int x)
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setUndecorated(true);
        f.setBackground(background);
        JButton b = new JButton("Text");
        b.setFont(new Font("Tahoma", 0, 15));
        f.getContentPane().add(b);
        f.setBounds(x, 400, 200, 50);
        f.setVisible(true);
    }
}

It clearly shows that the text is rendered differently, solely depending on the background being transparent - and of course, this should not be the case.

(This is not Nimbus-specific, by the way: It also applies to other LookAndFeels. Just remove the line where the LaF is set).

What I found out so far:

  • The behavior is somehow caused by the drawString method of the sun.swing.SwingUtilities2 class
  • It does not appear in all components. It can be observed on JButton and JLabel, but not on a normal JComponent
  • Update: It also does not depend on the font (although with other fonts, the effect is not so noticable). When rendered correctly, the font looks a little bit more bold, but of course, it is not simply the same font as a Font.BOLD.
  • The painting process is rather complicated.

(OK, some of you might already have known the latter).

Here is an example that shows the last observations, maybe it can serve as a starting point for further research of others:

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.lang.reflect.Method;

import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

public class TextRenderBugTest
{
    public static void main(String[] args)
    {
        SwingUtilities.invokeLater(new Runnable()
        {
            @Override
            public void run()
            {
                createAndShowGUI(new Color(0,0,0  ), 400);
                createAndShowGUI(new Color(0,0,0,0), 600);
            }
        });
    }

    private static void createAndShowGUI(Color background, int x)
    {
        JFrame f = new JFrame();
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.setUndecorated(true);
        f.setBackground(background);

        JButton b = new JButton("Text");
        b.setFont(new Font("Tahoma", 0, 15));

        JComponent c = new ExampleComponent();
        c.setFont(new Font("Tahoma", 0, 15));

        f.getContentPane().setLayout(new GridLayout(0,1));
        f.getContentPane().add(b);
        f.getContentPane().add(c);

        f.setBounds(x, 400, 200, 100);
        f.setVisible(true);
    }

    static class ExampleComponent 
        //extends JComponent
        extends JButton
    {
        @Override
        protected void paintComponent(Graphics g)
        {
            super.paintComponent(g);
            g.setColor(getBackground());
            g.fillRect(0, 0, getWidth(), getHeight());
            g.setColor(getForeground());
            g.drawString("Text", 10, 20);
            drawStringWithSwingUtilities(g, 60, 20);
        }

        private void drawStringWithSwingUtilities(Graphics g, int x, int y)
        {
            try
            {
                Class<?> c = Class.forName("sun.swing.SwingUtilities2");
                Method m = c.getMethod("drawString", JComponent.class,
                    Graphics.class, String.class, int.class, int.class);
                m.invoke(null, this, g, "Text", x, y);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }

        }

    }

}

I already tried to analyze this further, and played around with RenderingHints like KEY_TEXT_ANTIALIASING and KEY_TEXT_LCD_CONTRAST and other settings that are changed in the painting pipeline while it is heading towards the pixels that are finally placed on the screen, but no further insights until now.

(If you want to, you can add this information to your original question, then I'll delete this (not-)answer)

这篇关于在秋千上圆滑的圆角的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆