3

我将如何在 Java 中自定义滚动条,以便我可以进行类似于 chrome 的搜索,也就是说将彩色条纹放在结果所在的位置?

我不想要一个库,因为我更愿意自己编写代码。另外,我不想失去我拥有的 L&F。欢迎举例。

实际上它将是查看一个大的文本文件或一个长的 jtable,有没有人对我如何有一个有效的滚动条来查看这个有什么好主意?...我应该有一个从头到尾的双滚动条和一个在短范围内滚动的内部滚动条吗?

(对不起,这是一个双重问题,但彩色滚动条会打勾)

感谢您提供所有可能的帮助和想法。

编辑:没有代码示例很抱歉,因为我试图事先在脑海中计划出来......你会看到它将是一个带有快速搜索的长文本窗格。用户将需要加载这个大文件并快速访问详细信息。目前,我对加载速度保持轻描淡写。其次,文本将是动态的,因此通过单击一个单词,它将在滚动条中放置一条条纹,就好像搜索已激活一样。目前让我们说它是一个带有滚动条的简单文本区域。

4

1 回答 1

1

在此处输入图像描述

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.regex.*;
import javax.swing.*;
import javax.swing.text.*;
import javax.swing.plaf.metal.MetalScrollBarUI;

public class ScrollBarSearchHighlighterTest {
  private static final Highlighter.HighlightPainter highlightPainter
    = new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW);
  private static final String pattern = "Swing";
  private static final String initTxt =
    "Trail: Creating a GUI with JFC/Swing\n" +
    "Lesson: Learning Swing by Example\n" +
    "This lesson explains the concepts you need to\n" +
    " use Swing components in building a user interface.\n" +
    " First we examine the simplest Swing application you can write.\n" +
    " Then we present several progressively complicated examples of creating\n" +
    " user interfaces using components in the javax.swing package.\n" +
    " We cover several Swing components, such as buttons, labels, and text areas.\n" +
    " The handling of events is also discussed,\n" +
    " as are layout management and accessibility.\n" +
    " This lesson ends with a set of questions and exercises\n" +
    " so you can test yourself on what you've learned.\n" +
    "http://docs.oracle.com/javase/tutorial/uiswing/learn/index.html\n";

  private final JTextArea textArea   = new JTextArea();
  private final JScrollPane scroll   = new JScrollPane(textArea);
  private final JScrollBar scrollbar = new JScrollBar(JScrollBar.VERTICAL);
  public JComponent makeUI() {
    textArea.setEditable(false);
    textArea.setLineWrap(true);
    textArea.setText(initTxt+initTxt+initTxt);
    scrollbar.setUnitIncrement(10);

    scrollbar.setUI(new MetalScrollBarUI() {
      @Override protected void paintTrack(
            Graphics g, JComponent c, Rectangle trackBounds) {
        super.paintTrack(g, c, trackBounds);
        Rectangle rect = textArea.getBounds();
        double sy = trackBounds.getHeight() / rect.getHeight();
        AffineTransform at = AffineTransform.getScaleInstance(1.0, sy);
        Highlighter highlighter = textArea.getHighlighter();
        g.setColor(Color.YELLOW);
        try{
          for(Highlighter.Highlight hh: highlighter.getHighlights()) {
            Rectangle r = textArea.modelToView(hh.getStartOffset());
            Rectangle s = at.createTransformedShape(r).getBounds();
            int h = 2; //Math.max(2, s.height-2);
            g.fillRect(trackBounds.x+2, trackBounds.y+1+s.y, trackBounds.width, h);
          }
        } catch(BadLocationException e) {
          e.printStackTrace();
        }
      }
    });
    scroll.setVerticalScrollBar(scrollbar);

    Box box = Box.createHorizontalBox();
    box.add(Box.createHorizontalGlue());
    box.add(new JButton(new AbstractAction("highlight") {
      @Override public void actionPerformed(ActionEvent e) {
        setHighlight(textArea, pattern);
      }
    }));
    box.add(Box.createHorizontalStrut(2));
    box.add(new JButton(new AbstractAction("clear") {
      @Override public void actionPerformed(ActionEvent e) {
        textArea.getHighlighter().removeAllHighlights();
        scrollbar.repaint();
      }
    }));

    JPanel p = new JPanel(new BorderLayout());
    p.add(scroll);
    p.add(box, BorderLayout.SOUTH);
    return p;
  }
  public void setHighlight(JTextComponent jtc, String pattern) {
    Highlighter highlighter = jtc.getHighlighter();
    highlighter.removeAllHighlights();
    Document doc = jtc.getDocument();
    try{
      String text = doc.getText(0, doc.getLength());
      Matcher matcher = Pattern.compile(pattern).matcher(text);
      int pos = 0;
      while(matcher.find(pos)) {
        int start = matcher.start();
        int end   = matcher.end();
        highlighter.addHighlight(start, end, highlightPainter);
        pos = end;
      }
    }catch(BadLocationException e) {
      e.printStackTrace();
    }
    scroll.repaint();
  }
  public void removeHighlights(JTextComponent jtc) {
    Highlighter hilite = jtc.getHighlighter();
    Highlighter.Highlight[] hilites = hilite.getHighlights();
    for(int i=0; i<hilites.length; i++) {
      if(hilites[i].getPainter() instanceof
             DefaultHighlighter.DefaultHighlightPainter) {
        hilite.removeHighlight(hilites[i]);
      }
    }
    scroll.repaint();
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      @Override public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new ScrollBarSearchHighlighterTest().makeUI());
    frame.setSize(320, 240);
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}

或者另一种选择是使用“MatteBorder + Icon + RowHeader”:JScrollBar search highlighter

于 2013-03-24T15:53:40.810 回答