2012-12-03 170 views
0

我目前正在研究一個非常簡單的IDE,用於Java中的C編程。簡而言之,我的意思是它具有次要的代碼猜測(類似於Eclipse),一些次要的自動完成(再一次,思考Eclipse)和一些語法突出顯示。我幾乎所有的東西都已經算出來了,並且粗加工出來了(例如工作,但並不漂亮或者高效),除非我在正確的語法突出顯示方面遇到了一些麻煩。JTextPane語法高亮

我的意思是說,在我的代碼JFrame中,我放入了一個JTextPane,這樣我就可以使用不同的字體,粗體,非粗體,斜體,並且相對容易地添加不同的文本顏色。我有一個與這個JTextPane相連的關鍵偵聽器,並且在每個空格鍵按下時,它抓住你剛剛寫的內容,通過「if」語句樹運行它,看看你寫的單詞是否是關鍵字。如果你這樣做,它試圖突出(或不)你剛纔寫的東西。但是,有些情況下我需要在打空格鍵之前更改顏色(例如註釋或#define語句)。沒問題,對吧?只需添加另一個「if」語句來檢測該鍵是否被按下,如果有,則更改字體顏色。那麼,這是我試圖做的,但它不工作。當我用EXACT相同的代碼來改變我使用空格鍵按下時的顏色(它的工作原理是花哨的)時,它真的讓我大惑不解。

對不起,如果沒有多大意義,我會很樂意解釋多一點,如果它是必需的。我也刪除了儘可能多的不必要的代碼,以儘量縮短它。

非常感謝您的時間!

〜美分

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」所做的那樣。希望能幫助你們更多地理解問題。

回答

1

首先在這裏使用KeyListener是不正確的。

使用KeyBindingsDocumentListenerDocumentFilter,而不是(或者甚至替換自己的分機的文件覆蓋insertString()remove()方法)。不僅在空格鍵入之後,而且在有人從關鍵字中間刪除字符時,您應該更改高亮區。

請發佈SSCCE以顯示真實問題並提供步驟來重現實際行爲並描述所需的行爲。

+0

將發佈的代碼更改爲SSCCE,並添加了重現該問題的步驟。感謝您的提示! – centip3de

+0

我輸入「if#」,然後看到「數字符號命中!」在控制檯中。有什麼問題? – StanislavL

+0

正如您在閱讀重現問題的步驟或原始文章本身所閱讀的那樣,問題在於數字符號及其後面的所有內容都應該是綠色的,而不是。 – centip3de