我目前正在开发一个非常简单的IDE,用于Java中的C编程。简单地说,我的意思是它有少量的代码猜测(类似于Eclipse)、一些次要的自动完成(再一次,想想Eclipse),以及一些语法突出显示。我已经解决了几乎所有的问题,并粗略地解决了(即工作,但不漂亮或有效),除了我有一些问题,在正确的语法突出。
我的意思是:在我的代码JFrame中,我添加了一个JTextPane,这样我就可以使用不同的字体、粗体、非粗体、斜体,并相对容易地添加不同的文本颜色。我有一个键侦听器连接到这个JTextPane,在每个空格键上,它抓取您刚才写的内容,通过一个" if“语句树来查看您所写的单词是否是关键字。如果您这样做了,它试图突出(或不)您刚才所写的内容。但是,在某些情况下,我需要在单击空格之前更改颜色(例如注释或#define语句)。没问题对吧?只需添加另一个" if“语句,以检测该键是否已按下,如果已按下,则更改字体颜色。好吧,这就是我想要做的,但是它不起作用。这真的扰乱了我的头脑,因为我使用完全相同的代码来改变颜色,就像我用空格键做的那样(这真是太棒了)。
对不起,如果没有什么意义的话,如果需要的话,我很乐意再解释一下。我还删除了尽可能多的不必要的代码,试图缩短它。
非常感谢您的时间!
~分
SSCCE:
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import javax.swing.JFrame;
import javax.swing.JTextPane;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyledDocument;
public class Main implements Runnable
{
private static final long serialVersionUID = 1L;
private static final int WIDTH = 800;
private static final int HEIGHT = 600;
private static final String NAME = "";
private JFrame frame;
private JTextPane textPane = new JTextPane();
private int keysPressed = -1; /* Keys pressed */
private ArrayList<Integer> keyCode = new ArrayList<Integer>(); /* List of our keyCodes */
public void run()
{
frame = new JFrame(NAME);
frame.setPreferredSize(new Dimension(WIDTH, HEIGHT));
frame.setMinimumSize(new Dimension(WIDTH, HEIGHT));
frame.setMaximumSize(new Dimension(WIDTH, HEIGHT));
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(textPane, BorderLayout.CENTER);
textPane.setPreferredSize(new Dimension(WIDTH, HEIGHT));
textPane.setEditable(true);
textPane.addKeyListener(new KeyListener(){
@Override
public void keyPressed(KeyEvent e)
{
int previousPos; /* Previous position of the caret */
int length; /* Length of our grabbed string */
int currentPos; /* Current position of the caret */
String text; /* The entire text of the JTextPane */
String subText; /* Our sub-string-text we're using */
String subTextP; /* Our sub-string-text plus one character*/
boolean first = true; /* Be default, it's the first letter */
StyledDocument doc = textPane.getStyledDocument();
SimpleAttributeSet sas = new SimpleAttributeSet(); /* So we can set bold, and such */
keyCode.add(new Integer(e.getKeyCode())); /* The key pressed */
keysPressed++;
currentPos = textPane.getCaretPosition(); /* The current position of the caret */
text = textPane.getText(); /* Grabbing the text on the text pane */
previousPos = text.lastIndexOf(" ", currentPos); /* Getting the last position of a space */
if(previousPos <= 0) /* If the position if before or equal to 0 */
{
previousPos = 0; /* Then the position is 0 */
}
length = currentPos - previousPos; /* The length of the string we're messing with, is between the two positions */
subText = text.substring(previousPos, currentPos); /* Grabbing the string between our two positions */
if(first) /* If this is the first letter, or insert */
{
if(keyCode.contains(KeyEvent.VK_SHIFT))
{
first = true;
subTextP = text.substring(0, 0); /* Then we want to grab it, at 0, 0 */
}
else
{
subTextP = text.substring(0, 0); /* Then we want to grab it, at 0, 0 */
first = false; /* it's no longer the first */
}
}
else /* If it isn't */
{
subTextP = text.substring(previousPos + 1, currentPos); /* Then we want to grab the usual */
}
subText = subText.replaceAll("[\\n\\t\\r]", ""); /* Getting rid of all the tabs and newlines */
subTextP = subTextP.replaceAll("[\\n\\t\\r]", ""); /*Getting rid of all the tabs and new lines */
if(keyCode.contains(KeyEvent.VK_3))
{
if(keyCode.contains(KeyEvent.VK_SHIFT))
{
System.out.println("Number sign hit!");
StyleConstants.setForeground(sas, Color.GREEN); /* Anything following a number sign will be green */
doc.setCharacterAttributes(previousPos, length, sas, false); /* Turning it green */
}
}
if(keyCode.contains(KeyEvent.VK_SPACE)) /* If a space has been hit! */
{
/* This is were we'll do all text coloring and such */
if(subText.equals(" if") || subText.equals("if") || subTextP.equals("if")) /* All things to be bolded */
{
StyleConstants.setForeground(sas, Color.GRAY); /* All of these statements will be gray... */
StyleConstants.setBold(sas, true); /* ... and bold */
doc.setCharacterAttributes(previousPos, length, sas, false); /* Making them so! */
StyleConstants.setBold(sas, false); /* We don't want these attributes to remain... */
StyleConstants.setForeground(sas, Color.black); /* ... So we're removing them. */
}
}
}
public void keyReleased(KeyEvent e)
{
for(int i = keysPressed; i >= 0; i--) /* For loop to remove all keyPresses from our list */
{
keyCode.remove(i); /* Removing the specified keyPress */
}
keysPressed = -1; /* Because the first index is 0, and we want to add one to keysPressed, we need to start below 0 */
}
@Override
public void keyTyped(KeyEvent arg0) {
}
});
frame.pack();
frame.setVisible(true);
}
public void start()
{
new Thread(this).start();
}
public final static void main(String args[])
{
new Main().start();
}
}编辑:
若要再现问题,请运行上面提供的代码。在textPane中,输入单词"if“(没有引号),然后按空格键。这个词现在应该用粗体表示,颜色应该是灰色。现在,尝试在它之后输入一个"#“(没有引号),(中间的空格)并点击空格或任何其他键;什么都不会发生。但是,系统应该打印出“数字符号命中!”一旦输入了"#",就意味着代码实际上仍然是可访问的。还请注意,对于"#“,我使用了与"if”相同的代码(除了更改颜色)。希望这能帮助你们更好地理解这个问题。
发布于 2012-12-04 06:14:30
首先,在这里使用KeyListener是不正确的。
使用KeyBindings、DocumentListener或DocumentFilter (甚至用自己的扩展替换文档以覆盖insertString()和remove()方法)。您不仅应该在空格输入之后更改突出显示,而且当有人从关键字的中间移除字符时也应该更改。
请张贴SSCCE,以显示真实的问题,并提供步骤,以再现实际行为和描述期望的行为。
https://stackoverflow.com/questions/13690269
复制相似问题