2012-04-24 2 views
10

Проблема 1: Используя defaulthighlighter, я могу сделать сфокусированные линии меняющимися на синие. Теперь я хочу изменить его на другие цвета. Кто-нибудь знает, как изменить этот параметр? --- resolvedКак изменить цвет выделения в Java Swing TextArea? А также, измените начало текста, соответствующее местоположению выделения.

Проблема 2: pos - это начальный индекс моей подстроки, который я хочу выделить. Я использую setCaretPosition (pos); для обновления отображаемого содержимого. Но это всегда появляется в нижней части окна. Я хочу, чтобы он был наверху. Может ли кто-нибудь сказать мне, как с этим бороться?

Я использую одну демо, чтобы показать мою проблему:

import java.awt.Color; 
import java.net.MalformedURLException; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DefaultHighlighter; 

public class Test { 
    public static void main(final String[] args) throws MalformedURLException { 
     SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      try { 
       init(); 
      } catch (BadLocationException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
    }); 
} 

private static void init() throws BadLocationException { 
    JFrame frame = new JFrame(); 
    final JTextArea textArea = new JTextArea(); 
    JScrollPane pane = new JScrollPane(textArea); 
    textArea.setText("Something. Something else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Samething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sbmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Scmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sdmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Semething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sfmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sgmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"); 
    textArea.setSelectionColor(Color.RED); 
    frame.add(pane); 
    frame.setSize(300, 120); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 

    String turnToString2 = "Sdmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla"; 
    int pos2 = textArea.getText().indexOf(turnToString2); 
    textArea.getHighlighter().addHighlight(pos2, 
      pos2 + turnToString2.length(), 
      new DefaultHighlighter.DefaultHighlightPainter(Color.yellow)); 
    textArea.setCaretPosition(pos2); 

Результат: enter image description here

Я хочу, чтобы быть в верхней правой части экрана, но в этом коде показано в нижней части прокрутки. Кто-нибудь знает, как это изменить? Черты.

+0

Проверьте это мое последнее редактирование, это то, что вы хотели? –

+0

@nIcEcOw Привет, так важно для вашего редактирования. Теперь я использую демо-код Guillaume Polet, чтобы проиллюстрировать мою проблему. Не могли бы вы запустить его и посмотреть на него? Благодарю. – AnneS

+0

Я сделал это немного, попробую протестировать его, запустив последний код, надеюсь, что это может помочь :-) –

ответ

6

Чтобы установить цвет фона выбора, используйте setSelectionColor (показано ниже, но не используется).

Я не совсем понимаю, что вы говорите, с он всегда появляется в нижней части окна. Я хочу иметь его наверху, но я предполагаю (и, возможно, я ошибаюсь здесь), что ваше текстовое поле находится в scrollpane и что, выделив текст, он прокручивается до конца вашего выбора, поэтому я предлагаю установить каретку после выделения текста.

Вот пример того, что я понял.Дай мне знать, если это не то, что вы ищете:

import java.awt.Color; 
import java.net.MalformedURLException; 

import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTextArea; 
import javax.swing.SwingUtilities; 
import javax.swing.text.BadLocationException; 
import javax.swing.text.DefaultHighlighter; 

public class Test { 
    public static void main(final String[] args) throws MalformedURLException { 
     SwingUtilities.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        init(); 
       } catch (BadLocationException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

      } 
     }); 
    } 

    private static void init() throws BadLocationException { 
     JFrame frame = new JFrame(); 
     final JTextArea textArea = new JTextArea(); 
     JScrollPane pane = new JScrollPane(textArea); 
     textArea.setText("Something. Something else.\nA second line\na third line" 
       + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
       + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"); 
     textArea.setSelectionColor(Color.RED); 
     frame.add(pane); 
     frame.setSize(300, 120); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     String turnToString = "Something else.\nA second line\na third line" 
       + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla"; 
     final int pos = textArea.getText().indexOf(turnToString); 
     textArea.getHighlighter().addHighlight(pos, 
       pos + turnToString.length(), 
       new DefaultHighlighter.DefaultHighlightPainter(Color.yellow)); 
     textArea.scrollRectToVisible(new Rectangle(0, 0, pane.getViewport().getWidth(), pane.getViewport().getHeight())); 
      SwingUtilities.invokeLater(new Runnable() { 
        @Override 
        public void run() { 
         textArea.setCaretPosition(pos); 
        } 
      }); 
    } 
} 
+0

не работает, если не используется Highlighter – mKorbel

+0

@mKorbel эй, мы снова встречаемся;) Я фактически неправильно понял вопрос, касающийся выделения и выбора. Я не уверен, что ищет OP. Во всяком случае, я радикально изменил свой ответ благодаря вашим полезным комментариям. Приветствия. –

