text selection conflict between JTextPane and JTextField

后端 未结 4 539
-上瘾入骨i
-上瘾入骨i 2021-01-27 03:43

Why the text in JTextPane cannot be selected programmatically if there is a JTextField present? Has something to do with focus i think. Thx.

import java.awt.Flow         


        
4条回答
  •  悲哀的现实
    2021-01-27 04:21

    Just for fun (after all, it's Friday :-) I followed up Stanislav's comment, extending DefaultCaret to keep the selection visible for unfocused textComponents.

    The basic ideas

    • support two selection decorations: focused-selection, unfocused-selection
    • keep the appearance of the selection highlights as near to LAF default as possible, which boils down to re-using the selectionPainter (accessible only by ... cough, cough .. reflection)
    • fool super into believing that the selection is always visible

      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 

      */ @Override public void install(JTextComponent c) { super.install(c); installSelectionPainters(); setSelectionVisible(isSelectionVisible()); } /** * @inherited

      */ @Override public void setSelectionVisible(boolean vis) { focusedSelectionVisible = vis; super.setSelectionVisible(!isSelectionVisible()); super.setSelectionVisible(true); } /** * @inherited

      */ @Override protected HighlightPainter getSelectionPainter() { return focusedSelectionVisible ? focusedSelectionPainter : unfocusedSelectionPainter; } }

    Enjoy!

提交回复
热议问题