import javax.swing.*;
import javax.swing.text.BadLocationException;
import javax.swing.text.DefaultStyledDocument;
import javax.swing.text.Element;
import javax.swing.text.MutableAttributeSet;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Enumeration;
public class SqlTextPane extends JTextPane {
private DefaultStyledDocument styledDocument;
private MutableAttributeSet keyAttributeSet, normalAttributeSet;
private MutableAttributeSet commentsAttributeSet;
private String[] keywords = {
"select", "update", "delete",
"from", "where", "by", "order",
"group", "limit", "as",
"left", "join", "inner",
"on", "distinct", "case", "then",
"unique", "union", "exists", "not", "in"
};
public SqlTextPane() {
super();
styledDocument = new DefaultStyledDocument(new StyleContext());
this.setDocument(styledDocument);
this.addKeyListener(new KeyAdapter() {
public void keyReleased(KeyEvent ke) {
if (KeyEvent.getKeyText(ke.getKeyCode()).length() > 0) {
syntaxDocument();
}
}
});
final SqlTextPane ref = this;
this.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
if (e.getButton() == 3) {
JPopupMenu popupMenu = new JPopupMenu();
final String selectedText = ref.getSelectedText();
//beatify
JMenuItem beatifySQL = new JMenuItem("Beatify SQL") {
@Override
protected void fireActionPerformed(ActionEvent event) {
formatSelected(selectedText);
}
};
beatifySQL.setEnabled(selectedText != null && !"".equals(selectedText));
popupMenu.add(beatifySQL);
//beatify
JMenuItem join = new JMenuItem("Join") {
@Override
protected void fireActionPerformed(ActionEvent event) {
join(selectedText);
}
};
beatifySQL.setEnabled(selectedText != null && !"".equals(selectedText));
popupMenu.add(join);
// insert
popupMenu.add(new JMenuItem("Insert SELECT") {
@Override
protected void fireActionPerformed(ActionEvent event) {
insertText("SELECT * FROM table");
}
});
popupMenu.show(ref, e.getX(), e.getY());
}
}
});
//定义关键字显示属性
keyAttributeSet = new SimpleAttributeSet();
StyleConstants.setForeground(keyAttributeSet, Color.blue);
StyleConstants.setBold(keyAttributeSet, true);
//定义一般文本显示属性
normalAttributeSet = new SimpleAttributeSet();
StyleConstants.setForeground(normalAttributeSet, Color.black);
//定义一般文本显示属性
commentsAttributeSet = new SimpleAttributeSet();
StyleConstants.setForeground(commentsAttributeSet, Color.gray);
}
public static void main(String[] args) {
JFrame frame = new JFrame("test text pane");
frame.getContentPane().add(new SqlTextPane());
frame.addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
final int inset = 50;
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
frame.setBounds(inset, inset, screenSize.width - inset * 2, screenSize.height - inset * 2);
frame.setVisible(true);
}
/**
* ssss
*
* @param element
*/
private void syntaxElement(Element element) {
int startOffset = element.getStartOffset();
int endOffset = element.getEndOffset();
String text;
try {
text = styledDocument.getText(startOffset, endOffset - startOffset);
} catch (BadLocationException e) {
throw new RuntimeException(e);
}
styledDocument.setCharacterAttributes(startOffset, text.length(), normalAttributeSet, false);
SqlTokenizer st = new SqlTokenizer(text);
while (st.hasMoreElements()) {
int begin = st.getCurPosition();
String token = st.nextElement();
if (isKeyword(token)) {
styledDocument.setCharacterAttributes(startOffset + begin, token.length(), keyAttributeSet, false);
} else if (token.startsWith("--")) {
styledDocument.setCharacterAttributes(startOffset + begin, token.length(), commentsAttributeSet, false);
}
}
}
private void syntaxDocument() {
Element root = styledDocument.getDefaultRootElement();
int line = root.getElementIndex(getCaretPosition());
Element lineElement = root.getElement(line);
syntaxElement(lineElement);
}
private void syntaxAll() {
Element[] elements = styledDocument.getRootElements();
for (Element element : elements) {
syntaxElement(element);
}
}
private boolean isKeyword(String input) {
for (String keyword : keywords) {
if (keyword.equalsIgnoreCase(input)) {
return true;
}
}
return false;
}
private void insertText(String content) {
try {
styledDocument.insertString(styledDocument.getLength(), "\n" + content, null);
syntaxDocument();
} catch (BadLocationException e) {
e.printStackTrace();
}
}
private void formatSelected(String selectedText) {
if (!"".equals(selectedText)) {
String format = new BasicFormatter().format(selectedText).trim();
this.replaceSelection(format);
syntaxAll();
}
}
private void join(String selectedText) {
if (!"".equals(selectedText)) {
String format = selectedText.replaceAll("\n", "");
this.replaceSelection(format);
syntaxDocument();
}
}
}
class SqlTokenizer implements Enumeration {
private String sql;
private int curPosition;
private int maxPosition;
private int newPosition;
private char[] delimiters = new char[]{
' ', ';', '\n'
};
SqlTokenizer(String sql) {
this.sql = sql;
curPosition = 0;
newPosition = 0;
maxPosition = sql.length();
}
public static void main(String[] args) {
String sql = "hahaha -- hello\n hahaha --test ";
SqlTokenizer tokenizer = new SqlTokenizer(sql);
int i = 0;
while (tokenizer.hasMoreElements()) {
System.out.println((i++) + ">>" + tokenizer.nextElement());
}
}
@Override
public boolean hasMoreElements() {
movePosition();
return curPosition < maxPosition;
}
private void movePosition() {
while (curPosition < maxPosition) {
if (!isDelimiter(sql.charAt(curPosition))) {
newPosition = curPosition;
break;
} else {
curPosition++;
}
}
}
@Override
public String nextElement() {
while (curPosition < maxPosition && !isDelimiter(sql.charAt(curPosition))) {
curPosition++;
}
String str = sql.substring(newPosition, curPosition);
if ("--".startsWith(str)) {
while (curPosition <= maxPosition) {
if ('\n' == sql.charAt(curPosition)) {
str = sql.substring(newPosition, curPosition);
newPosition = curPosition;
curPosition++;
break;
} else {
curPosition++;
}
}
} else {
newPosition = curPosition;
curPosition++;
}
return str;
}
private boolean isDelimiter(char aChar) {
for (char delimiter : delimiters) {
if (aChar == delimiter) {
return true;
}
}
return false;
}
int getCurPosition() {
return curPosition;
}
}
一键复制
编辑
Web IDE
原始数据
按行查看
历史