+0

@GuillaumePolet Спасибо за ваш ответ. Вместо этого, используя DefaultHighlightPainter (Color.yellow), можно управлять цветом.Что касается caretPosition, моя проблема заключается в том, что, скажем, 20 строк, показанных в scrollPane, выделены 2 строки внизу, которые должны отображаться в первых двух строках в текущем окне. Вы знаете, что случилось? – AnneS

6

Я думаю, что не менять подъезд этих методов для всех JTextComponents в случае, который там используется Highlighter, но можно изменить только

передний план

, например

import java.awt.*; 
import javax.swing.*; 
import javax.swing.text.DefaultHighlighter; 

public class TextAreaLineHightLight { 

    public static void main(String[] args) throws Exception { 
     UIManager.put("TextArea.selectionBackground", Color.yellow); 
     UIManager.put("TextArea.selectionForeground", Color.red); 

     String string = "Lorem ipsum eum putant gubergren evertitur in, " 
       + "no assueverit vituperatoribus eum. Ea cibo offendit vim, est et vivendum qualisque prodesset. " 
       + "Vis doctus expetenda contentiones an, no ius mazim epicuri expetendis, " 
       + "saperet salutandi forensibus ne usu. Ex fugit alterum usu. " 
       + "His ignota cotidieque in, augue erroribus eam no."; 
     JTextArea textArea = new JTextArea(string); 
     textArea.setLineWrap(true); 
     textArea.setWrapStyleWord(true); 
     JScrollPane textAreaScroll = new JScrollPane(textArea); 
     JFrame frame = new JFrame(); 
     frame.setLayout(new BorderLayout()); 
     frame.add(textAreaScroll, BorderLayout.CENTER); 
     frame.setSize(400, 300); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setVisible(true); 
     String term = "qualisque prodesset. " 
       + "Vis doctus expetenda contentiones an, no ius mazim epicuri expetendis"; 
     int termOffset = string.indexOf(term); 
     Rectangle view = textArea.modelToView(termOffset); 
     int startOffset = textArea.viewToModel(new Point(0, view.y)); 
     //int rowH = textArea. 
     int endOffset = textArea.viewToModel(new Point(textArea.getSize().width, view.y)); 
     textArea.getHighlighter().addHighlight(startOffset, endOffset, new DefaultHighlighter.DefaultHighlightPainter(Color.YELLOW)); 
    } 
} 

с тем же результатом для JTextPane

import java.awt.*; 
import javax.swing.*; 
import javax.swing.text.*; 

