2013-01-28 11 views
6

In una sottoclasse di un JPanel sto facendo questo:Java testo ruotato ha invertito sequenziano

public void paintComponent(Graphics g) { 
    super.paintComponent(g); 
    Graphics2D g2d = (Graphics2D)g;   
    g2d.rotate(Math.toRadians(90.)); 
    g2d.drawString(aString, 40, -40); 
} 

Le lettere vengono ruotati in modo corretto, ma il secondo non si trova nella posizione prevista sotto la prima (al suo a destra, nello spazio ruotato), ma è sopra di esso (alla sua sinistra), il terzo è sopra (a sinistra di) il secondo, ecc. Cambiando l'angolo di rotazione a 45 gradi, ogni personaggio viene ruotato di 45 gradi cw, come previsto, ma la fila di caratteri viene ruotata di 45 gradi ccw, il che è coerente con entrambe le rotazioni essendo a metà strada verso il risultato per 90 gradi.

A 0 gradi di rotazione il testo viene visualizzato correttamente.

Sto sviluppando con NetBeans 7.1.2 su Mac OS X 10.8.2. La stessa versione di NetBeans su Win 7 SP1 non presenta il problema.

Cosa potrebbe causare questo?

+0

La tela grafico viene ruotato. Potresti chiamare drawString prima di ruotare. –

+0

Quindi non si allineano correttamente. –

+0

Il fatto che funzioni in Windows suggerisce un bug in OS X Java. Se si esegue la demo Java2D e si visualizza la scheda Transforms, vengono visualizzati problemi simili? (Java2D è nella demo/jfc/Java2D del pacchetto JDK "demo e campioni", scaricabile separatamente, disponibile all'indirizzo http://www.oracle.com/technetwork/java/javase/downloads/.) – VGR

risposta

0

Ci sono 2 cose che potrebbero funzionare da quello che posso vedere adesso.

Il primo sarebbe dividere la stringa in un array di caratteri, quindi dopo la rotazione andare 1 per 1 incrementando la dimensione del carattere (+1 o 2 se in grassetto) in modo che si allineino, andando dall'alto verso il basso.

Il secondo modo sarebbe creare il proprio carattere, che non consiglierei. Se si disegna la stringa prima della rotazione, quindi quando ruota ipoteticamente se si è fatto correttamente il carattere verrà visualizzato come dovrebbe.

Se riesco a pensare ad un altro modo, lo posterò.

Edit:

final AffineTransform at = new AffineTransform(); 
final Font font = g.getFont(); 
// Derive a new font using a rotatation transform (Theta is angle in radians). 
at.rotate(theta); 
final Font newFont = font.deriveFont(at); 
// set the derived font in the Graphics2D context 
g2d.setFont(newFont); 

// Render a label instance of type String using the derived font 
g2d.drawString(label, x, y); 

Così, per disegnare in senso verticale che sarebbe una rotazione di 270 gradi, o 3/2 * pi

+0

Entrambe sono soluzioni interessanti per correggere il sintomo, ma mi chiedo ancora se qualcuno può identificare la causa. – eclux

+0

Perché anche se si ruota la grafica, non cambierà ciò che non è stato reso. Se ruoti prima la stringa (che dovresti vedere), non sarà leggibile. –

1

Stiamo vedendo la stessa cosa. Abbiamo un codice che funziona alla grande su Windows, coprendo la maggior parte delle versioni di JRE 6 e 7. Lo stesso codice oggi esibiva il problema dei caratteri ruotati all'indietro. La versione di JRE del problema è 1.6.0_37 su OS X. Potrebbe aver funzionato prima o meno su OS X. Il 99,9% dei nostri utenti è su Windows.

Una soluzione potrebbe essere quella di eseguire il rendering del testo in un'immagine Buffered e quindi di ruotare l'immagine. Questo è un metodo che ho usato per ottenere un risultato migliore visivamente per ruotare il testo di 20-30 gradi o giù di lì.

2

ho trovato una soluzione per questo problema dispari (che corrisponde alla stranezza del bug)

FontRenderContext frc = new FontRenderContext(g2.getTransform(), true, true); 

g2.drawGlyphVector(currentFont.createGlyphVector(frc, aString), textX, textY); 

Per qualche impostazione anti-aliasing su true sul FontRenderContext motivo lo indurrà ad agire in modo corretto. Sembra che qualcuno manchi un segno meno da qualche parte nel codice di rendering, o abbia frainteso le specifiche per cui stavano scrivendo!

1

Il metodo di AffineTransformation pubblicato dall'utente1181445 di seguito funzionava per me per tutte le piattaforme, incluso il problematico OSX, fino al più recente aggiornamento di Java OSX (versione 7, aggiornamento 55). Ora il testo ruotato è incasinato, ma solo sull'applet. Non vedo alcun problema nella versione standalone della nostra app.

1

Su OS X 10.10 vs Windows 7, ho esattamente lo stesso problema, ma al contrario! Cioèruotare l'intero contesto grafico prima di disegnare il testo verticale sembra a posto, ma l'applicazione di un AffineTransform a un nuovo font produce un testo stranamente ruotato.

penso che sia un po 'più efficace per ruotare solo il testo, in modo pratico, se la soluzione poco elegante è quello di controllare la piattaforma prima:

Font font = g.getFont(); 
    if (System.getProperty("os.name").startsWith("Mac")) { 
     g.rotate(-Math.PI/2, x, y); 
     g.drawString(string, x, y); 
     g.rotate(Math.PI/2, x, y);     
    } else { 
     AffineTransform fontAT = new AffineTransform();     
     fontAT.rotate(-Math.PI/2); 
     g.setFont(font.deriveFont(fontAT)); 
     g.drawString(string, x, y); 
     g.setFont(font); 
    }