Hallo,
ein wirklich informatives Forum habt ihr - hab schon viel duch nur lesen mitbekommen .
Ich habe momentan ein Problem mit JText-Fields. Ich habe mir ein JTextField abgeleitet damit ich diesem RenderingHints zuweisen kann (in der paintComponent-Methode). Dies mache ich da ich eine eigene Schriftart anzeigen lassen will und ohne die wird diese scheinbar nicht Anti-Aliased. Wie auch immer, in der PainComponent-Methode sitzt außerdem die Funktionalität bestimmte Klammern (aus meiner Schriftart - daher die Unicode-Zeichen) mit einem Rahmen zu versehen wenn man nach die öffnende Klammer oder vor die entsprechende schließende Klammer klickt, bzw. der Caret da ist. (Die Rechtecke um die Klammern sind dann bei der öffnenden und schließenden Klammer - vgl. mit der Funkion vieler IDEs).
Das Problem ist dass die Position der Markierungs-Rechtecke über die Font berechnet wird und das klappt auch alles ganz gut bis ich das Look&Feel umstelle. Im "Metal"-L&F beginnt der Text im TextField fast ganz vorne am Rand und da stimmt die Angabe von Position über die Font, genauso im Motif. Aber wenn ich jetzt das Win-L&F lade beginnt der Text nicht ganz vorn in der Textbox, sondern ca 10px weiter rechts und damit sind die Markierungen verschoben.
Gibt es eine Möglichkeit rauszufinden wo der Text nun tatsächlich beginnt in der Textbox oder das Problem anders zu lösen? Danke euch.
Ist mein Problem verständlich beschrieben oder sollte ich vielleicht noch ein paar Screenshots hochladen?
Hier dier Code:
ein wirklich informatives Forum habt ihr - hab schon viel duch nur lesen mitbekommen .
Ich habe momentan ein Problem mit JText-Fields. Ich habe mir ein JTextField abgeleitet damit ich diesem RenderingHints zuweisen kann (in der paintComponent-Methode). Dies mache ich da ich eine eigene Schriftart anzeigen lassen will und ohne die wird diese scheinbar nicht Anti-Aliased. Wie auch immer, in der PainComponent-Methode sitzt außerdem die Funktionalität bestimmte Klammern (aus meiner Schriftart - daher die Unicode-Zeichen) mit einem Rahmen zu versehen wenn man nach die öffnende Klammer oder vor die entsprechende schließende Klammer klickt, bzw. der Caret da ist. (Die Rechtecke um die Klammern sind dann bei der öffnenden und schließenden Klammer - vgl. mit der Funkion vieler IDEs).
Das Problem ist dass die Position der Markierungs-Rechtecke über die Font berechnet wird und das klappt auch alles ganz gut bis ich das Look&Feel umstelle. Im "Metal"-L&F beginnt der Text im TextField fast ganz vorne am Rand und da stimmt die Angabe von Position über die Font, genauso im Motif. Aber wenn ich jetzt das Win-L&F lade beginnt der Text nicht ganz vorn in der Textbox, sondern ca 10px weiter rechts und damit sind die Markierungen verschoben.
Gibt es eine Möglichkeit rauszufinden wo der Text nun tatsächlich beginnt in der Textbox oder das Problem anders zu lösen? Danke euch.
Ist mein Problem verständlich beschrieben oder sollte ich vielleicht noch ein paar Screenshots hochladen?
Hier dier Code:
Code:
package org.jalgo.module.ebnf.gui.ebnf;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Rectangle2D;
import javax.swing.JTextField;
import javax.swing.text.BadLocationException;
/**Diese Klasse erstellt ein Textfield mit zusätzlichen RenderingHints für unsere EBNF-Schrift
* @author Tom
*
*/
public class EbnfTextField extends JTextField {
private int movecount = 0;
int nextpos = 0;
String text2 = "\u300C"+"\u300F"+"\u3011";
String text3 = "\u300D"+"\u3010"+"\u3012";
public EbnfTextField() {}
public EbnfTextField(String text)
{
super(text);
}
public void paintComponent(Graphics g)
{
// Unicode-Mappings: "\u300C" = [, "\u300D" = ], "\u300E" = |",
// "\u300F" = (, " \u3010" = ), " \u3011" = {, "\u3012" = }
// 3014 und 3015 sind nochmal () für die generierten Klammern
Graphics2D g2 = (Graphics2D)g;
int i = this.getCaretPosition();
String text = "";
try {
text = this.getText(i - 1, 1);
} catch (BadLocationException e) {
}
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
super.paintComponent(g);
if (text2.contains(text)) { //Bracket is opening
g2.setColor(Color.LIGHT_GRAY);
g2.draw(findCorrectCharacterPos(i));
nextpos = findNextChaaracterPos(i, text, true);
g2.draw(findCorrectCharacterPos(nextpos));
if ((movecount != i) || (movecount - 1 != i) || (movecount + 1 != i)) {
this.repaint();
}
movecount = i;
} else {
try {
text = this.getText(i, 1);
if (text3.contains(text)) { // Bracket is closing
g2.setColor(Color.LIGHT_GRAY);
g2.draw(findCorrectCharacterPos(i+1));
nextpos = findNextChaaracterPos(i+1, text, false);
g2.draw(findCorrectCharacterPos(nextpos));
if ((movecount != i) || (movecount - 1 != i) || (movecount + 1 != i)) {
this.repaint();
}
movecount = i;
}
} catch (BadLocationException e) {
}
}
}
/**The function <code>findCorrectCharacterPos</code> generates a fitting rectangle for
* out brackets, parenth. and braces.
*
* @param pos is the character-position in the TextField
* @return the correct rectangel is returned
*/private Rectangle2D findCorrectCharacterPos(int pos) {
Font font = this.getFont();
FontMetrics metrics = getFontMetrics( font );
Rectangle2D rect;
int position = 0;
int width = 0;
try {
position = metrics.stringWidth(this.getText(0, pos-1));
width = metrics.stringWidth(this.getText(pos-1, 1));
} catch (BadLocationException e) {
}
rect = new Rectangle2D.Float(position, 2, width + 3, 27);
return rect;
}
/**This function finds the correct closing or opening bracket/parenth./brace for an correspondending
* closing/opening one.
*
* @param pos is the start position to search from
* @param searchtext is the String of the bracket/parenth./brace to look for
* @param fromlefttoright should be set to true if the clicket bracket/.../... is opening, otherwise falses
* @return the position of the found matching bracket/.../... is given back
*/private int findNextChaaracterPos(int pos, String searchtext, boolean fromlefttoright) {
String nextbracket = "";
String text = this.getText();
int counter = 0;
if (searchtext.equals("\u300C")) nextbracket = "\u300D";
else if (searchtext.equals("\u300F")) nextbracket = "\u3010";
else if (searchtext.equals("\u3011")) nextbracket = "\u3012";
else if (searchtext.equals("\u300D")) nextbracket = "\u300C";
else if (searchtext.equals("\u3010")) nextbracket = "\u300F";
else if (searchtext.equals("\u3012")) nextbracket = "\u3011";
if (fromlefttoright) {
for(int i=pos;i<text.length(); i++) {
if ((text.substring(i,i+1).equals(nextbracket)) && (counter == 0)) {
return i+1;
} else if (text.substring(i,i+1).equals(searchtext)) {
counter++;
} else if ((text.substring(i,i+1).equals(nextbracket)) && (counter != 0)) {
counter--;
}
}
} else {
for(int i=pos-2;i>=0; i--) {
if ((text.substring(i,i+1).equals(nextbracket)) && (counter == 0)) {
return i+1;
} else if (text.substring(i,i+1).equals(searchtext)) {
counter++;
} else if ((text.substring(i,i+1).equals(nextbracket)) && (counter != 0)) {
counter--;
}
}
}
return 0;
}
}