public class TextPaneHighlighting extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private Highlighter.HighlightPainter cyanPainter; 
    private Highlighter.HighlightPainter redPainter; 

    public TextPaneHighlighting() { 
     UIManager.put("TextPane.selectionBackground", Color.yellow); 
     UIManager.put("TextPane.selectionForeground", Color.red); 
     JTextPane textPane = new JTextPane(); 
     textPane.setText("one\ntwo\nthree\nfour\nfive\nsix\nseven\neight\n"); 
     JScrollPane scrollPane = new JScrollPane(textPane); 
     getContentPane().add(scrollPane);// Highlight some text 
     cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.cyan); 
     redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.red); 
     try { 
      textPane.getHighlighter().addHighlight(0, 3, DefaultHighlighter.DefaultPainter); 
      textPane.getHighlighter().addHighlight(8, 14, cyanPainter); 
      textPane.getHighlighter().addHighlight(19, 24, redPainter); 
     } catch (BadLocationException ble) { 
     } 
    } 

    public static void main(String[] args) { 
     TextPaneHighlighting frame = new TextPaneHighlighting(); 
     frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
     frame.setSize(300, 200); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

Почему бы не использовать setSelectionColor и setSelectedTextColor изменить цвета, поскольку они доступны? –

+0

Спасибо! В принципе, у вас и Гийома есть одно и то же решение - DefaultHighlightPainter (Цвет. XXX). – AnneS

19

Вы можете добиться этого, хотя и не напрямую, так как вам нужно сохранить ссылку на Highlight, добавленную вами к указанной строке, поэтому вам нужно пройти через все основные моменты, чтобы удалить тот, который вы хотите, взгляните на программа прилагается, может быть, это поможет вам достичь того, что вам так хочется:

Последней EDIT: НОВЫЙ КОД, REMOVED НЕКОТОРЫХ ОШИБОК И походит ДОБАВЛЕНО желаемые ФУНКЦИОНАЛЬНЫЕ СВЯЗИ с УСТАНОВКОЙ CARET ПОЗИЦИИ

import java.awt.*; 
import java.awt.event.*; 
import java.util.Map; 
import java.util.HashMap; 
import javax.swing.*; 
import javax.swing.text.*; 

public class TextHighlight 
{ 
    private JTextArea tarea; 
    private JComboBox cbox; 
    private JTextField lineField; 
    private String[] colourNames = {"RED", "ORANGE", "CYAN"}; 

    private Highlighter.HighlightPainter redPainter; 
    private Highlighter.HighlightPainter orangePainter; 
    private Highlighter.HighlightPainter cyanPainter; 

    private int firstUpdateIndex; 
    private int counter; 

    private Map<Integer, Highlighter.Highlight> highlights = new HashMap<Integer, Highlighter.Highlight>(); 

    public TextHighlight() 
    { 
     redPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.RED); 
     orangePainter = new DefaultHighlighter.DefaultHighlightPainter(Color.ORANGE); 
     cyanPainter = new DefaultHighlighter.DefaultHighlightPainter(Color.CYAN); 

     firstUpdateIndex = -1; 
     counter = 0; 
    } 

    private void createAndDisplayGUI() 
    { 
     final JFrame frame = new JFrame("Text HIGHLIGHT"); 
     frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 

     JPanel contentPane = new JPanel(); 
     contentPane.setBorder(BorderFactory.createTitledBorder(
       BorderFactory.createEmptyBorder(5, 5, 5, 5), "Highlighter JTextArea")); 

     tarea = new JTextArea(10, 10); 
     JScrollPane scrollPane = new JScrollPane(tarea); 
     contentPane.add(scrollPane); 

     JButton remHighButton = new JButton("REMOVE HIGHLIGHT"); 
     remHighButton.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       String input = JOptionPane.showInputDialog(frame, "Please Enter Start Index : " 
                 , "Highlighting Options : " 
                 , JOptionPane.PLAIN_MESSAGE); 

       if (input != null && (highlights.size() > 0)) 
       {    
        int startIndex = Integer.parseInt(input.trim()); 
        Highlighter highlighter = tarea.getHighlighter(); 
        highlighter.removeHighlight(highlights.get(startIndex)); 
        tarea.setCaretPosition(startIndex); 
        tarea.requestFocusInWindow(); 
        highlights.remove(startIndex); 
       } 
      } 
     }); 

     JButton button = new JButton("HIGHLIGHT TEXT"); 
     button.addActionListener(new ActionListener() 
     { 
      public void actionPerformed(ActionEvent ae) 
      { 
       String text = null; 
       text = tarea.getSelectedText(); 
       if (text != null && text.length() > 0) 
       { 
        int startIndex = tarea.getText().indexOf(text); 
        int endIndex = startIndex + text.length(); 
        Highlighter highlighter = tarea.getHighlighter(); 

        int selection = JOptionPane.showConfirmDialog(
              frame, getOptionPanel(), "Highlight Colour : " 
               , JOptionPane.OK_CANCEL_OPTION 
               , JOptionPane.PLAIN_MESSAGE); 

        System.out.println("TEXT : " + text); 
        System.out.println("START INDEX : " + startIndex); 
        System.out.println("END INDEX : " + endIndex); 

        if (selection == JOptionPane.OK_OPTION) 
        { 
         String colour = (String) cbox.getSelectedItem(); 
         try 
         { 
          if (colour == colourNames[0]) 
          { 
           System.out.println("Colour Selected : " + colour); 
           highlighter.addHighlight(startIndex, endIndex, redPainter); 
          } 
          else if (colour == colourNames[1]) 
          { 
           System.out.println("Colour Selected : " + colour); 
           highlighter.addHighlight(startIndex, endIndex, orangePainter); 
          } 
          else if (colour == colourNames[2]) 
          { 
           System.out.println("Colour Selected : " + colour); 
           highlighter.addHighlight(startIndex, endIndex, cyanPainter); 
          } 
          Highlighter.Highlight[] highlightIndex = highlighter.getHighlights(); 
          System.out.println("Lengh of Highlights used : " + highlightIndex.length); 
          highlights.put(startIndex, highlightIndex[highlightIndex.length - 1]); 
         } 
         catch(BadLocationException ble) 
         { 
          ble.printStackTrace(); 
         } 
        } 
        else if (selection == JOptionPane.CANCEL_OPTION) 
        { 
         System.out.println("CANCEL BUTTON PRESSED."); 
        } 
        else if (selection == JOptionPane.CLOSED_OPTION) 
        { 
         System.out.println("JOPTIONPANE CLOSED DELIBERATELY."); 
        }     
       } 
      } 
     }); 

     frame.add(remHighButton, BorderLayout.PAGE_START); 
     frame.add(contentPane, BorderLayout.CENTER); 
     frame.add(button, BorderLayout.PAGE_END); 

     frame.pack(); 
     frame.setLocationByPlatform(true); 
     frame.setVisible(true); 
    } 

    private JPanel getOptionPanel() 
    { 
     JPanel panel = new JPanel(); 
     panel.setBorder(BorderFactory.createTitledBorder(
         BorderFactory.createLineBorder(Color.DARK_GRAY, 2), "COLOUR SELECTION")); 
     panel.setLayout(new GridLayout(0, 2, 5, 5)); 

     JLabel colourLabel = new JLabel("Select One Colour : "); 
     cbox = new JComboBox(colourNames); 

     panel.add(colourLabel); 
     panel.add(cbox); 

     return panel; 
    } 

    public static void main(String... args) 
    { 
     SwingUtilities.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new TextHighlight().createAndDisplayGUI(); 
      } 
     }); 
    } 
} 

