2014-11-05 128 views
1

不好意思问这个,因为还有一些关于同一主题的其他文章,但我没有设法将这些解决方案应用于我的问题。Java删除旧的亮点

简单情况。我有一个JTextPane,我有一个搜索方法。它检测所有匹配的单词并将其突出显示为灰色为了浏览不同的比赛,我有第二个突出显示当前“活动”比赛红色的荧光笔。通过按下按钮,有效高光会转到下一场比赛。 (基本上chromes搜索的工作原理)

除去删除旧的活动荧光笔,一切都可以工作。有一种叫做.removeHighlight()的方法,我需要删除旧的高亮区,但不管我插入什么参数,我会得到异常或者什么也没有发生。我会使用.removeAllHighlights(),但是因为我有其他亮点(突出显示所有命中灰色),所以我将它们松开,所以我只能删除最后一个有效的高光。 官方oracle文档与removeHighlight(hilites[i])做了一些事情,但老实说,我不知道那里发生了什么。 这里的代码我这么远:

private DefaultHighlightPainter highlightOne = new DefaultHighlightPainter(Color.RED); 
private Object last; 

public void paintAt(int pos){ 
    try { 
     if (last != null){ 
      motherFrame.tField.getHighlighter().removeHighlight(last); 
     } 
     last = motherFrame.tField.getHighlighter().addHighlight(pos, pos + searchWordLength, highlightOne); 
    } catch (BadLocationException e) { 
     //TODO 
    } 
} 

在这里,一峰:

enter image description here

UPDATE 这里是一个可运行:(很抱歉的乱码。)

http://hostcode.sourceforge.net/view/2563 and http://hostcode.sourceforge.net/view/2564

回答

0

感谢MadProgrammer我发现了问题所在:

对于原来的问题“如何删除旧的荧光笔”答案很简单: 这是示例代码我张贴。

private DefaultHighlightPainter highlightOne = new DefaultHighlightPainter(Color.RED); 
private Object last; 

public void paintAt(int pos){ 
    try { 
     if (last != null){ 
      textPane.getHighlighter().removeHighlight(last); 
     } 
     last = textPane.getHighlighter().addHighlight(pos, pos + searchWordLength, highlightOne); 
    } catch (BadLocationException e) { 
     //TODO 
    } 
} 

(因为我有两个荧光笔第一个被覆盖第二个,所以第二个是没有显示出来。这就是为什么我认为我的代码不能正常工作。)

有关更新问题“如何处理多个荧光笔”的答案也很简单。一个人必须知道的事情只有一个。荧光笔中的油漆不会被其他稍后调用的荧光笔覆盖。所以基本上我不得不颠倒荧光笔的调用顺序。 这看起来是这样的:

textPane.getHighlighter().removeAllHighlights(); 
textPane.getHighlighter().addHighlight(pos, pos + searchWordLength, red); 
for int i = 0; i < matchList.size(); i++){ 
    int position = matchList.get(i); 
    textPane.getHighlighter().addHighlight(position, possition + searchWordLength, grey); 
} 

这不是一个最佳的解决方案,因为你必须重新绘制与每一个变化每荧光笔。但是可以通过增量变化绘制来优化它(只重绘改变的部分)。

2

Highlighter#addHighlight返回代表当前高光的Object标记。这个标签应该调用Highlighter#removeHighlight时使用,这一点,我想,意味着你可以使用HighlightPainter的同一个实例,以突出显示文档的多个部分,但仍分别进行管理,例如...

Highlight

import java.awt.BorderLayout; 
import java.awt.Color; 
import java.awt.EventQueue; 
import java.awt.GridBagConstraints; 
import java.awt.GridBagLayout; 
import java.awt.Rectangle; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import java.io.FileReader; 
import java.io.IOException; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTextField; 
import javax.swing.JTextPane; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DefaultHighlighter; 
import javax.swing.text.Document; 

public class TestEditorPane01 { 

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

