在swing上圆滑的圆角

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

这是截图:

1. JFrame的setShape()

在此处输入图像描述

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

在此处输入图像描述

3. JFrame的setBackground(new Color(0, 0, 0, 0))

在此处输入图像描述

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

在第3步之前:

在此处输入图像描述

在第3步之后:

在此处输入图像描述

伙计们我很困惑,我已多次搜索,但没有任何帮助我…我该怎么办? 请帮我

这是完整的代码:

 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  0) { r--; } else if (g == 220 && r == 0 && b  0) { g--; } else if (b == 220 && g == 0 && r  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); } } 

谢谢。

对不起,不是答案,但希望至少朝着可接受的答案迈出一步:从我到目前为止的分析来看,这可能只是一个在渲染管道内某处深处(深夜!)的错误。

以下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; 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); } } 

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

TextRenderBug

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

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

  • 该行为以某种方式由sun.swing.SwingUtilities2类的drawString方法引起
  • 它不会出现在所有组件中。 它可以在JButtonJLabel上观察到,但不能在普通的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; 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(); } } } } 

我已经尝试进一步分析这个,并使用像KEY_TEXT_ANTIALIASINGKEY_TEXT_LCD_CONTRAST这样的KEY_TEXT_ANTIALIASING以及在绘制管道中更改的其他设置,当它朝向最终放置在屏幕上的像素时,但直到现在还没有进一步的见解。

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

你唯一的机会是与地区合作。 您需要硬编码并使用减法,但最终它看起来会很好。 您可以在mylyn的通知类中查看它是如何完成的: http : //grepcode.com/file/repository.grepcode.com/java/eclipse.org/3.6/org.eclipse.mylyn.commons/ui/3.4。 0 /组织/蚀/ Mylyn的/内部/临时/公地/ UI / AbstractNotificationPopup.java

希望它有所帮助,祝你好运!

编辑:记住这个可能有用的小教程: http : //www.java2s.com/Code/Java/SWT-JFace-Eclipse/SWTShellcreateanonrectangularwindow.htm