ВЫХОД:

НАЧАТЬ:AT START

ВЫСВЕТИТЬ FIRST LINEFIRST LINEВТОРОЙSECOND LINE

Удалены ВЫСВЕТИТЬAFTER

Подчеркивая одной линии с разной цветовойHIGHLIGHT AGAIN

последняя правка в строках с кодом SAMPLE в ВОПРОСЕ

import java.awt.*; 
import java.net.MalformedURLException; 

import javax.swing.*; 
import javax.swing.text.*; 

public class Test { 
    public static void main(final String[] args) throws MalformedURLException { 
     SwingUtilities.invokeLater(new Runnable() { 

     @Override 
     public void run() { 
      try { 
       init(); 
      } catch (BadLocationException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } 

     } 
    }); 
} 

private static void init() throws BadLocationException { 
    JFrame frame = new JFrame(); 
    final JTextArea textArea = new JTextArea(); 
    JScrollPane pane = new JScrollPane(textArea); 
    textArea.setText("Something. Something else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Samething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sbmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Scmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sdmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Semething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sfmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nSomething. Sgmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla\nBlabla\n"); 
    textArea.setSelectionColor(Color.RED); 
    frame.add(pane); 
    frame.setSize(300, 120); 
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
    frame.setVisible(true); 

    String turnToString2 = "Sdmething else.\nA second line\na third line" 
      + "Blabla\nBlabla\nBlabla\nBlabla\nBlabla"; 
    int pos2 = textArea.getText().indexOf(turnToString2); 
    Rectangle startIndex = textArea.modelToView(pos2); 
    textArea.getHighlighter().addHighlight(pos2, 
      pos2 + turnToString2.length(), 
      new DefaultHighlighter.DefaultHighlightPainter(Color.yellow));  
    int y = startIndex.y + (pane.getHeight() - 10); 
    System.out.println("Pane Height : " + pane.getHeight()); 
    System.out.println("X : " + startIndex.x); 
    System.out.println("Y : " + y); 
    System.out.println("Y (pos2) : " + startIndex.y); 
    textArea.setCaretPosition(textArea.viewToModel(new Point(startIndex.x, y))); 
    pane.scrollRectToVisible(new Rectangle(startIndex.x, y)); 
    } 
} 

Вот ВЫВОД:

TOP RIGHT

+0

Большое спасибо за ваш пример! Я изучаю sth .. Однако у вас есть решение для моей проблемы 2? В частности, предположим, что у меня есть много строк, которые требуют, чтобы scrollPane генерировала полосу прокрутки автоматически. Если я выделил одну строку, я хочу, чтобы первая строка, появившаяся в окне, была выделенной. Я использую: windowText.setCaretPosition (pos); где pos - индекс подстроки подчёркивания. Но это не сработало. Линия подсветки появится в конце этого окна. – AnneS

+0

Эта вещь немного сложная, для меня, по крайней мере, потому что, если я сделаю свои изменения, я смогу перенести курсор в первое редактирование, не касаясь JScrollPane, с помощью мыши или что-то еще, но если я вручную изменю положение JScrollPane, тогда он никогда не перемещается автоматически :(, глядя в эту штуку –

+0

@nlcE cOw Спасибо. Я не меняю позицию вручную. Я просто привязываю эту Textarea к другой панели. Поэтому, когда я нажимаю на какую-то строку, мне нужна такая же строка подчеркнутый в этом TextArea, поэтому мне нужна Caret, чтобы линии подсветки отображались вверху, а не только просто показано в окне, что недостаточно. Не имеет смысла, что SetCaretPosition (Position) не работает. должен привести линию позиционирования к вершине .... – AnneS

3

Для решения 2) Используйте modelToView, чтобы получить точку первой выбранной строки. Затем используйте scrollRectToVisible, используя точку (ПРИМЕЧАНИЕ: высота прямоугольника должна быть высотой вашего просмотра).

+0

Я много слышал о modelToView, похоже, сегодня я прогуливаюсь прямо через него, чтобы очистить мои сомнения :-) +1 –

Смежные вопросы