2011-03-23 14 views
8

मैं एक पाठ संपादक खिड़की के लिए एक विशिष्ट आवश्यकता को लागू करने की अधिक से अधिक 2 दिनों के लिए कोशिश कर रहा हूँ में वर्तमान पंक्ति को हाइलाइट करें ... दुर्भाग्य से सफलता नहीं मिली अब तक :(JTextPane

लक्ष्य एक पाठ संपादक खिड़की प्राप्त करने के लिए है जो वर्तमान पंक्ति को अन्य टेक्स्ट संपादकों की तरह हाइलाइट करेगा। वर्तमान पंक्ति के साथ मेरा मतलब है कि वर्तमान में कर्सर/कैरेट स्थित है।

मुझे पहले से ही दो अलग-अलग दृष्टिकोण मिलते हैं लेकिन दुर्भाग्य से मैं उन्हें अपनाने में सक्षम नहीं हूं वे उम्मीद के अनुसार काम करते हैं।

पहला दृष्टिकोण DefaultHighlighter (को ओवरराइट करना है))। दूसरे दृष्टिकोण में HighlighterPainter इसके बजाय ओवरराइट किया जाएगा (http://www.jroller.com/santhosh/date/20050622)।

अभी मैं अपनी परियोजना में पहला दृष्टिकोण अपनाने की कोशिश कर रहा हूं लेकिन जैसा कि मैंने कहा है कि यह वांछित के रूप में काम नहीं कर रहा है।

इस पोस्ट के अंत में मैं एक छोटा नमूना आवेदन पोस्ट कर रहा हूं जो समस्या का प्रदर्शन करता है।

  • यदि मैं प्रोग्राम शुरू करता हूं, तो देखभाल पहली पंक्ति की शुरुआत में रखी जाती है। हालांकि, रेखा को हाइलाइट नहीं किया गया है।
  • अब मैं कुछ पात्रों में टाइप करता हूं। उन वर्णों को हाइलाइट किया जाएगा लेकिन केवल उन वर्णों की पूरी लाइन
  • मैंने अगली पंक्ति में जाने के लिए एंटर दबाया। पहली पंक्ति अब और सही नहीं है जो सही है। दूसरी पंक्ति को भी हाइलाइट नहीं किया गया है, जो सही नहीं है। दोबारा, जब मैं कुछ वर्णों में टाइप करता हूं, तो वे higlighted होंगे लेकिन पूरी पंक्ति नहीं।
  • जब मैं अब पहली पंक्ति में कैरेट वापस ले जाता हूं, या तो कर्सर अप कुंजी या माउस क्लिक करके, पूरी पहली पंक्ति को केवल मौजूदा वर्णों पर ही हाइलाइट नहीं किया जाएगा। यह वही व्यवहार है जो मैं शुरुआत से ही चाहता हूं।

मुझे उम्मीद है कि कोई मुझे बता सकता है कि मैं यहां क्या कर रहा हूं ... या समझाओ कि इस मुद्दे को हल करना क्यों संभव नहीं है। किसी भी वैकल्पिक समाधान को मैं लाइन हाइलाइटिंग का एहसास कैसे कर सकता हूं, इसकी भी सराहना की जाती है!

धन्यवाद अग्रिम में एक बहुत चीयर्स Preachie

import java.awt.Color; 
import java.awt.Dimension; 
import java.awt.Graphics; 
import java.awt.Insets; 
import java.awt.Rectangle; 

import javax.swing.JFrame; 
import javax.swing.JTextPane; 
import javax.swing.event.CaretEvent; 
import javax.swing.event.CaretListener; 
import javax.swing.text.DefaultHighlighter; 
import javax.swing.text.Highlighter; 
import javax.swing.text.JTextComponent; 

public class HighlightProblem extends JFrame { 
    private static final long serialVersionUID = 1L; 
    private final JTextPane textPane; 
    private final Highlighter.HighlightPainter cyanPainter; 

    public HighlightProblem() { 
     cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.CYAN); 

     textPane = new JTextPane(); 
     textPane.setPreferredSize(new Dimension(500, 300)); 
     textPane.setHighlighter(new LineHighlighter()); 
     textPane.addCaretListener(new CaretListener() { 
      @Override 
      public void caretUpdate(CaretEvent e) { 
       setHighlight(e); 
      } 
     }); 
     getContentPane().add(textPane); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     pack(); 
     setVisible(true); 
    } 

    public static void main(String[] args) { 
     new HighlightProblem(); 
    } 

    public void setHighlight(CaretEvent e) { 
     textPane.getHighlighter().removeAllHighlights(); 
     int currentLine = getLineFromOffset(textPane, e.getDot()); 
     int startPos = getLineStartOffsetForLine(textPane, currentLine); 
     int endOffset = getLineEndOffsetForLine(textPane, currentLine); 

     try { 
      textPane.getHighlighter().addHighlight(startPos, endOffset, cyanPainter);   
     } catch (Exception ex) { 
      ex.printStackTrace(); 
     } 
     textPane.repaint(); 
    } 

    public int getLineFromOffset(JTextComponent component, int offset) { 
     return component.getDocument().getDefaultRootElement().getElementIndex(offset); 
    } 

    public int getLineStartOffsetForLine(JTextComponent component, int line) { 
     return component.getDocument().getDefaultRootElement().getElement(line).getStartOffset(); 
    } 

    public int getLineEndOffsetForLine(JTextComponent component, int line) { 
     return component.getDocument().getDefaultRootElement().getElement(line).getEndOffset(); 
    } 

    public class LineHighlighter extends DefaultHighlighter { 
     private JTextComponent component; 

     @Override 
     public final void install(final JTextComponent c) { 
      super.install(c); 
      this.component = c; 
     } 

     @Override 
     public final void deinstall(final JTextComponent c) { 
      super.deinstall(c); 
      this.component = null; 
     } 

     @Override 
     public final void paint(final Graphics g) { 
      final Highlighter.Highlight[] highlights = getHighlights(); 
      final int len = highlights.length; 
      for (int i = 0; i < len; i++) { 
       Highlighter.Highlight info = highlights[i]; 
       if (info.getClass().getName().indexOf("LayeredHighlightInfo") > -1) { 
        // Avoid allocing unless we need it. 
        final Rectangle a = this.component.getBounds(); 
        final Insets insets = this.component.getInsets(); 
        a.x = insets.left; 
        a.y = insets.top; 
        // a.width -= insets.left + insets.right + 100; 
        a.height -= insets.top + insets.bottom; 
        final Highlighter.HighlightPainter p = info.getPainter(); 
        p.paint(g, info.getStartOffset(), info.getEndOffset(), a, this.component); 
       } 
      } 
     } 

     @Override 
     public void removeAllHighlights() { 
      textPane.repaint(0, 0, textPane.getWidth(), textPane.getHeight()); 
      super.removeAllHighlights(); 
     } 
    } 
} 

