Прежде чем вы начнете читать, вот несколько пояснений о том, о чем идет речь:
- SSCCE предназначен для Java 7. Можно было бы использовать sun.*.AWTUtilities, чтобы адаптировать его к Java 6, но мне все равно, как он работает на Java 6.
- Линия разлома: [...]
new JDialog(someWindow)
. Дублирование можно исправить в SSCCE, просто изменив эту строку на[...]new JDialog()
.
Почему в окнах верхнего уровня не появляются ореолы?
Ожидаемое поведение: final JDialog d = new JDialog()
(см. SSCCE)
Как видите, правое окно имеет полупрозрачный фон (как и ожидалось).
Фактическое поведение: final JDialog d = new JDialog(f)
(см. SSCCE)
В этом случае правое окно имеет непрозрачный фон. На самом деле требуется 3-4 перерисовки по любой причине (проще всего воспроизвести перерисовку при ролловере), чтобы фон стал полностью непрозрачным.
SSCCE:
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.plaf.synth.ColorType;
import javax.swing.plaf.synth.Region;
import javax.swing.plaf.synth.SynthConstants;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthLookAndFeel;
import javax.swing.plaf.synth.SynthPainter;
import javax.swing.plaf.synth.SynthStyle;
import javax.swing.plaf.synth.SynthStyleFactory;
public class SynthSSCCE
{
public static void main(String[] args) throws Exception
{
final SynthLookAndFeel laf = new SynthLookAndFeel();
UIManager.setLookAndFeel(laf);
SynthLookAndFeel.setStyleFactory(new StyleFactory());
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
final JFrame f = new JFrame();
{
f.add(new JButton("Works properly"));
f.setUndecorated(true);
f.setBackground(new Color(0, true));
f.setSize(300, 300);
f.setLocation(0, 0);
f.setVisible(true);
}
{
final JDialog d = new JDialog(f);
final JButton btn = new JButton("WTF?");
// uncomment and notice that this has no effect
// btn.setContentAreaFilled(false);
d.add(btn);
d.setUndecorated(true);
d.setBackground(new Color(0, true));
d.setSize(300, 300);
d.setLocation(320, 0);
d.setVisible(true);
}
}
});
}
static class StyleFactory extends SynthStyleFactory
{
private final SynthStyle style = new Style();
@Override
public SynthStyle getStyle(JComponent c, Region id)
{
return style;
}
}
static class Style extends SynthStyle
{
private final SynthPainter painter = new Painter();
@Override
protected Color getColorForState(SynthContext context, ColorType type)
{
if (context.getRegion() == Region.BUTTON && type == ColorType.FOREGROUND)
return Color.GREEN;
return null;
}
@Override
protected Font getFontForState(SynthContext context)
{
return Font.decode("Monospaced-BOLD-30");
}
@Override
public SynthPainter getPainter(SynthContext context)
{
return painter;
}
@Override
public boolean isOpaque(SynthContext context)
{
return false;
}
}
static class Painter extends SynthPainter
{
@Override
public void paintPanelBackground(SynthContext context, Graphics g, int x, int y, int w, int h)
{
final Graphics g2 = g.create();
try
{
g2.setColor(new Color(255, 255, 255, 128));
g2.fillRect(x, y, w, h);
}
finally
{
g2.dispose();
}
}
@Override
public void paintButtonBackground(SynthContext context, Graphics g, int x, int y, int w, int h)
{
final Graphics g2 = g.create();
try
{
if ((context.getComponentState() & SynthConstants.MOUSE_OVER) == SynthConstants.MOUSE_OVER)
g2.setColor(new Color(255, 0, 0, 255));
else
g2.setColor(new Color(0xAA, 0xAA, 0xAA, 255));
g2.fillRoundRect(x, y, w, h, w / 2, h / 2);
}
finally
{
g2.dispose();
}
}
}
}
И это мои вопросы...
- Что происходит? Например, почему это демонстрирует поведение настраиваемого непрозрачного компонента, который забывает вызвать super?
- Почему этого не происходит с окнами TL?
- Как проще всего это исправить, кроме как не использовать окна без TL?
super("Test translucent window");
работает нормально, потому что мне нужны окна без TL, которые, к сожалению, демонстрируют какое-то странное поведение. - person afk5min   schedule 29.08.2013paintText
иpaintIcon
для экземпляраJButton
»: если бы я хотел иметь свой собственный пользовательский интерфейс и компоненты Swing Swing, такие какJOptionPane
,JFileChooser
и т. д., которые всегда будут использовать значения по умолчаниюJButton
/JPanel
, то я бы определенно Сделай так. «создать собственныйSyntButtonUI
»: это не то, как работает Synth. Да, я уже думал об инструментировании классов Synth (потому что вы не можете предоставить свои собственныеComponentUI
), но я хотел бы сделать это в крайнем случае. - person afk5min   schedule 30.08.2013