Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.java.programmer > #31890 > unrolled thread
| Started by | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| First post | 2015-06-30 16:55 +0000 |
| Last post | 2015-07-29 05:35 -0700 |
| Articles | 18 — 7 participants |
Back to article view | Back to comp.lang.java.programmer
Image rotation part 2 Martin Gregorie <martin@address-in-sig.invalid> - 2015-06-30 16:55 +0000
Re: Image rotation part 2 Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-30 14:03 -0400
Re: Image rotation part 2 Martin Gregorie <martin@address-in-sig.invalid> - 2015-06-30 20:04 +0000
Re: Image rotation part 2 Eric Sosman <esosman@comcast-dot-net.invalid> - 2015-06-30 16:20 -0400
Re: Image rotation part 2 Martin Gregorie <martin@address-in-sig.invalid> - 2015-06-30 20:52 +0000
Re: Image rotation part 2 e.d.programmer@gmail.com - 2015-06-30 12:07 -0700
Re: Image rotation part 2 Martin Gregorie <martin@address-in-sig.invalid> - 2015-06-30 20:18 +0000
Re: Image rotation part 2 Jeff Higgins <jeff@invalid.invalid> - 2015-06-30 19:04 -0400
Re: Image rotation part 2 Knute Johnson <nospam@rabbitbrush.frazmtn.com> - 2015-06-30 16:36 -0700
Re: Image rotation part 2 Jeff Higgins <jeff@invalid.invalid> - 2015-06-30 20:17 -0400
Re: Image rotation part 2 Jeff Higgins <jeff@invalid.invalid> - 2015-06-30 20:09 -0400
Re: Image rotation part 2 e.d.programmer@gmail.com - 2015-07-01 06:06 -0700
Re: Image rotation part 2 FredK <fred.l.kleinschmidt@gmail.com> - 2015-07-01 10:57 -0700
Re: Image rotation part 2 Jeff Higgins <jeff@invalid.invalid> - 2015-07-01 18:13 -0400
Re: Image rotation part 2 Arne Vajhøj <arne@vajhoej.dk> - 2015-07-27 22:28 -0400
Re: Image rotation part 2 e.d.programmer@gmail.com - 2015-07-28 04:58 -0700
Re: Image rotation part 2 Arne Vajhøj <arne@vajhoej.dk> - 2015-07-28 18:58 -0400
Re: Image rotation part 2 e.d.programmer@gmail.com - 2015-07-29 05:35 -0700
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2015-06-30 16:55 +0000 |
| Subject | Image rotation part 2 |
| Message-ID | <mmuhle$gp1$1@dont-email.me> |
Thanks to help from Knute about five 11 months ago I was able to create
JLabel subclasses that could display vertically aligned text, e.g.
N
a
m
e
by using HTML text, e.g. "<html>N<br>a<br>m<br>e</html>" This works well,
except that some of the longer names create very tall instances that use
up more screen than I can really spade (the row of names is near the top
of a matrix which has 50+ lines below it, so it would be nice to avoid as
much scrolling up and down as possible.
Having noticed that most Monospaced characters are just over half as wide
as they are high, I'm again thinking about somehow standing the character
string on end by rotating it through 90 degrees. I'm successfully
creating a JPG image containing black 10 pt Monospaced text on a
LIGHT_GRAY background within a minimal window (20 pixels high and
s.length() * (fontsize * 7 / 10) wide, whenever I try to rotate it, all
I'm getting is a solid black image thats rotated so its longest dimension
is now vertical.
The code looks like this:
BufferedImage im = new BufferedImage(width,
height,
BufferedImage.TYPE_INT_RGB);
// image created in im
BufferedImage om = new BufferedImage(height,
width,
BufferedImage.TYPE_INT_RGB);
AffineTransform at = new AffineTransform();
at.setToQuadrantRotation(-1);
AffineTransformOp aop = new AffineTransformOp(at,
AffineTransformOp.TYPE_BILINEAR);
aop.filter(im, om);
I've also tried setting the AffineTransformOp to TYPE_BICUBIC but that
also gave a black rectangle.
I'm obviously doing something stupid or have missed out a vital step, but
what?
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-06-30 14:03 -0400 |
| Message-ID | <mmulii$b3u$1@dont-email.me> |
| In reply to | #31890 |
On 6/30/2015 12:55 PM, Martin Gregorie wrote:
> [...]I'm again thinking about somehow standing the character
> string on end by rotating it through 90 degrees. I'm successfully
> creating a JPG image containing black 10 pt Monospaced text on a
> LIGHT_GRAY background within a minimal window (20 pixels high and
> s.length() * (fontsize * 7 / 10) wide, whenever I try to rotate it, all
> I'm getting is a solid black image thats rotated so its longest dimension
> is now vertical.
>
> The code looks like this:
>
> BufferedImage im = new BufferedImage(width,
> height,
> BufferedImage.TYPE_INT_RGB);
>
> // image created in im
>
> BufferedImage om = new BufferedImage(height,
> width,
> BufferedImage.TYPE_INT_RGB);
> AffineTransform at = new AffineTransform();
> at.setToQuadrantRotation(-1);
This may be the problem: You're rotating the image a quarter-turn,
but not moving the origin. I think that means you're rotating the
"payload" pixels clear out of the area that then fills the destination.
(Think about a closed door: After rotating it a quarter-turn about its
hinges, how much of the rotated door remains within the doorframe?)
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2015-06-30 20:04 +0000 |
| Message-ID | <mmusni$m87$1@dont-email.me> |
| In reply to | #31891 |
On Tue, 30 Jun 2015 14:03:17 -0400, Eric Sosman wrote:
> On 6/30/2015 12:55 PM, Martin Gregorie wrote:
>> [...]I'm again thinking about somehow standing the character string on
>> end by rotating it through 90 degrees. I'm successfully creating a JPG
>> image containing black 10 pt Monospaced text on a LIGHT_GRAY background
>> within a minimal window (20 pixels high and s.length() * (fontsize * 7
>> / 10) wide, whenever I try to rotate it, all I'm getting is a solid
>> black image thats rotated so its longest dimension is now vertical.
>>
>> The code looks like this:
>>
>> BufferedImage im = new BufferedImage(width,
>> height,
>> BufferedImage.TYPE_INT_RGB);
>>
>> // image created in im
>>
>> BufferedImage om = new BufferedImage(height,
>> width,
>> BufferedImage.TYPE_INT_RGB);
>> AffineTransform at = new AffineTransform();
>>
>
> This may be the problem: You're rotating the image a quarter-turn,
> but not moving the origin. I think that means you're rotating the
> "payload" pixels clear out of the area that then fills the destination.
> (Think about a closed door: After rotating it a quarter-turn about its
> hinges, how much of the rotated door remains within the doorframe?)
If I understand correctly that implies a one line change, replacing
at.setToQuadrantRotation(-1);
with
at.setToQuadrantRotation(direction,
new Double(width/2),
new Double(height/2));
which, sadly just produced another solid black image.
Is there a decent tutorial anywhere about using Affine transforms? I'm
pretty much out of my depth when it comes to this sort of thing.
--
martin@ | Martin Gregorie
gregorie. | Essex, UK
org |
[toc] | [prev] | [next] | [standalone]
| From | Eric Sosman <esosman@comcast-dot-net.invalid> |
|---|---|
| Date | 2015-06-30 16:20 -0400 |
| Message-ID | <mmutjf$hcb$1@dont-email.me> |
| In reply to | #31898 |
On 6/30/2015 4:04 PM, Martin Gregorie wrote:
> On Tue, 30 Jun 2015 14:03:17 -0400, Eric Sosman wrote:
>
>> On 6/30/2015 12:55 PM, Martin Gregorie wrote:
>>> [...]I'm again thinking about somehow standing the character string on
>>> end by rotating it through 90 degrees. I'm successfully creating a JPG
>>> image containing black 10 pt Monospaced text on a LIGHT_GRAY background
>>> within a minimal window (20 pixels high and s.length() * (fontsize * 7
>>> / 10) wide, whenever I try to rotate it, all I'm getting is a solid
>>> black image thats rotated so its longest dimension is now vertical.
>>>
>>> The code looks like this:
>>>
>>> BufferedImage im = new BufferedImage(width,
>>> height,
>>> BufferedImage.TYPE_INT_RGB);
>>>
>>> // image created in im
>>>
>>> BufferedImage om = new BufferedImage(height,
>>> width,
>>> BufferedImage.TYPE_INT_RGB);
>>> AffineTransform at = new AffineTransform();
>>>
>>
>> This may be the problem: You're rotating the image a quarter-turn,
>> but not moving the origin. I think that means you're rotating the
>> "payload" pixels clear out of the area that then fills the destination.
>> (Think about a closed door: After rotating it a quarter-turn about its
>> hinges, how much of the rotated door remains within the doorframe?)
>
> If I understand correctly that implies a one line change, replacing
>
> at.setToQuadrantRotation(-1);
>
> with
>
> at.setToQuadrantRotation(direction,
> new Double(width/2),
> new Double(height/2));
>
> which, sadly just produced another solid black image.
> Is there a decent tutorial anywhere about using Affine transforms? I'm
> pretty much out of my depth when it comes to this sort of thing.
I've used them a few times, but find them confusing -- in part
because the Y axis is inverted from The Way We Learned In School, which
is The Way I Always Picture It In My Foggy Little Brain. Basically,
though, I think the best way to build the transform you want is to
compose it out of simpler steps. In your case, the steps would be
1) Translate the center of your image to the origin,
2) Rotate the image a quarter-turn (rotation about the
origin is now rotation about the image's center),
3) Translate the origin to the center of the new image.
You can build these three transforms (it would take me a few tries to
get the translations right; see Y axis, above) and combine them into a
single transform (it would take me a few tries to get the order right;
matrix multiplication is not commutative but at least you know that the
rotation step is in the middle), and then apply the combined super-
transform to your image.
Applying your transform to a (non-square) Rectangle and simply
printing the original and transformed coordinates might help debug.
Good luck!
--
esosman@comcast-dot-net.invalid
"Don't be afraid of work. Make work afraid of you." -- TLM
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2015-06-30 20:52 +0000 |
| Message-ID | <mmuvj8$m87$4@dont-email.me> |
| In reply to | #31900 |
On Tue, 30 Jun 2015 16:20:17 -0400, Eric Sosman wrote: > I've used them a few times, but find them confusing -- in part > because the Y axis is inverted from The Way We Learned In School, which > is The Way I Always Picture It In My Foggy Little Brain. > I'm OK with that part due to a lot of time spent working with alphanumeric terminals - VT52, VT100, WY-120 etc. They all treat the top left corner of the screen as the origin. > 1) Translate the center of your image to the origin, 2) Rotate the > image a quarter-turn (rotation about the > origin is now rotation about the image's center), > 3) Translate the origin to the center of the new image. > > You can build these three transforms (it would take me a few tries to > get the translations right; see Y axis, above) and combine them into a > single transform (it would take me a few tries to get the order right; > matrix multiplication is not commutative but at least you know that the > rotation step is in the middle), and then apply the combined super- > transform to your image. > Good advice. Thanks. I'll look at that tomorrow. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
[toc] | [prev] | [next] | [standalone]
| From | e.d.programmer@gmail.com |
|---|---|
| Date | 2015-06-30 12:07 -0700 |
| Message-ID | <228707c4-33ce-4901-9636-97e08cf6ff84@googlegroups.com> |
| In reply to | #31890 |
On Tuesday, June 30, 2015 at 12:56:43 PM UTC-4, Martin Gregorie wrote: > Thanks to help from Knute about five 11 months ago I was able to create > JLabel subclasses that could display vertically aligned text, e.g. > > N > a > m > e > > by using HTML text, e.g. "<html>N<br>a<br>m<br>e</html>" This works well, > except that some of the longer names create very tall instances that use > up more screen than I can really spade (the row of names is near the top > of a matrix which has 50+ lines below it, so it would be nice to avoid as > much scrolling up and down as possible. > > Having noticed that most Monospaced characters are just over half as wide > as they are high, I'm again thinking about somehow standing the character > string on end by rotating it through 90 degrees. I'm successfully > creating a JPG image containing black 10 pt Monospaced text on a > LIGHT_GRAY background within a minimal window (20 pixels high and > s.length() * (fontsize * 7 / 10) wide, whenever I try to rotate it, all > I'm getting is a solid black image thats rotated so its longest dimension > is now vertical. > > The code looks like this: > > BufferedImage im = new BufferedImage(width, > height, > BufferedImage.TYPE_INT_RGB); > > // image created in im > > BufferedImage om = new BufferedImage(height, > width, > BufferedImage.TYPE_INT_RGB); > AffineTransform at = new AffineTransform(); > at.setToQuadrantRotation(-1); > AffineTransformOp aop = new AffineTransformOp(at, > AffineTransformOp.TYPE_BILINEAR); > aop.filter(im, om); > > I've also tried setting the AffineTransformOp to TYPE_BICUBIC but that > also gave a black rectangle. > > I'm obviously doing something stupid or have missed out a vital step, but > what? > > > -- > martin@ | Martin Gregorie > gregorie. | Essex, UK > org | Are you trying to rotate text or an image? Which direction is the original? Which direction did you need it to face after rotating? To rotate an image I just create a new AffineTransform, scale it, rotate it, and pass it into my drawImage method. If it's a perfect square the rotate method should be easy, just pass in the Math.toRadians(drawRotationAngle). If it's a rectangle, not a square, and you want to turn it 90 degrees and squish it to fit the same space you need to calculate a new x/y.
[toc] | [prev] | [next] | [standalone]
| From | Martin Gregorie <martin@address-in-sig.invalid> |
|---|---|
| Date | 2015-06-30 20:18 +0000 |
| Message-ID | <mmuti0$m87$2@dont-email.me> |
| In reply to | #31890 |
On Tue, 30 Jun 2015 18:15:41 +0000, Stefan Ram wrote: > Martin Gregorie <martin@address-in-sig.invalid> writes: >>s.length() * (fontsize * 7 / 10) wide, whenever I try to rotate it, all >>I'm getting is a solid black image thats rotated so its longest >>dimension is now vertical. > > FWIW, I once wrote a program that rotates letters and has ASCII > output: > Thanks for that code (snipped to save bandwidth). I have a transcription running so I can study and modify it to work with images rather than text output. It seems to be working, though it displays 35880 lines of text (2.8MB) as it slowly builds the rotated A line by line. I think I need to check it over to see why its doing that, as a particular part-built version of the A is output many times in the course of assembling the nest 'scan line'. -- martin@ | Martin Gregorie gregorie. | Essex, UK org |
[toc] | [prev] | [next] | [standalone]
| From | Jeff Higgins <jeff@invalid.invalid> |
|---|---|
| Date | 2015-06-30 19:04 -0400 |
| Message-ID | <mmv7cc$l2$1@dont-email.me> |
| In reply to | #31890 |
On 06/30/2015 12:55 PM, Martin Gregorie wrote:
Not real pretty but...
<http://www.rgagnon.com/javadetails/java-0259.html>
package scratch;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.AffineTransform;
public class DrawVerticalText extends JPanel {
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
String s = "Vertical text";
int x=10;
int y=10;
int v;
v=g.getFontMetrics(getFont()).getHeight()+1;
System.out.println(v);
int j =0;
int k= s.length();
while(j < k+1) {
if (j == k)
g.drawString(s.substring(j),x, y+(j*v));
else
g.drawString(s.substring(j,j+1),x, y+(j*v));
j++;
}
}
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setTitle("Draw Vertical Text Demo");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new DrawVerticalText());
frame.pack();
frame.setSize(200, 300);
frame.setVisible(true);
}
}
[toc] | [prev] | [next] | [standalone]
| From | Knute Johnson <nospam@rabbitbrush.frazmtn.com> |
|---|---|
| Date | 2015-06-30 16:36 -0700 |
| Message-ID | <mmv93r$6j9$1@dont-email.me> |
| In reply to | #31902 |
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class test4 extends JComponent {
private final String message = "VERTICAL TEXT";
private final int width = 20;
private final int height = 220;
public test4() {
setFont(new Font("Monospaced",Font.BOLD,16));
setPreferredSize(new Dimension(width,height));
}
public void paintComponent(Graphics g2d) {
Graphics2D g = (Graphics2D)g2d;
g.setColor(Color.BLACK);
g.fillRect(0,0,width,height);
g.setColor(Color.WHITE);
char[] chars = message.toCharArray();
FontMetrics metrics = g.getFontMetrics();
double charHeight = metrics.getHeight() * 0.7;
g.translate(
(width - metrics.charWidth(' '))/2.0,
(height - charHeight * chars.length)/2.0 + charHeight);
for (int i=0; i<chars.length; i++) {
g.drawChars(chars,i,1,0,0);
g.translate(0,charHeight);
}
}
public static void main(String... args) {
EventQueue.invokeLater(() -> {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.add(new test4(),BorderLayout.CENTER);
f.pack();
f.setVisible(true);
});
}
}
[toc] | [prev] | [next] | [standalone]
| From | Jeff Higgins <jeff@invalid.invalid> |
|---|---|
| Date | 2015-06-30 20:17 -0400 |
| Message-ID | <mmvbm5$fmi$1@dont-email.me> |
| In reply to | #31903 |
On 06/30/2015 07:36 PM, Knute Johnson wrote:
I changed the all caps to mixed case just to see.
Yep, pretty vertical text is hard.
> import java.awt.*;
> import java.awt.event.*;
> import javax.swing.*;
>
> public class test4 extends JComponent {
> private final String message = "VERTICAL TEXT";
> private final int width = 20;
> private final int height = 220;
>
> public test4() {
> setFont(new Font("Monospaced",Font.BOLD,16));
> setPreferredSize(new Dimension(width,height));
> }
>
> public void paintComponent(Graphics g2d) {
> Graphics2D g = (Graphics2D)g2d;
> g.setColor(Color.BLACK);
> g.fillRect(0,0,width,height);
> g.setColor(Color.WHITE);
> char[] chars = message.toCharArray();
> FontMetrics metrics = g.getFontMetrics();
> double charHeight = metrics.getHeight() * 0.7;
> g.translate(
> (width - metrics.charWidth(' '))/2.0,
> (height - charHeight * chars.length)/2.0 + charHeight);
> for (int i=0; i<chars.length; i++) {
> g.drawChars(chars,i,1,0,0);
> g.translate(0,charHeight);
> }
> }
>
> public static void main(String... args) {
> EventQueue.invokeLater(() -> {
> JFrame f = new JFrame();
> f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
> f.add(new test4(),BorderLayout.CENTER);
> f.pack();
> f.setVisible(true);
> });
> }
> }
>
>
[toc] | [prev] | [next] | [standalone]
| From | Jeff Higgins <jeff@invalid.invalid> |
|---|---|
| Date | 2015-06-30 20:09 -0400 |
| Message-ID | <mmvb6q$egh$1@dont-email.me> |
| In reply to | #31902 |
On 06/30/2015 07:04 PM, Jeff Higgins wrote: > On 06/30/2015 12:55 PM, Martin Gregorie wrote: > Another interesting idea - haven't tried it. VerticalLabelUI.java VerticalTableHeaderCellRenderer.java <https://java.net/projects/snat/sources/reposit/show/src/table?rev=69>
[toc] | [prev] | [next] | [standalone]
| From | e.d.programmer@gmail.com |
|---|---|
| Date | 2015-07-01 06:06 -0700 |
| Message-ID | <31e57656-27e3-46a4-abbd-a793c463adba@googlegroups.com> |
| In reply to | #31902 |
On Tuesday, June 30, 2015 at 7:07:21 PM UTC-4, Jeff Higgins wrote:
> On 06/30/2015 12:55 PM, Martin Gregorie wrote:
>
> Not real pretty but...
> <http://www.rgagnon.com/javadetails/java-0259.html>
>
> package scratch;
>
> import javax.swing.*;
> import java.awt.*;
> import java.awt.geom.AffineTransform;
>
> public class DrawVerticalText extends JPanel {
> @Override
> public void paint(Graphics g) {
> Graphics2D g2 = (Graphics2D) g;
> String s = "Vertical text";
> int x=10;
> int y=10;
> int v;
>
> v=g.getFontMetrics(getFont()).getHeight()+1;
> System.out.println(v);
> int j =0;
> int k= s.length();
> while(j < k+1) {
> if (j == k)
> g.drawString(s.substring(j),x, y+(j*v));
> else
> g.drawString(s.substring(j,j+1),x, y+(j*v));
> j++;
> }
> }
>
>
> public static void main(String[] args) {
> JFrame frame = new JFrame();
> frame.setTitle("Draw Vertical Text Demo");
> frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
> frame.add(new DrawVerticalText());
> frame.pack();
> frame.setSize(200, 300);
> frame.setVisible(true);
> }
> }
That doesn't look pretty, though it's using my default font, which is "family=Dialog,name=Dialog,style=plain,size=12".
It doesn't seem to matter in testing your code as is but you should be overriding paintComponent not paint. That does look prettier if we set a fixed width font.
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class TestRotatedText extends JPanel {
@Override
public void paintComponent(final Graphics g) {
final Graphics2D g2 = (Graphics2D) g;
final String s = "Vertical text";
final int x = 10;
final int y = 10;
int v;
g2.setFont(new Font("Lucida Sans TypeWriter", Font.PLAIN, 12));
v = g2.getFontMetrics(g2.getFont()).getHeight() + 1;
int j = 0;
final int k = s.length();
while (j < k + 1) {
if (j == k) {
g2.drawString(s.substring(j), x, y + (j * v));
} else {
g2.drawString(s.substring(j, j + 1), x, y + (j * v));
}
j++;
}
}
public static void main(final String[] args) {
final JFrame frame = new JFrame();
frame.setTitle("Draw Vertical Text Demo");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new TestRotatedText());
frame.pack();
frame.setSize(200, 300);
frame.setVisible(true);
}
}
It is prettier if you can just turn it.
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.WindowConstants;
public class TestRotatedText extends JPanel {
@Override
public void paintComponent(final Graphics g) {
final Graphics2D g2 = (Graphics2D) g;
final String s = "Vertical text";
int charHeight;
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
g2.setFont(new Font("Lucida Sans TypeWriter", Font.PLAIN, 12));
final Font theFont = g2.getFont();
final FontMetrics fm = g2.getFontMetrics(theFont);
charHeight = fm.getHeight();
// Create a rotation transformation for the font.
final AffineTransform fontAT = new AffineTransform();
fontAT.rotate(-Math.PI / 2.0);
final Font theDerivedFont = theFont.deriveFont(fontAT);
// set the derived font in the Graphics2D context
g2.setFont(theDerivedFont);
g2.drawString(s, charHeight, fm.stringWidth(s) + 5);
}
public static void main(final String[] args) {
final JFrame frame = new JFrame();
frame.setTitle("Draw Vertical Text Demo");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.add(new TestRotatedText());
frame.pack();
frame.setSize(200, 300);
frame.setVisible(true);
}
}
[toc] | [prev] | [next] | [standalone]
| From | FredK <fred.l.kleinschmidt@gmail.com> |
|---|---|
| Date | 2015-07-01 10:57 -0700 |
| Message-ID | <028164e2-9cba-4ba3-ad34-0cf46ae7210b@googlegroups.com> |
| In reply to | #31907 |
On Wednesday, July 1, 2015 at 6:06:43 AM UTC-7, e.d.pro...@gmail.com wrote:
> On Tuesday, June 30, 2015 at 7:07:21 PM UTC-4, Jeff Higgins wrote:
> > On 06/30/2015 12:55 PM, Martin Gregorie wrote:
> >
> > Not real pretty but...
> > <http://www.rgagnon.com/javadetails/java-0259.html>
> >
> > package scratch;
> >
> > import javax.swing.*;
> > import java.awt.*;
> > import java.awt.geom.AffineTransform;
> >
> > public class DrawVerticalText extends JPanel {
> > @Override
> > public void paint(Graphics g) {
> > Graphics2D g2 = (Graphics2D) g;
> > String s = "Vertical text";
> > int x=10;
> > int y=10;
> > int v;
> >
> > v=g.getFontMetrics(getFont()).getHeight()+1;
> > System.out.println(v);
> > int j =0;
> > int k= s.length();
> > while(j < k+1) {
> > if (j == k)
> > g.drawString(s.substring(j),x, y+(j*v));
> > else
> > g.drawString(s.substring(j,j+1),x, y+(j*v));
> > j++;
> > }
> > }
> >
> >
> > public static void main(String[] args) {
> > JFrame frame = new JFrame();
> > frame.setTitle("Draw Vertical Text Demo");
> > frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
> > frame.add(new DrawVerticalText());
> > frame.pack();
> > frame.setSize(200, 300);
> > frame.setVisible(true);
> > }
> > }
>
> That doesn't look pretty, though it's using my default font, which is "family=Dialog,name=Dialog,style=plain,size=12".
> It doesn't seem to matter in testing your code as is but you should be overriding paintComponent not paint. That does look prettier if we set a fixed width font.
>
> import java.awt.Font;
> import java.awt.Graphics;
> import java.awt.Graphics2D;
>
> import javax.swing.JFrame;
> import javax.swing.JPanel;
> import javax.swing.WindowConstants;
>
> public class TestRotatedText extends JPanel {
>
> @Override
> public void paintComponent(final Graphics g) {
> final Graphics2D g2 = (Graphics2D) g;
> final String s = "Vertical text";
> final int x = 10;
> final int y = 10;
> int v;
> g2.setFont(new Font("Lucida Sans TypeWriter", Font.PLAIN, 12));
> v = g2.getFontMetrics(g2.getFont()).getHeight() + 1;
>
> int j = 0;
> final int k = s.length();
> while (j < k + 1) {
> if (j == k) {
> g2.drawString(s.substring(j), x, y + (j * v));
> } else {
> g2.drawString(s.substring(j, j + 1), x, y + (j * v));
> }
> j++;
> }
> }
>
> public static void main(final String[] args) {
> final JFrame frame = new JFrame();
> frame.setTitle("Draw Vertical Text Demo");
> frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
> frame.add(new TestRotatedText());
> frame.pack();
> frame.setSize(200, 300);
> frame.setVisible(true);
> }
> }
>
> It is prettier if you can just turn it.
>
> import java.awt.Font;
> import java.awt.FontMetrics;
> import java.awt.Graphics;
> import java.awt.Graphics2D;
> import java.awt.RenderingHints;
> import java.awt.geom.AffineTransform;
>
> import javax.swing.JFrame;
> import javax.swing.JPanel;
> import javax.swing.WindowConstants;
>
> public class TestRotatedText extends JPanel {
>
> @Override
> public void paintComponent(final Graphics g) {
> final Graphics2D g2 = (Graphics2D) g;
> final String s = "Vertical text";
> int charHeight;
> g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
> g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
> g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
> g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
> g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
> g2.setFont(new Font("Lucida Sans TypeWriter", Font.PLAIN, 12));
> final Font theFont = g2.getFont();
> final FontMetrics fm = g2.getFontMetrics(theFont);
> charHeight = fm.getHeight();
> // Create a rotation transformation for the font.
> final AffineTransform fontAT = new AffineTransform();
> fontAT.rotate(-Math.PI / 2.0);
> final Font theDerivedFont = theFont.deriveFont(fontAT);
> // set the derived font in the Graphics2D context
> g2.setFont(theDerivedFont);
> g2.drawString(s, charHeight, fm.stringWidth(s) + 5);
> }
>
> public static void main(final String[] args) {
> final JFrame frame = new JFrame();
> frame.setTitle("Draw Vertical Text Demo");
> frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
> frame.add(new TestRotatedText());
> frame.pack();
> frame.setSize(200, 300);
> frame.setVisible(true);
> }
> }
Just extend JLabel. Note the horizontal and vertical alignments are kept relative to the text, so "vertical" refers to the height of the text, not the height of the widget.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Insets;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
public class VerticalLabel extends JLabel {
Insets insets;
public VerticalLabel( String string ) {
super( string );
}
@Override
public void paintComponent( Graphics g ) {
insets = getInsets();
Dimension size = getSize();
String text = getText();
int x = 0;
int y = 0;
int halign = getHorizontalAlignment();
int valign = getVerticalAlignment();
FontMetrics metrics = getFontMetrics( getFont() );
int ascent = metrics.getAscent();
int descent = metrics.getDescent();
setVerticalAlignment( SwingConstants.BOTTOM );
setHorizontalAlignment( SwingConstants.CENTER );
int line = metrics.stringWidth( text );
switch (halign) {
case SwingConstants.LEFT:
case SwingConstants.LEADING:
y = size.height - insets.bottom;
break;
case SwingConstants.CENTER:
y = (insets.top + size.height - insets.bottom + line) / 2;
break;
default:
y = insets.top + line;
break;
}
switch (valign) {
case SwingConstants.TOP:
x = insets.left + ascent;
break;
case SwingConstants.CENTER:
x = (insets.left + size.width - insets.right - ascent) / 2;
break;
default:
x = size.width - insets.right - descent;
break;
}
((Graphics2D)g).rotate( Math.toRadians( -90 ), x, y );
((Graphics2D)g).drawString( text, x, y );
((Graphics2D)g).rotate( Math.toRadians( 90 ), x, y );
}
@Override
public Dimension getPreferredSize() {
Dimension d = super.getPreferredSize();
int temp = d.height;
d.height = d.width;
d.width = temp;
return d;
}
}
--
Fred K
[toc] | [prev] | [next] | [standalone]
| From | Jeff Higgins <jeff@invalid.invalid> |
|---|---|
| Date | 2015-07-01 18:13 -0400 |
| Message-ID | <mn1ooh$pdu$1@dont-email.me> |
| In reply to | #31907 |
On 07/01/2015 09:06 AM, e.d.programmer@gmail.com wrote: > > It is prettier if you can just turn it. Yep, pretty, but then from the OP: > Thanks to help from Knute about five 11 months ago I was able to > create > JLabel subclasses that could display vertically aligned text, e.g. > N > a > m > e
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2015-07-27 22:28 -0400 |
| Message-ID | <mp6pbo$19j$4@speranza.aioe.org> |
| In reply to | #31907 |
On 7/1/2015 9:06 AM, e.d.programmer@gmail.com wrote:
> On Tuesday, June 30, 2015 at 7:07:21 PM UTC-4, Jeff Higgins wrote:
>> public static void main(String[] args) {
>> JFrame frame = new JFrame();
>> frame.setTitle("Draw Vertical Text Demo");
>> frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
>> frame.add(new DrawVerticalText());
>> frame.pack();
>> frame.setSize(200, 300);
>> frame.setVisible(true);
>> }
>> }
> public static void main(final String[] args) {
> final JFrame frame = new JFrame();
> frame.setTitle("Draw Vertical Text Demo");
> frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
> frame.add(new TestRotatedText());
> frame.pack();
> frame.setSize(200, 300);
> frame.setVisible(true);
> }
> }
And consider moving this stuff from main thread to the event thread,
since that is how it is supposed to be done.
Arne
[toc] | [prev] | [next] | [standalone]
| From | e.d.programmer@gmail.com |
|---|---|
| Date | 2015-07-28 04:58 -0700 |
| Message-ID | <4205e406-2568-4c74-a948-8fb425075b51@googlegroups.com> |
| In reply to | #32173 |
On Monday, July 27, 2015 at 10:28:21 PM UTC-4, Arne Vajhøj wrote: > And consider moving this stuff from main thread to the event thread, > since that is how it is supposed to be done. > > Arne I never put that stuff on the main thread. I was just modifying someone else's sample.
[toc] | [prev] | [next] | [standalone]
| From | Arne Vajhøj <arne@vajhoej.dk> |
|---|---|
| Date | 2015-07-28 18:58 -0400 |
| Message-ID | <mp91eg$6b7$2@speranza.aioe.org> |
| In reply to | #32180 |
On 7/28/2015 7:58 AM, e.d.programmer@gmail.com wrote: > On Monday, July 27, 2015 at 10:28:21 PM UTC-4, Arne Vajhøj wrote: >> And consider moving this stuff from main thread to the event thread, >> since that is how it is supposed to be done. > > I never put that stuff on the main thread. I was just modifying someone else's sample. Yes. And you chose not to modify that part. So I made a note so that readers do not get the wrong impression about what they should do. Arne
[toc] | [prev] | [next] | [standalone]
| From | e.d.programmer@gmail.com |
|---|---|
| Date | 2015-07-29 05:35 -0700 |
| Message-ID | <ef946ad1-468d-4b02-bc0e-eeeed0aa5d55@googlegroups.com> |
| In reply to | #32186 |
On Tuesday, July 28, 2015 at 6:58:31 PM UTC-4, Arne Vajhøj wrote:
> Yes.
>
> And you chose not to modify that part.
>
> So I made a note so that readers do not get the wrong impression
> about what they should do.
>
> Arne
Disclaimer: That is not production code. That was a sample modified to solve a specific problem. Any reader who thinks you should create a JFrame and make it visible in the main method should probably take a Java class.
I didn't modify that part because it wasn't relevant to solving the problem. If it were a final program to put into production I would personally change a lot more than moving the JFrame to an event thread.
The simplest change to fix that one issue would be to write all main threads with GUI like this.
public static void main(final String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
// test program here
}
});
}
Personally I don't use JFrame. I like to write flexible applications. I like making a window with a button that can open a second window and disable the first window until you close the second window. I couldn't find an easy way to do that with a JFrame, so I made all windows extend JDialog, so I can make them DOCUMENT_MODAL and pass one into another as it's owner. I also don't use EXIT_ON_CLOSE. I set DO_NOTHING_ON_CLOSE, then assign a WindowListener linked to a KeyStroke on the InputMap that can allow them to also close with an F# key and prompt when they try to close and do some cleanup ie identify if a control is modified and prompt them to save.
So anyway, don't nitpick a sample. If you want to make sure readers who are new to Java don't get the idea they should do something everyone ought to know not to do, you might as well point those readers to the Java tutorial.
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.java.programmer
csiph-web