Alloy Look and Feel and Anti-Aliasing

Does anyone here use Look and Feel Alloy? I ran into a weird bug with anti-aliasing and JTextComponents. The default alloy does not use anti-aliasing at all, so I have to force it to create its own user interfaces. This works great in most cases, but there are certain characters that damage antialiasing.

For example, if Alloy is set to Look and Feel, and I paste some Hebrew text into the JTextComponent, for example: ืฉืœื•ื, ืžื” ืฉืœื•ืžืš ืฉืžื™ ื”ื•ื ื”ืืงื–ื™ื“ ', WHOLE JTextComponent suddenly loses anti-aliasing - forever.

The strange thing is that I donโ€™t even extend AlloyTextPaneUI, but BasicTextPaneUI to do the smoothing, so I am puzzled that the alloy fits into the picture (other Look and Feels seem very good). A.

I find it very difficult to track this error ... Has anyone encountered the same problem?

Here is a quick example demonstrating the problem:

import com.incors.plaf.alloy.AlloyLookAndFeel; import com.incors.plaf.alloy.themes.glass.GlassTheme; import javax.swing.*; import javax.swing.plaf.ComponentUI; import javax.swing.plaf.basic.BasicTextPaneUI; import javax.swing.text.BadLocationException; import javax.swing.text.StyledDocument; import java.awt.*; public class Scrap { static { // NOTE: You need a license code for Alloy! AlloyLookAndFeel.setProperty("alloy.licenseCode", "your license here"); UIManager.put("TextPaneUI", MyTextPaneUI.class.getName()); try { UIManager.setLookAndFeel(new AlloyLookAndFeel(new GlassTheme())); } catch (UnsupportedLookAndFeelException e) { e.printStackTrace(); } // With system Look and Feel everything works just fine... // try { // UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // } catch (ClassNotFoundException e) { // e.printStackTrace(); // } catch (InstantiationException e) { // e.printStackTrace(); // } catch (IllegalAccessException e) { // e.printStackTrace(); // } catch (UnsupportedLookAndFeelException e) { // e.printStackTrace(); // } } public static void main(final String args[]) { JTextPane text = new JTextPane(); text.setFont(new Font("Monospaced", Font.PLAIN, 14)); StyledDocument doc = text.getStyledDocument(); try { doc.insertString(doc.getLength(), "Here some regular text. Nice and smooth with anti-aliasing.\n\n", null); doc.insertString(doc.getLength(), "Here some more text Blaa Blaa Blaaa. Lorem ipsum... now try to uncomment the Hebrew text.\n\n", null); // Try to uncomment this line and the anti-aliasing breaks for the whole JTextPane // doc.insertString(doc.getLength(), "ืฉืœื•ื, ืžื” ืฉืœื•ืžืš ืฉืžื™ ื”ื•ื ื”ืืงื–ื™ื“ืŸ\n\n", null); // Here another strange glyph that breaks the anti-aliasing // doc.insertString(doc.getLength(), "เฒ ", null); } catch (BadLocationException e) { e.printStackTrace(); } JFrame frame = new JFrame(); JScrollPane scroll = new JScrollPane(); scroll.setViewportView(text); scroll.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); frame.add(scroll, BorderLayout.CENTER); frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); frame.setSize(600, 300); frame.setLocationRelativeTo(null); frame.setVisible(true); } public static class MyTextPaneUI extends BasicTextPaneUI { @Override protected void paintSafely(Graphics g) { Graphics2D g2 = (Graphics2D) g; g2.setRenderingHint( RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); super.paintSafely(g); } public static ComponentUI createUI(JComponent c) { return new MyTextPaneUI(); } } } 
+4
source share
2 answers

After some very disappointing experiments, I realized this. I'm still not sure what exactly caused this, but here's how I fixed it. Obviously, in UIDefaults, the key is missing / not found in the alloy (I do not know which one). Therefore, I added all the default values โ€‹โ€‹from the original Look and Feel to Alloy property. This is a kind of quick and dirty solution (the only problem was that the menu became opaque), but it is good enough for my needs. Maybe this will help someone too.

 AlloyLookAndFeel laf = new AlloyLookAndFeel(theme) { @Override public UIDefaults getDefaults() { UIDefaults defs = new UIDefaults(); defs.putAll(UIManager.getLookAndFeelDefaults()); initClassDefaults(defs); initSystemColorDefaults(defs); initComponentDefaults(defs); defs.put("Menu.opaque", true); return defs; } }; 
+3
source

I had the same problem for a very long time. The proposed solution to set the "Menu.opaque" property to true helped make the text smoothed (strange), but it messed up the way my menus looked, and I had to abandon it.

The real problem is that Alloy L & F is poorly supported, but it looks good and has very good performance in my experience. After decompiling the confusing code (Alloy Look & Feel v1.4.4), I traced the problem in one way:

 public class AlloyLookAndFeel extends BasicLookAndFeel{ ... private static boolean j = false; ... public static boolean isTextAntialiasingEnabled() { return j; } ... } 

I could not find a way to change the value programmatically, and it is impossible to override the static method. So I had to resort to hacking:

  • Decompile the code using JD (see http://jd.benow.ca/ ). The code is obfuscated, so the variables and method names are not very significant.
  • Copy the code com.incors.plaf.alloy.AlloyLookAndFeel into your project, which depends on the LAF alloy (the package name must be the same)
  • fix j value

    private static boolean j = true ;

  • There was a small problem with the boolean fb variable, inaccessible after decompilation, so replacing all occurrences of fb with fbValue and adding the declaration to the class (the debugger will help you find the current value, in my case it's false).

    private static boolean fbVariable = false;

After compiling your project, you should have smoothed text. This is a hack, but this is what you need to do to maintain a good but poorly maintained library. I hope someone has an easier solution.

0
source

All Articles