    public TestEditorPane01() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
       } 

       JFrame frame = new JFrame(); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.setLayout(new BorderLayout()); 
       frame.add(new EditorPane()); 
       frame.setSize(400, 400); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 

      } 
     }); 
    } 

    public class EditorPane extends JPanel { 

     private JTextPane editor = new JTextPane(); 
     private int lastMatch; 
     private String find = "Method"; 
     private DefaultHighlighter.DefaultHighlightPainter highlightPainter; 
     private Object highlightTag; 

     private JTextField searchField; 
     private JButton searchButton; 

     public EditorPane() { 
      setLayout(new BorderLayout()); 
      editor = new JTextPane(); 
      try (FileReader reader = new FileReader(new File("/some file.txt"))) { 
       editor.read(reader, "script"); 
      } catch (IOException exp) { 
       exp.printStackTrace(); 
      } 
      add(new JScrollPane(editor)); 

      JPanel searchPane = new JPanel(new GridBagLayout()); 
      searchField = new JTextField(10); 
      searchButton = new JButton("Search"); 
      GridBagConstraints gbc = new GridBagConstraints(); 
      gbc.gridx = 0; 
      gbc.gridy = 0; 
      gbc.fill = GridBagConstraints.HORIZONTAL; 
      gbc.weightx = 1; 
      searchPane.add(searchField, gbc); 

      gbc.gridx++; 
      gbc.fill = GridBagConstraints.NONE; 
      gbc.weightx = 0; 
      searchPane.add(searchButton, gbc); 

      searchButton.addActionListener(new ActionListener() { 

       @Override 
       public void actionPerformed(ActionEvent e) { 
        String text = searchField.getText(); 
        if (!text.equals(find)) { 
         find = text; 
         lastMatch = 0; 
        } 
        highlightNext(); 
       } 
      }); 

      add(searchPane, BorderLayout.SOUTH); 

     } 

     public void highlightNext() { 

      Document document = editor.getDocument(); 
      try { 

       if (lastMatch + find.length() >= document.getLength()) { 
        lastMatch = 0; 
       } 

       for (; lastMatch + find.length() < document.getLength(); lastMatch++) { 
        String match = document.getText(lastMatch, find.length()); 
        if (find.equalsIgnoreCase(match)) { 
         if (highlightTag != null) { 
          editor.getHighlighter().removeHighlight(highlightTag); 
         } 

         if (highlightPainter == null) { 
          highlightPainter = new javax.swing.text.DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW); 
         } 

         highlightTag = editor.getHighlighter().addHighlight(lastMatch, lastMatch + find.length(), highlightPainter); 

         Rectangle viewRect = editor.modelToView(lastMatch); 
         editor.scrollRectToVisible(viewRect); 

         lastMatch += find.length(); 
         break; 
        } 
       } 
      } catch (BadLocationException ex) { 
       ex.printStackTrace(); 
      } 

     } 

    } 
} 

由于您正在这样做,并且它不工作,所以这会提示您的代码存在其他问题,这在您提供的代码段中不明显。考虑提供一个runnable example这表明你的问题。这将导致更少的混乱和更好的反应

更新...

  1. 不要你的示例代码链接到外部网站,而不是每个人都可以访问外部站点,或者可以不屑于跟踪链接反正...
  2. 可运行的例子应该是自包含的,对其他库或资源不依赖,喜欢的图标,应包含在单个文件中
  3. 不要暴露你的不必要的UI组件,也就是我不要认为SearchDialog真的需要要知道关于TestFrame,所有它感兴趣的是JTextComponent ...
  4. 您的“新”示例和您现有的代码片段不一致。您不再将addHighlight的结果分配给last
  5. 请勿使用null布局...

当我终于得到了您的示例代码编译,这就是我提交了......

Bad Screen 01

...好了,所以想,我只是扩展窗口...

Bad Screen 02

...嗯,有一个问题...我没有解决的时候。

避免使用null布局,像素完美的布局是现代UI设计中的幻想。影响组件的个体大小的因素太多,其中没有一个可以控制。 Swing旨在与布局经理一起工作,放弃这些将导致问题和问题的终结,您将花费越来越多的时间来尝试纠正

有关更多详细信息,请参阅Why is it frowned upon to use a null layout in SWING? ...

+0

嗯好吧谢谢你的评论。我将尝试将搜索对话框提取为可运行的片段。 – Haeri 2014-11-05 22:09:30

+0

好的我更新了OP。 – Haeri 2014-11-05 23:16:28

+0

好的,谢谢你的时间。这是我的第一个Java应用程序,所以我仍然在学习东西。我会按照你所说的更新一切。 PS:我链接到一个外部网站,因为我还没有想出如何在这里发布长代码片段.. PSS:该死..我用一个空布局制作了每一个JDialog ..但它看起来不错我的系统.. :( – Haeri 2014-11-05 23:52:51