Keilly: 2013

Wednesday, November 27, 2013

Fuzzy Remote Desktop / VNC with Retina Display

When viewing remote content on a retina display, it may appear fuzzier than when viewed on a non-retina display.
This is counter intuitive, after all the retina display is the ultimate in resolution no?
However it makes sense when you think about it as the machine doing the rendering of the text knows nothing about the retina display, so renders as usual for a regular one - doing antialiasing to smooth out the edges of text. The remote desktop/vnc app running on the local machine then takes that remote image and it must scale it up to fill the same physical area on the screen. So it doubles it and anti-aliases it again to smooth edges of shapes. It's this double anti-aliasing that makes text blurrier rather than smoother....

VNC viewed on a regular display:


VNC viewed on a retina display:

There is a general solution...

In Finder go to Applications, find the Remote/VNC program, right click and "Get Info".

Check on the "Open in Low Resolution", and things should be nice and crisp the next time it is launched.


Monday, June 17, 2013

Preferred Height of JTextComponents

Given some text and a text component (e.g. JTextArea), it is not obvious how to set the preferred size of the component to only show the current content.
Skip to Answer

This:
     JTextArea ta = new JTextArea();  
     ta.setLineWrap(true);  
     ta.setText("112 312 3 12 31 2432135r34534t 3 t3 4t34y4hthefbasdgagaergergwreg"  
         + "rwergerg ergergergefdav asdvsadg sadgsad gsdgsdgsadgsgd sdgsdg"  
         + "sdg sdgsdgsdg sdgsdgsdgsgh4hgaregwaegasdg sdgsdg sagae4gsaegs "  
         + " sdgsdg sdg s gs dg sd gs dg sdg sdg sadgsdg sad gsa dg s"  
         + "se gs eg se g saeg sa eg s eg sa eg e g eg aweg");  
     JScrollPane sp = new JScrollPane(ta);  
     System.out.println("TextArea Pref Size: " + ta.getPreferredSize());  
     System.out.println("ScrollPane Pref Size: " + sp.getPreferredSize());  

Gives:
TextArea Pref Size: java.awt.Dimension[width=100,height=16]
ScrollPane Pref Size: java.awt.Dimension[width=104,height=20]

The layout manager follows the preferred sizes and it looks like this:


Lets say we want a preferred width of 300, what do we put for the preferred height?
We can't put in an arbitrary preferred height and hope Swing will trim it down, instead it just obeys what we tell it:

     ta.setPreferredSize(new Dimension(300, 100000));

TextArea Pref Size: java.awt.Dimension[width=300,height=10000]
ScrollPane Pref Size: java.awt.Dimension[width=304,height=10004]




So the trick is to get Swing to calculate the height for a given width and text...

We're told never to user setSize() methods on components, we should let the layout manager set the size, we should always use setPreferredSize().
This is an exception, if we set our actual width and also pass an arbitrary and very large height: Swing will automatically set the preferred size to suit only the text at our given width. All the extra height will be ignored.

     JTextArea ta = new JTextArea();  
     ta.setLineWrap(true);  
     ta.setText("112 312 3 12 31 2432135r34534t 3 t3 4t34y4hthefbasdgagaergergwreg"  
         + "rwergerg ergergergefdav asdvsadg sadgsad gsdgsdgsadgsgd sdgsdg"  
         + "sdg sdgsdgsdg sdgsdgsdgsgh4hgaregwaegasdg sdgsdg sagae4gsaegs "  
         + " sdgsdg sdg s gs dg sd gs dg sdg sdg sadgsdg sad gsa dg s"  
         + "se gs eg se g saeg sa eg s eg sa eg e g eg aweg");  
     JScrollPane sp = new JScrollPane(ta);  
     ta.setSize(300, 100000); // desired width, but deliberately large height.  
     System.out.println("TextArea Pref Size: " + ta.getPreferredSize());  
     System.out.println("ScrollPane Pref Size: " + sp.getPreferredSize());  


TextArea Pref Size: java.awt.Dimension[width=300,height=112]
ScrollPane Pref Size: java.awt.Dimension[width=304,height=116]


Look, the component has been sized to exactly match our text at our preferred width!

Use textComponent.setSize(preferredWidth, 1000000)to set a preferred size for text components.