конфликт выделения текста между JTextPane и JTextField - PullRequest
1 голос
/ 05 мая 2011

Почему текст в JTextPane нельзя выделить программно, если присутствует JTextField? Я думаю, что-то связано с фокусом. Thx.

import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.beans.PropertyChangeListener;

import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JTextPane;
import javax.swing.KeyStroke;

public class align extends JFrame  {

    private align() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addPane(this, "one");
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        align t = new align();
    }

    private void addPane(JFrame frame, String name) {

        JPanel panel = new JPanel();
        panel.setLayout(new FlowLayout(FlowLayout.LEFT));
        // if the next line is disabled, then the text is JTextPane is correctly highlighted.,,
        panel.add(makeField("line1"));

        JTextPane p = new JTextPane();
        p.setText("abcdef");
        p.setSelectionStart(2);
        p.setSelectionEnd(4);
        p.setFocusable(true);
        p.requestFocus();
        p.requestDefaultFocus();
        panel.add(p);

        frame.getContentPane().add(panel);
    }

    private JComponent makeField(String name) {
        JTextField textArea = new JTextField();
        textArea.setText(name);
        textArea.setEditable(false);

        return textArea;
    }
}

EDIT:

Получил его, чтобы отобразить выделенный текст, запустив ключевое событие после того, как кадр был построен. Лучшим (более длинным) решением было бы иметь TextPane только для чтения с настраиваемым Highlighter и DocumentListener, который обновляет буфер обмена по Ctrl-C.

    Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(
            new KeyEvent(textPane, KeyEvent.KEY_PRESSED, System.currentTimeMillis(), 0, KeyEvent.VK_TAB));

Ответы [ 4 ]

3 голосов
/ 06 мая 2011

Просто для забавы (в конце концов, сегодня пятница :-) Я проследил за комментарием Станислава, расширив DefaultCaret, чтобы сохранить выделение для несфокусированных текстовых компонентов.

Основные идеи

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

    public static class WrappingCaret extends DefaultCaret {
    
        private DefaultCaret delegate;
        private HighlightPainter focusedSelectionPainter;
        private HighlightPainter unfocusedSelectionPainter;
        private boolean focusedSelectionVisible;
    
        public WrappingCaret(JTextComponent target) {
            installDelegate((DefaultCaret) target.getCaret());
            target.setCaret(this);
        }
    
        private void installDelegate(DefaultCaret delegate) {
            this.delegate = delegate;
            setBlinkRate(delegate.getBlinkRate());
        }
    
        private void installSelectionPainters() {
            if (delegate instanceof BasicCaret) {
                installDefaultPainters();
            } else {
                try {
                    Method method = delegate.getClass().getDeclaredMethod(
                            "getSelectionPainter");
                    method.setAccessible(true);
                    focusedSelectionPainter = (HighlightPainter) method
                            .invoke(delegate);
                    Constructor<?>[] constructors = focusedSelectionPainter
                            .getClass().getDeclaredConstructors();
                    constructors[0].setAccessible(true);
                    unfocusedSelectionPainter = (HighlightPainter) constructors[0]
                            .newInstance(getUnfocusedSelectionColor());
                } catch (Exception e) {
                    installDefaultPainters();
                }
            }
        }
    
        private Color getUnfocusedSelectionColor() {
            Color first = getComponent().getSelectionColor();
            // create a reasonable unfocusedSelectionColor
            return PaintUtils.setAlpha(first, 125);
        }
    
        private void installDefaultPainters() {
            focusedSelectionPainter = super.getSelectionPainter();
            unfocusedSelectionPainter = new DefaultHighlightPainter(
                    getUnfocusedSelectionColor());
        }
    
        /**
         * @inherited <p>
         */
        @Override
        public void install(JTextComponent c) {
            super.install(c);
            installSelectionPainters();
            setSelectionVisible(isSelectionVisible());
        }
    
        /**
         * @inherited <p>
         */
        @Override
        public void setSelectionVisible(boolean vis) {
            focusedSelectionVisible = vis;
            super.setSelectionVisible(!isSelectionVisible());
            super.setSelectionVisible(true);
        }
    
        /**
         * @inherited <p>
         */
        @Override
        protected HighlightPainter getSelectionPainter() {
            return focusedSelectionVisible ? focusedSelectionPainter
                    : unfocusedSelectionPainter;
        }
    
    }
    

Наслаждайтесь!

3 голосов
/ 05 мая 2011

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

Highlighter.HighlightPainter yellow = 
    new DefaultHighlighter.DefaultHighlightPainter( Color.YELLOW );

try
{
    textPane.getHighlighter().addHighlight(2, 4, yellow);
}
catch(BadLocationException ble) { System.out.println(ble); }
3 голосов
/ 06 мая 2011
p.getCaret().setSelectionVisible(true);
3 голосов
/ 05 мая 2011

Текст в JTextPane выбран . Проблема в том, что он не дает никакой визуальной индикации, если компонент не сфокусирован. Попробуйте открыть вкладку для компонента, как только появится GUI.


так, я должен выпустить это к сведению?

Нет, вам следует перепроектировать ваш сломанный графический интерфейс, который использует выделение текста для идентификации интересующего вас текста. Выбор текста - это нечто большее, чем должен делать конечный пользователь, а не приложение.

Учитывая, что JTextPane является компонентом, который поддерживает форматирование, возможно, сделайте текст полужирным или курсивом , например.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...