gpt4 book ai didi

java - JPanel 何时绘制(或重新绘制)其子组件?

转载 作者:搜寻专家 更新时间:2023-11-01 01:57:31 24 4
gpt4 key购买 nike

我有一个使用自定义 UI 委托(delegate)绘制的 JButton(CustomButtonUI 扩展了 BasicButtonUI)。 CustomButtonUI 的 paint() 方法绘制带有“抗锯齿”圆角的按钮,使外观尽可能“平滑”。

每次我将鼠标拖到按钮。这使得按钮边缘看起来“像素化”。但是,一旦我添加了一行代码来重新绘制按钮的父项,即使我将鼠标拖到按钮上,抗锯齿功能也会启动。

现在,我的问题是这是否是个好主意?毕竟我会从子组件重新绘制父组件。我想知道这是否会导致重绘循环?如果 parent 尝试重绘其子项,而子项尝试重绘其父项 - 那么我假设我们正在谈论一个循环。

我附上了我的代码作为引用。非常欢迎任何意见!

public class JCustomButtonUI extends BasicButtonUI {

@Override
public void installUI(JComponent c) {
super.installUI(c);

AbstractButton b = (AbstractButton) c;
b.setBorderPainted(false);
}

@Override
public void paint(Graphics g, JComponent c) {

//Cast the Graphics instance to a Graphics2D instance.
Graphics2D g2d = (Graphics2D) g;
JButton b = (JButton) c;

//Repaint parent component to make sure that we get "antialiased"
//edges.
b.getParent().repaint();

//Get the component's height and width.
int w = (int) g.getClipBounds().getWidth();
int h = ((int) g.getClipBounds().getHeight());

//Make sure the button is drawn with "antialiased" edges.
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.GRAY);
g2d.fillRoundRect(0, 0, w, h, w, h);
}
}

更新 1

只是为了说明锯齿和抗锯齿的边框,请看下面的两张图片。当我(从 ButtonUI 的 paint() 方法)手动调用父 JPanel 的重绘方法时,所有边框都始终完美抗锯齿。但是,当我不手动调用父级 JPanel 的重绘方法时,一旦我将鼠标悬停在按钮上,边框就不再抗锯齿。

Aliased Antialiased

更新2

我已经在 Snipt 上分享了整个“组件”,它由一个 JPanel、一个 JSlider 和几个 JButton 组成。请从http://snipt.org/wnllg获取.

更新3

看来我已经设法让它工作了。我没有在其 paintComponent() 方法中绘制 JPanel 的背景,而是创建了一个安装在 JPanel 上的 JCustomPanelUI。我认为这不是解决方案本身,但我没有使用 Graphics 实例的宽度和高度,而是尝试使用 JPanel 本身的宽度和高度。当我使用 Graphics 实例的宽度和高度时,我不太确定为什么会出错。我认为 Graphics 实例的宽度和高度已经根据 JPanel 组件的尺寸“准备好”了。您可以在这里查看最终组件:http://snipt.org/wnlli ,

最佳答案

我已将示例缩减为仅抗锯齿,但我无法重现该问题。它似乎不依赖于平台。我不确定您为什么要使用 getClipBounds()

附录:

The JPanel background (a gradient) needs to shine through…

我更新了示例以在透明按钮后面使用渐变背景;我并排放置了抗锯齿(左)和锯齿(右)示例。我没有看到意外的行为。

ButtonUITest.png

import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.RenderingHints;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.plaf.basic.BasicButtonUI;

/** @see http://stackoverflow.com/questions/5169647 */
public class ButtonUITest extends JPanel {

public ButtonUITest() {
this.setLayout(new GridLayout(1, 0));
this.setPreferredSize(new Dimension(640, 480));
this.add(new CustomButton(true));
this.add(new CustomButton(false));
}

@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int w = this.getWidth();
int h = this.getHeight();
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(new GradientPaint(0, 0, Color.blue, w, h, Color.red));
g2d.fillRect(0, 0, w, h);
}

private void display() {
JFrame f = new JFrame("ButtonUITest");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(this);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}

private static class CustomButton extends JButton {

public CustomButton(boolean antialiased) {
this.setOpaque(false);
this.setUI(new CustomButtonUI(antialiased));
}
}

private static class CustomButtonUI extends BasicButtonUI {

private boolean antialiased;

public CustomButtonUI(boolean antialiased) {
this.antialiased = antialiased;
}

@Override
public void paint(Graphics g, JComponent c) {
int w = c.getWidth();
int h = c.getHeight();
Graphics2D g2d = (Graphics2D) g;
if (antialiased) {
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
}
g2d.setColor(Color.LIGHT_GRAY);
g2d.fillOval(0, 0, w, 2 * h);
}
}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

@Override
public void run() {
new ButtonUITest().display();
}
});
}
}

关于java - JPanel 何时绘制(或重新绘制)其子组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5169647/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com