उत्तर

3

http://tips4java.wordpress.com/2008/10/29/line-painter/

मुझे लगता है कि यह आपके लिए क्या देख रहे है। मुझे लगता है कि LinePainter वर्ग लिया और अपने निर्माता एक मुख्य विधि में कॉपी, अपने हाइलाइटर भागों बाहर ले गई और एक new LinePainter(textPane); वर्क्स एक आकर्षण

+0

धन्यवाद एक बहुत मिलता है और लेख को हाइलाइट करने के लिए कर सकते हैं ... यह वास्तव में जैसे कि यह एक आकर्षण की तरह काम कर रहा है लग रहा है। – Preachie

+0

आपका स्वागत है। :) – spedsal

1

मैं इस हाइलाइटर का उपयोग कर प्राप्त करने के लिए मुश्किल हो सकता है लगता है की तरह जोड़ा - मुझे नहीं लगता कि यह है वे किसके लिए डिजाइन किए गए थे। आपको कस्टम पेंटिंग कोड के साथ ऐसा करने की आवश्यकता हो सकती है:

import java.awt.Color; 
import java.awt.Graphics; 
import java.awt.Rectangle; 

import javax.swing.JFrame; 
import javax.swing.JTextPane; 
import javax.swing.text.BadLocationException; 

public class HighlightLineTest { 
    private static class HighlightLineTextPane extends JTextPane { 
     public HighlightLineTextPane() { 
      // Has to be marked as transparent so the background is not replaced by 
      // super.paintComponent(g); 
      setOpaque(false); 
     } 

     @Override 
     protected void paintComponent(Graphics g) { 
      g.setColor(getBackground()); 
      g.fillRect(0, 0, getWidth(), getHeight()); 
      try { 
       Rectangle rect = modelToView(getCaretPosition()); 
       if (rect != null) { 
        g.setColor(Color.CYAN); 
        g.fillRect(0, rect.y, getWidth(), rect.height); 
       } 
      } catch (BadLocationException e) { 
      } 
      super.paintComponent(g); 
     } 

     @Override 
     public void repaint(long tm, int x, int y, int width, int height) { 
      // This forces repaints to repaint the entire TextPane. 
      super.repaint(tm, 0, 0, getWidth(), getHeight()); 
     } 
    } 

    public static void main(String[] args) { 
     JFrame frame = new JFrame("Highlight test"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new HighlightLineTextPane()); 
     frame.setBounds(100, 100, 300, 400); 
     frame.setVisible(true); 
    } 
} 
2

नीचे वर्तमान पंक्ति से टेक्स्ट निकालने के लिए कोड है। आप एक ही तर्क का उपयोग आवश्यक अनुक्रमित

private String getCurrentEditLine() { 
     int readBackChars = 100; 
     int caretPosition = scriptEditor.getCaretPosition(); 

     if (caretPosition == 0) { 
      return null; 
     } 

     StyledDocument doc = scriptEditor.getStyledDocument(); 

     int offset = caretPosition <= readBackChars ? 0 : caretPosition 
       - readBackChars; 

     String text = null; 
     try { 
      text = doc.getText(offset, caretPosition); 
     } catch (BadLocationException e) { 
     } 

     if (text != null) { 
      int idx = text.lastIndexOf("\n"); 
      if(idx != -1) { 
       return text.substring(idx); 
      }else { 
       return text; 
      } 
     } 

     return null; 
    }