Я вызвал setOpaque (false) на JButton, чтобы фон просвечивал. Это отлично работает. Края кнопок также сначала идеально сглаживаются на фоне. Однако, когда я наведу курсор мыши на кнопку, ее края станут пиксельными. Единственным выходом из этого (до сих пор) было запросить родительский компонент JButton (JPanel) сначала перерисовать себя. Тем не менее, я не слишком доволен этим, поскольку на ButtonUI теперь возложена обязанность позаботиться о том, чтобы родительский элемент кнопки был перекрашен раньше, чем сама кнопка. Лучшее решение должно быть там ...
я есть JButton, который нарисован с использованием пользовательского интерфейса делегата (CustomButtonUI расширяет BasicButtonUI). Метод paint () в CustomButtonUI рисует кнопку с закругленными «сглаженными» углами, чтобы сделать внешний вид как можно более «плавным».
Каким-то образом «сглаженные» края кнопки исчезают каждый раз, когда я перетаскиваю мышь над кнопкой. Это заставляет края кнопки выглядеть «пикселизированными». Однако, как только я добавляю строку кода, чтобы перекрасить родительский элемент кнопки, сглаживание включается, даже когда я перетаскиваю мышь над кнопкой.
Теперь мой вопрос касается того, хорошая ли это идея? Я все-таки перекрашиваю родительский компонент из дочернего компонента. Интересно, приведет ли это к циклу перекрасок? Если родитель пытается перекрасить своих детей, и дети пытаются перекрасить своих родителей - тогда я предполагаю, что мы говорим о цикле.
Я приложил свой код в качестве ссылки. Любые комментарии очень приветствуются!
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Просто, чтобы проиллюстрировать псевдоним и сглаженную границу, взгляните на две ниже картинки. Когда я (из метода paintUI ButtonUI) вручную вызывает метод перерисовки родительского JPanel, все границы всегда идеально сглаживаются. Однако, когда я не вызываю вручную метод перерисовки родительского JPanel, границы больше не сглаживаются, когда я наводю указатель мыши на кнопку.
Обновление 2
Я поделился всем «компонентом», который состоит из JPanel, JSlider и нескольких кнопок J на Snipt. Пожалуйста, получите это отhttp://snipt.org/wnllg.
Обновление 3Кажется, мне удалось заставить его работать. Вместо того, чтобы рисовать фон JPanel в его методе paintComponent (), я создал JCustomPanelUI, который я установил на JPanel. Я не думаю, что это было само решение, но вместо того, чтобы использовать ширину и высоту из экземпляра Graphics, я попытался использовать widht и height из самой JPanel. Я не совсем уверен, почему все идет не так, когда я использую ширину и высоту из экземпляра Graphics. Я думал, что ширина и высота из экземпляра Graphics уже «подготовлены» в отношении размеров из компонента JPanel. Вы можете взглянуть на последний компонент здесь:http://snipt.org/wnlli,